diff --git a/build.gradle b/build.gradle index cb72795b..489c2c40 100644 --- a/build.gradle +++ b/build.gradle @@ -107,7 +107,7 @@ loom { gametestClient { inherit client name "GameTest Client" - vmArg "-Dfabric-api.gametest.structures.output-dir=${file("src/gametest/resources/data/itematic/gametest/structure")}" + vmArg "-Ditematic.gametest.structure-output-directory=${file("src/gametest/resources/data")}" runDir "run" source sourceSets.gametest diff --git a/gradle.properties b/gradle.properties index dfad5f1c..8ced8aab 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,8 +3,8 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/develop - minecraft_version=1.21.3 - yarn_mappings=1.21.3+build.2 + minecraft_version=1.21.5 + yarn_mappings=1.21.5+build.1 loader_version=0.18.4 # Mod Properties @@ -13,4 +13,4 @@ org.gradle.jvmargs=-Xmx1G archives_base_name = itematic # Dependencies - fabric_version=0.114.1+1.21.3 + fabric_version=0.128.2+1.21.5 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a4b76b95..d997cfc6 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index bad7c246..dbc3ce4a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index f5feea6d..0262dcbd 100644 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -57,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/b631911858264c0b6e4d6603d677ff5218766cee/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -86,8 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -115,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -173,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -206,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 9d21a218..c4bdd3ab 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -70,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/src/client/java/net/errorcraft/itematic/access/client/gui/screen/GameModeSelectionScreenGameModeSelectionAccess.java b/src/client/java/net/errorcraft/itematic/access/client/gui/screen/GameModeSelectionScreenGameModeSelectionAccess.java deleted file mode 100644 index a5a02c6f..00000000 --- a/src/client/java/net/errorcraft/itematic/access/client/gui/screen/GameModeSelectionScreenGameModeSelectionAccess.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.errorcraft.itematic.access.client.gui.screen; - -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.registry.Registry; - -public interface GameModeSelectionScreenGameModeSelectionAccess { - default ItemStack itematic$icon(Registry registry) { - return ItemStack.EMPTY; - } -} diff --git a/src/client/java/net/errorcraft/itematic/access/client/gui/screen/GameModeSwitcherScreenAccess.java b/src/client/java/net/errorcraft/itematic/access/client/gui/screen/GameModeSwitcherScreenAccess.java new file mode 100644 index 00000000..3d0b218a --- /dev/null +++ b/src/client/java/net/errorcraft/itematic/access/client/gui/screen/GameModeSwitcherScreenAccess.java @@ -0,0 +1,15 @@ +package net.errorcraft.itematic.access.client.gui.screen; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; + +public interface GameModeSwitcherScreenAccess { + interface GameModeSelectionAccess { + default ItemStack itematic$icon(Registry registry) { + return ItemStack.EMPTY; + } + default void itematic$setIcon(RegistryKey item) {} + } +} diff --git a/src/client/java/net/errorcraft/itematic/client/item/ModelPredicateProviderWrapper.java b/src/client/java/net/errorcraft/itematic/client/item/ModelPredicateProviderWrapper.java deleted file mode 100644 index 075bf479..00000000 --- a/src/client/java/net/errorcraft/itematic/client/item/ModelPredicateProviderWrapper.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.errorcraft.itematic.client.item; - -import net.errorcraft.itematic.item.model.override.ModelOverride; -import net.minecraft.client.item.ModelPredicateProvider; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import org.jetbrains.annotations.Nullable; - -@SuppressWarnings("deprecation") -public record ModelPredicateProviderWrapper(ModelOverride override) implements ModelPredicateProvider { - @Override - public float call(ItemStack stack, @Nullable ClientWorld world, @Nullable LivingEntity entity, int seed) { - return this.override.apply(stack, world, entity, seed); - } -} diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/color/item/ItemColorsExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/color/item/ItemColorsExtender.java deleted file mode 100644 index 42380574..00000000 --- a/src/client/java/net/errorcraft/itematic/mixin/client/color/item/ItemColorsExtender.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.errorcraft.itematic.mixin.client.color.item; - -import net.errorcraft.itematic.item.color.ItemColor; -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.component.components.TintedItemComponent; -import net.minecraft.client.color.item.ItemColors; -import net.minecraft.item.ItemStack; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; - -@Mixin(ItemColors.class) -public class ItemColorsExtender { - /** - * @author ErrorCraft - * @reason Uses the ItemComponent implementation for data-driven items. - */ - @Overwrite - public int getColor(ItemStack item, int tintIndex) { - return item.itematic$getBehavior(ItemComponentTypes.TINTED) - .map(TintedItemComponent::tint) - .map(c -> c.color(item, tintIndex)) - .orElse(ItemColor.DEFAULT_COLOR); - } -} diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/gui/DrawContextExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/gui/DrawContextExtender.java index ba041388..13ffbb85 100644 --- a/src/client/java/net/errorcraft/itematic/mixin/client/gui/DrawContextExtender.java +++ b/src/client/java/net/errorcraft/itematic/mixin/client/gui/DrawContextExtender.java @@ -10,9 +10,7 @@ import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.registry.tag.TagKey; import net.minecraft.util.Identifier; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -46,17 +44,6 @@ private void setItemBarStyles(MinecraftClient client, MatrixStack matrices, Vert this.itemBarStyles = ((MinecraftClientAccess) client).itematic$itemBarStyles(); } - @Redirect( - method = "drawItem(Lnet/minecraft/entity/LivingEntity;Lnet/minecraft/world/World;Lnet/minecraft/item/ItemStack;IIII)V", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isIn(Lnet/minecraft/registry/tag/TagKey;)Z" - ) - ) - private boolean isInForBundlesReturnFalse(ItemStack instance, TagKey tag) { - return false; - } - @ModifyExpressionValue( method = "drawItemBar", at = @At( diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/GameModeSelectionScreenExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/GameModeSwitcherScreenExtender.java similarity index 66% rename from src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/GameModeSelectionScreenExtender.java rename to src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/GameModeSwitcherScreenExtender.java index 41f2183b..52617d07 100644 --- a/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/GameModeSelectionScreenExtender.java +++ b/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/GameModeSwitcherScreenExtender.java @@ -1,11 +1,11 @@ package net.errorcraft.itematic.mixin.client.gui.screen; -import net.errorcraft.itematic.access.client.gui.screen.GameModeSelectionScreenGameModeSelectionAccess; +import net.errorcraft.itematic.access.client.gui.screen.GameModeSwitcherScreenAccess; import net.errorcraft.itematic.item.ItemKeys; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.GameModeSelectionScreen; +import net.minecraft.client.gui.screen.GameModeSwitcherScreen; import net.minecraft.item.Item; import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; @@ -20,52 +20,53 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -public class GameModeSelectionScreenExtender { - @Mixin(GameModeSelectionScreen.ButtonWidget.class) +public class GameModeSwitcherScreenExtender { + @Mixin(GameModeSwitcherScreen.ButtonWidget.class) public static class ButtonWidgetExtender { @Redirect( method = "renderWidget", at = @At( value = "INVOKE", - target = "Lnet/minecraft/client/gui/screen/GameModeSelectionScreen$GameModeSelection;renderIcon(Lnet/minecraft/client/gui/DrawContext;II)V" + target = "Lnet/minecraft/client/gui/screen/GameModeSwitcherScreen$GameModeSelection;renderIcon(Lnet/minecraft/client/gui/DrawContext;II)V" ) ) - private void renderIconUseRegistryEntry(GameModeSelectionScreen.GameModeSelection instance, DrawContext context, int x, int y) { + private void renderIconUseRegistryEntry(GameModeSwitcherScreen.GameModeSelection instance, DrawContext context, int x, int y) { World world = MinecraftClient.getInstance().world; if (world == null) { return; } + ItemStack stack = instance.itematic$icon(world.getRegistryManager().getOrThrow(RegistryKeys.ITEM)); context.drawItem(stack, x, y); } } - @Mixin(GameModeSelectionScreen.GameModeSelection.class) - public static class GameModeSelectionExtender implements GameModeSelectionScreenGameModeSelectionAccess { - @Final + @Mixin(GameModeSwitcherScreen.GameModeSelection.class) + public static class GameModeSelectionExtender implements GameModeSwitcherScreenAccess.GameModeSelectionAccess { @Shadow - public static GameModeSelectionScreen.GameModeSelection CREATIVE; - @Final - @Shadow - public static GameModeSelectionScreen.GameModeSelection SURVIVAL; + public static GameModeSwitcherScreen.GameModeSelection CREATIVE; - @Final @Shadow - public static GameModeSelectionScreen.GameModeSelection ADVENTURE; + @Final + public static GameModeSwitcherScreen.GameModeSelection SURVIVAL; + @Shadow @Final + public static GameModeSwitcherScreen.GameModeSelection ADVENTURE; + @Shadow - public static GameModeSelectionScreen.GameModeSelection SPECTATOR; + @Final + public static GameModeSwitcherScreen.GameModeSelection SPECTATOR; @Unique private RegistryKey icon; static { - ((GameModeSelectionExtender)(Object) CREATIVE).icon = ItemKeys.GRASS_BLOCK; - ((GameModeSelectionExtender)(Object) SURVIVAL).icon = ItemKeys.IRON_SWORD; - ((GameModeSelectionExtender)(Object) ADVENTURE).icon = ItemKeys.MAP; - ((GameModeSelectionExtender)(Object) SPECTATOR).icon = ItemKeys.ENDER_EYE; + CREATIVE.itematic$setIcon(ItemKeys.GRASS_BLOCK); + SURVIVAL.itematic$setIcon(ItemKeys.IRON_SWORD); + ADVENTURE.itematic$setIcon(ItemKeys.MAP); + SPECTATOR.itematic$setIcon(ItemKeys.ENDER_EYE); } @Redirect( @@ -84,9 +85,15 @@ private static ItemStack newItemStackReturnEmptyStack(ItemConvertible item) { if (this.icon == null) { return ItemStack.EMPTY; } + return registry.getOptional(this.icon) .map(ItemStack::new) .orElse(ItemStack.EMPTY); } + + @Override + public void itematic$setIcon(RegistryKey icon) { + this.icon = icon; + } } } diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/ingame/SmithingScreenExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/ingame/SmithingScreenExtender.java index 2c5d00de..ddc61d1b 100644 --- a/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/ingame/SmithingScreenExtender.java +++ b/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/ingame/SmithingScreenExtender.java @@ -6,7 +6,7 @@ import com.llamalad7.mixinextras.sugar.Share; import com.llamalad7.mixinextras.sugar.ref.LocalRef; import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.component.components.SmithingTemplateItemComponent; +import net.errorcraft.itematic.item.component.components.SmithingTemplateProviderItemComponent; import net.errorcraft.itematic.item.smithing.template.SmithingTemplate; import net.minecraft.client.gui.screen.ingame.ForgingScreen; import net.minecraft.client.gui.screen.ingame.SmithingScreen; @@ -16,7 +16,6 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.SmithingTemplateItem; -import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.screen.SmithingScreenHandler; import net.minecraft.text.Text; import net.minecraft.util.Identifier; @@ -44,9 +43,8 @@ public SmithingScreenExtender(SmithingScreenHandler handler, PlayerInventory pla private void storeSmithingTemplate(CallbackInfo info, @Share("smithingTemplate") LocalRef> smithingTemplate) { smithingTemplate.set(this.handler.getSlot(0) .getStack() - .itematic$getBehavior(ItemComponentTypes.SMITHING_TEMPLATE) - .map(SmithingTemplateItemComponent::template) - .map(RegistryEntry::value) + .itematic$getBehavior(ItemComponentTypes.SMITHING_TEMPLATE_PROVIDER) + .map(SmithingTemplateProviderItemComponent::template) ); } @@ -97,9 +95,8 @@ private Object checkPresenceEquipmentBehavior(ItemStack instance, ComponentType< ) ) private boolean instanceOfSmithingTemplateItemUseItemComponentCheck(Object reference, Class clazz, @Local(ordinal = 0) ItemStack itemStack, @Share("smithingTemplate") LocalRef smithingTemplate) { - Optional optionalSmithingTemplate = itemStack.itematic$getBehavior(ItemComponentTypes.SMITHING_TEMPLATE) - .map(SmithingTemplateItemComponent::template) - .map(RegistryEntry::value); + Optional optionalSmithingTemplate = itemStack.itematic$getBehavior(ItemComponentTypes.SMITHING_TEMPLATE_PROVIDER) + .map(SmithingTemplateProviderItemComponent::template); optionalSmithingTemplate.ifPresent(smithingTemplate::set); return optionalSmithingTemplate.isPresent(); } diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/network/ClientPlayerInteractionManagerExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/network/ClientPlayerInteractionManagerExtender.java deleted file mode 100644 index b082d966..00000000 --- a/src/client/java/net/errorcraft/itematic/mixin/client/network/ClientPlayerInteractionManagerExtender.java +++ /dev/null @@ -1,33 +0,0 @@ -package net.errorcraft.itematic.mixin.client.network; - -import net.minecraft.block.BlockState; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -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.Redirect; - -@Mixin(ClientPlayerInteractionManager.class) -public class ClientPlayerInteractionManagerExtender { - @Shadow - @Final - private MinecraftClient client; - - @Redirect( - method = "breakBlock", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/Item;canMine(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/player/PlayerEntity;)Z" - ) - ) - @SuppressWarnings("ConstantConditions") - private boolean breakBlockCanMineUseItemStackVersion(Item instance, BlockState state, World world, BlockPos pos, PlayerEntity miner) { - return this.client.player.getMainHandStack().itematic$canMine(state, world, pos, miner); - } -} diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/render/block/BlockRenderManagerExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/render/block/BlockRenderManagerExtender.java deleted file mode 100644 index 1dd50523..00000000 --- a/src/client/java/net/errorcraft/itematic/mixin/client/render/block/BlockRenderManagerExtender.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.errorcraft.itematic.mixin.client.render.block; - -import net.minecraft.block.BlockState; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.block.BlockRenderManager; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.item.ItemConvertible; -import net.minecraft.item.ItemStack; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(BlockRenderManager.class) -public class BlockRenderManagerExtender { - @Redirect( - method = "renderBlockAsEntity", - at = @At( - value = "NEW", - target = "(Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/item/ItemStack;" - ) - ) - private ItemStack newItemStackUseCreateStack(ItemConvertible item, BlockState state) { - ClientWorld world = MinecraftClient.getInstance().world; - if (world == null) { - return ItemStack.EMPTY; - } - return world.itematic$createStack(state.getBlock().itematic$asItemKey()); - } -} diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/model/SkeletonEntityModelExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/AbstractSkeletonEntityRendererExtender.java similarity index 52% rename from src/client/java/net/errorcraft/itematic/mixin/client/render/entity/model/SkeletonEntityModelExtender.java rename to src/client/java/net/errorcraft/itematic/mixin/client/render/entity/AbstractSkeletonEntityRendererExtender.java index 85e32b2a..ad48caca 100644 --- a/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/model/SkeletonEntityModelExtender.java +++ b/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/AbstractSkeletonEntityRendererExtender.java @@ -1,20 +1,17 @@ -package net.errorcraft.itematic.mixin.client.render.entity.model; +package net.errorcraft.itematic.mixin.client.render.entity; import net.errorcraft.itematic.item.ItemKeys; -import net.minecraft.client.render.entity.model.SkeletonEntityModel; +import net.minecraft.client.render.entity.AbstractSkeletonEntityRenderer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(SkeletonEntityModel.class) -public class SkeletonEntityModelExtender { +@Mixin(AbstractSkeletonEntityRenderer.class) +public class AbstractSkeletonEntityRendererExtender { @Redirect( - method = { - "getArmPose(Lnet/minecraft/client/render/entity/state/SkeletonEntityRenderState;Lnet/minecraft/util/Arm;)Lnet/minecraft/client/render/entity/model/BipedEntityModel$ArmPose;", - "setAngles(Lnet/minecraft/client/render/entity/state/SkeletonEntityRenderState;)V" - }, + method = "updateRenderState(Lnet/minecraft/entity/mob/AbstractSkeletonEntity;Lnet/minecraft/client/render/entity/state/SkeletonEntityRenderState;F)V", at = @At( value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/model/DrownedEntityModelExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/DrownedEntityRendererExtender.java similarity index 59% rename from src/client/java/net/errorcraft/itematic/mixin/client/render/entity/model/DrownedEntityModelExtender.java rename to src/client/java/net/errorcraft/itematic/mixin/client/render/entity/DrownedEntityRendererExtender.java index b915bdda..cea5c190 100644 --- a/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/model/DrownedEntityModelExtender.java +++ b/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/DrownedEntityRendererExtender.java @@ -1,17 +1,17 @@ -package net.errorcraft.itematic.mixin.client.render.entity.model; +package net.errorcraft.itematic.mixin.client.render.entity; import net.errorcraft.itematic.item.ItemKeys; -import net.minecraft.client.render.entity.model.DrownedEntityModel; +import net.minecraft.client.render.entity.DrownedEntityRenderer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(DrownedEntityModel.class) -public class DrownedEntityModelExtender { +@Mixin(DrownedEntityRenderer.class) +public class DrownedEntityRendererExtender { @Redirect( - method = "getArmPose(Lnet/minecraft/client/render/entity/state/ZombieEntityRenderState;Lnet/minecraft/util/Arm;)Lnet/minecraft/client/render/entity/model/BipedEntityModel$ArmPose;", + method = "getArmPose(Lnet/minecraft/entity/mob/DrownedEntity;Lnet/minecraft/util/Arm;)Lnet/minecraft/client/render/entity/model/BipedEntityModel$ArmPose;", at = @At( value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/FishingBobberEntityRendererExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/FishingBobberEntityRendererExtender.java deleted file mode 100644 index a6b98961..00000000 --- a/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/FishingBobberEntityRendererExtender.java +++ /dev/null @@ -1,23 +0,0 @@ -package net.errorcraft.itematic.mixin.client.render.entity; - -import net.errorcraft.itematic.item.ItemKeys; -import net.minecraft.client.render.entity.FishingBobberEntityRenderer; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(FishingBobberEntityRenderer.class) -public class FishingBobberEntityRendererExtender { - @Redirect( - method = "getHandPos", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" - ) - ) - private boolean isOfForFishingRodUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.FISHING_ROD); - } -} diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/PlayerEntityRendererExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/PlayerEntityRendererExtender.java index bcc3a501..b9f2f5a5 100644 --- a/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/PlayerEntityRendererExtender.java +++ b/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/PlayerEntityRendererExtender.java @@ -13,7 +13,7 @@ @Mixin(PlayerEntityRenderer.class) public class PlayerEntityRendererExtender { @Redirect( - method = "updateHandState", + method = "getArmPose(Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/item/ItemStack;Lnet/minecraft/util/Hand;)Lnet/minecraft/client/render/entity/model/BipedEntityModel$ArmPose;", at = @At( value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" @@ -25,4 +25,15 @@ private static boolean isOfForCrossbowUseItemComponent(ItemStack instance, Item .filter(method -> method.type() == ShooterMethodTypes.CHARGEABLE) .isPresent(); } + + @Redirect( + method = "updateRenderState(Lnet/minecraft/client/network/AbstractClientPlayerEntity;Lnet/minecraft/client/render/entity/state/PlayerEntityRenderState;F)V", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" + ) + ) + private static boolean isOfForSpyglassUseItemComponentCheck(ItemStack instance, Item item) { + return instance.itematic$hasBehavior(ItemComponentTypes.ZOOM); + } } diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/render/feature/WitchHeldItemFeatureRendererExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/WitchEntityRendererExtender.java similarity index 57% rename from src/client/java/net/errorcraft/itematic/mixin/client/render/feature/WitchHeldItemFeatureRendererExtender.java rename to src/client/java/net/errorcraft/itematic/mixin/client/render/entity/WitchEntityRendererExtender.java index 76681564..615b79b5 100644 --- a/src/client/java/net/errorcraft/itematic/mixin/client/render/feature/WitchHeldItemFeatureRendererExtender.java +++ b/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/WitchEntityRendererExtender.java @@ -1,17 +1,17 @@ -package net.errorcraft.itematic.mixin.client.render.feature; +package net.errorcraft.itematic.mixin.client.render.entity; import net.errorcraft.itematic.item.ItemKeys; -import net.minecraft.client.render.entity.feature.WitchHeldItemFeatureRenderer; +import net.minecraft.client.render.entity.WitchEntityRenderer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(WitchHeldItemFeatureRenderer.class) -public class WitchHeldItemFeatureRendererExtender { +@Mixin(WitchEntityRenderer.class) +public class WitchEntityRendererExtender { @Redirect( - method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/state/WitchEntityRenderState;FF)V", + method = "updateRenderState(Lnet/minecraft/entity/mob/WitchEntity;Lnet/minecraft/client/render/entity/state/WitchEntityRenderState;F)V", at = @At( value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/feature/CapeFeatureRendererExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/feature/CapeFeatureRendererExtender.java index b8a743f6..eae4daa3 100644 --- a/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/feature/CapeFeatureRendererExtender.java +++ b/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/feature/CapeFeatureRendererExtender.java @@ -1,9 +1,9 @@ package net.errorcraft.itematic.mixin.client.render.entity.feature; import net.errorcraft.itematic.item.component.ItemComponentTypes; +import net.minecraft.client.render.entity.equipment.EquipmentModel; import net.minecraft.client.render.entity.feature.CapeFeatureRenderer; import net.minecraft.item.ItemStack; -import net.minecraft.item.equipment.EquipmentModel; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/feature/HeadFeatureRendererExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/feature/HeadFeatureRendererExtender.java deleted file mode 100644 index 84527b02..00000000 --- a/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/feature/HeadFeatureRendererExtender.java +++ /dev/null @@ -1,60 +0,0 @@ -package net.errorcraft.itematic.mixin.client.render.entity.feature; - -import com.llamalad7.mixinextras.sugar.Local; -import com.llamalad7.mixinextras.sugar.Share; -import com.llamalad7.mixinextras.sugar.ref.LocalRef; -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.component.components.BlockItemComponent; -import net.minecraft.block.Block; -import net.minecraft.client.render.entity.feature.HeadFeatureRenderer; -import net.minecraft.item.BlockItem; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.*; - -import java.util.Optional; - -@Mixin(HeadFeatureRenderer.class) -public class HeadFeatureRendererExtender { - @ModifyConstant( - method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/state/LivingEntityRenderState;FF)V", - constant = @Constant( - classValue = BlockItem.class, - ordinal = 0 - ) - ) - private boolean instanceOfBlockItemUseItemComponentCheck(Object reference, Class clazz, @Local ItemStack itemStack, @Share("blockItemComponent") LocalRef blockItemComponent) { - Optional optionalComponent = itemStack.itematic$getBehavior(ItemComponentTypes.BLOCK); - optionalComponent.ifPresent(blockItemComponent::set); - return optionalComponent.isPresent(); - } - - @ModifyVariable( - method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/state/LivingEntityRenderState;FF)V", - at = @At( - value = "LOAD", - ordinal = 0 - ), - slice = @Slice( - from = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/render/entity/feature/HeadFeatureRenderer;getContextModel()Lnet/minecraft/client/render/entity/model/EntityModel;" - ) - ) - ) - private Item castToBlockItemUseNull(Item instance) { - return null; - } - - @Redirect( - method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/state/LivingEntityRenderState;FF)V", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/BlockItem;getBlock()Lnet/minecraft/block/Block;" - ) - ) - private Block getBlockUseItemComponent(BlockItem instance, @Share("blockItemComponent") LocalRef blockItemComponent) { - return blockItemComponent.get().block().defaultBlock().value(); - } -} diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/feature/HorseArmorFeatureRendererExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/feature/HorseArmorFeatureRendererExtender.java deleted file mode 100644 index 12ddeda3..00000000 --- a/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/feature/HorseArmorFeatureRendererExtender.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.errorcraft.itematic.mixin.client.render.entity.feature; - -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.feature.HorseArmorFeatureRenderer; -import net.minecraft.client.render.entity.state.HorseEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -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.CallbackInfo; - -@Mixin(HorseArmorFeatureRenderer.class) -public class HorseArmorFeatureRendererExtender { - @Inject( - method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/state/HorseEntityRenderState;FF)V", - at = @At("HEAD"), - cancellable = true - ) - private void checkPresenceEquipmentBehavior(MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, HorseEntityRenderState horseEntityRenderState, float f, float g, CallbackInfo info) { - if (!horseEntityRenderState.armor.itematic$hasBehavior(ItemComponentTypes.EQUIPMENT)) { - info.cancel(); - } - } -} diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/feature/PlayerHeldItemFeatureRendererExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/feature/PlayerHeldItemFeatureRendererExtender.java deleted file mode 100644 index f1083acc..00000000 --- a/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/feature/PlayerHeldItemFeatureRendererExtender.java +++ /dev/null @@ -1,23 +0,0 @@ -package net.errorcraft.itematic.mixin.client.render.entity.feature; - -import net.errorcraft.itematic.item.ItemKeys; -import net.minecraft.client.render.entity.feature.PlayerHeldItemFeatureRenderer; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(PlayerHeldItemFeatureRenderer.class) -public class PlayerHeldItemFeatureRendererExtender { - @Redirect( - method = "renderItem(Lnet/minecraft/client/render/entity/state/PlayerEntityRenderState;Lnet/minecraft/client/render/model/BakedModel;Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ModelTransformationMode;Lnet/minecraft/util/Arm;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" - ) - ) - private boolean isOfForSpyglassUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.SPYGLASS); - } -} diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/ItemEntityRendererExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/state/ItemStackEntityRenderStateExtender.java similarity index 70% rename from src/client/java/net/errorcraft/itematic/mixin/client/render/entity/ItemEntityRendererExtender.java rename to src/client/java/net/errorcraft/itematic/mixin/client/render/entity/state/ItemStackEntityRenderStateExtender.java index 333f9b91..aa4af3e8 100644 --- a/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/ItemEntityRendererExtender.java +++ b/src/client/java/net/errorcraft/itematic/mixin/client/render/entity/state/ItemStackEntityRenderStateExtender.java @@ -1,14 +1,14 @@ -package net.errorcraft.itematic.mixin.client.render.entity; +package net.errorcraft.itematic.mixin.client.render.entity.state; -import net.minecraft.client.render.entity.ItemEntityRenderer; +import net.minecraft.client.render.entity.state.ItemStackEntityRenderState; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(ItemEntityRenderer.class) -public class ItemEntityRendererExtender { +@Mixin(ItemStackEntityRenderState.class) +public class ItemStackEntityRenderStateExtender { @Redirect( method = "getSeed", at = @At( diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/render/item/BuiltinModelItemRendererExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/render/item/BuiltinModelItemRendererExtender.java deleted file mode 100644 index 1def2676..00000000 --- a/src/client/java/net/errorcraft/itematic/mixin/client/render/item/BuiltinModelItemRendererExtender.java +++ /dev/null @@ -1,110 +0,0 @@ -package net.errorcraft.itematic.mixin.client.render.item; - -import com.llamalad7.mixinextras.sugar.Local; -import com.llamalad7.mixinextras.sugar.Share; -import com.llamalad7.mixinextras.sugar.ref.LocalRef; -import net.errorcraft.itematic.item.ItemKeys; -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.component.components.BlockItemComponent; -import net.minecraft.block.Block; -import net.minecraft.block.ShulkerBoxBlock; -import net.minecraft.client.render.item.BuiltinModelItemRenderer; -import net.minecraft.item.BlockItem; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.util.DyeColor; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.*; - -import java.util.Optional; - -@Mixin(BuiltinModelItemRenderer.class) -public class BuiltinModelItemRendererExtender { - @ModifyConstant( - method = "render", - constant = @Constant( - classValue = BlockItem.class, - ordinal = 0 - ) - ) - private boolean instanceOfBlockItemUseItemComponentCheck(Object reference, Class clazz, @Local(argsOnly = true) ItemStack itemStack, @Share("blockItemComponent") LocalRef blockItemComponent) { - Optional optionalComponent = itemStack.itematic$getBehavior(ItemComponentTypes.BLOCK); - optionalComponent.ifPresent(blockItemComponent::set); - return optionalComponent.isPresent(); - } - - @ModifyVariable( - method = "render", - at = @At("LOAD"), - slice = @Slice( - to = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/BlockItem;getBlock()Lnet/minecraft/block/Block;" - ) - ) - ) - private Item castToBlockItemUseNull(Item instance) { - return null; - } - - @Redirect( - method = "render", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/BlockItem;getBlock()Lnet/minecraft/block/Block;" - ) - ) - private Block getBlockUseItemComponent(BlockItem instance, @Share("blockItemComponent") LocalRef blockItemComponent) { - return blockItemComponent.get() - .block() - .defaultBlock() - .value(); - } - - @Redirect( - method = "render", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/block/ShulkerBoxBlock;getColor(Lnet/minecraft/item/Item;)Lnet/minecraft/util/DyeColor;" - ) - ) - private DyeColor getColorUseInstanceMethod(Item item, @Local Block block) { - return ((ShulkerBoxBlock) block).getColor(); - } - - @Redirect( - method = "render", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z", - ordinal = 0 - ), - slice = @Slice( - from = @At( - value = "FIELD", - target = "Lnet/minecraft/item/Items;SHIELD:Lnet/minecraft/item/Item;" - ) - ) - ) - private boolean isOfForShieldUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.SHIELD); - } - - @Redirect( - method = "render", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z", - ordinal = 0 - ), - slice = @Slice( - from = @At( - value = "FIELD", - target = "Lnet/minecraft/item/Items;TRIDENT:Lnet/minecraft/item/Item;" - ) - ) - ) - private boolean isOfForTridentUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.TRIDENT); - } -} diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/render/item/HeldItemRendererExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/render/item/HeldItemRendererExtender.java index 8c196845..52048f3b 100644 --- a/src/client/java/net/errorcraft/itematic/mixin/client/render/item/HeldItemRendererExtender.java +++ b/src/client/java/net/errorcraft/itematic/mixin/client/render/item/HeldItemRendererExtender.java @@ -136,7 +136,7 @@ private int getUseTimeLeftForCrossbowUseNegatedUsedTicks(AbstractClientPlayerEnt slice = @Slice( from = @At( value = "INVOKE", - target = "Lnet/minecraft/client/render/item/HeldItemRenderer;renderItem(Lnet/minecraft/entity/LivingEntity;Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ModelTransformationMode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", + target = "Lnet/minecraft/client/render/item/HeldItemRenderer;renderItem(Lnet/minecraft/entity/LivingEntity;Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ItemDisplayContext;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", ordinal = 0 ) ) diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/render/item/ItemRendererExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/render/item/ItemRendererExtender.java deleted file mode 100644 index d0dc8765..00000000 --- a/src/client/java/net/errorcraft/itematic/mixin/client/render/item/ItemRendererExtender.java +++ /dev/null @@ -1,66 +0,0 @@ -package net.errorcraft.itematic.mixin.client.render.item; - -import net.errorcraft.itematic.item.ItemKeys; -import net.minecraft.client.render.item.ItemRenderer; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import org.objectweb.asm.Opcodes; -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(ItemRenderer.class) -public class ItemRendererExtender { - @Redirect( - method = { - "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ModelTransformationMode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;Z)V", - "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ModelTransformationMode;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;Z)V" - }, - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z", - ordinal = 0 - ), - slice = @Slice( - from = @At( - value = "FIELD", - target = "Lnet/minecraft/item/Items;TRIDENT:Lnet/minecraft/item/Item;", - opcode = Opcodes.GETSTATIC - ) - ) - ) - private boolean isOfForTridentUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.TRIDENT); - } - - @Redirect( - method = "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ModelTransformationMode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;Z)V", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z", - ordinal = 0 - ), - slice = @Slice( - from = @At( - value = "FIELD", - target = "Lnet/minecraft/item/Items;SPYGLASS:Lnet/minecraft/item/Item;", - opcode = Opcodes.GETSTATIC - ) - ) - ) - private boolean isOfForSpyglassUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.SPYGLASS); - } - - @Redirect( - method = "usesDynamicDisplay", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" - ) - ) - private static boolean isOfForClockUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.CLOCK); - } -} diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/render/item/property/select/ChargeTypePropertyExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/render/item/property/select/ChargeTypePropertyExtender.java new file mode 100644 index 00000000..897d5b6a --- /dev/null +++ b/src/client/java/net/errorcraft/itematic/mixin/client/render/item/property/select/ChargeTypePropertyExtender.java @@ -0,0 +1,23 @@ +package net.errorcraft.itematic.mixin.client.render.item.property.select; + +import net.errorcraft.itematic.item.ItemKeys; +import net.minecraft.client.render.item.property.select.ChargeTypeProperty; +import net.minecraft.component.type.ChargedProjectilesComponent; +import net.minecraft.item.Item; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(ChargeTypeProperty.class) +public class ChargeTypePropertyExtender { + @Redirect( + method = "getValue(Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/world/ClientWorld;Lnet/minecraft/entity/LivingEntity;ILnet/minecraft/item/ItemDisplayContext;)Lnet/minecraft/item/CrossbowItem$ChargeType;", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/component/type/ChargedProjectilesComponent;contains(Lnet/minecraft/item/Item;)Z" + ) + ) + private boolean containsForFireworkRocketUseRegistryKeyCheck(ChargedProjectilesComponent instance, Item item) { + return instance.itematic$contains(ItemKeys.FIREWORK_ROCKET); + } +} diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/render/model/json/ModelOverrideListExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/render/model/json/ModelOverrideListExtender.java deleted file mode 100644 index 42aebf4a..00000000 --- a/src/client/java/net/errorcraft/itematic/mixin/client/render/model/json/ModelOverrideListExtender.java +++ /dev/null @@ -1,38 +0,0 @@ -package net.errorcraft.itematic.mixin.client.render.model.json; - -import net.errorcraft.itematic.client.item.ModelPredicateProviderWrapper; -import net.errorcraft.itematic.item.model.override.ModelOverride; -import net.errorcraft.itematic.registry.ItematicRegistries; -import net.minecraft.client.item.ModelPredicateProvider; -import net.minecraft.client.render.model.json.ModelOverrideList; -import net.minecraft.item.ItemStack; -import net.minecraft.util.Identifier; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(ModelOverrideList.class) -public class ModelOverrideListExtender { - @Redirect( - method = "getModel", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/item/ModelPredicateProviderRegistry;get(Lnet/minecraft/item/ItemStack;Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/item/ModelPredicateProvider;" - ) - ) - @Nullable - @SuppressWarnings("deprecation") - private ModelPredicateProvider getModelOverrideUseRegistry(ItemStack stack, Identifier id) { - ModelOverride override = ItematicRegistries.MODEL_OVERRIDE.get(id); - if (override == null) { - return null; - } - - if (!override.isApplicable(stack)) { - return null; - } - - return new ModelPredicateProviderWrapper(override); - } -} diff --git a/src/client/resources/itematic.client.mixins.json b/src/client/resources/itematic.client.mixins.json index 6d3c8fd7..87426a16 100644 --- a/src/client/resources/itematic.client.mixins.json +++ b/src/client/resources/itematic.client.mixins.json @@ -7,14 +7,13 @@ }, "client": [ "MinecraftClientExtender", - "color.item.ItemColorsExtender", "gui.DrawContextExtender", "gui.hud.InGameHudExtender", "gui.screen.CustomizeFlatLevelScreenExtender", "gui.screen.CustomizeFlatLevelScreenExtender$SuperflatLayersListWidgetExtender", "gui.screen.CustomizeFlatLevelScreenExtender$SuperflatLayersListWidgetExtender$SuperflatLayerEntryExtender", - "gui.screen.GameModeSelectionScreenExtender$ButtonWidgetExtender", - "gui.screen.GameModeSelectionScreenExtender$GameModeSelectionExtender", + "gui.screen.GameModeSwitcherScreenExtender$ButtonWidgetExtender", + "gui.screen.GameModeSwitcherScreenExtender$GameModeSelectionExtender", "gui.screen.StatsScreenAccessor$ItemStatsListWidgetAccessor$EntryAccessor", "gui.screen.StatsScreenExtender", "gui.screen.StatsScreenExtender$ItemStatsListWidgetExtender", @@ -41,31 +40,23 @@ "gui.tooltip.TooltipComponentExtender", "network.AbstractClientPlayerEntityExtender", "network.ClientPlayerEntityExtender", - "network.ClientPlayerInteractionManagerExtender", "network.ClientPlayNetworkHandlerExtender", "option.HotbarStorageEntryExtender", "particle.CrackParticleExtender$SlimeballFactoryExtender", "particle.CrackParticleExtender$SnowballFactoryExtender", "recipebook.RecipeBookWidgetExtender$TabExtender", - "render.block.BlockRenderManagerExtender", "render.block.entity.DecoratedPotBlockEntityRendererExtender", - "render.entity.FishingBobberEntityRendererExtender", - "render.entity.ItemEntityRendererExtender", + "render.entity.AbstractSkeletonEntityRendererExtender", + "render.entity.DrownedEntityRendererExtender", "render.entity.PlayerEntityRendererExtender", + "render.entity.WitchEntityRendererExtender", "render.entity.feature.ArmorFeatureRendererExtender", "render.entity.feature.CapeFeatureRendererExtender", "render.entity.feature.ElytraFeatureRendererExtender", - "render.entity.feature.HeadFeatureRendererExtender", - "render.entity.feature.HorseArmorFeatureRendererExtender", - "render.entity.feature.PlayerHeldItemFeatureRendererExtender", "render.entity.feature.WolfArmorFeatureRendererExtender", - "render.entity.model.DrownedEntityModelExtender", - "render.entity.model.SkeletonEntityModelExtender", - "render.feature.WitchHeldItemFeatureRendererExtender", - "render.item.BuiltinModelItemRendererExtender", + "render.entity.state.ItemStackEntityRenderStateExtender", "render.item.HeldItemRendererExtender", - "render.item.ItemRendererExtender", - "render.model.json.ModelOverrideListExtender", + "render.item.property.select.ChargeTypePropertyExtender", "tutorial.CraftPlanksTutorialStepHandlerExtender", "world.ClientWorldExtender", "world.WorldEventHandlerExtender" diff --git a/src/datagen/java/net/errorcraft/itematic/data/ItematicData.java b/src/datagen/java/net/errorcraft/itematic/data/ItematicData.java index 0abd3367..5dfc3abb 100644 --- a/src/datagen/java/net/errorcraft/itematic/data/ItematicData.java +++ b/src/datagen/java/net/errorcraft/itematic/data/ItematicData.java @@ -29,7 +29,6 @@ public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { pack.addProvider(TradeTagProvider::new); pack.addProvider(ActionProvider::new); pack.addProvider(ActionTagProvider::new); - pack.addProvider(SmithingTemplateProvider::new); pack.addProvider(ModifiedRecipeProvider::new); pack.addProvider(PotionTagProvider::new); pack.addProvider(DispenseBehaviorProvider::new); diff --git a/src/datagen/java/net/errorcraft/itematic/data/recipe/brewing/BrewingRecipeBuilder.java b/src/datagen/java/net/errorcraft/itematic/data/recipe/brewing/BrewingRecipeBuilder.java index 90daa7bc..7d4dcf55 100644 --- a/src/datagen/java/net/errorcraft/itematic/data/recipe/brewing/BrewingRecipeBuilder.java +++ b/src/datagen/java/net/errorcraft/itematic/data/recipe/brewing/BrewingRecipeBuilder.java @@ -6,7 +6,7 @@ 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.data.recipe.RecipeExporter; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.predicate.item.ItemPredicate; diff --git a/src/datagen/java/net/errorcraft/itematic/data/server/ModifiedRecipeProvider.java b/src/datagen/java/net/errorcraft/itematic/data/server/ModifiedRecipeProvider.java index 46d4adf1..ef74cced 100644 --- a/src/datagen/java/net/errorcraft/itematic/data/server/ModifiedRecipeProvider.java +++ b/src/datagen/java/net/errorcraft/itematic/data/server/ModifiedRecipeProvider.java @@ -6,7 +6,7 @@ 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.data.recipe.CraftingRecipeJsonBuilder; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.recipe.*; diff --git a/src/datagen/java/net/errorcraft/itematic/data/server/RecipeProvider.java b/src/datagen/java/net/errorcraft/itematic/data/server/RecipeProvider.java index 8fd5b6b3..b6e0a3fd 100644 --- a/src/datagen/java/net/errorcraft/itematic/data/server/RecipeProvider.java +++ b/src/datagen/java/net/errorcraft/itematic/data/server/RecipeProvider.java @@ -7,8 +7,8 @@ import net.errorcraft.itematic.potion.PotionKeys; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; -import net.minecraft.data.server.recipe.RecipeExporter; -import net.minecraft.data.server.recipe.RecipeGenerator; +import net.minecraft.data.recipe.RecipeExporter; +import net.minecraft.data.recipe.RecipeGenerator; import net.minecraft.item.Item; import net.minecraft.potion.Potion; import net.minecraft.registry.RegistryEntryLookup; diff --git a/src/datagen/java/net/errorcraft/itematic/data/server/registry/SmithingTemplateProvider.java b/src/datagen/java/net/errorcraft/itematic/data/server/registry/SmithingTemplateProvider.java deleted file mode 100644 index c7fcc658..00000000 --- a/src/datagen/java/net/errorcraft/itematic/data/server/registry/SmithingTemplateProvider.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.errorcraft.itematic.data.server.registry; - -import net.errorcraft.itematic.registry.ItematicRegistryKeys; -import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; -import net.fabricmc.fabric.api.datagen.v1.provider.FabricDynamicRegistryProvider; -import net.minecraft.registry.RegistryWrapper; - -import java.util.concurrent.CompletableFuture; - -public class SmithingTemplateProvider extends FabricDynamicRegistryProvider { - public SmithingTemplateProvider(FabricDataOutput output, CompletableFuture registriesFuture) { - super(output, registriesFuture); - } - - @Override - protected void configure(RegistryWrapper.WrapperLookup registries, Entries entries) { - DynamicRegistryProviderUtil.addAll(entries, registries.getOrThrow(ItematicRegistryKeys.SMITHING_TEMPLATE)); - } - - @Override - public String getName() { - return "Smithing Templates"; - } -} 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 81b37760..8c2c9781 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 @@ -167,6 +167,20 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(ItemKeys.CHERRY_TRAPDOOR) .add(ItemKeys.CHERRY_PRESSURE_PLATE) .add(ItemKeys.CHERRY_BUTTON); + this.getOrCreateTagBuilder(ItematicItemTags.PALE_OAK_BUILDING_BLOCKS) + .add(ItemKeys.PALE_OAK_LOG) + .add(ItemKeys.PALE_OAK_WOOD) + .add(ItemKeys.STRIPPED_PALE_OAK_LOG) + .add(ItemKeys.STRIPPED_PALE_OAK_WOOD) + .add(ItemKeys.PALE_OAK_PLANKS) + .add(ItemKeys.PALE_OAK_STAIRS) + .add(ItemKeys.PALE_OAK_SLAB) + .add(ItemKeys.PALE_OAK_FENCE) + .add(ItemKeys.PALE_OAK_FENCE_GATE) + .add(ItemKeys.PALE_OAK_DOOR) + .add(ItemKeys.PALE_OAK_TRAPDOOR) + .add(ItemKeys.PALE_OAK_PRESSURE_PLATE) + .add(ItemKeys.PALE_OAK_BUTTON); this.getOrCreateTagBuilder(ItematicItemTags.BAMBOO_BUILDING_BLOCKS) .add(ItemKeys.BAMBOO_BLOCK) .add(ItemKeys.STRIPPED_BAMBOO_BLOCK) @@ -219,6 +233,7 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .addTag(ItematicItemTags.DARK_OAK_BUILDING_BLOCKS) .addTag(ItematicItemTags.MANGROVE_BUILDING_BLOCKS) .addTag(ItematicItemTags.CHERRY_BUILDING_BLOCKS) + .addTag(ItematicItemTags.PALE_OAK_BUILDING_BLOCKS) .addTag(ItematicItemTags.BAMBOO_BUILDING_BLOCKS) .addTag(ItematicItemTags.CRIMSON_BUILDING_BLOCKS) .addTag(ItematicItemTags.WARPED_BUILDING_BLOCKS); @@ -327,6 +342,12 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(ItemKeys.MUD_BRICK_STAIRS) .add(ItemKeys.MUD_BRICK_SLAB) .add(ItemKeys.MUD_BRICK_WALL); + this.getOrCreateTagBuilder(ItematicItemTags.RESIN_BRICK_BUILDING_BLOCKS) + .add(ItemKeys.RESIN_BRICKS) + .add(ItemKeys.RESIN_BRICK_STAIRS) + .add(ItemKeys.RESIN_BRICK_SLAB) + .add(ItemKeys.RESIN_BRICK_WALL) + .add(ItemKeys.CHISELED_RESIN_BRICKS); this.getOrCreateTagBuilder(ItematicItemTags.SANDSTONE_BUILDING_BLOCKS) .add(ItemKeys.SANDSTONE) .add(ItemKeys.SANDSTONE_STAIRS) @@ -437,6 +458,7 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .addTag(ItematicItemTags.BRICK_BUILDING_BLOCKS) .add(ItemKeys.PACKED_MUD) .addTag(ItematicItemTags.MUD_BRICK_BUILDING_BLOCKS) + .addTag(ItematicItemTags.RESIN_BRICK_BUILDING_BLOCKS) .addTag(ItematicItemTags.SANDSTONE_BUILDING_BLOCKS) .addTag(ItematicItemTags.SMOOTH_SANDSTONE_BUILDING_BLOCKS) .addTag(ItematicItemTags.CUT_SANDSTONE_BUILDING_BLOCKS) @@ -803,7 +825,10 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(ItemKeys.SNOW); this.getOrCreateTagBuilder(ItematicItemTags.MOSS_BLOCKS) .add(ItemKeys.MOSS_BLOCK) - .add(ItemKeys.MOSS_CARPET); + .add(ItemKeys.MOSS_CARPET) + .add(ItemKeys.PALE_MOSS_BLOCK) + .add(ItemKeys.PALE_MOSS_CARPET) + .add(ItemKeys.PALE_HANGING_MOSS); this.getOrCreateTagBuilder(ItematicItemTags.STONE_LIKE_BLOCKS) .add(ItemKeys.STONE) .add(ItemKeys.DEEPSLATE) @@ -864,6 +889,7 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(ItemKeys.MANGROVE_ROOTS) .add(ItemKeys.MUDDY_MANGROVE_ROOTS) .add(ItemKeys.CHERRY_LOG) + .add(ItemKeys.PALE_OAK_LOG) .add(ItemKeys.MUSHROOM_STEM) .add(ItemKeys.CRIMSON_STEM) .add(ItemKeys.WARPED_STEM); @@ -876,6 +902,7 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(ItemKeys.DARK_OAK_LEAVES) .add(ItemKeys.MANGROVE_LEAVES) .add(ItemKeys.CHERRY_LEAVES) + .add(ItemKeys.PALE_OAK_LEAVES) .add(ItemKeys.AZALEA_LEAVES) .add(ItemKeys.FLOWERING_AZALEA_LEAVES); this.getOrCreateTagBuilder(ItematicItemTags.MUSHROOM_LIKE_BLOCKS) @@ -892,7 +919,8 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(ItemKeys.ACACIA_SAPLING) .add(ItemKeys.DARK_OAK_SAPLING) .add(ItemKeys.MANGROVE_PROPAGULE) - .add(ItemKeys.CHERRY_SAPLING); + .add(ItemKeys.CHERRY_SAPLING) + .add(ItemKeys.PALE_OAK_SAPLING); this.getOrCreateTagBuilder(ItematicItemTags.PLANTS) .add(ItemKeys.AZALEA) .add(ItemKeys.FLOWERING_AZALEA) @@ -902,6 +930,8 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(ItemKeys.WARPED_FUNGUS) .add(ItemKeys.SHORT_GRASS) .add(ItemKeys.FERN) + .add(ItemKeys.SHORT_DRY_GRASS) + .add(ItemKeys.BUSH) .add(ItemKeys.DEAD_BUSH) .add(ItemKeys.DANDELION) .add(ItemKeys.POPPY) @@ -916,9 +946,15 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(ItemKeys.CORNFLOWER) .add(ItemKeys.LILY_OF_THE_VALLEY) .add(ItemKeys.TORCHFLOWER) + .add(ItemKeys.CACTUS_FLOWER) + .add(ItemKeys.CLOSED_EYEBLOSSOM) + .add(ItemKeys.OPEN_EYEBLOSSOM) .add(ItemKeys.WITHER_ROSE) .add(ItemKeys.PINK_PETALS) + .add(ItemKeys.WILDFLOWERS) + .add(ItemKeys.LEAF_LITTER) .add(ItemKeys.SPORE_BLOSSOM) + .add(ItemKeys.FIREFLY_BUSH) .add(ItemKeys.BAMBOO) .add(ItemKeys.SUGAR_CANE) .add(ItemKeys.CACTUS) @@ -930,6 +966,7 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(ItemKeys.VINE) .add(ItemKeys.TALL_GRASS) .add(ItemKeys.LARGE_FERN) + .add(ItemKeys.TALL_DRY_GRASS) .add(ItemKeys.SUNFLOWER) .add(ItemKeys.LILAC) .add(ItemKeys.ROSE_BUSH) @@ -1054,6 +1091,8 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(ItemKeys.MANGROVE_HANGING_SIGN) .add(ItemKeys.CHERRY_SIGN) .add(ItemKeys.CHERRY_HANGING_SIGN) + .add(ItemKeys.PALE_OAK_SIGN) + .add(ItemKeys.PALE_OAK_HANGING_SIGN) .add(ItemKeys.BAMBOO_SIGN) .add(ItemKeys.BAMBOO_HANGING_SIGN) .add(ItemKeys.CRIMSON_SIGN) @@ -1159,6 +1198,8 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(ItemKeys.MANGROVE_CHEST_BOAT) .add(ItemKeys.CHERRY_BOAT) .add(ItemKeys.CHERRY_CHEST_BOAT) + .add(ItemKeys.PALE_OAK_BOAT) + .add(ItemKeys.PALE_OAK_CHEST_BOAT) .add(ItemKeys.BAMBOO_RAFT) .add(ItemKeys.BAMBOO_CHEST_RAFT); this.getOrCreateTagBuilder(ItematicItemTags.MUSIC_DISCS) @@ -1226,6 +1267,10 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(ItemKeys.IRON_HORSE_ARMOR) .add(ItemKeys.GOLDEN_HORSE_ARMOR) .add(ItemKeys.DIAMOND_HORSE_ARMOR); + this.getOrCreateTagBuilder(ItematicItemTags.EGGS) + .add(ItemKeys.EGG) + .add(ItemKeys.BROWN_EGG) + .add(ItemKeys.BLUE_EGG); this.getOrCreateTagBuilder(ItematicItemTags.FOOD) .add(ItemKeys.APPLE) .add(ItemKeys.GOLDEN_APPLE) @@ -1356,9 +1401,6 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(ItemKeys.RED_SHULKER_BOX) .add(ItemKeys.WHITE_SHULKER_BOX) .add(ItemKeys.YELLOW_SHULKER_BOX); - this.getOrCreateTagBuilder(ItematicItemTags.PREVENTS_MINING_IN_CREATIVE) - .forceAddTag(ItemTags.SWORDS) - .add(ItemKeys.TRIDENT); this.getOrCreateTagBuilder(ItematicItemTags.PREVENTS_TAKING_POTTED_ITEM_OUT) .add(ItemKeys.OAK_SAPLING) .add(ItemKeys.SPRUCE_SAPLING) diff --git a/src/datagen/java/net/errorcraft/itematic/data/server/tag/TradeTagProvider.java b/src/datagen/java/net/errorcraft/itematic/data/server/tag/TradeTagProvider.java index 23bd7670..1f25f09a 100644 --- a/src/datagen/java/net/errorcraft/itematic/data/server/tag/TradeTagProvider.java +++ b/src/datagen/java/net/errorcraft/itematic/data/server/tag/TradeTagProvider.java @@ -70,22 +70,22 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(Trades.BUY_BLACK_DYE) .add(Trades.BUY_LIGHT_BLUE_DYE) .add(Trades.BUY_LIME_DYE) - .add(Trades.SELL_WHITE_WOOL) - .add(Trades.SELL_ORANGE_WOOL) - .add(Trades.SELL_MAGENTA_WOOL) - .add(Trades.SELL_LIGHT_BLUE_WOOL) - .add(Trades.SELL_YELLOW_WOOL) - .add(Trades.SELL_LIME_WOOL) - .add(Trades.SELL_PINK_WOOL) - .add(Trades.SELL_GRAY_WOOL) - .add(Trades.SELL_LIGHT_GRAY_WOOL) - .add(Trades.SELL_CYAN_WOOL) - .add(Trades.SELL_PURPLE_WOOL) - .add(Trades.SELL_BLUE_WOOL) - .add(Trades.SELL_BROWN_WOOL) - .add(Trades.SELL_GREEN_WOOL) - .add(Trades.SELL_RED_WOOL) - .add(Trades.SELL_BLACK_WOOL) + .add(Trades.SELL_WHITE_WOOL_SHEPHERD) + .add(Trades.SELL_ORANGE_WOOL_SHEPHERD) + .add(Trades.SELL_MAGENTA_WOOL_SHEPHERD) + .add(Trades.SELL_LIGHT_BLUE_WOOL_SHEPHERD) + .add(Trades.SELL_YELLOW_WOOL_SHEPHERD) + .add(Trades.SELL_LIME_WOOL_SHEPHERD) + .add(Trades.SELL_PINK_WOOL_SHEPHERD) + .add(Trades.SELL_GRAY_WOOL_SHEPHERD) + .add(Trades.SELL_LIGHT_GRAY_WOOL_SHEPHERD) + .add(Trades.SELL_CYAN_WOOL_SHEPHERD) + .add(Trades.SELL_PURPLE_WOOL_SHEPHERD) + .add(Trades.SELL_BLUE_WOOL_SHEPHERD) + .add(Trades.SELL_BROWN_WOOL_SHEPHERD) + .add(Trades.SELL_GREEN_WOOL_SHEPHERD) + .add(Trades.SELL_RED_WOOL_SHEPHERD) + .add(Trades.SELL_BLACK_WOOL_SHEPHERD) .add(Trades.SELL_WHITE_CARPET) .add(Trades.SELL_ORANGE_CARPET) .add(Trades.SELL_MAGENTA_CARPET) @@ -167,7 +167,7 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(Trades.SELL_ENCHANTED_CROSSBOW) .add(Trades.SELL_TIPPED_ARROW); this.getOrCreateTagBuilder(TradeTags.LIBRARIAN_NOVICE) - .add(Trades.BUY_PAPER) + .add(Trades.BUY_PAPER_LIBRARIAN) .add(Trades.SELL_ENCHANTED_BOOK_NOVICE) .add(Trades.SELL_BOOKSHELF); this.getOrCreateTagBuilder(TradeTags.LIBRARIAN_APPRENTICE) @@ -186,34 +186,41 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { this.getOrCreateTagBuilder(TradeTags.LIBRARIAN_MASTER) .add(Trades.SELL_NAME_TAG); this.getOrCreateTagBuilder(TradeTags.CARTOGRAPHER_NOVICE) - .add(Trades.BUY_PAPER) + .add(Trades.BUY_PAPER_CARTOGRAPHER) .add(Trades.SELL_MAP); this.getOrCreateTagBuilder(TradeTags.CARTOGRAPHER_APPRENTICE) .add(Trades.BUY_GLASS_PANE) - .add(Trades.SELL_MONUMENT_MAP); + .add(Trades.SELL_TAIGA_VILLAGE_MAP) + .add(Trades.SELL_SWAMP_HUT_MAP) + .add(Trades.SELL_SNOWY_VILLAGE_MAP) + .add(Trades.SELL_SAVANNA_VILLAGE_MAP) + .add(Trades.SELL_PLAINS_VILLAGE_MAP) + .add(Trades.SELL_JUNGLE_TEMPLE_MAP) + .add(Trades.SELL_DESERT_VILLAGE_MAP); this.getOrCreateTagBuilder(TradeTags.CARTOGRAPHER_JOURNEYMAN) .add(Trades.BUY_COMPASS) - .add(Trades.SELL_MANSION_MAP); + .add(Trades.SELL_MONUMENT_MAP) + .add(Trades.SELL_TRIAL_CHAMBER_MAP); this.getOrCreateTagBuilder(TradeTags.CARTOGRAPHER_EXPERT) .add(Trades.SELL_ITEM_FRAME) - .add(Trades.SELL_WHITE_BANNER) - .add(Trades.SELL_BLUE_BANNER) - .add(Trades.SELL_LIGHT_BLUE_BANNER) - .add(Trades.SELL_RED_BANNER) - .add(Trades.SELL_PINK_BANNER) - .add(Trades.SELL_GREEN_BANNER) - .add(Trades.SELL_LIME_BANNER) - .add(Trades.SELL_GRAY_BANNER) - .add(Trades.SELL_BLACK_BANNER) - .add(Trades.SELL_PURPLE_BANNER) - .add(Trades.SELL_MAGENTA_BANNER) - .add(Trades.SELL_CYAN_BANNER) - .add(Trades.SELL_BROWN_BANNER) - .add(Trades.SELL_YELLOW_BANNER) - .add(Trades.SELL_ORANGE_BANNER) - .add(Trades.SELL_LIGHT_GRAY_BANNER); + .add(Trades.SELL_BLUE_BANNER_CARTOGRAPHER) + .add(Trades.SELL_WHITE_BANNER_CARTOGRAPHER) + .add(Trades.SELL_RED_BANNER_CARTOGRAPHER) + .add(Trades.SELL_GREEN_BANNER_CARTOGRAPHER) + .add(Trades.SELL_LIME_BANNER_CARTOGRAPHER) + .add(Trades.SELL_PURPLE_BANNER_CARTOGRAPHER) + .add(Trades.SELL_CYAN_BANNER_CARTOGRAPHER) + .add(Trades.SELL_YELLOW_BANNER_CARTOGRAPHER) + .add(Trades.SELL_ORANGE_BANNER_CARTOGRAPHER) + .add(Trades.SELL_BROWN_BANNER_CARTOGRAPHER) + .add(Trades.SELL_MAGENTA_BANNER_CARTOGRAPHER) + .add(Trades.SELL_LIGHT_BLUE_BANNER_CARTOGRAPHER) + .add(Trades.SELL_PINK_BANNER_CARTOGRAPHER) + .add(Trades.SELL_GRAY_BANNER_CARTOGRAPHER) + .add(Trades.SELL_BLACK_BANNER_CARTOGRAPHER); this.getOrCreateTagBuilder(TradeTags.CARTOGRAPHER_MASTER) - .add(Trades.SELL_GLOBE_BANNER_PATTERN); + .add(Trades.SELL_GLOBE_BANNER_PATTERN) + .add(Trades.SELL_MANSION_MAP); this.getOrCreateTagBuilder(TradeTags.CLERIC_NOVICE) .add(Trades.BUY_ROTTEN_FLESH) .add(Trades.SELL_REDSTONE); @@ -372,7 +379,32 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { this.getOrCreateTagBuilder(TradeTags.MASON_MASTER) .add(Trades.SELL_QUARTZ_PILLAR) .add(Trades.SELL_QUARTZ_BLOCK); + this.getOrCreateTagBuilder(TradeTags.WANDERING_TRADER_BUYING) + .add(Trades.BUY_WATER_BOTTLE) + .add(Trades.BUY_WATER_BUCKET) + .add(Trades.BUY_MILK_BUCKET) + .add(Trades.BUY_FERMENTED_SPIDER_EYE) + .add(Trades.BUY_BAKED_POTATO) + .add(Trades.BUY_HAY_BLOCK); + this.getOrCreateTagBuilder(TradeTags.WANDERING_TRADER_SPECIAL) + .add(Trades.SELL_PACKED_ICE) + .add(Trades.SELL_BLUE_ICE) + .add(Trades.SELL_GUNPOWDER) + .add(Trades.SELL_PODZOL) + .add(Trades.SELL_ACACIA_LOG) + .add(Trades.SELL_BIRCH_LOG) + .add(Trades.SELL_DARK_OAK_LOG) + .add(Trades.SELL_JUNGLE_LOG) + .add(Trades.SELL_OAK_LOG) + .add(Trades.SELL_SPRUCE_LOG) + .add(Trades.SELL_CHERRY_LOG) + .add(Trades.SELL_MANGROVE_LOG) + .add(Trades.SELL_PALE_OAK_LOG) + .add(Trades.SELL_ENCHANTED_IRON_PICKAXE_WANDERING_TRADER) + .add(Trades.SELL_LONG_INVISIBILITY_POTION); this.getOrCreateTagBuilder(TradeTags.WANDERING_TRADER_REGULAR) + .add(Trades.SELL_TROPICAL_FISH_BUCKET) + .add(Trades.SELL_PUFFERFISH_BUCKET) .add(Trades.SELL_SEA_PICKLE) .add(Trades.SELL_SLIME_BALL) .add(Trades.SELL_GLOWSTONE_WANDERING_TRADER) @@ -394,6 +426,7 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(Trades.SELL_OXEYE_DAISY) .add(Trades.SELL_CORNFLOWER) .add(Trades.SELL_LILY_OF_THE_VALLEY) + .add(Trades.SELL_OPEN_EYEBLOSSOM) .add(Trades.SELL_WHEAT_SEEDS) .add(Trades.SELL_BEETROOT_SEEDS) .add(Trades.SELL_PUMPKIN_SEEDS) @@ -405,6 +438,7 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(Trades.SELL_OAK_SAPLING) .add(Trades.SELL_SPRUCE_SAPLING) .add(Trades.SELL_CHERRY_SAPLING) + .add(Trades.SELL_PALE_OAK_SAPLING) .add(Trades.SELL_MANGROVE_PROPAGULE) .add(Trades.SELL_RED_DYE) .add(Trades.SELL_WHITE_DYE) @@ -428,6 +462,7 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(Trades.SELL_HORN_CORAL_BLOCK) .add(Trades.SELL_TUBE_CORAL_BLOCK) .add(Trades.SELL_VINE) + .add(Trades.SELL_PALE_HANGING_MOSS) .add(Trades.SELL_BROWN_MUSHROOM) .add(Trades.SELL_RED_MUSHROOM) .add(Trades.SELL_LILY_PAD) @@ -436,13 +471,10 @@ protected void configure(RegistryWrapper.WrapperLookup lookup) { .add(Trades.SELL_RED_SAND) .add(Trades.SELL_POINTED_DRIPSTONE) .add(Trades.SELL_ROOTED_DIRT) - .add(Trades.SELL_MOSS_BLOCK); - this.getOrCreateTagBuilder(TradeTags.WANDERING_TRADER_SPECIAL) - .add(Trades.SELL_TROPICAL_FISH_BUCKET) - .add(Trades.SELL_PUFFERFISH_BUCKET) - .add(Trades.SELL_PACKED_ICE) - .add(Trades.SELL_BLUE_ICE) - .add(Trades.SELL_GUNPOWDER) - .add(Trades.SELL_PODZOL); + .add(Trades.SELL_MOSS_BLOCK) + .add(Trades.SELL_PALE_MOSS_BLOCK) + .add(Trades.SELL_WILDFLOWERS) + .add(Trades.SELL_TALL_DRY_GRASS) + .add(Trades.SELL_FIREFLY_BUSH); } } diff --git a/src/gametest/java/net/errorcraft/itematic/assertion/Assert.java b/src/gametest/java/net/errorcraft/itematic/assertion/Assert.java new file mode 100644 index 00000000..276312c4 --- /dev/null +++ b/src/gametest/java/net/errorcraft/itematic/assertion/Assert.java @@ -0,0 +1,101 @@ +package net.errorcraft.itematic.assertion; + +import net.errorcraft.itematic.util.TestUtil; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.fluid.FluidState; +import net.minecraft.item.ItemStack; +import net.minecraft.test.TestContext; +import net.minecraft.text.Text; +import net.minecraft.util.math.BlockPos; + +import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class Assert { + private Assert() {} + + public static void isTrue(TestContext helper, boolean condition, Supplier message) { + if (!condition) { + throw helper.createError(Text.literal(message.get())); + } + } + + public static void isFalse(TestContext helper, boolean condition, Supplier message) { + isTrue(helper, !condition, message); + } + + public static T isNotNull(TestContext helper, T object, String name) { + if (object == null) { + throw helper.createError( + "test.error.expected_not_null", + name + ); + } + + return object; + } + + public static void areEqual(TestContext helper, T value, T expected, String type) { + if (Objects.equals(value, expected)) { + return; + } + + throw helper.createError( + "test.error.expected_type", + type, + value, + expected + ); + } + + public static void isInstance(TestContext helper, T value, Class expectedClass, Supplier message, Consumer assertion) { + if (expectedClass.isInstance(value)) { + assertion.accept(expectedClass.cast(value)); + return; + } + + throw helper.createError(Text.literal(message.get())); + } + + public static IntsAssert ints(TestContext helper, int value, String name) { + return new IntsAssert(helper, value, name); + } + + public static FloatsAssert floats(TestContext helper, float value, String name) { + return new FloatsAssert(helper, value, name); + } + + public static DoublesAssert doubles(TestContext helper, double value, String name) { + return new DoublesAssert(helper, value, name); + } + + public static BlockStateAssert blockState(TestContext helper, BlockPos pos) { + BlockState state = helper.getWorld().getBlockState(helper.getAbsolutePos(pos)); + return new BlockStateAssert(helper, state); + } + + public static void blockEntity(TestContext helper, BlockPos pos, BlockEntityType type, Consumer assertion) { + assertion.accept(TestUtil.getBlockEntity(helper, pos, type)); + } + + public static FluidStateAssert fluidState(TestContext helper, BlockPos pos) { + FluidState state = helper.getWorld().getFluidState(helper.getAbsolutePos(pos)); + return new FluidStateAssert(helper, state); + } + + public static LivingEntityAssert livingEntity(TestContext helper, LivingEntity entity) { + return new LivingEntityAssert(helper, entity); + } + + public static ItemStackAssert itemStack(TestContext helper, ItemStack stack) { + return new ItemStackAssert(helper, stack); + } + + public static ItemStackAssert itemStack(TestContext helper, ItemStack stack, String name) { + return new ItemStackAssert(helper, stack, name); + } +} diff --git a/src/gametest/java/net/errorcraft/itematic/assertion/BlockStateAssert.java b/src/gametest/java/net/errorcraft/itematic/assertion/BlockStateAssert.java new file mode 100644 index 00000000..74c763a6 --- /dev/null +++ b/src/gametest/java/net/errorcraft/itematic/assertion/BlockStateAssert.java @@ -0,0 +1,87 @@ +package net.errorcraft.itematic.assertion; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.registry.Registries; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.state.property.IntProperty; +import net.minecraft.state.property.Property; +import net.minecraft.test.TestContext; +import net.minecraft.text.Text; + +import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class BlockStateAssert { + private final TestContext helper; + private final BlockState state; + + BlockStateAssert(TestContext helper, BlockState state) { + this.helper = Objects.requireNonNull(helper); + this.state = Assert.isNotNull(this.helper, state, "block state"); + } + + public BlockStateAssert is(Block block) { + if (this.state.isOf(block)) { + return this; + } + + throw this.helper.createError( + "test.error.expected_type", + "block", + Registries.BLOCK.getId(block), + Registries.BLOCK.getId(this.state.getBlock()) + ); + } + + public BlockStateAssert isNot(Block block) { + if (!this.state.isOf(block)) { + return this; + } + + throw this.helper.createError( + "test.error.did_not_expect_type", + "block", + Registries.BLOCK.getId(block) + ); + } + + public BlockStateAssert is(TagKey tag) { + if (this.state.isIn(tag)) { + return this; + } + + throw this.helper.createError( + "test.error.expected_tag", + "block", + tag.id() + ); + } + + public > BlockStateAssert hasProperty(Property property, T expected) { + if (expected.equals(this.state.get(property))) { + return this; + } + + throw this.helper.createError( + "test.error.expected_type", + property.getName() + " block state property", + expected, + this.state.get(property) + ); + } + + public > BlockStateAssert hasProperty(Property expected, T value, Supplier message) { + if (value.equals(this.state.get(expected))) { + return this; + } + + throw this.helper.createError(Text.literal(message.get())); + } + + public BlockStateAssert hasProperty(IntProperty property, Consumer expectedAssertion) { + expectedAssertion.accept(Assert.ints(this.helper, this.state.get(property), property.getName() + " block state property")); + return this; + } +} diff --git a/src/gametest/java/net/errorcraft/itematic/assertion/DoublesAssert.java b/src/gametest/java/net/errorcraft/itematic/assertion/DoublesAssert.java new file mode 100644 index 00000000..837945ee --- /dev/null +++ b/src/gametest/java/net/errorcraft/itematic/assertion/DoublesAssert.java @@ -0,0 +1,30 @@ +package net.errorcraft.itematic.assertion; + +import net.minecraft.test.TestContext; + +import java.util.Objects; + +public class DoublesAssert { + private final TestContext helper; + private final double value; + private final String name; + + DoublesAssert(TestContext helper, double value, String name) { + this.helper = Objects.requireNonNull(helper); + this.value = value; + this.name = Objects.requireNonNull(name); + } + + public DoublesAssert equals(double expected) { + if (this.value == expected) { + return this; + } + + throw this.helper.createError( + "test.error.value_not_equal", + this.name, + expected, + this.value + ); + } +} diff --git a/src/gametest/java/net/errorcraft/itematic/assertion/FloatsAssert.java b/src/gametest/java/net/errorcraft/itematic/assertion/FloatsAssert.java new file mode 100644 index 00000000..1174007b --- /dev/null +++ b/src/gametest/java/net/errorcraft/itematic/assertion/FloatsAssert.java @@ -0,0 +1,43 @@ +package net.errorcraft.itematic.assertion; + +import net.minecraft.test.TestContext; + +import java.util.Objects; + +public class FloatsAssert { + private final TestContext helper; + private final float value; + private final String name; + + FloatsAssert(TestContext helper, float value, String name) { + this.helper = Objects.requireNonNull(helper); + this.value = value; + this.name = Objects.requireNonNull(name); + } + + public FloatsAssert equals(float expected) { + if (this.value == expected) { + return this; + } + + throw this.helper.createError( + "test.error.value_not_equal", + this.name, + expected, + this.value + ); + } + + public FloatsAssert isGreaterThan(float expected) { + if (this.value > expected) { + return this; + } + + throw this.helper.createError( + "test.error.expected_value_greater_than", + this.name, + expected, + this.value + ); + } +} diff --git a/src/gametest/java/net/errorcraft/itematic/assertion/FluidStateAssert.java b/src/gametest/java/net/errorcraft/itematic/assertion/FluidStateAssert.java new file mode 100644 index 00000000..ad1f2b0f --- /dev/null +++ b/src/gametest/java/net/errorcraft/itematic/assertion/FluidStateAssert.java @@ -0,0 +1,44 @@ +package net.errorcraft.itematic.assertion; + +import net.minecraft.fluid.Fluid; +import net.minecraft.fluid.FluidState; +import net.minecraft.registry.Registries; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.test.TestContext; + +import java.util.Objects; + +public class FluidStateAssert { + private final TestContext helper; + private final FluidState state; + + FluidStateAssert(TestContext helper, FluidState state) { + this.helper = Objects.requireNonNull(helper); + this.state = Assert.isNotNull(this.helper, state, "fluid state"); + } + + public FluidStateAssert is(Fluid fluid) { + if (this.state.isOf(fluid)) { + return this; + } + + throw this.helper.createError( + "test.error.expected_type", + "fluid", + Registries.FLUID.getId(fluid), + Registries.FLUID.getId(this.state.getFluid()) + ); + } + + public FluidStateAssert is(TagKey tag) { + if (this.state.isIn(tag)) { + return this; + } + + throw this.helper.createError( + "test.error.expected_tag", + "fluid", + tag.id() + ); + } +} diff --git a/src/gametest/java/net/errorcraft/itematic/assertion/IntsAssert.java b/src/gametest/java/net/errorcraft/itematic/assertion/IntsAssert.java new file mode 100644 index 00000000..773ed86d --- /dev/null +++ b/src/gametest/java/net/errorcraft/itematic/assertion/IntsAssert.java @@ -0,0 +1,30 @@ +package net.errorcraft.itematic.assertion; + +import net.minecraft.test.TestContext; + +import java.util.Objects; + +public class IntsAssert { + private final TestContext helper; + private final int value; + private final String name; + + IntsAssert(TestContext helper, int value, String name) { + this.helper = Objects.requireNonNull(helper); + this.value = value; + this.name = Objects.requireNonNull(name); + } + + public IntsAssert equals(int expected) { + if (this.value == expected) { + return this; + } + + throw this.helper.createError( + "test.error.value_not_equal", + this.name, + expected, + this.value + ); + } +} diff --git a/src/gametest/java/net/errorcraft/itematic/assertion/ItemStackAssert.java b/src/gametest/java/net/errorcraft/itematic/assertion/ItemStackAssert.java new file mode 100644 index 00000000..fc43e792 --- /dev/null +++ b/src/gametest/java/net/errorcraft/itematic/assertion/ItemStackAssert.java @@ -0,0 +1,194 @@ +package net.errorcraft.itematic.assertion; + +import net.errorcraft.itematic.mixin.enchantment.EnchantmentHelperAccessor; +import net.errorcraft.itematic.util.TestUtil; +import net.minecraft.component.ComponentType; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.enchantment.Enchantment; +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.test.TestContext; +import net.minecraft.util.Identifier; + +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +public class ItemStackAssert { + private final TestContext helper; + private final ItemStack stack; + private final String name; + + ItemStackAssert(TestContext helper, ItemStack stack) { + this(helper, stack, "item stack"); + } + + ItemStackAssert(TestContext helper, ItemStack stack, String name) { + this.helper = Objects.requireNonNull(helper); + this.stack = Assert.isNotNull(this.helper, stack, name); + this.name = Objects.requireNonNull(name); + } + + public ItemStackAssert is(RegistryKey id) { + if (this.stack.itematic$isOf(id)) { + return this; + } + + throw this.helper.createError( + "test.error.expected_type", + this.name, + id.getValue(), + this.stack.getRegistryEntry().getIdAsString() + ); + } + + public ItemStackAssert isEmpty() { + if (this.stack.isEmpty()) { + return this; + } + + throw this.helper.createError( + "test.error.item_stack.expected_empty", + this.name, + this.stack.getRegistryEntry().getIdAsString() + ); + } + + public ItemStackAssert isNotEmpty() { + if (!this.stack.isEmpty()) { + return this; + } + + throw this.helper.createError( + "test.error.item_stack.expected_not_empty", + this.name + ); + } + + public ItemStackAssert hasCount(Consumer countAssertion) { + countAssertion.accept(Assert.ints(this.helper, this.stack.getCount(), "item stack count")); + return this; + } + + public ItemStackAssert isDamaged() { + if (this.stack.isDamaged()) { + return this; + } + + throw this.helper.createError( + "test.error.item_stack.damaged", + this.name + ); + } + + public ItemStackAssert isNotDamaged() { + if (!this.stack.isDamaged()) { + return this; + } + + throw this.helper.createError( + "test.error.item_stack.expected_not_damaged", + this.name + ); + } + + public ItemStackAssert hasComponent(ComponentType type) { + if (this.stack.contains(type)) { + return this; + } + + throw this.helper.createError( + "test.error.item_stack.expected_data_component", + this.name, + type + ); + } + + public ItemStackAssert hasComponent(ComponentType type, Consumer assertion) { + assertion.accept(TestUtil.getDataComponent(this.helper, this.stack, type)); + return this; + } + + public ItemStackAssert doesNotHaveComponent(ComponentType type) { + if (!this.stack.contains(type)) { + return this; + } + + throw this.helper.createError( + "test.error.item_stack.did_not_expect_data_component", + this.name, + type + ); + } + + public ItemStackAssert hasPotion(RegistryEntry expected) { + return this.hasComponent(DataComponentTypes.POTION_CONTENTS, potionContents -> { + RegistryEntry potion = potionContents.potion() + .orElseThrow(() -> this.helper.createError( + "test.error.item_stack.expected_potion", + this.name, + expected.getIdAsString() + )); + if (expected != potion) { + throw this.helper.createError( + "test.error.item_stack.expected_other_potion", + this.name, + expected.getIdAsString(), + potion.getIdAsString() + ); + } + }); + } + + public ItemStackAssert hasEnchantments() { + return this.hasComponent(EnchantmentHelperAccessor.getComponentType(this.stack), enchantments -> { + if (enchantments.isEmpty()) { + throw this.helper.createError( + "test.error.item_stack.expected_enchantments", + this.name + ); + } + }); + } + + public ItemStackAssert hasNoEnchantments() { + return this.hasComponent(EnchantmentHelperAccessor.getComponentType(this.stack), enchantments -> { + if (!enchantments.isEmpty()) { + throw this.helper.createError( + "test.error.item_stack.expected_no_enchantments", + this.name + ); + } + }); + } + + @SafeVarargs + public final ItemStackAssert hasEnchantments(RegistryKey... expected) { + return this.hasComponent(EnchantmentHelperAccessor.getComponentType(this.stack), enchantments -> { + Set> remaining = new HashSet<>(List.of(expected)); + for (RegistryEntry enchantment : enchantments.getEnchantments()) { + enchantment.getKey().ifPresent(remaining::remove); + } + + if (remaining.isEmpty()) { + return; + } + + throw this.helper.createError( + "test.error.item_stack.expected_specified_enchantments", + this.name, + remaining.stream() + .map(RegistryKey::getValue) + .sorted() + .map(Identifier::toString) + .collect(Collectors.joining(", ")) + ); + }); + } +} diff --git a/src/gametest/java/net/errorcraft/itematic/assertion/LivingEntityAssert.java b/src/gametest/java/net/errorcraft/itematic/assertion/LivingEntityAssert.java new file mode 100644 index 00000000..efeb3d6b --- /dev/null +++ b/src/gametest/java/net/errorcraft/itematic/assertion/LivingEntityAssert.java @@ -0,0 +1,93 @@ +package net.errorcraft.itematic.assertion; + +import net.minecraft.component.type.PotionContentsComponent; +import net.minecraft.component.type.SuspiciousStewEffectsComponent; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.effect.StatusEffect; +import net.minecraft.entity.effect.StatusEffectInstance; +import net.minecraft.potion.Potion; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.test.TestContext; +import net.minecraft.util.Hand; + +import java.util.List; +import java.util.function.Consumer; + +public class LivingEntityAssert { + private final TestContext helper; + private final LivingEntity entity; + + LivingEntityAssert(TestContext helper, LivingEntity entity) { + this.helper = helper; + this.entity = entity; + } + + public LivingEntityAssert hasHealth(Consumer healthAssertion) { + healthAssertion.accept(Assert.floats(this.helper, this.entity.getHealth(), "entity health")); + return this; + } + + public LivingEntityAssert hasStackInHand(Hand hand, Consumer stackAssertion) { + stackAssertion.accept(Assert.itemStack(this.helper, this.entity.getStackInHand(hand), "item stack in hand")); + return this; + } + + public LivingEntityAssert hasEquippedStack(EquipmentSlot slot, Consumer stackAssertion) { + stackAssertion.accept(Assert.itemStack(this.helper, this.entity.getEquippedStack(slot), "equipped item stack")); + return this; + } + + public LivingEntityAssert hasEffect(RegistryEntry effect) { + if (this.entity.hasStatusEffect(effect)) { + return this; + } + + throw this.helper.createError( + "test.error.entity.expected_effect", + this.entity.getName(), + PotionContentsComponent.getEffectText(effect, 0) + ); + } + + public LivingEntityAssert hasEffect(RegistryEntry effect, int amplifier) { + StatusEffectInstance effectInstance = this.entity.getStatusEffect(effect); + if (effectInstance != null && effectInstance.getAmplifier() == amplifier) { + return this; + } + + throw this.helper.createError( + "test.error.entity.expected_effect", + this.entity.getName(), + PotionContentsComponent.getEffectText(effect, amplifier) + ); + } + + public LivingEntityAssert doesNotHaveEffect(RegistryEntry effect) { + if (!this.entity.hasStatusEffect(effect)) { + return this; + } + + throw this.helper.createError( + "test.error.entity.did_not_expect_effect", + this.entity.getName(), + PotionContentsComponent.getEffectText(effect, 0) + ); + } + + public LivingEntityAssert hasEffects(RegistryEntry potion) { + for (StatusEffectInstance effect : potion.value().getEffects()) { + this.hasEffect(effect.getEffectType(), effect.getAmplifier()); + } + + return this; + } + + public LivingEntityAssert hasEffects(List effects) { + for (SuspiciousStewEffectsComponent.StewEffect effect : effects) { + this.hasEffect(effect.effect(), effect.createStatusEffectInstance().getAmplifier()); + } + + return this; + } +} diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/Assert.java b/src/gametest/java/net/errorcraft/itematic/gametest/Assert.java deleted file mode 100644 index 13d1b661..00000000 --- a/src/gametest/java/net/errorcraft/itematic/gametest/Assert.java +++ /dev/null @@ -1,154 +0,0 @@ -package net.errorcraft.itematic.gametest; - -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.BlockEntityType; -import net.minecraft.component.ComponentType; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.ItemEnchantmentsComponent; -import net.minecraft.enchantment.Enchantment; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.effect.StatusEffect; -import net.minecraft.fluid.Fluid; -import net.minecraft.fluid.FluidState; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.potion.Potion; -import net.minecraft.registry.Registries; -import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.registry.tag.TagKey; -import net.minecraft.test.GameTestException; -import net.minecraft.test.TestContext; -import net.minecraft.util.math.BlockPos; - -import java.util.function.Consumer; - -public class Assert { - private Assert() {} - - public static void fluidIsOf(TestContext context, Fluid fluid, BlockPos pos) { - FluidState state = context.getWorld().getFluidState(context.getAbsolutePos(pos)); - if (!state.isOf(fluid)) { - throw new GameTestException("Expected fluid to be of " + Registries.FLUID.getId(fluid) + ", got " + Registries.FLUID.getId(state.getFluid()) + " instead"); - } - } - - public static void fluidIsIn(TestContext context, TagKey fluid, BlockPos pos) { - FluidState state = context.getWorld().getFluidState(context.getAbsolutePos(pos)); - if (!state.isIn(fluid)) { - throw new GameTestException("Expected fluid to be in " + fluid.id() + ", got " + Registries.FLUID.getId(state.getFluid()) + " instead"); - } - } - - public static void itemStackIsOf(ItemStack value, RegistryKey expected) { - if (value == null) { - throw new GameTestException("Expected item stack to be of " + expected + ", but the item stack was null"); - } - - if (!value.itematic$isOf(expected)) { - throw new GameTestException("Expected item stack to be of " + expected + ", got " + value.itematic$key() + " instead"); - } - } - - public static void itemStackIsEmpty(ItemStack value) { - if (!value.isEmpty()) { - throw new GameTestException("Expected item stack to be empty, got " + value + " instead"); - } - } - - public static void itemStackIsNotEmpty(ItemStack value) { - if (value.isEmpty()) { - throw new GameTestException("Expected item stack not to be empty"); - } - } - - public static void itemStackHasDataComponent(ItemStack value, ComponentType type) { - if (value.get(type) == null) { - throw new GameTestException("Expected item stack to contain the " + type + " component"); - } - } - - public static void itemStackDoesNotHaveDataComponent(ItemStack value, ComponentType type) { - if (value.get(type) != null) { - throw new GameTestException("Expected item stack to not contain the " + type + " component"); - } - } - - public static void itemStackHasDataComponent(ItemStack value, ComponentType type, Consumer assertion) { - itemStackHasDataComponent(value, type); - assertion.accept(TestUtil.getDataComponent(value, type)); - } - - public static void itemStackHasPotion(ItemStack value, RegistryEntry expected) { - itemStackHasDataComponent(value, DataComponentTypes.POTION_CONTENTS, component -> { - RegistryEntry potion = component.potion() - .orElseThrow(() -> new GameTestException("Expected item stack to have potion " + expected.getKey().orElseThrow())); - if (expected != potion) { - throw new GameTestException("Expected item stack to have potion " + expected.getKey().orElseThrow() + ", got " + potion.getKey().orElseThrow() + " instead"); - } - }); - } - - public static void dataComponentHasEnchantment(ItemEnchantmentsComponent enchantments, RegistryKey expected) { - for (RegistryEntry enchantment : enchantments.getEnchantments()) { - if (enchantment.matchesKey(expected)) { - return; - } - } - - throw new GameTestException("Expected data component to have enchantment " + expected); - } - - public static void entityDoesNotHaveStatusEffect(LivingEntity entity, RegistryEntry effect) { - if (entity.getStatusEffect(effect) != null) { - throw new GameTestException("Expected entity to not have the " + effect.getKey().orElseThrow() + " status effect"); - } - } - - public static void blockEntityExists(TestContext context, BlockPos pos, BlockEntityType type, Consumer assertion) { - assertion.accept(TestUtil.getBlockEntity(context, pos, type)); - } - - public static void areIntsEqual(int value, int expected) { - areIntsEqual(value, expected, (v, e) -> "Expected value to be " + e + ", got " + v + " instead"); - } - - public static void areIntsEqual(int value, int expected, ComparingIntStringSupplier messageSupplier) { - if (value != expected) { - throw new GameTestException(messageSupplier.get(value, expected)); - } - } - - public static void areFloatsEqual(float value, float expected, ComparingFloatStringSupplier messageSupplier) { - if (value != expected) { - throw new GameTestException(messageSupplier.get(value, expected)); - } - } - - public static void areDoublesEqual(double value, double expected, ComparingDoubleStringSupplier messageSupplier) { - if (value != expected) { - throw new GameTestException(messageSupplier.get(value, expected)); - } - } - - public static void forAll(Iterable elements, Consumer elementAssertion) { - for (T element : elements) { - elementAssertion.accept(element); - } - } - - @FunctionalInterface - public interface ComparingIntStringSupplier { - String get(int value, int expected); - } - - @FunctionalInterface - public interface ComparingFloatStringSupplier { - String get(float value, float expected); - } - - @FunctionalInterface - public interface ComparingDoubleStringSupplier { - String get(double value, double expected); - } -} diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/block/AnvilBlockTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/block/AnvilBlockTestSuite.java index bb864064..f7471b8b 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/block/AnvilBlockTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/block/AnvilBlockTestSuite.java @@ -1,16 +1,14 @@ package net.errorcraft.itematic.gametest.block; -import net.errorcraft.itematic.gametest.Assert; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; -import net.minecraft.component.DataComponentTypes; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.enchantment.Enchantments; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; import net.minecraft.screen.AnvilScreenHandler; import net.minecraft.screen.ScreenHandlerType; 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; @@ -18,7 +16,7 @@ public class AnvilBlockTestSuite { private static final BlockPos BLOCK_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:block.anvil") + @GameTest(structure = "itematic:block.anvil") public void combiningEnchantedItemsWithSameIdInAnvilCombinesEnchantments(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); @@ -27,17 +25,12 @@ public void combiningEnchantedItemsWithSameIdInAnvilCombinesEnchantments(TestCon .setStack(TestUtil.createItemStackWithEnchantment(world, ItemKeys.IRON_PICKAXE, Enchantments.UNBREAKING)); anvilMenu.getSlot(1) .setStack(TestUtil.createItemStackWithEnchantment(world, ItemKeys.IRON_PICKAXE, Enchantments.EFFICIENCY)); - context.addInstantFinalTask(() -> { - ItemStack result = anvilMenu.getSlot(2).getStack(); - Assert.itemStackIsOf(result, ItemKeys.IRON_PICKAXE); - Assert.itemStackHasDataComponent(result, DataComponentTypes.ENCHANTMENTS, enchantments -> { - Assert.dataComponentHasEnchantment(enchantments, Enchantments.UNBREAKING); - Assert.dataComponentHasEnchantment(enchantments, Enchantments.EFFICIENCY); - }); - }); + context.addFinalTask(() -> Assert.itemStack(context, anvilMenu.getSlot(2).getStack()) + .is(ItemKeys.IRON_PICKAXE) + .hasEnchantments(Enchantments.UNBREAKING, Enchantments.EFFICIENCY)); } - @GameTest(templateName = "itematic:block.anvil") + @GameTest(structure = "itematic:block.anvil") public void combiningEnchantedItemsWithDifferentIdsInAnvilRejectsCombination(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); @@ -46,10 +39,11 @@ public void combiningEnchantedItemsWithDifferentIdsInAnvilRejectsCombination(Tes .setStack(TestUtil.createItemStackWithEnchantment(world, ItemKeys.IRON_PICKAXE, Enchantments.UNBREAKING)); anvilMenu.getSlot(1) .setStack(TestUtil.createItemStackWithEnchantment(world, ItemKeys.DIAMOND_PICKAXE, Enchantments.EFFICIENCY)); - context.addInstantFinalTask(() -> Assert.itemStackIsEmpty(anvilMenu.getSlot(2).getStack())); + context.addFinalTask(() -> Assert.itemStack(context, anvilMenu.getSlot(2).getStack()) + .isEmpty()); } - @GameTest(templateName = "itematic:block.anvil") + @GameTest(structure = "itematic:block.anvil") public void combiningItemWithEnchantedBookInAnvilAddsEnchantment(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); @@ -58,17 +52,12 @@ public void combiningItemWithEnchantedBookInAnvilAddsEnchantment(TestContext con .setStack(TestUtil.createItemStackWithEnchantment(world, ItemKeys.IRON_PICKAXE, Enchantments.UNBREAKING)); anvilMenu.getSlot(1) .setStack(TestUtil.createItemStackWithEnchantment(world, ItemKeys.ENCHANTED_BOOK, Enchantments.EFFICIENCY)); - context.addInstantFinalTask(() -> { - ItemStack result = anvilMenu.getSlot(2).getStack(); - Assert.itemStackIsOf(result, ItemKeys.IRON_PICKAXE); - Assert.itemStackHasDataComponent(result, DataComponentTypes.ENCHANTMENTS, enchantments -> { - Assert.dataComponentHasEnchantment(enchantments, Enchantments.UNBREAKING); - Assert.dataComponentHasEnchantment(enchantments, Enchantments.EFFICIENCY); - }); - }); + context.addFinalTask(() -> Assert.itemStack(context, anvilMenu.getSlot(2).getStack()) + .is(ItemKeys.IRON_PICKAXE) + .hasEnchantments(Enchantments.UNBREAKING, Enchantments.EFFICIENCY)); } - @GameTest(templateName = "itematic:block.anvil") + @GameTest(structure = "itematic:block.anvil") public void combiningItemWithEnchantedBookWithIncompatibleEnchantmentInAnvilRejectsCombination(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); @@ -77,10 +66,11 @@ public void combiningItemWithEnchantedBookWithIncompatibleEnchantmentInAnvilReje .setStack(TestUtil.createItemStackWithEnchantment(world, ItemKeys.IRON_PICKAXE, Enchantments.UNBREAKING)); anvilMenu.getSlot(1) .setStack(TestUtil.createItemStackWithEnchantment(world, ItemKeys.ENCHANTED_BOOK, Enchantments.SHARPNESS)); - context.addInstantFinalTask(() -> Assert.itemStackIsEmpty(anvilMenu.getSlot(2).getStack())); + context.addFinalTask(() -> Assert.itemStack(context, anvilMenu.getSlot(2).getStack()) + .isEmpty()); } - @GameTest(templateName = "itematic:block.anvil") + @GameTest(structure = "itematic:block.anvil") public void combiningEnchantedBooksInAnvilCombinesEnchantments(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); @@ -89,13 +79,8 @@ public void combiningEnchantedBooksInAnvilCombinesEnchantments(TestContext conte .setStack(TestUtil.createItemStackWithEnchantment(world, ItemKeys.ENCHANTED_BOOK, Enchantments.UNBREAKING)); anvilMenu.getSlot(1) .setStack(TestUtil.createItemStackWithEnchantment(world, ItemKeys.ENCHANTED_BOOK, Enchantments.EFFICIENCY)); - context.addInstantFinalTask(() -> { - ItemStack result = anvilMenu.getSlot(2).getStack(); - Assert.itemStackIsOf(result, ItemKeys.ENCHANTED_BOOK); - Assert.itemStackHasDataComponent(result, DataComponentTypes.STORED_ENCHANTMENTS, storedEnchantments -> { - Assert.dataComponentHasEnchantment(storedEnchantments, Enchantments.UNBREAKING); - Assert.dataComponentHasEnchantment(storedEnchantments, Enchantments.EFFICIENCY); - }); - }); + context.addFinalTask(() -> Assert.itemStack(context, anvilMenu.getSlot(2).getStack()) + .is(ItemKeys.ENCHANTED_BOOK) + .hasEnchantments(Enchantments.UNBREAKING, Enchantments.EFFICIENCY)); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/block/BeehiveBlockTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/block/BeehiveBlockTestSuite.java index d8617395..fb01b616 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/block/BeehiveBlockTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/block/BeehiveBlockTestSuite.java @@ -1,10 +1,10 @@ package net.errorcraft.itematic.gametest.block; import net.errorcraft.itematic.item.ItemKeys; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; 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; @@ -12,23 +12,23 @@ public class BeehiveBlockTestSuite { private static final BlockPos BLOCK_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:block.beehive") + @GameTest(structure = "itematic:block.beehive") public void breakingBeehiveWithHoneyInCreativeModeDropsBeehive(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.CREATIVE); ServerWorld world = context.getWorld(); BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); state.getBlock().onBreak(world, absolutePos, state, player); - context.addInstantFinalTask(() -> context.expectItem(context.getWorld().itematic$getItem(ItemKeys.BEEHIVE).value())); + context.addFinalTask(() -> context.expectItem(context.getWorld().itematic$getItem(ItemKeys.BEEHIVE).value())); } - @GameTest(templateName = "itematic:block.bee_nest") + @GameTest(structure = "itematic:block.bee_nest") public void breakingBeeNestWithHoneyInCreativeModeDropsBeeNest(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.CREATIVE); ServerWorld world = context.getWorld(); BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); state.getBlock().onBreak(world, absolutePos, state, player); - context.addInstantFinalTask(() -> context.expectItem(context.getWorld().itematic$getItem(ItemKeys.BEE_NEST).value())); + context.addFinalTask(() -> context.expectItem(context.getWorld().itematic$getItem(ItemKeys.BEE_NEST).value())); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/block/BrewingStandBlockTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/block/BrewingStandBlockTestSuite.java index fef85671..25d52957 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/block/BrewingStandBlockTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/block/BrewingStandBlockTestSuite.java @@ -1,16 +1,16 @@ package net.errorcraft.itematic.gametest.block; +import net.errorcraft.itematic.assertion.Assert; 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.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; 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; @@ -18,7 +18,7 @@ public class BrewingStandBlockTestSuite { private static final BlockPos BLOCK_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:block.brewing_stand", tickLimit = 401) + @GameTest(structure = "itematic:block.brewing_stand", maxTicks = 401) public void brewingWaterBottleWithNetherWartTurnsItIntoAwkwardPotion(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); @@ -32,16 +32,14 @@ public void brewingWaterBottleWithNetherWartTurnsItIntoAwkwardPotion(TestContext context.createTimedTaskRunner() .expectMinDurationAndRun( 401, - () -> { - ItemStack resultPotion = brewingStandMenu.getSlot(0).getStack(); - Assert.itemStackIsOf(resultPotion, ItemKeys.POTION); - Assert.itemStackHasPotion(resultPotion, Potions.AWKWARD); - } + () -> Assert.itemStack(context, brewingStandMenu.getSlot(0).getStack()) + .is(ItemKeys.POTION) + .hasPotion(Potions.AWKWARD) ) .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.brewing_stand", tickLimit = 401) + @GameTest(structure = "itematic:block.brewing_stand", maxTicks = 401) public void brewingAwkwardPotionWithSugarTurnsItIntoSwiftnessPotion(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); @@ -57,14 +55,15 @@ public void brewingAwkwardPotionWithSugarTurnsItIntoSwiftnessPotion(TestContext 401, () -> { ItemStack resultPotion = brewingStandMenu.getSlot(0).getStack(); - Assert.itemStackIsOf(resultPotion, ItemKeys.POTION); - Assert.itemStackHasPotion(resultPotion, Potions.SWIFTNESS); + Assert.itemStack(context, resultPotion) + .is(ItemKeys.POTION) + .hasPotion(Potions.SWIFTNESS); } ) .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.brewing_stand", tickLimit = 401) + @GameTest(structure = "itematic:block.brewing_stand", maxTicks = 401) public void brewingSwiftnessPotionWithGlowstoneDustTurnsItIntoStrongSwiftnessPotion(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); @@ -80,14 +79,15 @@ public void brewingSwiftnessPotionWithGlowstoneDustTurnsItIntoStrongSwiftnessPot 401, () -> { ItemStack resultPotion = brewingStandMenu.getSlot(0).getStack(); - Assert.itemStackIsOf(resultPotion, ItemKeys.POTION); - Assert.itemStackHasPotion(resultPotion, Potions.STRONG_SWIFTNESS); + Assert.itemStack(context, resultPotion) + .is(ItemKeys.POTION) + .hasPotion(Potions.STRONG_SWIFTNESS); } ) .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.brewing_stand", tickLimit = 401) + @GameTest(structure = "itematic:block.brewing_stand", maxTicks = 401) public void brewingSwiftnessPotionWithRedstoneTurnsItIntoLongSwiftnessPotion(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); @@ -103,14 +103,15 @@ public void brewingSwiftnessPotionWithRedstoneTurnsItIntoLongSwiftnessPotion(Tes 401, () -> { ItemStack resultPotion = brewingStandMenu.getSlot(0).getStack(); - Assert.itemStackIsOf(resultPotion, ItemKeys.POTION); - Assert.itemStackHasPotion(resultPotion, Potions.LONG_SWIFTNESS); + Assert.itemStack(context, resultPotion) + .is(ItemKeys.POTION) + .hasPotion(Potions.LONG_SWIFTNESS); } ) .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.brewing_stand", tickLimit = 401) + @GameTest(structure = "itematic:block.brewing_stand", maxTicks = 401) public void brewingSwiftnessPotionWithGunpowderTurnsItIntoSwiftnessSplashPotion(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); @@ -126,14 +127,15 @@ public void brewingSwiftnessPotionWithGunpowderTurnsItIntoSwiftnessSplashPotion( 401, () -> { ItemStack resultPotion = brewingStandMenu.getSlot(0).getStack(); - Assert.itemStackIsOf(resultPotion, ItemKeys.SPLASH_POTION); - Assert.itemStackHasPotion(resultPotion, Potions.SWIFTNESS); + Assert.itemStack(context, resultPotion) + .is(ItemKeys.SPLASH_POTION) + .hasPotion(Potions.SWIFTNESS); } ) .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.brewing_stand", tickLimit = 401) + @GameTest(structure = "itematic:block.brewing_stand", maxTicks = 401) public void brewingSwiftnessSplashPotionWithDragonBreathTurnsItIntoSwiftnessLingeringPotionAndLeavesGlassBottle(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); @@ -149,16 +151,18 @@ public void brewingSwiftnessSplashPotionWithDragonBreathTurnsItIntoSwiftnessLing 401, () -> { ItemStack resultPotion = brewingStandMenu.getSlot(0).getStack(); - Assert.itemStackIsOf(resultPotion, ItemKeys.LINGERING_POTION); - Assert.itemStackHasPotion(resultPotion, Potions.SWIFTNESS); + Assert.itemStack(context, resultPotion) + .is(ItemKeys.LINGERING_POTION) + .hasPotion(Potions.SWIFTNESS); ItemStack ingredientRemainder = brewingStandMenu.getSlot(3).getStack(); - Assert.itemStackIsOf(ingredientRemainder, ItemKeys.GLASS_BOTTLE); + Assert.itemStack(context, ingredientRemainder) + .is(ItemKeys.GLASS_BOTTLE); } ) .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.brewing_stand", tickLimit = 401) + @GameTest(structure = "itematic:block.brewing_stand", maxTicks = 401) public void brewingDifferentPotionsOnlyModifiesCorrectTargets(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); @@ -178,20 +182,23 @@ public void brewingDifferentPotionsOnlyModifiesCorrectTargets(TestContext contex 401, () -> { ItemStack firstPotion = brewingStandMenu.getSlot(0).getStack(); - Assert.itemStackIsOf(firstPotion, ItemKeys.POTION); - Assert.itemStackHasPotion(firstPotion, Potions.SWIFTNESS); + Assert.itemStack(context, firstPotion) + .is(ItemKeys.POTION) + .hasPotion(Potions.SWIFTNESS); ItemStack secondPotion = brewingStandMenu.getSlot(1).getStack(); - Assert.itemStackIsOf(secondPotion, ItemKeys.POTION); - Assert.itemStackHasPotion(secondPotion, Potions.AWKWARD); + Assert.itemStack(context, secondPotion) + .is(ItemKeys.POTION) + .hasPotion(Potions.AWKWARD); ItemStack thirdPotion = brewingStandMenu.getSlot(2).getStack(); - Assert.itemStackIsOf(thirdPotion, ItemKeys.POTION); - Assert.itemStackHasPotion(thirdPotion, Potions.LEAPING); + Assert.itemStack(context, thirdPotion) + .is(ItemKeys.POTION) + .hasPotion(Potions.LEAPING); } ) .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.brewing_stand", tickLimit = 401) + @GameTest(structure = "itematic:block.brewing_stand", maxTicks = 401) public void brewingPotionsTargetingMultipleValidRecipesModifiesBoth(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); @@ -209,11 +216,13 @@ public void brewingPotionsTargetingMultipleValidRecipesModifiesBoth(TestContext 401, () -> { ItemStack firstPotion = brewingStandMenu.getSlot(0).getStack(); - Assert.itemStackIsOf(firstPotion, ItemKeys.POTION); - Assert.itemStackHasPotion(firstPotion, Potions.MUNDANE); + Assert.itemStack(context, firstPotion) + .is(ItemKeys.POTION) + .hasPotion(Potions.MUNDANE); ItemStack secondPotion = brewingStandMenu.getSlot(1).getStack(); - Assert.itemStackIsOf(secondPotion, ItemKeys.POTION); - Assert.itemStackHasPotion(secondPotion, Potions.SWIFTNESS); + Assert.itemStack(context, secondPotion) + .is(ItemKeys.POTION) + .hasPotion(Potions.SWIFTNESS); } ) .completeIfSuccessful(); diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/block/CandleBlockTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/block/CandleBlockTestSuite.java index 5c0bdecc..313fc9bb 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/block/CandleBlockTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/block/CandleBlockTestSuite.java @@ -1,13 +1,14 @@ package net.errorcraft.itematic.gametest.block; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.block.Blocks; import net.minecraft.block.CandleBlock; 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.util.math.BlockPos; @@ -18,25 +19,27 @@ public class CandleBlockTestSuite { private static final BlockPos GROUND_POSITION = new BlockPos(1, 0, 1); private static final BlockPos PLACED_BLOCK_POSITION = GROUND_POSITION.add(0, 1, 0); - @GameTest(templateName = "itematic:block.white_candle") + @GameTest(structure = "itematic:block.white_candle") public void usingSameCandleOnCandleBlockIncreasesCandles(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.WHITE_CANDLE); + ItemStack whiteCandle = world.itematic$createStack(ItemKeys.WHITE_CANDLE); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, whiteCandle); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, GROUND_POSITION, Direction.UP); - context.addInstantFinalTask(() -> context.expectBlockProperty(PLACED_BLOCK_POSITION, CandleBlock.CANDLES, 2)); + TestUtil.useStackOnBlockInside(context, player, whiteCandle, GROUND_POSITION, Direction.UP); + context.addFinalTask(() -> Assert.blockState(context, PLACED_BLOCK_POSITION) + .hasProperty(CandleBlock.CANDLES, 2)); } - @GameTest(templateName = "itematic:block.white_candle") + @GameTest(structure = "itematic:block.white_candle") public void usingDifferentlyColoredCandleOnCandleBlockDoesNotReplaceBlock(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.WHITE_CANDLE); + ItemStack whiteCandle = world.itematic$createStack(ItemKeys.WHITE_CANDLE); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, whiteCandle); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, GROUND_POSITION, Direction.UP); - context.addInstantFinalTask(() -> context.expectBlock(Blocks.WHITE_CANDLE, PLACED_BLOCK_POSITION)); + TestUtil.useStackOnBlockInside(context, player, whiteCandle, GROUND_POSITION, Direction.UP); + context.addFinalTask(() -> Assert.blockState(context, PLACED_BLOCK_POSITION) + .is(Blocks.WHITE_CANDLE)); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/block/ComposterBlockTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/block/ComposterBlockTestSuite.java index 6f288616..ae8cf541 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/block/ComposterBlockTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/block/ComposterBlockTestSuite.java @@ -1,11 +1,10 @@ package net.errorcraft.itematic.gametest.block; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.server.world.ServerWorld; import net.minecraft.state.property.Properties; -import net.minecraft.test.GameTest; import net.minecraft.test.TestContext; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; @@ -14,29 +13,21 @@ public class ComposterBlockTestSuite { private static final BlockPos COMPOSTER_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:block.composter.empty") + @GameTest(structure = "itematic:block.composter.empty") public void usingCompostableItemOnComposterIncreasesLevel(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.PUMPKIN_PIE); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, context.getWorld().itematic$createStack(ItemKeys.PUMPKIN_PIE)); context.useBlock(COMPOSTER_POSITION, player); - context.addInstantFinalTask(() -> context.checkBlockState( - COMPOSTER_POSITION, - state -> state.get(Properties.LEVEL_8) == 1, - () -> "Composter block level did not increase to 1" - )); + context.addFinalTask(() -> Assert.blockState(context, COMPOSTER_POSITION) + .hasProperty(Properties.LEVEL_8, 1, () -> "Expected Composter level to increase to 1")); } - @GameTest(templateName = "itematic:block.composter.full") + @GameTest(structure = "itematic:block.composter.full") public void usingBlockOnFullComposterEmptiesComposterAndSpawnsBoneMeal(TestContext context) { context.useBlock(COMPOSTER_POSITION); - context.addInstantFinalTask(() -> { - context.checkBlockState( - COMPOSTER_POSITION, - state -> state.get(Properties.LEVEL_8) == 0, - () -> "Composter block was not emptied" - ); + context.addFinalTask(() -> { + Assert.blockState(context, COMPOSTER_POSITION) + .hasProperty(Properties.LEVEL_8, 0, () -> "Expected Composter to be emptied"); context.expectItem(context.getWorld().itematic$getItem(ItemKeys.BONE_MEAL).value()); }); } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/block/DispenserBehaviorTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/block/DispenserBehaviorTestSuite.java index 60ba2b7e..1ea0f1e6 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/block/DispenserBehaviorTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/block/DispenserBehaviorTestSuite.java @@ -1,9 +1,10 @@ package net.errorcraft.itematic.gametest.block; +import net.errorcraft.itematic.assertion.Assert; 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.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.block.BeehiveBlock; import net.minecraft.block.Blocks; import net.minecraft.block.FacingBlock; @@ -20,7 +21,6 @@ import net.minecraft.registry.tag.FluidTags; import net.minecraft.server.world.ServerWorld; import net.minecraft.state.property.Properties; -import net.minecraft.test.GameTest; import net.minecraft.test.TestContext; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; @@ -32,125 +32,137 @@ public class DispenserBehaviorTestSuite { private static final BlockPos OUTPUT_POSITION = DISPENSER_POSITION.add(0, 0, -1); private static final BlockPos ABOVE_OUTPUT_POSITION = OUTPUT_POSITION.add(0, 1, 0); - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingArrowSpawnsArrow(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.ARROW); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectEntity(EntityType.ARROW); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.ARROW)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectEntity(EntityType.ARROW); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingExperienceBottleSpawnsExperienceBottle(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.EXPERIENCE_BOTTLE); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectEntity(EntityType.EXPERIENCE_BOTTLE); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.EXPERIENCE_BOTTLE)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectEntity(EntityType.EXPERIENCE_BOTTLE); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingFireworkRocketSpawnsFireworkRocket(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.FIREWORK_ROCKET); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectEntity(EntityType.FIREWORK_ROCKET); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.FIREWORK_ROCKET)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectEntity(EntityType.FIREWORK_ROCKET); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingFireChargeSpawnsEntity(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.FIRE_CHARGE); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectEntity(EntityType.SMALL_FIREBALL); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.FIRE_CHARGE)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectEntity(EntityType.SMALL_FIREBALL); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingPigSpawnEggSpawnsPig(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.PIG_SPAWN_EGG); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectEntity(EntityType.PIG); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.PIG_SPAWN_EGG)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectEntity(EntityType.PIG); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingArmorStandSpawnsArmorStand(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.ARMOR_STAND); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectEntity(EntityType.ARMOR_STAND); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.ARMOR_STAND)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectEntity(EntityType.ARMOR_STAND); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingSpruceBoatSpawnsSpruceBoat(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SPRUCE_BOAT); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectEntityAt(EntityType.SPRUCE_BOAT, OUTPUT_POSITION); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.SPRUCE_BOAT)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectEntityAt(EntityType.SPRUCE_BOAT, OUTPUT_POSITION); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser.grass_block") + @GameTest(structure = "itematic:block.dispenser.grass_block") public void dispensingBoneMealFertilizesBlock(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BONE_MEAL); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.dontExpectBlock(Blocks.AIR, ABOVE_OUTPUT_POSITION); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.BONE_MEAL)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.blockState(context, ABOVE_OUTPUT_POSITION) + .isNot(Blocks.AIR); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser.bedrock") + @GameTest(structure = "itematic:block.dispenser.bedrock") public void dispensingBoneMealOnInvalidBlockKeepsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BONE_MEAL); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectBlock(Blocks.AIR, ABOVE_OUTPUT_POSITION); - context.dontExpectItem(world.itematic$getItem(ItemKeys.BONE_MEAL).value()); - Assert.itemStackIsOf(blockEntity.getStack(0), ItemKeys.BONE_MEAL); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.BONE_MEAL)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.blockState(context, ABOVE_OUTPUT_POSITION) + .is(Blocks.AIR); + context.dontExpectItem(world.itematic$getItem(ItemKeys.BONE_MEAL).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .is(ItemKeys.BONE_MEAL); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingEquipmentEquipsEntity(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); @@ -159,27 +171,33 @@ public void dispensingEquipmentEquipsEntity(TestContext context) { world.spawnEntity(player); ItemStack stack = world.itematic$createStack(ItemKeys.IRON_HELMET); blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - Assert.itemStackIsOf(player.getEquippedStack(EquipmentSlot.HEAD), ItemKeys.IRON_HELMET); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.itemStack(context, player.getEquippedStack(EquipmentSlot.HEAD)) + .is(ItemKeys.IRON_HELMET); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingEquipmentWithNoEntityDropsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.IRON_HELMET); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectItem(world.itematic$getItem(ItemKeys.IRON_HELMET).value()); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.IRON_HELMET)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectItem(world.itematic$getItem(ItemKeys.IRON_HELMET).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingHeadEquipsEntity(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); @@ -188,365 +206,424 @@ public void dispensingHeadEquipsEntity(TestContext context) { world.spawnEntity(player); ItemStack stack = world.itematic$createStack(ItemKeys.SKELETON_SKULL); blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - Assert.itemStackIsOf(player.getEquippedStack(EquipmentSlot.HEAD), ItemKeys.SKELETON_SKULL); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.itemStack(context, player.getEquippedStack(EquipmentSlot.HEAD)) + .is(ItemKeys.SKELETON_SKULL); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingHeadWithNoEntityKeepsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SKELETON_SKULL); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.dontExpectItem(world.itematic$getItem(ItemKeys.SKELETON_SKULL).value()); - Assert.itemStackIsOf(blockEntity.getStack(0), ItemKeys.SKELETON_SKULL); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.SKELETON_SKULL)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.dontExpectItem(world.itematic$getItem(ItemKeys.SKELETON_SKULL).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .is(ItemKeys.SKELETON_SKULL); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingWaterBucketPlacesWater(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.WATER_BUCKET); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - Assert.fluidIsIn(context, FluidTags.WATER, OUTPUT_POSITION); - Assert.itemStackIsOf(blockEntity.getStack(0), ItemKeys.BUCKET); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.WATER_BUCKET)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.fluidState(context, OUTPUT_POSITION) + .is(FluidTags.WATER); + Assert.itemStack(context, blockEntity.getStack(0)) + .is(ItemKeys.BUCKET); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser.bedrock") + @GameTest(structure = "itematic:block.dispenser.bedrock") public void dispensingWaterBucketWithObstructedBlockDropsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.WATER_BUCKET); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectItem(world.itematic$getItem(ItemKeys.WATER_BUCKET).value()); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.WATER_BUCKET)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectItem(world.itematic$getItem(ItemKeys.WATER_BUCKET).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingPowderSnowBucketPlacesPowderSnow(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.POWDER_SNOW_BUCKET); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectBlock(Blocks.POWDER_SNOW, OUTPUT_POSITION); - Assert.itemStackIsOf(blockEntity.getStack(0), ItemKeys.BUCKET); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.POWDER_SNOW_BUCKET)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.blockState(context, OUTPUT_POSITION) + .is(Blocks.POWDER_SNOW); + Assert.itemStack(context, blockEntity.getStack(0)) + .is(ItemKeys.BUCKET); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser.bedrock") + @GameTest(structure = "itematic:block.dispenser.bedrock") public void dispensingPowderSnowBucketWithObstructedBlockDropsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.POWDER_SNOW_BUCKET); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectItem(world.itematic$getItem(ItemKeys.POWDER_SNOW_BUCKET).value()); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.POWDER_SNOW_BUCKET)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectItem(world.itematic$getItem(ItemKeys.POWDER_SNOW_BUCKET).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingSalmonBucketPlacesWaterAndSpawnsSalmon(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SALMON_BUCKET); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - Assert.fluidIsIn(context, FluidTags.WATER, OUTPUT_POSITION); - context.expectEntity(EntityType.SALMON); - Assert.itemStackIsOf(blockEntity.getStack(0), ItemKeys.BUCKET); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.SALMON_BUCKET)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.fluidState(context, OUTPUT_POSITION) + .is(FluidTags.WATER); + context.expectEntity(EntityType.SALMON); + Assert.itemStack(context, blockEntity.getStack(0)) + .is(ItemKeys.BUCKET); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser.bedrock") + @GameTest(structure = "itematic:block.dispenser.bedrock") public void dispensingSalmonBucketWithObstructedBlockDropsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SALMON_BUCKET); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectItem(world.itematic$getItem(ItemKeys.SALMON_BUCKET).value()); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.SALMON_BUCKET)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectItem(world.itematic$getItem(ItemKeys.SALMON_BUCKET).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser.water") + @GameTest(structure = "itematic:block.dispenser.water") public void dispensingBucketPicksUpFluid(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BUCKET); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - Assert.fluidIsOf(context, Fluids.EMPTY, OUTPUT_POSITION); - Assert.itemStackIsOf(blockEntity.getStack(0), ItemKeys.WATER_BUCKET); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.BUCKET)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.fluidState(context, OUTPUT_POSITION) + .is(Fluids.EMPTY); + Assert.itemStack(context, blockEntity.getStack(0)) + .is(ItemKeys.WATER_BUCKET); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingBucketWithNothingToPickUpDropsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BUCKET); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectItem(world.itematic$getItem(ItemKeys.BUCKET).value()); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.BUCKET)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectItem(world.itematic$getItem(ItemKeys.BUCKET).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser.dirt") + @GameTest(structure = "itematic:block.dispenser.dirt") public void dispensingWaterBottleConvertsBlockToMud(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); ItemStack stack = PotionContentsComponentUtil.setPotion(world.itematic$createStack(ItemKeys.POTION), Potions.WATER); blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectBlock(Blocks.MUD, OUTPUT_POSITION); - Assert.itemStackIsOf(blockEntity.getStack(0), ItemKeys.GLASS_BOTTLE); - })); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.blockState(context, OUTPUT_POSITION) + .is(Blocks.MUD); + Assert.itemStack(context, blockEntity.getStack(0)) + .is(ItemKeys.GLASS_BOTTLE); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser.bedrock") + @GameTest(structure = "itematic:block.dispenser.bedrock") public void dispensingWaterBottleOnInvalidBlockDropsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); ItemStack stack = PotionContentsComponentUtil.setPotion(world.itematic$createStack(ItemKeys.POTION), Potions.WATER); blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectItem(world.itematic$getItem(ItemKeys.POTION).value()); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectItem(world.itematic$getItem(ItemKeys.POTION).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser.beehive") + @GameTest(structure = "itematic:block.dispenser.beehive") public void dispensingGlassBottleOnBeehiveFillsBottleWithHoney(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.GLASS_BOTTLE); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.checkBlockState( - OUTPUT_POSITION, - state -> state.get(Properties.HONEY_LEVEL) == 0, - () -> "Honey level was not reset" - ); - Assert.itemStackIsOf(blockEntity.getStack(0), ItemKeys.HONEY_BOTTLE); - })); - } - - @GameTest(templateName = "itematic:block.dispenser.water") + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.GLASS_BOTTLE)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.blockState(context, OUTPUT_POSITION) + .hasProperty(Properties.HONEY_LEVEL, 0, () -> "Expected honey level to be reset"); + Assert.itemStack(context, blockEntity.getStack(0)) + .is(ItemKeys.HONEY_BOTTLE); + }) + .completeIfSuccessful(); + } + + @GameTest(structure = "itematic:block.dispenser.water") public void dispensingGlassBottleOnWaterFillsBottleWithWater(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.GLASS_BOTTLE); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - Assert.itemStackIsOf(blockEntity.getStack(0), ItemKeys.POTION); - Assert.itemStackHasPotion(blockEntity.getStack(0), Potions.WATER); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.GLASS_BOTTLE)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> Assert.itemStack(context, blockEntity.getStack(0)) + .is(ItemKeys.POTION) + .hasPotion(Potions.WATER)) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser.bedrock") + @GameTest(structure = "itematic:block.dispenser.bedrock") public void dispensingGlassBottleOnInvalidBlockDropsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.GLASS_BOTTLE); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectItem(world.itematic$getItem(ItemKeys.GLASS_BOTTLE).value()); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.GLASS_BOTTLE)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectItem(world.itematic$getItem(ItemKeys.GLASS_BOTTLE).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingHorseArmorOnHorseEquipsHorse(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.IRON_HORSE_ARMOR); - blockEntity.addToFirstFreeSlot(stack); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.IRON_HORSE_ARMOR)); HorseEntity horse = TestUtil.createEntity(context, EntityType.HORSE, entity -> { TestUtil.setEntityPos(context, entity, OUTPUT_POSITION); entity.setTame(true); }); world.spawnEntity(horse); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - Assert.itemStackIsOf(horse.getBodyArmor(), ItemKeys.IRON_HORSE_ARMOR); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); - } - - @GameTest(templateName = "itematic:block.dispenser") + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.itemStack(context, horse.getBodyArmor()) + .is(ItemKeys.IRON_HORSE_ARMOR); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); + } + + @GameTest(structure = "itematic:block.dispenser") public void dispensingHorseArmorWithNoEntityDropsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.IRON_HORSE_ARMOR); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectItem(world.itematic$getItem(ItemKeys.IRON_HORSE_ARMOR).value()); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.IRON_HORSE_ARMOR)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectItem(world.itematic$getItem(ItemKeys.IRON_HORSE_ARMOR).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingCarpetOnLlamaEquipsLlama(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.WHITE_CARPET); - blockEntity.addToFirstFreeSlot(stack); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.WHITE_CARPET)); LlamaEntity llama = TestUtil.createEntity(context, EntityType.LLAMA, entity -> { TestUtil.setEntityPos(context, entity, OUTPUT_POSITION); entity.setTame(true); }); world.spawnEntity(llama); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - Assert.itemStackIsOf(llama.getBodyArmor(), ItemKeys.WHITE_CARPET); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); - } - - @GameTest(templateName = "itematic:block.dispenser") + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.itemStack(context, llama.getBodyArmor()) + .is(ItemKeys.WHITE_CARPET); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); + } + + @GameTest(structure = "itematic:block.dispenser") public void dispensingCarpetWithNoEntityDropsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.WHITE_CARPET); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectItem(world.itematic$getItem(ItemKeys.WHITE_CARPET).value()); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.WHITE_CARPET)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectItem(world.itematic$getItem(ItemKeys.WHITE_CARPET).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingChestOnMuleEquipsMuleWithChest(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CHEST); - blockEntity.addToFirstFreeSlot(stack); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.CHEST)); MuleEntity mule = TestUtil.createEntity(context, EntityType.MULE, entity -> { TestUtil.setEntityPos(context, entity, OUTPUT_POSITION); entity.setTame(true); }); world.spawnEntity(mule); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.assertTrue(mule.hasChest(), "Expected mule to have a chest"); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); - } - - @GameTest(templateName = "itematic:block.dispenser") + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.isTrue( + context, + mule.hasChest(), + () -> "Expected Mule to have a chest" + ); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); + } + + @GameTest(structure = "itematic:block.dispenser") public void dispensingChestOnLlamaEquipsLlamaWithChest(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CHEST); - blockEntity.addToFirstFreeSlot(stack); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.CHEST)); LlamaEntity llama = TestUtil.createEntity(context, EntityType.LLAMA, entity -> { TestUtil.setEntityPos(context, entity, OUTPUT_POSITION); entity.setTame(true); }); world.spawnEntity(llama); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.assertTrue(llama.hasChest(), "Expected llama to have a chest"); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); - } - - @GameTest(templateName = "itematic:block.dispenser") + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.isTrue( + context, + llama.hasChest(), + () -> "Expected Llama to have a chest" + ); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); + } + + @GameTest(structure = "itematic:block.dispenser") public void dispensingChestWithNoEntityDropsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CHEST); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectItem(world.itematic$getItem(ItemKeys.CHEST).value()); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.CHEST)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectItem(world.itematic$getItem(ItemKeys.CHEST).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingShulkerBoxWithBlockBelowOutputPlacesShulkerBoxFacingUp(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SHULKER_BOX); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectBlockProperty(OUTPUT_POSITION, FacingBlock.FACING, Direction.UP); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.SHULKER_BOX)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.blockState(context, OUTPUT_POSITION) + .hasProperty(FacingBlock.FACING, Direction.UP); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser.gap_below_output") + @GameTest(structure = "itematic:block.dispenser.gap_below_output") public void dispensingShulkerBoxWithoutBlockBelowOutputPlacesShulkerBoxWithDispenserDirection(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SHULKER_BOX); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - Direction dispenserDirection = context.getBlockState(DISPENSER_POSITION).get(FacingBlock.FACING); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectBlockProperty(OUTPUT_POSITION, FacingBlock.FACING, dispenserDirection); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.SHULKER_BOX)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Direction dispenserDirection = context.getBlockState(DISPENSER_POSITION).get(FacingBlock.FACING); + Assert.blockState(context, OUTPUT_POSITION) + .hasProperty(FacingBlock.FACING, dispenserDirection); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser.bedrock") + @GameTest(structure = "itematic:block.dispenser.bedrock") public void dispensingShulkerBoxWithObstructedBlockKeepsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SHULKER_BOX); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.dontExpectItem(world.itematic$getItem(ItemKeys.SHULKER_BOX).value()); - Assert.itemStackIsOf(blockEntity.getStack(0), ItemKeys.SHULKER_BOX); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.SHULKER_BOX)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.dontExpectItem(world.itematic$getItem(ItemKeys.SHULKER_BOX).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .is(ItemKeys.SHULKER_BOX); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingTntSpawnsTnt(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.TNT); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectEntity(EntityType.TNT); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.TNT)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectEntity(EntityType.TNT); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingCarvedPumpkinEquipsEntity(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); @@ -555,245 +632,289 @@ public void dispensingCarvedPumpkinEquipsEntity(TestContext context) { world.spawnEntity(player); ItemStack stack = world.itematic$createStack(ItemKeys.CARVED_PUMPKIN); blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - Assert.itemStackIsOf(player.getEquippedStack(EquipmentSlot.HEAD), ItemKeys.CARVED_PUMPKIN); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.itemStack(context, player.getEquippedStack(EquipmentSlot.HEAD)) + .is(ItemKeys.CARVED_PUMPKIN); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser.iron_golem_structure") + @GameTest(structure = "itematic:block.dispenser.iron_golem_structure") public void dispensingCarvedPumpkinPlacesCarvedPumpkinOnIronGolemStructure(TestContext context) { BlockPos offset = new BlockPos(0, 2, 0); DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION.add(offset), BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CARVED_PUMPKIN); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION.add(offset)); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectEntity(EntityType.IRON_GOLEM); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); - } - - @GameTest(templateName = "itematic:block.dispenser") + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.CARVED_PUMPKIN)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION.add(offset))) + .expectMinDurationAndRun(4, () -> { + context.expectEntity(EntityType.IRON_GOLEM); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); + } + + @GameTest(structure = "itematic:block.dispenser") public void dispensingCarvedPumpkinWithNoValidTargetKeepsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CARVED_PUMPKIN); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.dontExpectItem(world.itematic$getItem(ItemKeys.CARVED_PUMPKIN).value()); - Assert.itemStackIsOf(blockEntity.getStack(0), ItemKeys.CARVED_PUMPKIN); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.CARVED_PUMPKIN)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.dontExpectItem(world.itematic$getItem(ItemKeys.CARVED_PUMPKIN).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .is(ItemKeys.CARVED_PUMPKIN); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser.respawn_anchor") + @GameTest(structure = "itematic:block.dispenser.respawn_anchor") public void dispensingGlowstoneOnRespawnAnchorChargesRespawnAnchor(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.GLOWSTONE); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectBlockProperty(OUTPUT_POSITION, RespawnAnchorBlock.CHARGES, 1); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.GLOWSTONE)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.blockState(context, OUTPUT_POSITION) + .hasProperty(RespawnAnchorBlock.CHARGES, 1); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser.respawn_anchor.full") + @GameTest(structure = "itematic:block.dispenser.respawn_anchor.full") public void dispensingGlowstoneOnFullRespawnAnchorKeepsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.GLOWSTONE); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.dontExpectItem(world.itematic$getItem(ItemKeys.GLOWSTONE).value()); - Assert.itemStackIsOf(blockEntity.getStack(0), ItemKeys.GLOWSTONE); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.GLOWSTONE)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.dontExpectItem(world.itematic$getItem(ItemKeys.GLOWSTONE).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .is(ItemKeys.GLOWSTONE); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingGlowstoneOnInvalidBlockDropsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.GLOWSTONE); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectItem(world.itematic$getItem(ItemKeys.GLOWSTONE).value()); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.GLOWSTONE)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectItem(world.itematic$getItem(ItemKeys.GLOWSTONE).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingShearsOnSheepShearsSheep(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SHEARS); - blockEntity.addToFirstFreeSlot(stack); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.SHEARS)); SheepEntity sheep = context.spawnEntity(EntityType.SHEEP, OUTPUT_POSITION); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.assertTrue(sheep.isSheared(), "Expected sheep to be sheared"); - context.expectItem(world.itematic$getItem(ItemKeys.WHITE_WOOL).value()); - context.assertTrue(blockEntity.getStack(0).isDamaged(), "Expected item stack to be damaged"); - })); - } - - @GameTest(templateName = "itematic:block.dispenser.beehive") + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.isTrue( + context, + sheep.isSheared(), + () -> "Expected Sheep to be sheared" + ); + context.expectItem(world.itematic$getItem(ItemKeys.WHITE_WOOL).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .isDamaged(); + }) + .completeIfSuccessful(); + } + + @GameTest(structure = "itematic:block.dispenser.beehive") public void dispensingShearsOnBeehiveWithHoneyShearsBeehive(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SHEARS); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectBlockProperty(OUTPUT_POSITION, BeehiveBlock.HONEY_LEVEL, 0); - context.expectItem(world.itematic$getItem(ItemKeys.HONEYCOMB).value()); - context.assertTrue(blockEntity.getStack(0).isDamaged(), "Expected item stack to be damaged"); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.SHEARS)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.blockState(context, OUTPUT_POSITION) + .hasProperty(BeehiveBlock.HONEY_LEVEL, 0); + context.expectItem(world.itematic$getItem(ItemKeys.HONEYCOMB).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .isDamaged(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingShearsWithNoValidTargetKeepsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SHEARS); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.dontExpectItem(world.itematic$getItem(ItemKeys.SHEARS).value()); - Assert.itemStackIsOf(blockEntity.getStack(0), ItemKeys.SHEARS); - context.assertFalse(blockEntity.getStack(0).isDamaged(), "Expected item stack not to be damaged"); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.SHEARS)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.dontExpectItem(world.itematic$getItem(ItemKeys.SHEARS).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .is(ItemKeys.SHEARS) + .isNotDamaged(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingSaddleOnPigEquipsPig(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SADDLE); - blockEntity.addToFirstFreeSlot(stack); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.SADDLE)); PigEntity pig = context.spawnEntity(EntityType.PIG, OUTPUT_POSITION); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.assertTrue(pig.isSaddled(), "Expected pig to be saddled"); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); - } - - @GameTest(templateName = "itematic:block.dispenser") + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.livingEntity(context, pig) + .hasEquippedStack(EquipmentSlot.SADDLE, stack -> stack.is(ItemKeys.SADDLE)); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); + } + + @GameTest(structure = "itematic:block.dispenser") public void dispensingSaddleOnHorseEquipsHorse(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SADDLE); - blockEntity.addToFirstFreeSlot(stack); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.SADDLE)); HorseEntity horse = TestUtil.createEntity(context, EntityType.HORSE, entity -> { TestUtil.setEntityPos(context, entity, OUTPUT_POSITION); entity.setTame(true); }); world.spawnEntity(horse); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.assertTrue(horse.isSaddled(), "Expected horse to be saddled"); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); - } - - @GameTest(templateName = "itematic:block.dispenser") + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.livingEntity(context, horse) + .hasEquippedStack(EquipmentSlot.SADDLE, stack -> stack.is(ItemKeys.SADDLE)); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); + } + + @GameTest(structure = "itematic:block.dispenser") public void dispensingSaddleWithNoEntityDropsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SADDLE); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectItem(world.itematic$getItem(ItemKeys.SADDLE).value()); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.SADDLE)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectItem(world.itematic$getItem(ItemKeys.SADDLE).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingFlintAndSteelPlacesFire(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.FLINT_AND_STEEL); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectBlock(Blocks.FIRE, OUTPUT_POSITION); - context.assertTrue(blockEntity.getStack(0).isDamaged(), "Expected item stack to be damaged"); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.FLINT_AND_STEEL)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.blockState(context, OUTPUT_POSITION) + .is(Blocks.FIRE); + Assert.itemStack(context, blockEntity.getStack(0)) + .isDamaged(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser.gap_below_output") + @GameTest(structure = "itematic:block.dispenser.gap_below_output") public void dispensingFlintAndSteelOnInvalidBlockKeepsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.FLINT_AND_STEEL); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.dontExpectItem(world.itematic$getItem(ItemKeys.FLINT_AND_STEEL).value()); - Assert.itemStackIsOf(blockEntity.getStack(0), ItemKeys.FLINT_AND_STEEL); - context.assertFalse(blockEntity.getStack(0).isDamaged(), "Expected item stack not to be damaged"); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.FLINT_AND_STEEL)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.dontExpectItem(world.itematic$getItem(ItemKeys.FLINT_AND_STEEL).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .is(ItemKeys.FLINT_AND_STEEL) + .isNotDamaged(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingBrushDropsArmadilloScute(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BRUSH); - blockEntity.addToFirstFreeSlot(stack); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.BRUSH)); context.spawnEntity(EntityType.ARMADILLO, OUTPUT_POSITION); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectItem(world.itematic$getItem(ItemKeys.ARMADILLO_SCUTE).value()); - context.assertTrue(blockEntity.getStack(0).isDamaged(), "Expected item stack to be damaged"); - })); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectItem(world.itematic$getItem(ItemKeys.ARMADILLO_SCUTE).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .isDamaged(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingBrushWithNoEntityKeepsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BRUSH); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.dontExpectItem(world.itematic$getItem(ItemKeys.BRUSH).value()); - Assert.itemStackIsOf(blockEntity.getStack(0), ItemKeys.BRUSH); - context.assertFalse(blockEntity.getStack(0).isDamaged(), "Expected item stack not to be damaged"); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.BRUSH)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.dontExpectItem(world.itematic$getItem(ItemKeys.BRUSH).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .is(ItemKeys.BRUSH) + .isNotDamaged(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser.copper_block") + @GameTest(structure = "itematic:block.dispenser.copper_block") public void dispensingHoneycombWaxesBlock(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.HONEYCOMB); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectBlock(Blocks.WAXED_COPPER_BLOCK, OUTPUT_POSITION); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(context.getWorld().itematic$createStack(ItemKeys.HONEYCOMB)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + Assert.blockState(context, OUTPUT_POSITION) + .is(Blocks.WAXED_COPPER_BLOCK); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } - @GameTest(templateName = "itematic:block.dispenser") + @GameTest(structure = "itematic:block.dispenser") public void dispensingHoneycombOnInvalidBlockDropsItem(TestContext context) { DispenserBlockEntity blockEntity = TestUtil.getBlockEntity(context, DISPENSER_POSITION, BlockEntityType.DISPENSER); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.HONEYCOMB); - blockEntity.addToFirstFreeSlot(stack); - context.pushButton(BUTTON_POSITION); - context.runAtTick(4, () -> context.addFinalTask(() -> { - context.expectItem(world.itematic$getItem(ItemKeys.HONEYCOMB).value()); - Assert.itemStackIsEmpty(blockEntity.getStack(0)); - })); + blockEntity.addToFirstFreeSlot(world.itematic$createStack(ItemKeys.HONEYCOMB)); + context.createTimedTaskRunner() + .createAndAddReported(() -> context.pushButton(BUTTON_POSITION)) + .expectMinDurationAndRun(4, () -> { + context.expectItem(world.itematic$getItem(ItemKeys.HONEYCOMB).value()); + Assert.itemStack(context, blockEntity.getStack(0)) + .isEmpty(); + }) + .completeIfSuccessful(); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/block/EnchantingTableTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/block/EnchantingTableTestSuite.java index e176b5e5..3de057bc 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/block/EnchantingTableTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/block/EnchantingTableTestSuite.java @@ -1,16 +1,15 @@ package net.errorcraft.itematic.gametest.block; -import net.errorcraft.itematic.gametest.Assert; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.component.DataComponentTypes; import net.minecraft.enchantment.Enchantments; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; import net.minecraft.screen.EnchantmentScreenHandler; import net.minecraft.screen.ScreenHandlerType; 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; @@ -18,7 +17,7 @@ public class EnchantingTableTestSuite { private static final BlockPos BLOCK_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:block.enchanting_table") + @GameTest(structure = "itematic:block.enchanting_table") public void placingEnchantableItemWithoutEnchantmentsSuggestsEnchantments(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); @@ -27,12 +26,14 @@ public void placingEnchantableItemWithoutEnchantmentsSuggestsEnchantments(TestCo .setStack(world.itematic$createStack(ItemKeys.IRON_PICKAXE)); enchantmentMenu.getSlot(1) .setStack(world.itematic$createStack(ItemKeys.LAPIS_LAZULI)); - context.addInstantFinalTask(() -> { - context.assertTrue(enchantmentMenu.enchantmentPower[0] > 0, "Expected enchantments to be suggested"); - }); + context.addFinalTask(() -> Assert.isTrue( + context, + enchantmentMenu.enchantmentPower[0] > 0, + () -> "Expected enchantments to be suggested" + )); } - @GameTest(templateName = "itematic:block.enchanting_table") + @GameTest(structure = "itematic:block.enchanting_table") public void placingUnenchantableItemInEnchantingTableDoesNotSuggestEnchantments(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); @@ -41,12 +42,14 @@ public void placingUnenchantableItemInEnchantingTableDoesNotSuggestEnchantments( .setStack(world.itematic$createStack(ItemKeys.STICK)); enchantmentMenu.getSlot(1) .setStack(world.itematic$createStack(ItemKeys.LAPIS_LAZULI)); - context.addInstantFinalTask(() -> { - context.assertTrue(enchantmentMenu.enchantmentPower[0] == 0, "Expected no enchantments to be suggested"); - }); + context.addFinalTask(() -> Assert.isTrue( + context, + enchantmentMenu.enchantmentPower[0] == 0, + () -> "Expected no enchantments to be suggested" + )); } - @GameTest(templateName = "itematic:block.enchanting_table") + @GameTest(structure = "itematic:block.enchanting_table") public void placingEnchantableItemWithEnchantmentsInEnchantingTableDoesNotSuggestEnchantments(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); @@ -55,12 +58,14 @@ public void placingEnchantableItemWithEnchantmentsInEnchantingTableDoesNotSugges .setStack(TestUtil.createItemStackWithEnchantment(world, ItemKeys.IRON_PICKAXE, Enchantments.UNBREAKING)); enchantmentMenu.getSlot(1) .setStack(world.itematic$createStack(ItemKeys.LAPIS_LAZULI)); - context.addInstantFinalTask(() -> { - context.assertTrue(enchantmentMenu.enchantmentPower[0] == 0, "Expected no enchantments to be suggested"); - }); + context.addFinalTask(() -> Assert.isTrue( + context, + enchantmentMenu.enchantmentPower[0] == 0, + () -> "Expected no enchantments to be suggested" + )); } - @GameTest(templateName = "itematic:block.enchanting_table") + @GameTest(structure = "itematic:block.enchanting_table") public void enchantingEnchantableItemInEnchantingTableAddsEnchantments(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); @@ -71,16 +76,12 @@ public void enchantingEnchantableItemInEnchantingTableAddsEnchantments(TestConte enchantmentMenu.getSlot(1) .setStack(world.itematic$createStack(ItemKeys.LAPIS_LAZULI)); enchantmentMenu.onButtonClick(player, 0); - context.addInstantFinalTask(() -> { - ItemStack result = enchantmentMenu.getSlot(0).getStack(); - Assert.itemStackIsOf(result, ItemKeys.IRON_PICKAXE); - Assert.itemStackHasDataComponent(result, DataComponentTypes.ENCHANTMENTS, enchantments -> { - context.assertFalse(enchantments.isEmpty(), "Expected enchantments to be added to " + DataComponentTypes.ENCHANTMENTS); - }); - }); + context.addFinalTask(() -> Assert.itemStack(context, enchantmentMenu.getSlot(0).getStack()) + .is(ItemKeys.IRON_PICKAXE) + .hasEnchantments()); } - @GameTest(templateName = "itematic:block.enchanting_table") + @GameTest(structure = "itematic:block.enchanting_table") public void enchantingBookInEnchantingTableTransformsItemIntoEnchantedBookAndAddsEnchantmentsToStoredEnchantments(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); @@ -91,15 +92,17 @@ public void enchantingBookInEnchantingTableTransformsItemIntoEnchantedBookAndAdd enchantmentMenu.getSlot(1) .setStack(world.itematic$createStack(ItemKeys.LAPIS_LAZULI)); enchantmentMenu.onButtonClick(player, 0); - context.addInstantFinalTask(() -> { - ItemStack result = enchantmentMenu.getSlot(0).getStack(); - Assert.itemStackIsOf(result, ItemKeys.ENCHANTED_BOOK); - Assert.itemStackHasDataComponent(result, DataComponentTypes.ENCHANTMENTS, enchantments -> { - context.assertTrue(enchantments.isEmpty(), "Expected enchantments not to be added to " + DataComponentTypes.ENCHANTMENTS); - }); - Assert.itemStackHasDataComponent(result, DataComponentTypes.STORED_ENCHANTMENTS, storedEnchantments -> { - context.assertFalse(storedEnchantments.isEmpty(), "Expected enchantments to be added to " + DataComponentTypes.STORED_ENCHANTMENTS); - }); - }); + context.addFinalTask(() -> Assert.itemStack(context, enchantmentMenu.getSlot(0).getStack()) + .is(ItemKeys.ENCHANTED_BOOK) + .hasComponent(DataComponentTypes.ENCHANTMENTS, enchantments -> Assert.isTrue( + context, + enchantments.isEmpty(), + () -> "Expected enchantments not to be added to " + DataComponentTypes.ENCHANTMENTS + )) + .hasComponent(DataComponentTypes.STORED_ENCHANTMENTS, storedEnchantments -> Assert.isFalse( + context, + storedEnchantments.isEmpty(), + () -> "Expected enchantments to be added to " + DataComponentTypes.STORED_ENCHANTMENTS + ))); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/block/GrindstoneTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/block/GrindstoneTestSuite.java index f327500b..33d2fff6 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/block/GrindstoneTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/block/GrindstoneTestSuite.java @@ -1,16 +1,14 @@ package net.errorcraft.itematic.gametest.block; -import net.errorcraft.itematic.gametest.Assert; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; -import net.minecraft.component.DataComponentTypes; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.enchantment.Enchantments; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; import net.minecraft.screen.GrindstoneScreenHandler; import net.minecraft.screen.ScreenHandlerType; 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; @@ -18,65 +16,60 @@ public class GrindstoneTestSuite { private static final BlockPos BLOCK_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:block.grindstone") + @GameTest(structure = "itematic:block.grindstone") public void placingEnchantedItemInGrindstoneDisenchantsItem(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); GrindstoneScreenHandler grindstoneMenu = TestUtil.getMenuFromBlock(context, BLOCK_POSITION, player, ScreenHandlerType.GRINDSTONE); - grindstoneMenu.getSlot(0) - .setStack(TestUtil.createItemStackWithEnchantment(world, ItemKeys.IRON_PICKAXE, Enchantments.UNBREAKING)); - context.addInstantFinalTask(() -> { - ItemStack result = grindstoneMenu.getSlot(2).getStack(); - Assert.itemStackIsOf(result, ItemKeys.IRON_PICKAXE); - Assert.itemStackHasDataComponent(result, DataComponentTypes.ENCHANTMENTS, enchantments -> { - context.assertTrue(enchantments.isEmpty(), "Expected item to not have any enchantments"); - }); - }); + grindstoneMenu.getSlot(0).setStack( + TestUtil.createItemStackWithEnchantment(world, ItemKeys.IRON_PICKAXE, Enchantments.UNBREAKING) + ); + context.addFinalTask(() -> Assert.itemStack(context, grindstoneMenu.getSlot(2).getStack()) + .is(ItemKeys.IRON_PICKAXE) + .hasNoEnchantments()); } - @GameTest(templateName = "itematic:block.grindstone") + @GameTest(structure = "itematic:block.grindstone") public void placingEnchantedBookInGrindstoneTransformsItemIntoBook(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); GrindstoneScreenHandler grindstoneMenu = TestUtil.getMenuFromBlock(context, BLOCK_POSITION, player, ScreenHandlerType.GRINDSTONE); - grindstoneMenu.getSlot(0) - .setStack(TestUtil.createItemStackWithEnchantment(world, ItemKeys.ENCHANTED_BOOK, Enchantments.UNBREAKING)); - context.addInstantFinalTask(() -> { - ItemStack result = grindstoneMenu.getSlot(2).getStack(); - Assert.itemStackIsOf(result, ItemKeys.BOOK); - Assert.itemStackHasDataComponent(result, DataComponentTypes.ENCHANTMENTS, enchantments -> { - context.assertTrue(enchantments.isEmpty(), "Expected item to not have any enchantments"); - }); - }); + grindstoneMenu.getSlot(0).setStack( + TestUtil.createItemStackWithEnchantment(world, ItemKeys.ENCHANTED_BOOK, Enchantments.UNBREAKING) + ); + context.addFinalTask(() -> Assert.itemStack(context, grindstoneMenu.getSlot(2).getStack()) + .is(ItemKeys.BOOK) + .hasNoEnchantments()); } - @GameTest(templateName = "itematic:block.grindstone") + @GameTest(structure = "itematic:block.grindstone") public void placingDamageableItemsWithSameIsInGrindstoneRepairsItem(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); GrindstoneScreenHandler grindstoneMenu = TestUtil.getMenuFromBlock(context, BLOCK_POSITION, player, ScreenHandlerType.GRINDSTONE); - grindstoneMenu.getSlot(0) - .setStack(TestUtil.createItemStackWithSlightDamage(world, ItemKeys.IRON_PICKAXE)); - grindstoneMenu.getSlot(1) - .setStack(TestUtil.createItemStackWithSlightDamage(world, ItemKeys.IRON_PICKAXE)); - context.addInstantFinalTask(() -> { - ItemStack result = grindstoneMenu.getSlot(2).getStack(); - Assert.itemStackIsOf(result, ItemKeys.IRON_PICKAXE); - context.assertFalse(result.isDamaged(), "Expected item stack not to be damaged"); - }); + grindstoneMenu.getSlot(0).setStack( + TestUtil.createItemStackWithSlightDamage(world, ItemKeys.IRON_PICKAXE) + ); + grindstoneMenu.getSlot(1).setStack( + TestUtil.createItemStackWithSlightDamage(world, ItemKeys.IRON_PICKAXE) + ); + context.addFinalTask(() -> Assert.itemStack(context, grindstoneMenu.getSlot(2).getStack()) + .is(ItemKeys.IRON_PICKAXE) + .isNotDamaged()); } - @GameTest(templateName = "itematic:block.grindstone") + @GameTest(structure = "itematic:block.grindstone") public void placingDamageableItemsWithDifferentIdsInGrindstoneRejectsRepair(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); GrindstoneScreenHandler grindstoneMenu = TestUtil.getMenuFromBlock(context, BLOCK_POSITION, player, ScreenHandlerType.GRINDSTONE); - grindstoneMenu.getSlot(0) - .setStack(TestUtil.createItemStackWithSlightDamage(world, ItemKeys.IRON_PICKAXE)); - grindstoneMenu.getSlot(1) - .setStack(TestUtil.createItemStackWithSlightDamage(world, ItemKeys.DIAMOND_PICKAXE)); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(grindstoneMenu.getSlot(2).getStack()); - }); + grindstoneMenu.getSlot(0).setStack( + TestUtil.createItemStackWithSlightDamage(world, ItemKeys.IRON_PICKAXE) + ); + grindstoneMenu.getSlot(1).setStack( + TestUtil.createItemStackWithSlightDamage(world, ItemKeys.DIAMOND_PICKAXE) + ); + context.addFinalTask(() -> Assert.itemStack(context, grindstoneMenu.getSlot(2).getStack()) + .isEmpty()); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/block/PickBlockTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/block/PickBlockTestSuite.java index 59ca17a5..336bf9d1 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/block/PickBlockTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/block/PickBlockTestSuite.java @@ -1,1101 +1,1413 @@ package net.errorcraft.itematic.gametest.block; -import net.errorcraft.itematic.gametest.Assert; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.block.BlockState; import net.minecraft.item.ItemStack; -import net.minecraft.test.GameTest; import net.minecraft.test.TestContext; import net.minecraft.util.math.BlockPos; public class PickBlockTestSuite { private static final BlockPos BLOCK_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:block.piston_head") + @GameTest(structure = "itematic:block.piston_head") public void getPickStackOnPistonHeadGivesPistonItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.PISTON)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PISTON) + ); } - @GameTest(templateName = "itematic:block.piston_head.sticky") + @GameTest(structure = "itematic:block.piston_head.sticky") public void getPickStackOnStickyPistonHeadGivesStickyPistonItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.STICKY_PISTON)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.STICKY_PISTON) + ); } - @GameTest(templateName = "itematic:block.redstone_wire") + @GameTest(structure = "itematic:block.redstone_wire") public void getPickStackOnRedstoneWireGivesRedstoneItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.REDSTONE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.REDSTONE) + ); } - @GameTest(templateName = "itematic:block.tripwire") + @GameTest(structure = "itematic:block.tripwire") public void getPickStackOnTripwireGivesStringItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.STRING)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.STRING) + ); } - @GameTest(templateName = "itematic:block.wall_torch") + @GameTest(structure = "itematic:block.wall_torch") public void getPickStackOnWallTorchGivesTorchItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.TORCH)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.TORCH) + ); } - @GameTest(templateName = "itematic:block.redstone_wall_torch") + @GameTest(structure = "itematic:block.redstone_wall_torch") public void getPickStackOnRedstoneWallTorchGivesRedstoneTorchItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.REDSTONE_TORCH)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.REDSTONE_TORCH) + ); } - @GameTest(templateName = "itematic:block.soul_wall_torch") + @GameTest(structure = "itematic:block.soul_wall_torch") public void getPickStackOnSoulWallTorchGivesSoulTorchItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SOUL_TORCH)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SOUL_TORCH) + ); } - @GameTest(templateName = "itematic:block.oak_wall_sign") + @GameTest(structure = "itematic:block.oak_wall_sign") public void getPickStackOnOakWallSignGivesOakSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.OAK_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.OAK_SIGN) + ); } - @GameTest(templateName = "itematic:block.spruce_wall_sign") + @GameTest(structure = "itematic:block.spruce_wall_sign") public void getPickStackOnSpruceWallSignGivesSpruceSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SPRUCE_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SPRUCE_SIGN) + ); } - @GameTest(templateName = "itematic:block.birch_wall_sign") + @GameTest(structure = "itematic:block.birch_wall_sign") public void getPickStackOnBirchWallSignGivesBirchSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BIRCH_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BIRCH_SIGN) + ); } - @GameTest(templateName = "itematic:block.acacia_wall_sign") + @GameTest(structure = "itematic:block.acacia_wall_sign") public void getPickStackOnAcaciaWallSignGivesAcaciaSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ACACIA_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ACACIA_SIGN) + ); } - @GameTest(templateName = "itematic:block.cherry_wall_sign") + @GameTest(structure = "itematic:block.cherry_wall_sign") public void getPickStackOnCherryWallSignGivesCherrySignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CHERRY_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CHERRY_SIGN) + ); } - @GameTest(templateName = "itematic:block.jungle_wall_sign") + @GameTest(structure = "itematic:block.pale_oak_wall_sign") + public void getPickStackOnPaleOakWallSignGivesPaleOakSignItemStack(TestContext context) { + BlockState state = context.getBlockState(BLOCK_POSITION); + BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PALE_OAK_SIGN) + ); + } + + @GameTest(structure = "itematic:block.jungle_wall_sign") public void getPickStackOnJungleWallSignGivesJungleSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.JUNGLE_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.JUNGLE_SIGN) + ); } - @GameTest(templateName = "itematic:block.dark_oak_wall_sign") + @GameTest(structure = "itematic:block.dark_oak_wall_sign") public void getPickStackOnDarkOakWallSignGivesDarkOakSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.DARK_OAK_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.DARK_OAK_SIGN) + ); } - @GameTest(templateName = "itematic:block.mangrove_wall_sign") + @GameTest(structure = "itematic:block.mangrove_wall_sign") public void getPickStackOnMangroveWallSignGivesMangroveSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.MANGROVE_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.MANGROVE_SIGN) + ); } - @GameTest(templateName = "itematic:block.bamboo_wall_sign") + @GameTest(structure = "itematic:block.bamboo_wall_sign") public void getPickStackOnBambooWallSignGivesBambooSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BAMBOO_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BAMBOO_SIGN) + ); } - @GameTest(templateName = "itematic:block.crimson_wall_sign") + @GameTest(structure = "itematic:block.crimson_wall_sign") public void getPickStackOnCrimsonWallSignGivesCrimsonSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CRIMSON_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CRIMSON_SIGN) + ); } - @GameTest(templateName = "itematic:block.warped_wall_sign") + @GameTest(structure = "itematic:block.warped_wall_sign") public void getPickStackOnWarpedWallSignGivesWarpedSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.WARPED_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.WARPED_SIGN) + ); } - @GameTest(templateName = "itematic:block.oak_wall_hanging_sign") + @GameTest(structure = "itematic:block.oak_wall_hanging_sign") public void getPickStackOnOakWallHangingSignGivesOakHangingSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.OAK_HANGING_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.OAK_HANGING_SIGN) + ); } - @GameTest(templateName = "itematic:block.spruce_wall_hanging_sign") + @GameTest(structure = "itematic:block.spruce_wall_hanging_sign") public void getPickStackOnSpruceWallHangingSignGivesSpruceHangingSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SPRUCE_HANGING_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SPRUCE_HANGING_SIGN) + ); } - @GameTest(templateName = "itematic:block.birch_wall_hanging_sign") + @GameTest(structure = "itematic:block.birch_wall_hanging_sign") public void getPickStackOnBirchWallHangingSignGivesBirchHangingSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BIRCH_HANGING_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BIRCH_HANGING_SIGN) + ); } - @GameTest(templateName = "itematic:block.acacia_wall_hanging_sign") + @GameTest(structure = "itematic:block.acacia_wall_hanging_sign") public void getPickStackOnAcaciaWallHangingSignGivesAcaciaHangingSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ACACIA_HANGING_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ACACIA_HANGING_SIGN) + ); } - @GameTest(templateName = "itematic:block.cherry_wall_hanging_sign") + @GameTest(structure = "itematic:block.cherry_wall_hanging_sign") public void getPickStackOnCherryWallHangingSignGivesCherryHangingSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CHERRY_HANGING_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CHERRY_HANGING_SIGN) + ); + } + + @GameTest(structure = "itematic:block.pale_oak_wall_hanging_sign") + public void getPickStackOnPaleOakWallHangingSignGivesPaleOakHangingSignItemStack(TestContext context) { + BlockState state = context.getBlockState(BLOCK_POSITION); + BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PALE_OAK_HANGING_SIGN) + ); } - @GameTest(templateName = "itematic:block.jungle_wall_hanging_sign") + @GameTest(structure = "itematic:block.jungle_wall_hanging_sign") public void getPickStackOnJungleWallHangingSignGivesJungleHangingSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.JUNGLE_HANGING_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.JUNGLE_HANGING_SIGN) + ); } - @GameTest(templateName = "itematic:block.dark_oak_wall_hanging_sign") + @GameTest(structure = "itematic:block.dark_oak_wall_hanging_sign") public void getPickStackOnDarkOakWallHangingSignGivesDarkOakHangingSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.DARK_OAK_HANGING_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.DARK_OAK_HANGING_SIGN) + ); } - @GameTest(templateName = "itematic:block.mangrove_wall_hanging_sign") + @GameTest(structure = "itematic:block.mangrove_wall_hanging_sign") public void getPickStackOnMangroveWallHangingSignGivesMangroveHangingSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.MANGROVE_HANGING_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.MANGROVE_HANGING_SIGN) + ); } - @GameTest(templateName = "itematic:block.crimson_wall_hanging_sign") + @GameTest(structure = "itematic:block.crimson_wall_hanging_sign") public void getPickStackOnCrimsonWallHangingSignGivesCrimsonHangingSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CRIMSON_HANGING_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CRIMSON_HANGING_SIGN) + ); } - @GameTest(templateName = "itematic:block.warped_wall_hanging_sign") + @GameTest(structure = "itematic:block.warped_wall_hanging_sign") public void getPickStackOnWarpedWallHangingSignGivesWarpedHangingSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.WARPED_HANGING_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.WARPED_HANGING_SIGN) + ); } - @GameTest(templateName = "itematic:block.bamboo_wall_hanging_sign") + @GameTest(structure = "itematic:block.bamboo_wall_hanging_sign") public void getPickStackOnBambooWallHangingSignGivesBambooHangingSignItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BAMBOO_HANGING_SIGN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BAMBOO_HANGING_SIGN) + ); } - @GameTest(templateName = "itematic:block.attached_pumpkin_stem") + @GameTest(structure = "itematic:block.attached_pumpkin_stem") public void getPickStackOnAttachedPumpkinStemGivesPumpkinSeedsItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.PUMPKIN_SEEDS)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PUMPKIN_SEEDS) + ); } - @GameTest(templateName = "itematic:block.attached_melon_stem") + @GameTest(structure = "itematic:block.attached_melon_stem") public void getPickStackOnAttachedMelonStemGivesMelonSeedsItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.MELON_SEEDS)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.MELON_SEEDS) + ); } - @GameTest(templateName = "itematic:block.pumpkin_stem") + @GameTest(structure = "itematic:block.pumpkin_stem") public void getPickStackOnPumpkinStemGivesPumpkinSeedsItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.PUMPKIN_SEEDS)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PUMPKIN_SEEDS) + ); } - @GameTest(templateName = "itematic:block.melon_stem") + @GameTest(structure = "itematic:block.melon_stem") public void getPickStackOnMelonStemGivesMelonSeedsItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.MELON_SEEDS)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.MELON_SEEDS) + ); } - @GameTest(templateName = "itematic:block.cocoa") + @GameTest(structure = "itematic:block.cocoa") public void getPickStackOnCocoaGivesCocoaBeansItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.COCOA_BEANS)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.COCOA_BEANS) + ); } - @GameTest(templateName = "itematic:block.carrots") + @GameTest(structure = "itematic:block.carrots") public void getPickStackOnCarrotsGivesCarrotItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CARROT)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CARROT) + ); } - @GameTest(templateName = "itematic:block.potatoes") + @GameTest(structure = "itematic:block.potatoes") public void getPickStackOnPotatoesGivesPotatoItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.POTATO)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.POTATO) + ); } - @GameTest(templateName = "itematic:block.torchflower_crop") + @GameTest(structure = "itematic:block.torchflower_crop") public void getPickStackOnTorchflowerCropGivesTorchflowerSeedsItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.TORCHFLOWER_SEEDS)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.TORCHFLOWER_SEEDS) + ); } - @GameTest(templateName = "itematic:block.pitcher_crop") + @GameTest(structure = "itematic:block.pitcher_crop") public void getPickStackOnPitcherCropGivesPitcherPodItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.PITCHER_POD)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PITCHER_POD) + ); } - @GameTest(templateName = "itematic:block.beetroots") + @GameTest(structure = "itematic:block.beetroots") public void getPickStackOnBeetrootsGivesBeetrootSeedsItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BEETROOT_SEEDS)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BEETROOT_SEEDS) + ); } - @GameTest(templateName = "itematic:block.cave_vines") + @GameTest(structure = "itematic:block.cave_vines") public void getPickStackOnCaveVinesGivesGlowBerriesItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.GLOW_BERRIES)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.GLOW_BERRIES) + ); } - @GameTest(templateName = "itematic:block.cave_vines_plant") + @GameTest(structure = "itematic:block.cave_vines_plant") public void getPickStackOnCaveVinesPlantGivesGlowBerriesItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.GLOW_BERRIES)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.GLOW_BERRIES) + ); } - @GameTest(templateName = "itematic:block.big_dripleaf_stem") + @GameTest(structure = "itematic:block.big_dripleaf_stem") public void getPickStackOnBigDripleafStemGivesBigDripleafItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BIG_DRIPLEAF)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BIG_DRIPLEAF) + ); } - @GameTest(templateName = "itematic:block.tall_seagrass") + @GameTest(structure = "itematic:block.tall_seagrass") public void getPickStackOnTallSeagrassGivesSeagrassItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SEAGRASS)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SEAGRASS) + ); } - @GameTest(templateName = "itematic:block.kelp_plant") + @GameTest(structure = "itematic:block.kelp_plant") public void getPickStackOnKelpPlantGivesKelpItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.KELP)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.KELP) + ); } - @GameTest(templateName = "itematic:block.water_cauldron") + @GameTest(structure = "itematic:block.water_cauldron") public void getPickStackOnWaterCauldronGivesCauldronItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAULDRON)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAULDRON) + ); } - @GameTest(templateName = "itematic:block.lava_cauldron") + @GameTest(structure = "itematic:block.lava_cauldron") public void getPickStackOnLavaCauldronGivesCauldronItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAULDRON)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAULDRON) + ); } - @GameTest(templateName = "itematic:block.powder_snow_cauldron") + @GameTest(structure = "itematic:block.powder_snow_cauldron") public void getPickStackOnPowderSnowCauldronGivesCauldronItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAULDRON)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAULDRON) + ); } - @GameTest(templateName = "itematic:block.powder_snow") + @GameTest(structure = "itematic:block.powder_snow") public void getPickStackOnPowderSnowGivesPowderSnowBucketItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.POWDER_SNOW_BUCKET)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.POWDER_SNOW_BUCKET) + ); } - @GameTest(templateName = "itematic:block.potted_torchflower") + @GameTest(structure = "itematic:block.potted_torchflower") public void getPickStackOnPottedTorchflowerGivesTorchflowerItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.TORCHFLOWER)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.TORCHFLOWER) + ); } - @GameTest(templateName = "itematic:block.potted_oak_sapling") + @GameTest(structure = "itematic:block.potted_oak_sapling") public void getPickStackOnPottedOakSaplingGivesOakSaplingItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.OAK_SAPLING)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.OAK_SAPLING) + ); } - @GameTest(templateName = "itematic:block.potted_spruce_sapling") + @GameTest(structure = "itematic:block.potted_spruce_sapling") public void getPickStackOnPottedSpruceSaplingGivesSpruceSaplingItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SPRUCE_SAPLING)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SPRUCE_SAPLING) + ); } - @GameTest(templateName = "itematic:block.potted_birch_sapling") + @GameTest(structure = "itematic:block.potted_birch_sapling") public void getPickStackOnPottedBirchSaplingGivesBirchSaplingItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BIRCH_SAPLING)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BIRCH_SAPLING) + ); } - @GameTest(templateName = "itematic:block.potted_jungle_sapling") + @GameTest(structure = "itematic:block.potted_jungle_sapling") public void getPickStackOnPottedJungleSaplingGivesJungleSaplingItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.JUNGLE_SAPLING)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.JUNGLE_SAPLING) + ); } - @GameTest(templateName = "itematic:block.potted_acacia_sapling") + @GameTest(structure = "itematic:block.potted_acacia_sapling") public void getPickStackOnPottedAcaciaSaplingGivesAcaciaSaplingItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ACACIA_SAPLING)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ACACIA_SAPLING) + ); } - @GameTest(templateName = "itematic:block.potted_cherry_sapling") + @GameTest(structure = "itematic:block.potted_cherry_sapling") public void getPickStackOnPottedCherrySaplingGivesCherrySaplingItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CHERRY_SAPLING)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CHERRY_SAPLING) + ); } - @GameTest(templateName = "itematic:block.potted_dark_oak_sapling") + @GameTest(structure = "itematic:block.potted_dark_oak_sapling") public void getPickStackOnPottedDarkOakSaplingGivesDarkOakSaplingItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.DARK_OAK_SAPLING)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.DARK_OAK_SAPLING) + ); } - @GameTest(templateName = "itematic:block.potted_mangrove_propagule") + @GameTest(structure = "itematic:block.potted_mangrove_propagule") public void getPickStackOnPottedMangrovePropaguleGivesMangrovePropaguleItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.MANGROVE_PROPAGULE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.MANGROVE_PROPAGULE) + ); } - @GameTest(templateName = "itematic:block.potted_fern") + @GameTest(structure = "itematic:block.potted_fern") public void getPickStackOnPottedFernGivesFernItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.FERN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.FERN) + ); } - @GameTest(templateName = "itematic:block.potted_dandelion") + @GameTest(structure = "itematic:block.potted_dandelion") public void getPickStackOnPottedDandelionGivesDandelionItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.DANDELION)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.DANDELION) + ); } - @GameTest(templateName = "itematic:block.potted_poppy") + @GameTest(structure = "itematic:block.potted_poppy") public void getPickStackOnPottedPoppyGivesPoppyItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.POPPY)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.POPPY) + ); } - @GameTest(templateName = "itematic:block.potted_blue_orchid") + @GameTest(structure = "itematic:block.potted_blue_orchid") public void getPickStackOnPottedBlueOrchidGivesBlueOrchidItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BLUE_ORCHID)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BLUE_ORCHID) + ); } - @GameTest(templateName = "itematic:block.potted_allium") + @GameTest(structure = "itematic:block.potted_allium") public void getPickStackOnPottedAlliumGivesAlliumItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ALLIUM)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ALLIUM) + ); } - @GameTest(templateName = "itematic:block.potted_azure_bluet") + @GameTest(structure = "itematic:block.potted_azure_bluet") public void getPickStackOnPottedAzureBluetGivesAzureBluetItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.AZURE_BLUET)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.AZURE_BLUET) + ); } - @GameTest(templateName = "itematic:block.potted_red_tulip") + @GameTest(structure = "itematic:block.potted_red_tulip") public void getPickStackOnPottedRedTulipGivesRedTulipItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.RED_TULIP)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.RED_TULIP) + ); } - @GameTest(templateName = "itematic:block.potted_orange_tulip") + @GameTest(structure = "itematic:block.potted_orange_tulip") public void getPickStackOnPottedOrangeTulipGivesOrangeTulipItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ORANGE_TULIP)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ORANGE_TULIP) + ); } - @GameTest(templateName = "itematic:block.potted_white_tulip") + @GameTest(structure = "itematic:block.potted_white_tulip") public void getPickStackOnPottedWhiteTulipGivesWhiteTulipItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.WHITE_TULIP)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.WHITE_TULIP) + ); } - @GameTest(templateName = "itematic:block.potted_pink_tulip") + @GameTest(structure = "itematic:block.potted_pink_tulip") public void getPickStackOnPottedPinkTulipGivesPinkTulipItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.PINK_TULIP)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PINK_TULIP) + ); } - @GameTest(templateName = "itematic:block.potted_oxeye_daisy") + @GameTest(structure = "itematic:block.potted_oxeye_daisy") public void getPickStackOnPottedOxeyeDaisyGivesOxeyeDaisyItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.OXEYE_DAISY)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.OXEYE_DAISY) + ); } - @GameTest(templateName = "itematic:block.potted_cornflower") + @GameTest(structure = "itematic:block.potted_cornflower") public void getPickStackOnPottedCornflowerGivesCornflowerItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CORNFLOWER)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CORNFLOWER) + ); } - @GameTest(templateName = "itematic:block.potted_lily_of_the_valley") + @GameTest(structure = "itematic:block.potted_lily_of_the_valley") public void getPickStackOnPottedLilyOfTheValleyGivesLilyOfTheValleyItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.LILY_OF_THE_VALLEY)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.LILY_OF_THE_VALLEY) + ); } - @GameTest(templateName = "itematic:block.potted_wither_rose") + @GameTest(structure = "itematic:block.potted_wither_rose") public void getPickStackOnPottedWitherRoseGivesWitherRoseItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.WITHER_ROSE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.WITHER_ROSE) + ); } - @GameTest(templateName = "itematic:block.potted_red_mushroom") + @GameTest(structure = "itematic:block.potted_red_mushroom") public void getPickStackOnPottedRedMushroomGivesRedMushroomItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.RED_MUSHROOM)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.RED_MUSHROOM) + ); } - @GameTest(templateName = "itematic:block.potted_brown_mushroom") + @GameTest(structure = "itematic:block.potted_brown_mushroom") public void getPickStackOnPottedBrownMushroomGivesBrownMushroomItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BROWN_MUSHROOM)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BROWN_MUSHROOM) + ); } - @GameTest(templateName = "itematic:block.potted_dead_bush") + @GameTest(structure = "itematic:block.potted_dead_bush") public void getPickStackOnPottedDeadBushGivesDeadBushItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.DEAD_BUSH)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.DEAD_BUSH) + ); } - @GameTest(templateName = "itematic:block.potted_cactus") + @GameTest(structure = "itematic:block.potted_cactus") public void getPickStackOnPottedCactusGivesCactusItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CACTUS)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CACTUS) + ); } - @GameTest(templateName = "itematic:block.potted_bamboo") + @GameTest(structure = "itematic:block.potted_bamboo") public void getPickStackOnPottedBambooGivesBambooItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BAMBOO)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BAMBOO) + ); } - @GameTest(templateName = "itematic:block.potted_crimson_fungus") + @GameTest(structure = "itematic:block.potted_crimson_fungus") public void getPickStackOnPottedCrimsonFungusGivesCrimsonFungusItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CRIMSON_FUNGUS)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CRIMSON_FUNGUS) + ); } - @GameTest(templateName = "itematic:block.potted_warped_fungus") + @GameTest(structure = "itematic:block.potted_warped_fungus") public void getPickStackOnPottedWarpedFungusGivesWarpedFungusItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.WARPED_FUNGUS)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.WARPED_FUNGUS) + ); } - @GameTest(templateName = "itematic:block.potted_crimson_roots") + @GameTest(structure = "itematic:block.potted_crimson_roots") public void getPickStackOnPottedCrimsonRootsGivesCrimsonRootsItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CRIMSON_ROOTS)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CRIMSON_ROOTS) + ); } - @GameTest(templateName = "itematic:block.potted_warped_roots") + @GameTest(structure = "itematic:block.potted_warped_roots") public void getPickStackOnPottedWarpedRootsGivesWarpedRootsItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.WARPED_ROOTS)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.WARPED_ROOTS) + ); } - @GameTest(templateName = "itematic:block.potted_azalea_bush") + @GameTest(structure = "itematic:block.potted_azalea_bush") public void getPickStackOnPottedAzaleaBushGivesAzaleaItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.AZALEA)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.AZALEA) + ); } - @GameTest(templateName = "itematic:block.potted_flowering_azalea_bush") + @GameTest(structure = "itematic:block.potted_flowering_azalea_bush") public void getPickStackOnPottedFloweringAzaleaBushGivesFloweringAzaleaItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.FLOWERING_AZALEA)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.FLOWERING_AZALEA) + ); + } + + @GameTest(structure = "itematic:block.potted_open_eyeblossom") + public void getPickStackOnPottedOpenEyeblossomGivesOpenEyeblossomItemStack(TestContext context) { + BlockState state = context.getBlockState(BLOCK_POSITION); + BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.OPEN_EYEBLOSSOM) + ); + } + + @GameTest(structure = "itematic:block.potted_closed_eyeblossom") + public void getPickStackOnPottedClosedEyeblossomGivesClosedEyeblossomItemStack(TestContext context) { + BlockState state = context.getBlockState(BLOCK_POSITION); + BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CLOSED_EYEBLOSSOM) + ); } - @GameTest(templateName = "itematic:block.skeleton_wall_skull") + @GameTest(structure = "itematic:block.skeleton_wall_skull") public void getPickStackOnSkeletonWallSkullGivesSkeletonSkullItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SKELETON_SKULL)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SKELETON_SKULL) + ); } - @GameTest(templateName = "itematic:block.wither_skeleton_wall_skull") + @GameTest(structure = "itematic:block.wither_skeleton_wall_skull") public void getPickStackOnWitherSkeletonWallSkullGivesWitherSkeletonSkullItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.WITHER_SKELETON_SKULL)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.WITHER_SKELETON_SKULL) + ); } - @GameTest(templateName = "itematic:block.zombie_wall_head") + @GameTest(structure = "itematic:block.zombie_wall_head") public void getPickStackOnZombieWallHeadGivesZombieHeadItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ZOMBIE_HEAD)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ZOMBIE_HEAD) + ); } - @GameTest(templateName = "itematic:block.player_wall_head") + @GameTest(structure = "itematic:block.player_wall_head") public void getPickStackOnPlayerWallHeadGivesPlayerHeadItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.PLAYER_HEAD)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PLAYER_HEAD) + ); } - @GameTest(templateName = "itematic:block.creeper_wall_head") + @GameTest(structure = "itematic:block.creeper_wall_head") public void getPickStackOnCreeperWallHeadGivesCreeperHeadItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CREEPER_HEAD)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CREEPER_HEAD) + ); } - @GameTest(templateName = "itematic:block.dragon_wall_head") + @GameTest(structure = "itematic:block.dragon_wall_head") public void getPickStackOnDragonWallHeadGivesDragonHeadItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.DRAGON_HEAD)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.DRAGON_HEAD) + ); } - @GameTest(templateName = "itematic:block.piglin_wall_head") + @GameTest(structure = "itematic:block.piglin_wall_head") public void getPickStackOnPiglinWallHeadGivesPiglinHeadItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.PIGLIN_HEAD)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PIGLIN_HEAD) + ); } - @GameTest(templateName = "itematic:block.white_wall_banner") + @GameTest(structure = "itematic:block.white_wall_banner") public void getPickStackOnWhiteWallBannerGivesWhiteBannerItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.WHITE_BANNER)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.WHITE_BANNER) + ); } - @GameTest(templateName = "itematic:block.orange_wall_banner") + @GameTest(structure = "itematic:block.orange_wall_banner") public void getPickStackOnOrangeWallBannerGivesOrangeBannerItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ORANGE_BANNER)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ORANGE_BANNER) + ); } - @GameTest(templateName = "itematic:block.magenta_wall_banner") + @GameTest(structure = "itematic:block.magenta_wall_banner") public void getPickStackOnMagentaWallBannerGivesMagentaBannerItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.MAGENTA_BANNER)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.MAGENTA_BANNER) + ); } - @GameTest(templateName = "itematic:block.light_blue_wall_banner") + @GameTest(structure = "itematic:block.light_blue_wall_banner") public void getPickStackOnLightBlueWallBannerGivesLightBlueBannerItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.LIGHT_BLUE_BANNER)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.LIGHT_BLUE_BANNER) + ); } - @GameTest(templateName = "itematic:block.yellow_wall_banner") + @GameTest(structure = "itematic:block.yellow_wall_banner") public void getPickStackOnYellowWallBannerGivesYellowBannerItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.YELLOW_BANNER)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.YELLOW_BANNER) + ); } - @GameTest(templateName = "itematic:block.lime_wall_banner") + @GameTest(structure = "itematic:block.lime_wall_banner") public void getPickStackOnLimeWallBannerGivesLimeBannerItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.LIME_BANNER)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.LIME_BANNER) + ); } - @GameTest(templateName = "itematic:block.pink_wall_banner") + @GameTest(structure = "itematic:block.pink_wall_banner") public void getPickStackOnPinkWallBannerGivesPinkBannerItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.PINK_BANNER)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PINK_BANNER) + ); } - @GameTest(templateName = "itematic:block.gray_wall_banner") + @GameTest(structure = "itematic:block.gray_wall_banner") public void getPickStackOnGrayWallBannerGivesGrayBannerItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.GRAY_BANNER)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.GRAY_BANNER) + ); } - @GameTest(templateName = "itematic:block.light_gray_wall_banner") + @GameTest(structure = "itematic:block.light_gray_wall_banner") public void getPickStackOnLightGrayWallBannerGivesLightGrayBannerItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.LIGHT_GRAY_BANNER)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.LIGHT_GRAY_BANNER) + ); } - @GameTest(templateName = "itematic:block.cyan_wall_banner") + @GameTest(structure = "itematic:block.cyan_wall_banner") public void getPickStackOnCyanWallBannerGivesCyanBannerItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CYAN_BANNER)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CYAN_BANNER) + ); } - @GameTest(templateName = "itematic:block.purple_wall_banner") + @GameTest(structure = "itematic:block.purple_wall_banner") public void getPickStackOnPurpleWallBannerGivesPurpleBannerItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.PURPLE_BANNER)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PURPLE_BANNER) + ); } - @GameTest(templateName = "itematic:block.blue_wall_banner") + @GameTest(structure = "itematic:block.blue_wall_banner") public void getPickStackOnBlueWallBannerGivesBlueBannerItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BLUE_BANNER)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BLUE_BANNER) + ); } - @GameTest(templateName = "itematic:block.brown_wall_banner") + @GameTest(structure = "itematic:block.brown_wall_banner") public void getPickStackOnBrownWallBannerGivesBrownBannerItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BROWN_BANNER)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BROWN_BANNER) + ); } - @GameTest(templateName = "itematic:block.green_wall_banner") + @GameTest(structure = "itematic:block.green_wall_banner") public void getPickStackOnGreenWallBannerGivesGreenBannerItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.GREEN_BANNER)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.GREEN_BANNER) + ); } - @GameTest(templateName = "itematic:block.red_wall_banner") + @GameTest(structure = "itematic:block.red_wall_banner") public void getPickStackOnRedWallBannerGivesRedBannerItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.RED_BANNER)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.RED_BANNER) + ); } - @GameTest(templateName = "itematic:block.black_wall_banner") + @GameTest(structure = "itematic:block.black_wall_banner") public void getPickStackOnBlackWallBannerGivesBlackBannerItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BLACK_BANNER)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BLACK_BANNER) + ); } - @GameTest(templateName = "itematic:block.dead_tube_coral_wall_fan") + @GameTest(structure = "itematic:block.dead_tube_coral_wall_fan") public void getPickStackOnDeadTubeCoralWallFanGivesDeadTubeCoralFanItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.DEAD_TUBE_CORAL_FAN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.DEAD_TUBE_CORAL_FAN) + ); } - @GameTest(templateName = "itematic:block.dead_brain_coral_wall_fan") + @GameTest(structure = "itematic:block.dead_brain_coral_wall_fan") public void getPickStackOnDeadBrainCoralWallFanGivesDeadBrainCoralFanItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.DEAD_BRAIN_CORAL_FAN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.DEAD_BRAIN_CORAL_FAN) + ); } - @GameTest(templateName = "itematic:block.dead_bubble_coral_wall_fan") + @GameTest(structure = "itematic:block.dead_bubble_coral_wall_fan") public void getPickStackOnDeadBubbleCoralWallFanGivesDeadBubbleCoralFanItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.DEAD_BUBBLE_CORAL_FAN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.DEAD_BUBBLE_CORAL_FAN) + ); } - @GameTest(templateName = "itematic:block.dead_fire_coral_wall_fan") + @GameTest(structure = "itematic:block.dead_fire_coral_wall_fan") public void getPickStackOnDeadFireCoralWallFanGivesDeadFireCoralFanItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.DEAD_FIRE_CORAL_FAN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.DEAD_FIRE_CORAL_FAN) + ); } - @GameTest(templateName = "itematic:block.dead_horn_coral_wall_fan") + @GameTest(structure = "itematic:block.dead_horn_coral_wall_fan") public void getPickStackOnDeadHornCoralWallFanGivesDeadHornCoralFanItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.DEAD_HORN_CORAL_FAN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.DEAD_HORN_CORAL_FAN) + ); } - @GameTest(templateName = "itematic:block.tube_coral_wall_fan") + @GameTest(structure = "itematic:block.tube_coral_wall_fan") public void getPickStackOnTubeCoralWallFanGivesTubeCoralFanItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.TUBE_CORAL_FAN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.TUBE_CORAL_FAN) + ); } - @GameTest(templateName = "itematic:block.brain_coral_wall_fan") + @GameTest(structure = "itematic:block.brain_coral_wall_fan") public void getPickStackOnBrainCoralWallFanGivesBrainCoralFanItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BRAIN_CORAL_FAN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BRAIN_CORAL_FAN) + ); } - @GameTest(templateName = "itematic:block.bubble_coral_wall_fan") + @GameTest(structure = "itematic:block.bubble_coral_wall_fan") public void getPickStackOnBubbleCoralWallFanGivesBubbleCoralFanItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BUBBLE_CORAL_FAN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BUBBLE_CORAL_FAN) + ); } - @GameTest(templateName = "itematic:block.fire_coral_wall_fan") + @GameTest(structure = "itematic:block.fire_coral_wall_fan") public void getPickStackOnFireCoralWallFanGivesFireCoralFanItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.FIRE_CORAL_FAN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.FIRE_CORAL_FAN) + ); } - @GameTest(templateName = "itematic:block.horn_coral_wall_fan") + @GameTest(structure = "itematic:block.horn_coral_wall_fan") public void getPickStackOnHornCoralWallFanGivesHornCoralFanItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.HORN_CORAL_FAN)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.HORN_CORAL_FAN) + ); } - @GameTest(templateName = "itematic:block.bamboo_sapling") + @GameTest(structure = "itematic:block.bamboo_sapling") public void getPickStackOnBambooSaplingGivesBambooItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BAMBOO)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BAMBOO) + ); } - @GameTest(templateName = "itematic:block.sweet_berry_bush") + @GameTest(structure = "itematic:block.sweet_berry_bush") public void getPickStackOnSweetBerryBushGivesSweetBerriesItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SWEET_BERRIES)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SWEET_BERRIES) + ); } - @GameTest(templateName = "itematic:block.weeping_vines_plant") + @GameTest(structure = "itematic:block.weeping_vines_plant") public void getPickStackOnWeepingVinesPlantGivesWeepingVinesItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.WEEPING_VINES)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.WEEPING_VINES) + ); } - @GameTest(templateName = "itematic:block.twisting_vines_plant") + @GameTest(structure = "itematic:block.twisting_vines_plant") public void getPickStackOnTwistingVinesPlantGivesTwistingVinesItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.TWISTING_VINES)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.TWISTING_VINES) + ); } - @GameTest(templateName = "itematic:block.candle_cake") + @GameTest(structure = "itematic:block.candle_cake") public void getPickStackOnCandleCakeGivesCakeItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAKE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAKE) + ); } - @GameTest(templateName = "itematic:block.white_candle_cake") + @GameTest(structure = "itematic:block.white_candle_cake") public void getPickStackOnWhiteCandleCakeGivesCakeItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAKE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAKE) + ); } - @GameTest(templateName = "itematic:block.orange_candle_cake") + @GameTest(structure = "itematic:block.orange_candle_cake") public void getPickStackOnOrangeCandleCakeGivesCakeItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAKE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAKE) + ); } - @GameTest(templateName = "itematic:block.magenta_candle_cake") + @GameTest(structure = "itematic:block.magenta_candle_cake") public void getPickStackOnMagentaCandleCakeGivesCakeItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAKE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAKE) + ); } - @GameTest(templateName = "itematic:block.light_blue_candle_cake") + @GameTest(structure = "itematic:block.light_blue_candle_cake") public void getPickStackOnLightBlueCandleCakeGivesCakeItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAKE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAKE) + ); } - @GameTest(templateName = "itematic:block.yellow_candle_cake") + @GameTest(structure = "itematic:block.yellow_candle_cake") public void getPickStackOnYellowCandleCakeGivesCakeItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAKE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAKE) + ); } - @GameTest(templateName = "itematic:block.lime_candle_cake") + @GameTest(structure = "itematic:block.lime_candle_cake") public void getPickStackOnLimeCandleCakeGivesCakeItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAKE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAKE) + ); } - @GameTest(templateName = "itematic:block.pink_candle_cake") + @GameTest(structure = "itematic:block.pink_candle_cake") public void getPickStackOnPinkCandleCakeGivesCakeItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAKE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAKE) + ); } - @GameTest(templateName = "itematic:block.gray_candle_cake") + @GameTest(structure = "itematic:block.gray_candle_cake") public void getPickStackOnGrayCandleCakeGivesCakeItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAKE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAKE) + ); } - @GameTest(templateName = "itematic:block.light_gray_candle_cake") + @GameTest(structure = "itematic:block.light_gray_candle_cake") public void getPickStackOnLightGrayCandleCakeGivesCakeItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAKE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAKE) + ); } - @GameTest(templateName = "itematic:block.cyan_candle_cake") + @GameTest(structure = "itematic:block.cyan_candle_cake") public void getPickStackOnCyanCandleCakeGivesCakeItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAKE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAKE) + ); } - @GameTest(templateName = "itematic:block.purple_candle_cake") + @GameTest(structure = "itematic:block.purple_candle_cake") public void getPickStackOnPurpleCandleCakeGivesCakeItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAKE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAKE) + ); } - @GameTest(templateName = "itematic:block.blue_candle_cake") + @GameTest(structure = "itematic:block.blue_candle_cake") public void getPickStackOnBlueCandleCakeGivesCakeItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAKE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAKE) + ); } - @GameTest(templateName = "itematic:block.brown_candle_cake") + @GameTest(structure = "itematic:block.brown_candle_cake") public void getPickStackOnBrownCandleCakeGivesCakeItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAKE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAKE) + ); } - @GameTest(templateName = "itematic:block.green_candle_cake") + @GameTest(structure = "itematic:block.green_candle_cake") public void getPickStackOnGreenCandleCakeGivesCakeItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAKE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAKE) + ); } - @GameTest(templateName = "itematic:block.red_candle_cake") + @GameTest(structure = "itematic:block.red_candle_cake") public void getPickStackOnRedCandleCakeGivesCakeItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAKE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAKE) + ); } - @GameTest(templateName = "itematic:block.black_candle_cake") + @GameTest(structure = "itematic:block.black_candle_cake") public void getPickStackOnBlackCandleCakeGivesCakeItemStack(TestContext context) { BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); - ItemStack stack = state.getBlock().getPickStack(context.getWorld(), absolutePos, state); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAKE)); + ItemStack stack = state.getPickStack(context.getWorld(), absolutePos, false); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAKE) + ); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/block/ShulkerBoxBlockTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/block/ShulkerBoxBlockTestSuite.java index 5edad272..a6828c58 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/block/ShulkerBoxBlockTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/block/ShulkerBoxBlockTestSuite.java @@ -1,10 +1,10 @@ package net.errorcraft.itematic.gametest.block; import net.errorcraft.itematic.item.ItemKeys; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; 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; @@ -12,23 +12,23 @@ public class ShulkerBoxBlockTestSuite { private static final BlockPos BLOCK_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:block.shulker_box") + @GameTest(structure = "itematic:block.shulker_box") public void breakingShulkerBoxInCreativeModeDropsShulkerBox(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.CREATIVE); ServerWorld world = context.getWorld(); BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); state.getBlock().onBreak(world, absolutePos, state, player); - context.addInstantFinalTask(() -> context.expectItem(context.getWorld().itematic$getItem(ItemKeys.SHULKER_BOX).value())); + context.addFinalTask(() -> context.expectItem(context.getWorld().itematic$getItem(ItemKeys.SHULKER_BOX).value())); } - @GameTest(templateName = "itematic:block.red_shulker_box") + @GameTest(structure = "itematic:block.red_shulker_box") public void breakingRedShulkerBoxInCreativeModeDropsRedShulkerBox(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.CREATIVE); ServerWorld world = context.getWorld(); BlockState state = context.getBlockState(BLOCK_POSITION); BlockPos absolutePos = context.getAbsolutePos(BLOCK_POSITION); state.getBlock().onBreak(world, absolutePos, state, player); - context.addInstantFinalTask(() -> context.expectItem(context.getWorld().itematic$getItem(ItemKeys.RED_SHULKER_BOX).value())); + context.addFinalTask(() -> context.expectItem(context.getWorld().itematic$getItem(ItemKeys.RED_SHULKER_BOX).value())); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/block/WaterCauldronBlockTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/block/WaterCauldronBlockTestSuite.java index b47ea56d..b2092de5 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/block/WaterCauldronBlockTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/block/WaterCauldronBlockTestSuite.java @@ -1,13 +1,13 @@ package net.errorcraft.itematic.gametest.block; -import net.errorcraft.itematic.gametest.Assert; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.DyedColorComponent; 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.util.math.BlockPos; @@ -16,26 +16,28 @@ public class WaterCauldronBlockTestSuite { private static final BlockPos WATER_CAULDRON_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:block.water_cauldron") + @GameTest(structure = "itematic:block.water_cauldron") public void usingColoredShulkerBoxOnWaterCauldronClearsColor(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.WHITE_SHULKER_BOX); - player.setStackInHand(Hand.MAIN_HAND, stack); + ItemStack whiteShulkerBox = world.itematic$createStack(ItemKeys.WHITE_SHULKER_BOX); + player.setStackInHand(Hand.MAIN_HAND, whiteShulkerBox); world.spawnEntity(player); context.useBlock(WATER_CAULDRON_POSITION, player); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.SHULKER_BOX)); + context.addFinalTask(() -> Assert.itemStack(context, player.getStackInHand(Hand.MAIN_HAND)) + .is(ItemKeys.SHULKER_BOX)); } - @GameTest(templateName = "itematic:block.water_cauldron") + @GameTest(structure = "itematic:block.water_cauldron") public void usingColoredWolfArmorOnWaterCauldronClearsColor(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.WOLF_ARMOR); - stack.set(DataComponentTypes.DYED_COLOR, new DyedColorComponent(0xffffff, true)); - player.setStackInHand(Hand.MAIN_HAND, stack); + ItemStack wolfArmor = world.itematic$createStack(ItemKeys.WOLF_ARMOR); + wolfArmor.set(DataComponentTypes.DYED_COLOR, new DyedColorComponent(0xffffff)); + player.setStackInHand(Hand.MAIN_HAND, wolfArmor); world.spawnEntity(player); context.useBlock(WATER_CAULDRON_POSITION, player); - context.addFinalTask(() -> Assert.itemStackDoesNotHaveDataComponent(player.getStackInHand(Hand.MAIN_HAND), DataComponentTypes.DYED_COLOR)); + context.addFinalTask(() -> Assert.itemStack(context, player.getStackInHand(Hand.MAIN_HAND)) + .doesNotHaveComponent(DataComponentTypes.DYED_COLOR)); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/entity/PickEntityTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/entity/PickEntityTestSuite.java index 6955d6d7..c9554365 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/entity/PickEntityTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/entity/PickEntityTestSuite.java @@ -1,7 +1,8 @@ package net.errorcraft.itematic.gametest.entity; -import net.errorcraft.itematic.gametest.Assert; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.entity.EntityType; import net.minecraft.entity.boss.WitherEntity; import net.minecraft.entity.boss.dragon.EnderDragonEntity; @@ -12,682 +13,873 @@ import net.minecraft.entity.vehicle.ChestRaftEntity; import net.minecraft.entity.vehicle.RaftEntity; import net.minecraft.item.ItemStack; -import net.minecraft.test.GameTest; import net.minecraft.test.TestContext; import net.minecraft.util.math.BlockPos; public class PickEntityTestSuite { private static final BlockPos SPAWN_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnArmadilloGivesArmadilloSpawnEggItemStack(TestContext context) { ArmadilloEntity armadillo = context.spawnEntity(EntityType.ARMADILLO, SPAWN_POSITION); ItemStack stack = armadillo.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ARMADILLO_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ARMADILLO_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnAllayGivesAllaySpawnEggItemStack(TestContext context) { AllayEntity allay = context.spawnEntity(EntityType.ALLAY, SPAWN_POSITION); ItemStack stack = allay.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ALLAY_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ALLAY_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnAxolotlGivesAxolotlSpawnEggItemStack(TestContext context) { AxolotlEntity axolotl = context.spawnEntity(EntityType.AXOLOTL, SPAWN_POSITION); ItemStack stack = axolotl.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.AXOLOTL_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.AXOLOTL_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnBatGivesBatSpawnEggItemStack(TestContext context) { BatEntity bat = context.spawnEntity(EntityType.BAT, SPAWN_POSITION); ItemStack stack = bat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BAT_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BAT_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnBeeGivesBeeSpawnEggItemStack(TestContext context) { BeeEntity bee = context.spawnEntity(EntityType.BEE, SPAWN_POSITION); ItemStack stack = bee.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BEE_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BEE_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnBlazeGivesBlazeSpawnEggItemStack(TestContext context) { BlazeEntity blaze = context.spawnEntity(EntityType.BLAZE, SPAWN_POSITION); ItemStack stack = blaze.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BLAZE_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BLAZE_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnCatGivesCatSpawnEggItemStack(TestContext context) { CatEntity cat = context.spawnEntity(EntityType.CAT, SPAWN_POSITION); ItemStack stack = cat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAT_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAT_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnCamelGivesCamelSpawnEggItemStack(TestContext context) { CamelEntity camel = context.spawnEntity(EntityType.CAMEL, SPAWN_POSITION); ItemStack stack = camel.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAMEL_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAMEL_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnCaveSpiderGivesCaveSpiderSpawnEggItemStack(TestContext context) { CaveSpiderEntity caveSpider = context.spawnEntity(EntityType.CAVE_SPIDER, SPAWN_POSITION); ItemStack stack = caveSpider.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CAVE_SPIDER_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CAVE_SPIDER_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnChickenGivesChickenSpawnEggItemStack(TestContext context) { ChickenEntity chicken = context.spawnEntity(EntityType.CHICKEN, SPAWN_POSITION); ItemStack stack = chicken.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CHICKEN_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CHICKEN_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnCodGivesCodSpawnEggItemStack(TestContext context) { CodEntity cod = context.spawnEntity(EntityType.COD, SPAWN_POSITION); ItemStack stack = cod.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.COD_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.COD_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnCowGivesCowSpawnEggItemStack(TestContext context) { CowEntity cow = context.spawnEntity(EntityType.COW, SPAWN_POSITION); ItemStack stack = cow.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.COW_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.COW_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnCreeperGivesCreeperSpawnEggItemStack(TestContext context) { CreeperEntity creeper = context.spawnEntity(EntityType.CREEPER, SPAWN_POSITION); ItemStack stack = creeper.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CREEPER_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CREEPER_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnDolphinGivesDolphinSpawnEggItemStack(TestContext context) { DolphinEntity dolphin = context.spawnEntity(EntityType.DOLPHIN, SPAWN_POSITION); ItemStack stack = dolphin.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.DOLPHIN_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.DOLPHIN_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnDonkeyGivesDonkeySpawnEggItemStack(TestContext context) { DonkeyEntity donkey = context.spawnEntity(EntityType.DONKEY, SPAWN_POSITION); ItemStack stack = donkey.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.DONKEY_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.DONKEY_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnDrownedGivesDrownedSpawnEggItemStack(TestContext context) { DrownedEntity drowned = context.spawnEntity(EntityType.DROWNED, SPAWN_POSITION); ItemStack stack = drowned.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.DROWNED_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.DROWNED_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnElderGuardianGivesElderGuardianSpawnEggItemStack(TestContext context) { ElderGuardianEntity elderGuardian = context.spawnEntity(EntityType.ELDER_GUARDIAN, SPAWN_POSITION); ItemStack stack = elderGuardian.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ELDER_GUARDIAN_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ELDER_GUARDIAN_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnEnderDragonGivesEnderDragonSpawnEggItemStack(TestContext context) { EnderDragonEntity enderDragon = context.spawnEntity(EntityType.ENDER_DRAGON, SPAWN_POSITION); ItemStack stack = enderDragon.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ENDER_DRAGON_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ENDER_DRAGON_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnEndermanGivesEndermanSpawnEggItemStack(TestContext context) { EndermanEntity enderman = context.spawnEntity(EntityType.ENDERMAN, SPAWN_POSITION); ItemStack stack = enderman.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ENDERMAN_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ENDERMAN_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnEndermiteGivesEndermiteSpawnEggItemStack(TestContext context) { EndermiteEntity endermite = context.spawnEntity(EntityType.ENDERMITE, SPAWN_POSITION); ItemStack stack = endermite.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ENDERMITE_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ENDERMITE_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnEvokerGivesEvokerSpawnEggItemStack(TestContext context) { EvokerEntity evoker = context.spawnEntity(EntityType.EVOKER, SPAWN_POSITION); ItemStack stack = evoker.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.EVOKER_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.EVOKER_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnFoxGivesFoxSpawnEggItemStack(TestContext context) { FoxEntity fox = context.spawnEntity(EntityType.FOX, SPAWN_POSITION); ItemStack stack = fox.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.FOX_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.FOX_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnFrogGivesFrogSpawnEggItemStack(TestContext context) { FrogEntity frog = context.spawnEntity(EntityType.FROG, SPAWN_POSITION); ItemStack stack = frog.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.FROG_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.FROG_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnGhastGivesGhastSpawnEggItemStack(TestContext context) { GhastEntity ghast = context.spawnEntity(EntityType.GHAST, SPAWN_POSITION); ItemStack stack = ghast.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.GHAST_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.GHAST_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnGlowSquidGivesGlowSquidSpawnEggItemStack(TestContext context) { GlowSquidEntity glowSquid = context.spawnEntity(EntityType.GLOW_SQUID, SPAWN_POSITION); ItemStack stack = glowSquid.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.GLOW_SQUID_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.GLOW_SQUID_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnGoatGivesGoatSpawnEggItemStack(TestContext context) { GoatEntity goat = context.spawnEntity(EntityType.GOAT, SPAWN_POSITION); ItemStack stack = goat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.GOAT_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.GOAT_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnGuardianGivesGuardianSpawnEggItemStack(TestContext context) { GuardianEntity guardian = context.spawnEntity(EntityType.GUARDIAN, SPAWN_POSITION); ItemStack stack = guardian.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.GUARDIAN_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.GUARDIAN_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnHoglinGivesHoglinSpawnEggItemStack(TestContext context) { HoglinEntity hoglin = context.spawnEntity(EntityType.HOGLIN, SPAWN_POSITION); ItemStack stack = hoglin.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.HOGLIN_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.HOGLIN_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnHorseGivesHorseSpawnEggItemStack(TestContext context) { HorseEntity horse = context.spawnEntity(EntityType.HORSE, SPAWN_POSITION); ItemStack stack = horse.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.HORSE_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.HORSE_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnHuskGivesHuskSpawnEggItemStack(TestContext context) { HuskEntity husk = context.spawnEntity(EntityType.HUSK, SPAWN_POSITION); ItemStack stack = husk.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.HUSK_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.HUSK_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnIronGolemGivesIronGolemSpawnEggItemStack(TestContext context) { IronGolemEntity ironGolem = context.spawnEntity(EntityType.IRON_GOLEM, SPAWN_POSITION); ItemStack stack = ironGolem.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.IRON_GOLEM_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.IRON_GOLEM_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnLlamaGivesLlamaSpawnEggItemStack(TestContext context) { LlamaEntity llama = context.spawnEntity(EntityType.LLAMA, SPAWN_POSITION); ItemStack stack = llama.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.LLAMA_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.LLAMA_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnMagmaCubeGivesMagmaCubeSpawnEggItemStack(TestContext context) { MagmaCubeEntity magmaCube = context.spawnEntity(EntityType.MAGMA_CUBE, SPAWN_POSITION); ItemStack stack = magmaCube.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.MAGMA_CUBE_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.MAGMA_CUBE_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnMooshroomGivesMooshroomSpawnEggItemStack(TestContext context) { MooshroomEntity mooshroom = context.spawnEntity(EntityType.MOOSHROOM, SPAWN_POSITION); ItemStack stack = mooshroom.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.MOOSHROOM_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.MOOSHROOM_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnMuleGivesMuleSpawnEggItemStack(TestContext context) { MuleEntity mule = context.spawnEntity(EntityType.MULE, SPAWN_POSITION); ItemStack stack = mule.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.MULE_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.MULE_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnOcelotGivesOcelotSpawnEggItemStack(TestContext context) { OcelotEntity ocelot = context.spawnEntity(EntityType.OCELOT, SPAWN_POSITION); ItemStack stack = ocelot.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.OCELOT_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.OCELOT_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnPandaGivesPandaSpawnEggItemStack(TestContext context) { PandaEntity panda = context.spawnEntity(EntityType.PANDA, SPAWN_POSITION); ItemStack stack = panda.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.PANDA_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PANDA_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnParrotGivesParrotSpawnEggItemStack(TestContext context) { ParrotEntity parrot = context.spawnEntity(EntityType.PARROT, SPAWN_POSITION); ItemStack stack = parrot.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.PARROT_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PARROT_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnPhantomGivesPhantomSpawnEggItemStack(TestContext context) { PhantomEntity phantom = context.spawnEntity(EntityType.PHANTOM, SPAWN_POSITION); ItemStack stack = phantom.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.PHANTOM_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PHANTOM_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnPigGivesPigSpawnEggItemStack(TestContext context) { PigEntity pig = context.spawnEntity(EntityType.PIG, SPAWN_POSITION); ItemStack stack = pig.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.PIG_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PIG_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnPiglinGivesPiglinSpawnEggItemStack(TestContext context) { PiglinEntity piglin = context.spawnEntity(EntityType.PIGLIN, SPAWN_POSITION); ItemStack stack = piglin.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.PIGLIN_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PIGLIN_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnPiglinBruteGivesPiglinBruteSpawnEggItemStack(TestContext context) { PiglinBruteEntity piglinBrute = context.spawnEntity(EntityType.PIGLIN_BRUTE, SPAWN_POSITION); ItemStack stack = piglinBrute.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.PIGLIN_BRUTE_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PIGLIN_BRUTE_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnPillagerGivesPillagerSpawnEggItemStack(TestContext context) { PillagerEntity pillager = context.spawnEntity(EntityType.PILLAGER, SPAWN_POSITION); ItemStack stack = pillager.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.PILLAGER_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PILLAGER_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnPolarBearGivesPolarBearSpawnEggItemStack(TestContext context) { PolarBearEntity polarBear = context.spawnEntity(EntityType.POLAR_BEAR, SPAWN_POSITION); ItemStack stack = polarBear.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.POLAR_BEAR_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.POLAR_BEAR_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnPufferfishGivesPufferfishSpawnEggItemStack(TestContext context) { PufferfishEntity pufferfish = context.spawnEntity(EntityType.PUFFERFISH, SPAWN_POSITION); ItemStack stack = pufferfish.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.PUFFERFISH_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.PUFFERFISH_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnRabbitGivesRabbitSpawnEggItemStack(TestContext context) { RabbitEntity rabbit = context.spawnEntity(EntityType.RABBIT, SPAWN_POSITION); ItemStack stack = rabbit.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.RABBIT_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.RABBIT_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnRavagerGivesRavagerSpawnEggItemStack(TestContext context) { RavagerEntity ravager = context.spawnEntity(EntityType.RAVAGER, SPAWN_POSITION); ItemStack stack = ravager.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.RAVAGER_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.RAVAGER_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnSalmonGivesSalmonSpawnEggItemStack(TestContext context) { SalmonEntity salmon = context.spawnEntity(EntityType.SALMON, SPAWN_POSITION); ItemStack stack = salmon.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SALMON_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SALMON_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnSheepGivesSheepSpawnEggItemStack(TestContext context) { SheepEntity sheep = context.spawnEntity(EntityType.SHEEP, SPAWN_POSITION); ItemStack stack = sheep.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SHEEP_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SHEEP_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnShulkerGivesShulkerSpawnEggItemStack(TestContext context) { ShulkerEntity shulker = context.spawnEntity(EntityType.SHULKER, SPAWN_POSITION); ItemStack stack = shulker.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SHULKER_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SHULKER_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnSilverfishGivesSilverfishSpawnEggItemStack(TestContext context) { SilverfishEntity silverfish = context.spawnEntity(EntityType.SILVERFISH, SPAWN_POSITION); ItemStack stack = silverfish.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SILVERFISH_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SILVERFISH_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnSkeletonGivesSkeletonSpawnEggItemStack(TestContext context) { SkeletonEntity skeleton = context.spawnEntity(EntityType.SKELETON, SPAWN_POSITION); ItemStack stack = skeleton.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SKELETON_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SKELETON_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnSkeletonHorseGivesSkeletonHorseSpawnEggItemStack(TestContext context) { SkeletonHorseEntity skeletonHorse = context.spawnEntity(EntityType.SKELETON_HORSE, SPAWN_POSITION); ItemStack stack = skeletonHorse.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SKELETON_HORSE_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SKELETON_HORSE_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnSlimeGivesSlimeSpawnEggItemStack(TestContext context) { SlimeEntity slime = context.spawnEntity(EntityType.SLIME, SPAWN_POSITION); ItemStack stack = slime.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SLIME_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SLIME_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnSnifferGivesSnifferSpawnEggItemStack(TestContext context) { SnifferEntity sniffer = context.spawnEntity(EntityType.SNIFFER, SPAWN_POSITION); ItemStack stack = sniffer.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SNIFFER_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SNIFFER_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnSnowGolemGivesSnowGolemSpawnEggItemStack(TestContext context) { SnowGolemEntity snowGolem = context.spawnEntity(EntityType.SNOW_GOLEM, SPAWN_POSITION); ItemStack stack = snowGolem.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SNOW_GOLEM_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SNOW_GOLEM_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnSpiderGivesSpiderSpawnEggItemStack(TestContext context) { SpiderEntity spider = context.spawnEntity(EntityType.SPIDER, SPAWN_POSITION); ItemStack stack = spider.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SPIDER_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SPIDER_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnSquidGivesSquidSpawnEggItemStack(TestContext context) { SquidEntity squid = context.spawnEntity(EntityType.SQUID, SPAWN_POSITION); ItemStack stack = squid.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SQUID_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SQUID_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnStrayGivesStraySpawnEggItemStack(TestContext context) { StrayEntity stray = context.spawnEntity(EntityType.STRAY, SPAWN_POSITION); ItemStack stack = stray.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.STRAY_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.STRAY_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnStriderGivesStriderSpawnEggItemStack(TestContext context) { StriderEntity strider = context.spawnEntity(EntityType.STRIDER, SPAWN_POSITION); ItemStack stack = strider.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.STRIDER_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.STRIDER_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnTadpoleGivesTadpoleSpawnEggItemStack(TestContext context) { TadpoleEntity tadpole = context.spawnEntity(EntityType.TADPOLE, SPAWN_POSITION); ItemStack stack = tadpole.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.TADPOLE_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.TADPOLE_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnTraderLlamaGivesTraderLlamaSpawnEggItemStack(TestContext context) { TraderLlamaEntity traderLlama = context.spawnEntity(EntityType.TRADER_LLAMA, SPAWN_POSITION); ItemStack stack = traderLlama.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.TRADER_LLAMA_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.TRADER_LLAMA_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnTropicalFishGivesTropicalFishSpawnEggItemStack(TestContext context) { TropicalFishEntity tropicalFish = context.spawnEntity(EntityType.TROPICAL_FISH, SPAWN_POSITION); ItemStack stack = tropicalFish.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.TROPICAL_FISH_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.TROPICAL_FISH_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnTurtleGivesTurtleSpawnEggItemStack(TestContext context) { TurtleEntity turtle = context.spawnEntity(EntityType.TURTLE, SPAWN_POSITION); ItemStack stack = turtle.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.TURTLE_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.TURTLE_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnVexGivesVexSpawnEggItemStack(TestContext context) { VexEntity vex = context.spawnEntity(EntityType.VEX, SPAWN_POSITION); ItemStack stack = vex.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.VEX_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.VEX_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnVillagerGivesVillagerSpawnEggItemStack(TestContext context) { VillagerEntity villager = context.spawnEntity(EntityType.VILLAGER, SPAWN_POSITION); ItemStack stack = villager.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.VILLAGER_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.VILLAGER_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnVindicatorGivesVindicatorSpawnEggItemStack(TestContext context) { VindicatorEntity vindicator = context.spawnEntity(EntityType.VINDICATOR, SPAWN_POSITION); ItemStack stack = vindicator.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.VINDICATOR_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.VINDICATOR_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnWanderingTraderGivesWanderingTraderSpawnEggItemStack(TestContext context) { WanderingTraderEntity wanderingTrader = context.spawnEntity(EntityType.WANDERING_TRADER, SPAWN_POSITION); ItemStack stack = wanderingTrader.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.WANDERING_TRADER_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.WANDERING_TRADER_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnWardenGivesWardenSpawnEggItemStack(TestContext context) { WardenEntity warden = context.spawnEntity(EntityType.WARDEN, SPAWN_POSITION); ItemStack stack = warden.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.WARDEN_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.WARDEN_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnWitchGivesWitchSpawnEggItemStack(TestContext context) { WitchEntity witch = context.spawnEntity(EntityType.WITCH, SPAWN_POSITION); ItemStack stack = witch.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.WITCH_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.WITCH_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnWitherGivesWitherSpawnEggItemStack(TestContext context) { WitherEntity wither = context.spawnEntity(EntityType.WITHER, SPAWN_POSITION); ItemStack stack = wither.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.WITHER_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.WITHER_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnWitherSkeletonGivesWitherSkeletonSpawnEggItemStack(TestContext context) { WitherSkeletonEntity witherSkeleton = context.spawnEntity(EntityType.WITHER_SKELETON, SPAWN_POSITION); ItemStack stack = witherSkeleton.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.WITHER_SKELETON_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.WITHER_SKELETON_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnWolfGivesWolfSpawnEggItemStack(TestContext context) { WolfEntity wolf = context.spawnEntity(EntityType.WOLF, SPAWN_POSITION); ItemStack stack = wolf.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.WOLF_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.WOLF_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnZoglinGivesZoglinSpawnEggItemStack(TestContext context) { ZoglinEntity zoglin = context.spawnEntity(EntityType.ZOGLIN, SPAWN_POSITION); ItemStack stack = zoglin.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ZOGLIN_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ZOGLIN_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnZombieGivesZombieSpawnEggItemStack(TestContext context) { ZombieEntity zombie = context.spawnEntity(EntityType.ZOMBIE, SPAWN_POSITION); ItemStack stack = zombie.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ZOMBIE_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ZOMBIE_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnZombieHorseGivesZombieHorseSpawnEggItemStack(TestContext context) { ZombieHorseEntity zombieHorse = context.spawnEntity(EntityType.ZOMBIE_HORSE, SPAWN_POSITION); ItemStack stack = zombieHorse.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ZOMBIE_HORSE_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ZOMBIE_HORSE_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnZombieVillagerGivesZombieVillagerSpawnEggItemStack(TestContext context) { ZombieVillagerEntity zombieVillager = context.spawnEntity(EntityType.ZOMBIE_VILLAGER, SPAWN_POSITION); ItemStack stack = zombieVillager.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ZOMBIE_VILLAGER_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ZOMBIE_VILLAGER_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnZombifiedPiglinGivesZombifiedPiglinSpawnEggItemStack(TestContext context) { ZombifiedPiglinEntity zombifiedPiglin = context.spawnEntity(EntityType.ZOMBIFIED_PIGLIN, SPAWN_POSITION); ItemStack stack = zombifiedPiglin.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ZOMBIFIED_PIGLIN_SPAWN_EGG)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ZOMBIFIED_PIGLIN_SPAWN_EGG) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnAcaciaBoatGivesAcaciaBoatItemStack(TestContext context) { BoatEntity acaciaBoat = context.spawnEntity(EntityType.ACACIA_BOAT, SPAWN_POSITION); ItemStack stack = acaciaBoat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ACACIA_BOAT)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ACACIA_BOAT) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnAcaciaChestBoatGivesAcaciaChestBoatItemStack(TestContext context) { ChestBoatEntity acaciaChestBoat = context.spawnEntity(EntityType.ACACIA_CHEST_BOAT, SPAWN_POSITION); ItemStack stack = acaciaChestBoat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.ACACIA_CHEST_BOAT)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.ACACIA_CHEST_BOAT) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnBambooRaftGivesBambooRaftItemStack(TestContext context) { RaftEntity bambooRaft = context.spawnEntity(EntityType.BAMBOO_RAFT, SPAWN_POSITION); ItemStack stack = bambooRaft.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BAMBOO_RAFT)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BAMBOO_RAFT) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnBambooChestRaftGivesBambooChestRaftItemStack(TestContext context) { ChestRaftEntity bambooChestRaft = context.spawnEntity(EntityType.BAMBOO_CHEST_RAFT, SPAWN_POSITION); ItemStack stack = bambooChestRaft.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BAMBOO_CHEST_RAFT)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BAMBOO_CHEST_RAFT) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnBirchBoatGivesBirchBoatItemStack(TestContext context) { BoatEntity birchBoat = context.spawnEntity(EntityType.BIRCH_BOAT, SPAWN_POSITION); ItemStack stack = birchBoat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BIRCH_BOAT)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BIRCH_BOAT) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnBirchChestBoatGivesBirchChestBoatItemStack(TestContext context) { ChestBoatEntity birchChestBoat = context.spawnEntity(EntityType.BIRCH_CHEST_BOAT, SPAWN_POSITION); ItemStack stack = birchChestBoat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.BIRCH_CHEST_BOAT)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.BIRCH_CHEST_BOAT) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnCherryBoatGivesCherryBoatItemStack(TestContext context) { BoatEntity cherryBoat = context.spawnEntity(EntityType.CHERRY_BOAT, SPAWN_POSITION); ItemStack stack = cherryBoat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CHERRY_BOAT)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CHERRY_BOAT) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnCherryChestBoatGivesCherryChestBoatItemStack(TestContext context) { ChestBoatEntity cherryChestBoat = context.spawnEntity(EntityType.CHERRY_CHEST_BOAT, SPAWN_POSITION); ItemStack stack = cherryChestBoat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.CHERRY_CHEST_BOAT)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.CHERRY_CHEST_BOAT) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnDarkOakBoatGivesDarkOakBoatItemStack(TestContext context) { BoatEntity darkOakBoat = context.spawnEntity(EntityType.DARK_OAK_BOAT, SPAWN_POSITION); ItemStack stack = darkOakBoat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.DARK_OAK_BOAT)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.DARK_OAK_BOAT) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnDarkOakChestBoatGivesDarkOakChestBoatItemStack(TestContext context) { ChestBoatEntity darkOakChestBoat = context.spawnEntity(EntityType.DARK_OAK_CHEST_BOAT, SPAWN_POSITION); ItemStack stack = darkOakChestBoat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.DARK_OAK_CHEST_BOAT)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.DARK_OAK_CHEST_BOAT) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnJungleBoatGivesJungleBoatItemStack(TestContext context) { BoatEntity jungleBoat = context.spawnEntity(EntityType.JUNGLE_BOAT, SPAWN_POSITION); ItemStack stack = jungleBoat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.JUNGLE_BOAT)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.JUNGLE_BOAT) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnJungleChestBoatGivesJungleChestBoatItemStack(TestContext context) { ChestBoatEntity jungleChestBoat = context.spawnEntity(EntityType.JUNGLE_CHEST_BOAT, SPAWN_POSITION); ItemStack stack = jungleChestBoat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.JUNGLE_CHEST_BOAT)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.JUNGLE_CHEST_BOAT) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnMangroveBoatGivesMangroveBoatItemStack(TestContext context) { BoatEntity mangroveBoat = context.spawnEntity(EntityType.MANGROVE_BOAT, SPAWN_POSITION); ItemStack stack = mangroveBoat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.MANGROVE_BOAT)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.MANGROVE_BOAT) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnMangroveChestBoatGivesMangroveChestBoatItemStack(TestContext context) { ChestBoatEntity mangroveChestBoat = context.spawnEntity(EntityType.MANGROVE_CHEST_BOAT, SPAWN_POSITION); ItemStack stack = mangroveChestBoat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.MANGROVE_CHEST_BOAT)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.MANGROVE_CHEST_BOAT) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnOakBoatGivesOakBoatItemStack(TestContext context) { BoatEntity oakBoat = context.spawnEntity(EntityType.OAK_BOAT, SPAWN_POSITION); ItemStack stack = oakBoat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.OAK_BOAT)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.OAK_BOAT) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnOakChestBoatGivesOakChestBoatItemStack(TestContext context) { ChestBoatEntity oakChestBoat = context.spawnEntity(EntityType.OAK_CHEST_BOAT, SPAWN_POSITION); ItemStack stack = oakChestBoat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.OAK_CHEST_BOAT)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.OAK_CHEST_BOAT) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnSpruceBoatGivesSpruceBoatItemStack(TestContext context) { BoatEntity spruceBoat = context.spawnEntity(EntityType.SPRUCE_BOAT, SPAWN_POSITION); ItemStack stack = spruceBoat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SPRUCE_BOAT)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SPRUCE_BOAT) + ); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void getPickStackOnSpruceChestBoatGivesSpruceChestBoatItemStack(TestContext context) { ChestBoatEntity spruceChestBoat = context.spawnEntity(EntityType.SPRUCE_CHEST_BOAT, SPAWN_POSITION); ItemStack stack = spruceChestBoat.getPickBlockStack(); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(stack, ItemKeys.SPRUCE_CHEST_BOAT)); + context.addFinalTask(() -> Assert.itemStack(context, stack) + .is(ItemKeys.SPRUCE_CHEST_BOAT) + ); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/ArmadilloEntityTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/ArmadilloEntityTestSuite.java index 17ded874..a8ba6298 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/ArmadilloEntityTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/ArmadilloEntityTestSuite.java @@ -1,16 +1,14 @@ package net.errorcraft.itematic.gametest.entity.passive; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.entity.EntityType; import net.minecraft.entity.ai.brain.MemoryModuleType; import net.minecraft.entity.passive.ArmadilloEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.test.GameTest; -import net.minecraft.test.GameTestException; import net.minecraft.test.TestContext; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; @@ -20,24 +18,17 @@ public class ArmadilloEntityTestSuite { private static final BlockPos SPAWN_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") @SuppressWarnings("removal") public void holdingSpiderEyeTemptsArmadillo(TestContext context) { ArmadilloEntity armadillo = context.spawnEntity(EntityType.ARMADILLO, SPAWN_POSITION); ServerPlayerEntity player = context.createMockCreativeServerPlayerInWorld(); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SPIDER_EYE); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, context.getWorld().itematic$createStack(ItemKeys.SPIDER_EYE)); TestUtil.setEntityPos(context, player, SPAWN_POSITION); context.addInstantFinalTask(() -> { Optional temptingPlayer = armadillo.getBrain().getOptionalRegisteredMemory(MemoryModuleType.TEMPTING_PLAYER); - if (temptingPlayer.isEmpty()) { - throw new GameTestException("Armadillo was not tempted by a player"); - } - - if (temptingPlayer.get() != player) { - throw new GameTestException("Armadillo was not tempted by the expected player"); - } + Assert.isTrue(context, temptingPlayer.isPresent(), () -> "Armadillo was not tempted by a Player"); + Assert.areEqual(context, temptingPlayer.get(), player, "Armadillo was not tempted by the expected Player"); }); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/AxolotlEntityTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/AxolotlEntityTestSuite.java index 44ac7e82..64e0dd45 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/AxolotlEntityTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/AxolotlEntityTestSuite.java @@ -1,16 +1,14 @@ package net.errorcraft.itematic.gametest.entity.passive; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.entity.EntityType; import net.minecraft.entity.ai.brain.MemoryModuleType; import net.minecraft.entity.passive.AxolotlEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.test.GameTest; -import net.minecraft.test.GameTestException; import net.minecraft.test.TestContext; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; @@ -20,24 +18,17 @@ public class AxolotlEntityTestSuite { private static final BlockPos SPAWN_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") @SuppressWarnings("removal") public void holdingTropicalFishBucketTemptsAxolotl(TestContext context) { AxolotlEntity axolotl = context.spawnEntity(EntityType.AXOLOTL, SPAWN_POSITION); ServerPlayerEntity player = context.createMockCreativeServerPlayerInWorld(); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.TROPICAL_FISH_BUCKET); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, context.getWorld().itematic$createStack(ItemKeys.TROPICAL_FISH_BUCKET)); TestUtil.setEntityPos(context, player, SPAWN_POSITION); context.addInstantFinalTask(() -> { Optional temptingPlayer = axolotl.getBrain().getOptionalRegisteredMemory(MemoryModuleType.TEMPTING_PLAYER); - if (temptingPlayer.isEmpty()) { - throw new GameTestException("Axolotl was not tempted by a player"); - } - - if (temptingPlayer.get() != player) { - throw new GameTestException("Axolotl was not tempted by the expected player"); - } + Assert.isTrue(context, temptingPlayer.isPresent(), () -> "Axolotl was not tempted by a Player"); + Assert.areEqual(context, temptingPlayer.get(), player, "Axolotl was not tempted by the expected Player"); }); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/CamelEntityTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/CamelEntityTestSuite.java index fbf88a25..ac785c79 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/CamelEntityTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/CamelEntityTestSuite.java @@ -1,16 +1,14 @@ package net.errorcraft.itematic.gametest.entity.passive; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.entity.EntityType; import net.minecraft.entity.ai.brain.MemoryModuleType; import net.minecraft.entity.passive.CamelEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.test.GameTest; -import net.minecraft.test.GameTestException; import net.minecraft.test.TestContext; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; @@ -20,24 +18,17 @@ public class CamelEntityTestSuite { private static final BlockPos SPAWN_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") @SuppressWarnings("removal") public void holdingCactusTemptsCamel(TestContext context) { CamelEntity camel = context.spawnEntity(EntityType.CAMEL, SPAWN_POSITION); ServerPlayerEntity player = context.createMockCreativeServerPlayerInWorld(); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CACTUS); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, context.getWorld().itematic$createStack(ItemKeys.CACTUS)); TestUtil.setEntityPos(context, player, SPAWN_POSITION); context.addInstantFinalTask(() -> { Optional temptingPlayer = camel.getBrain().getOptionalRegisteredMemory(MemoryModuleType.TEMPTING_PLAYER); - if (temptingPlayer.isEmpty()) { - throw new GameTestException("Camel was not tempted by a player"); - } - - if (temptingPlayer.get() != player) { - throw new GameTestException("Camel was not tempted by the expected player"); - } + Assert.isTrue(context, temptingPlayer.isPresent(), () -> "Camel was not tempted by a Player"); + Assert.areEqual(context, temptingPlayer.get(), player, "Camel was not tempted by the expected Player"); }); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/FrogEntityTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/FrogEntityTestSuite.java index 4d45d647..5e64b892 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/FrogEntityTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/FrogEntityTestSuite.java @@ -1,16 +1,14 @@ package net.errorcraft.itematic.gametest.entity.passive; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.entity.EntityType; import net.minecraft.entity.ai.brain.MemoryModuleType; import net.minecraft.entity.passive.FrogEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.test.GameTest; -import net.minecraft.test.GameTestException; import net.minecraft.test.TestContext; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; @@ -20,24 +18,17 @@ public class FrogEntityTestSuite { private static final BlockPos SPAWN_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") @SuppressWarnings("removal") public void holdingSlimeBallTemptsFrog(TestContext context) { FrogEntity frog = context.spawnEntity(EntityType.FROG, SPAWN_POSITION); ServerPlayerEntity player = context.createMockCreativeServerPlayerInWorld(); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SLIME_BALL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, context.getWorld().itematic$createStack(ItemKeys.SLIME_BALL)); TestUtil.setEntityPos(context, player, SPAWN_POSITION); context.addInstantFinalTask(() -> { Optional temptingPlayer = frog.getBrain().getOptionalRegisteredMemory(MemoryModuleType.TEMPTING_PLAYER); - if (temptingPlayer.isEmpty()) { - throw new GameTestException("Frog was not tempted by a player"); - } - - if (temptingPlayer.get() != player) { - throw new GameTestException("Frog was not tempted by the expected player"); - } + Assert.isTrue(context, temptingPlayer.isPresent(), () -> "Frog was not tempted by a Player"); + Assert.areEqual(context, temptingPlayer.get(), player, "Frog was not tempted by the expected Player"); }); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/GoatEntityTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/GoatEntityTestSuite.java index 45ec4d5a..2665e625 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/GoatEntityTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/GoatEntityTestSuite.java @@ -1,16 +1,14 @@ package net.errorcraft.itematic.gametest.entity.passive; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.entity.EntityType; import net.minecraft.entity.ai.brain.MemoryModuleType; import net.minecraft.entity.passive.GoatEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.test.GameTest; -import net.minecraft.test.GameTestException; import net.minecraft.test.TestContext; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; @@ -20,24 +18,17 @@ public class GoatEntityTestSuite { private static final BlockPos SPAWN_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") @SuppressWarnings("removal") public void holdingWheatTemptsGoat(TestContext context) { GoatEntity goat = context.spawnEntity(EntityType.GOAT, SPAWN_POSITION); ServerPlayerEntity player = context.createMockCreativeServerPlayerInWorld(); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.WHEAT); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, context.getWorld().itematic$createStack(ItemKeys.WHEAT)); TestUtil.setEntityPos(context, player, SPAWN_POSITION); context.addInstantFinalTask(() -> { Optional temptingPlayer = goat.getBrain().getOptionalRegisteredMemory(MemoryModuleType.TEMPTING_PLAYER); - if (temptingPlayer.isEmpty()) { - throw new GameTestException("Goat was not tempted by a player"); - } - - if (temptingPlayer.get() != player) { - throw new GameTestException("Goat was not tempted by the expected player"); - } + Assert.isTrue(context, temptingPlayer.isPresent(), () -> "Goat was not tempted by a Player"); + Assert.areEqual(context, temptingPlayer.get(), player, "Goat was not tempted by the expected Player"); }); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/MooshroomEntityTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/MooshroomEntityTestSuite.java index d0d4196a..4a91abe8 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/MooshroomEntityTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/MooshroomEntityTestSuite.java @@ -1,14 +1,13 @@ package net.errorcraft.itematic.gametest.entity.passive; -import net.errorcraft.itematic.gametest.Assert; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.component.DataComponentTypes; import net.minecraft.entity.EntityType; import net.minecraft.entity.passive.MooshroomEntity; 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.ActionResult; import net.minecraft.util.Hand; @@ -18,39 +17,54 @@ public class MooshroomEntityTestSuite { private static final BlockPos SPAWN_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void usingFlowerOnBrownMooshroomGivesMooshroomSuspiciousEffects(TestContext context) { MooshroomEntity mooshroom = context.spawnEntity(EntityType.MOOSHROOM, SPAWN_POSITION); - mooshroom.setVariant(MooshroomEntity.Type.BROWN); + mooshroom.setComponent(DataComponentTypes.MOOSHROOM_VARIANT, MooshroomEntity.Variant.BROWN); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.DANDELION); - player.setStackInHand(Hand.MAIN_HAND, stack); - ActionResult result = mooshroom.interactMob(player, Hand.MAIN_HAND); - context.addInstantFinalTask(() -> { - context.assertTrue(result.isAccepted(), "Expected interaction with dandelion on brown Mooshroom to be successful"); + context.addFinalTask(() -> { + ServerWorld world = context.getWorld(); + player.setStackInHand(Hand.MAIN_HAND, world.itematic$createStack(ItemKeys.DANDELION)); + ActionResult dandelionResult = mooshroom.interactMob(player, Hand.MAIN_HAND); + Assert.isTrue( + context, + dandelionResult.isAccepted(), + () -> "Expected interaction with Dandelion on brown Mooshroom to be successful" + ); player.setStackInHand(Hand.MAIN_HAND, world.itematic$createStack(ItemKeys.BOWL)); ActionResult bowlResult = mooshroom.interactMob(player, Hand.MAIN_HAND); - context.assertTrue(bowlResult.isAccepted(), "Expected interaction with bowl on brown Mooshroom to be successful"); - ItemStack heldStack = player.getStackInHand(Hand.MAIN_HAND); - Assert.itemStackIsOf(heldStack, ItemKeys.SUSPICIOUS_STEW); - Assert.itemStackHasDataComponent(heldStack, DataComponentTypes.SUSPICIOUS_STEW_EFFECTS, - component -> context.assertTrue(!component.effects().isEmpty(), "Expected item stack to have suspicious effects") + Assert.isTrue( + context, + bowlResult.isAccepted(), + () -> "Expected interaction with Bowl on brown Mooshroom to be successful" ); + Assert.itemStack(context, player.getStackInHand(Hand.MAIN_HAND)) + .is(ItemKeys.SUSPICIOUS_STEW) + .hasComponent( + DataComponentTypes.SUSPICIOUS_STEW_EFFECTS, + suspiciousStewEffects -> Assert.isFalse( + context, + suspiciousStewEffects.effects().isEmpty(), + () -> "Expected item stack to have suspicious effects" + ) + ); }); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void usingBowlOnMooshroomGivesMushroomStew(TestContext context) { MooshroomEntity mooshroom = context.spawnEntity(EntityType.MOOSHROOM, SPAWN_POSITION); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BOWL); - player.setStackInHand(Hand.MAIN_HAND, stack); - ActionResult result = mooshroom.interactMob(player, Hand.MAIN_HAND); - context.addInstantFinalTask(() -> { - context.assertTrue(result.isAccepted(), "Expected interaction with bowl on Mooshroom to be successful"); - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.MUSHROOM_STEW); + context.addFinalTask(() -> { + player.setStackInHand(Hand.MAIN_HAND, context.getWorld().itematic$createStack(ItemKeys.BOWL)); + ActionResult bowlResult = mooshroom.interactMob(player, Hand.MAIN_HAND); + Assert.isTrue( + context, + bowlResult.isAccepted(), + () -> "Expected interaction with Bowl on Mooshroom to be successful" + ); + Assert.itemStack(context, player.getStackInHand(Hand.MAIN_HAND)) + .is(ItemKeys.MUSHROOM_STEW); }); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/SheepEntityTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/SheepEntityTestSuite.java index 42b9d0c4..e13fa0f8 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/SheepEntityTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/SheepEntityTestSuite.java @@ -1,8 +1,9 @@ package net.errorcraft.itematic.gametest.entity.passive; +import net.errorcraft.itematic.assertion.Assert; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.entity.EntityType; import net.minecraft.entity.passive.SheepEntity; -import net.minecraft.test.GameTest; import net.minecraft.test.TestContext; import net.minecraft.util.DyeColor; import net.minecraft.util.math.BlockPos; @@ -10,33 +11,34 @@ public class SheepEntityTestSuite { private static final BlockPos SPAWN_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:entity.platform") - @SuppressWarnings("DataFlowIssue") + @GameTest(structure = "itematic:entity.platform") public void breedingRedAndYellowSheepResultsInOrangeSheep(TestContext context) { SheepEntity firstSheep = context.spawnEntity(EntityType.SHEEP, SPAWN_POSITION); firstSheep.setColor(DyeColor.RED); SheepEntity secondSheep = context.spawnEntity(EntityType.SHEEP, SPAWN_POSITION); secondSheep.setColor(DyeColor.YELLOW); SheepEntity childSheep = firstSheep.createChild(context.getWorld(), secondSheep); - context.addInstantFinalTask(() -> { - context.assertTrue(childSheep != null, "Expected child sheep to exist"); - DyeColor color = childSheep.getColor(); - context.assertTrue(color == DyeColor.ORANGE, "Expected child sheep to be orange, got " + color + " instead"); + context.addFinalTask(() -> { + Assert.isNotNull(context, childSheep, "child Sheep"); + Assert.areEqual(context, childSheep.getColor(), DyeColor.ORANGE, "child Sheep"); }); } - @GameTest(templateName = "itematic:entity.platform") - @SuppressWarnings("DataFlowIssue") + @GameTest(structure = "itematic:entity.platform") public void breedingRedAndLimeSheepResultsInEitherColorSheep(TestContext context) { SheepEntity firstSheep = context.spawnEntity(EntityType.SHEEP, SPAWN_POSITION); firstSheep.setColor(DyeColor.RED); SheepEntity secondSheep = context.spawnEntity(EntityType.SHEEP, SPAWN_POSITION); secondSheep.setColor(DyeColor.LIME); SheepEntity childSheep = firstSheep.createChild(context.getWorld(), secondSheep); - context.addInstantFinalTask(() -> { - context.assertTrue(childSheep != null, "Expected child sheep to exist"); + context.addFinalTask(() -> { + Assert.isNotNull(context, childSheep, "child Sheep"); DyeColor color = childSheep.getColor(); - context.assertTrue(color == DyeColor.RED || color == DyeColor.LIME, "Expected child sheep to be red or lime, got " + color + " instead"); + Assert.isTrue( + context, + color == DyeColor.RED || color == DyeColor.LIME, + () -> "Expected child Sheep to be red or lime, got " + color + " instead" + ); }); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/SnifferEntityTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/SnifferEntityTestSuite.java index 59ce951c..52bd67bd 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/SnifferEntityTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/SnifferEntityTestSuite.java @@ -1,16 +1,14 @@ package net.errorcraft.itematic.gametest.entity.passive; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.entity.EntityType; import net.minecraft.entity.ai.brain.MemoryModuleType; import net.minecraft.entity.passive.SnifferEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.test.GameTest; -import net.minecraft.test.GameTestException; import net.minecraft.test.TestContext; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; @@ -20,24 +18,17 @@ public class SnifferEntityTestSuite { private static final BlockPos SPAWN_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") @SuppressWarnings("removal") public void holdingTorchflowerSeedsTemptsSniffer(TestContext context) { SnifferEntity sniffer = context.spawnEntity(EntityType.SNIFFER, SPAWN_POSITION); ServerPlayerEntity player = context.createMockCreativeServerPlayerInWorld(); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.TORCHFLOWER_SEEDS); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, context.getWorld().itematic$createStack(ItemKeys.TORCHFLOWER_SEEDS)); TestUtil.setEntityPos(context, player, SPAWN_POSITION); context.addInstantFinalTask(() -> { Optional temptingPlayer = sniffer.getBrain().getOptionalRegisteredMemory(MemoryModuleType.TEMPTING_PLAYER); - if (temptingPlayer.isEmpty()) { - throw new GameTestException("Sniffer was not tempted by a player"); - } - - if (temptingPlayer.get() != player) { - throw new GameTestException("Sniffer was not tempted by the expected player"); - } + Assert.isTrue(context, temptingPlayer.isPresent(), () -> "Sniffer was not tempted by a Player"); + Assert.areEqual(context, temptingPlayer.get(), player, "Sniffer was not tempted by the expected Player"); }); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/WolfEntityTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/WolfEntityTestSuite.java index de343d49..d7abb7f5 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/WolfEntityTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/entity/passive/WolfEntityTestSuite.java @@ -1,14 +1,13 @@ package net.errorcraft.itematic.gametest.entity.passive; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.entity.EntityType; import net.minecraft.entity.passive.WolfEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.test.GameTest; import net.minecraft.test.TestContext; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; @@ -17,42 +16,45 @@ public class WolfEntityTestSuite { private static final BlockPos SPAWN_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") @SuppressWarnings("removal") public void holdingBoneTemptsWolf(TestContext context) { WolfEntity wolf = context.spawnEntity(EntityType.WOLF, SPAWN_POSITION); wolf.setTamed(true, true); ServerPlayerEntity player = context.createMockCreativeServerPlayerInWorld(); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BONE); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, context.getWorld().itematic$createStack(ItemKeys.BONE)); TestUtil.setEntityPos(context, player, SPAWN_POSITION); - context.addInstantFinalTask(() -> context.assertTrue(wolf.isBegging(), "Expected wolf to be begging")); + context.addInstantFinalTask(() -> Assert.isTrue( + context, + wolf.isBegging(), + () -> "Expected wolf to be begging" + )); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") @SuppressWarnings("removal") public void holdingMeatTemptsWolf(TestContext context) { WolfEntity wolf = context.spawnEntity(EntityType.WOLF, SPAWN_POSITION); wolf.setTamed(true, true); ServerPlayerEntity player = context.createMockCreativeServerPlayerInWorld(); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BEEF); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, context.getWorld().itematic$createStack(ItemKeys.BEEF)); TestUtil.setEntityPos(context, player, SPAWN_POSITION); - context.addInstantFinalTask(() -> context.assertTrue(wolf.isBegging(), "Expected wolf to be begging")); + context.addInstantFinalTask(() -> Assert.isTrue( + context, + wolf.isBegging(), + () -> "Expected wolf to be begging" + )); } - @GameTest(templateName = "itematic:entity.platform") + @GameTest(structure = "itematic:entity.platform") public void feedingWolfMeatHealsWolf(TestContext context) { WolfEntity wolf = context.spawnEntity(EntityType.WOLF, SPAWN_POSITION); wolf.setTamed(true, true); context.setHealthLow(wolf); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BEEF); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, context.getWorld().itematic$createStack(ItemKeys.BEEF)); wolf.interactMob(player, Hand.MAIN_HAND); - context.addInstantFinalTask(() -> context.assertTrue(wolf.getHealth() > 0.25f, "Expected wolf to be healed")); + context.addFinalTask(() -> Assert.livingEntity(context, wolf) + .hasHealth(health -> health.isGreaterThan(0.25f))); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/BeetrootSoupTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/BeetrootSoupTestSuite.java index e20dc6d6..dbd6bcd2 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/BeetrootSoupTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/BeetrootSoupTestSuite.java @@ -1,29 +1,33 @@ package net.errorcraft.itematic.gametest.item; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; -import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.fabricmc.fabric.api.gametest.v1.GameTest; 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 BeetrootSoupTestSuite { - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest(maxTicks = 100) public void eatingBeetrootSoupLeavesBowlAfterConsuming(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); player.getHungerManager().setFoodLevel(0); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BEETROOT_SOUP); - player.setStackInHand(Hand.MAIN_HAND, stack); + ItemStack beetrootSoup = world.itematic$createStack(ItemKeys.BEETROOT_SOUP); + player.setStackInHand(Hand.MAIN_HAND, beetrootSoup); world.spawnEntity(player); context.createTimedTaskRunner() - .createAndAddReported(() -> stack.use(world, player, Hand.MAIN_HAND)) + .createAndAddReported(() -> beetrootSoup.use(world, player, Hand.MAIN_HAND)) .expectMinDurationAndRun( - stack.getMaxUseTime(player), - () -> context.assertTrue(player.getInventory().contains(s -> s.itematic$isOf(ItemKeys.BOWL)), "Expected Player to have a Bowl in their inventory") + beetrootSoup.getMaxUseTime(player), + () -> Assert.isTrue( + context, + player.getInventory().contains(stack -> stack.itematic$isOf(ItemKeys.BOWL)), + () -> "Expected Player to have a Bowl in their inventory" + ) ) .completeIfSuccessful(); } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/BowTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/BowTestSuite.java index 5432f4cf..db1c8cd6 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/BowTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/BowTestSuite.java @@ -1,14 +1,14 @@ package net.errorcraft.itematic.gametest.item; -import net.errorcraft.itematic.gametest.TestUtil; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.enchantment.Enchantments; import net.minecraft.entity.EntityType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.registry.RegistryKeys; import net.minecraft.server.world.ServerWorld; -import net.minecraft.test.GameTest; import net.minecraft.test.TestContext; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; @@ -17,11 +17,11 @@ public class BowTestSuite { private static final BlockPos SPAWN_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:item.bow.platform") + @GameTest(structure = "itematic:item.bow.platform") public void usingBowWithMultishotSpawnsMultipleArrows(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BOW); - stack.addEnchantment( + ItemStack bow = world.itematic$createStack(ItemKeys.BOW); + bow.addEnchantment( world.getRegistryManager() .getOrThrow(RegistryKeys.ENCHANTMENT) .getOrThrow(Enchantments.MULTISHOT), @@ -30,11 +30,11 @@ public void usingBowWithMultishotSpawnsMultipleArrows(TestContext context) { ItemStack ammunition = world.itematic$createStack(ItemKeys.ARROW); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); TestUtil.setEntityPos(context, player, SPAWN_POSITION); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, bow); player.getInventory().insertStack(ammunition); world.spawnEntity(player); context.createTimedTaskRunner() - .createAndAddReported(() -> stack.use(world, player, Hand.MAIN_HAND)) + .createAndAddReported(() -> bow.use(world, player, Hand.MAIN_HAND)) .expectMinDurationAndRun(20, () -> { player.stopUsingItem(); context.expectEntities(EntityType.ARROW, 3); diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/BrushTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/BrushTestSuite.java index d7a9801a..c5b6835d 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/BrushTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/BrushTestSuite.java @@ -1,11 +1,12 @@ package net.errorcraft.itematic.gametest.item; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; 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.util.math.BlockPos; @@ -13,37 +14,52 @@ import net.minecraft.world.GameMode; public class BrushTestSuite { - private static final BlockPos BLOCK_POSITION = new BlockPos(2, 0, 2); + private static final BlockPos BLOCK_POSITION = new BlockPos(1, 2, 1); + private static final BlockPos SPAWN_POSITION = new BlockPos(1, 1, 0); - @GameTest(templateName = "itematic:item.brush.platform") + @GameTest(structure = "itematic:item.brush.platform") public void usingBrushDoesNotStartBrushing(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BRUSH); + ItemStack brush = world.itematic$createStack(ItemKeys.BRUSH); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); - stack.use(world, player, Hand.MAIN_HAND); - context.addInstantFinalTask(() -> context.assertFalse(player.isUsingItem(), "Expected player to not have started using a Brush")); + player.setStackInHand(Hand.MAIN_HAND, brush); + brush.use(world, player, Hand.MAIN_HAND); + context.addFinalTask(() -> Assert.isFalse( + context, + player.isUsingItem(), + () -> "Expected Player not to have started using a Brush" + )); } - @GameTest(templateName = "itematic:item.brush.platform.suspicious_sand") + @GameTest(structure = "itematic:item.brush.platform.suspicious_sand") public void usingBrushOnBlockStartsBrushing(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BRUSH); + ItemStack brush = world.itematic$createStack(ItemKeys.BRUSH); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + TestUtil.setEntityPos(context, player, SPAWN_POSITION); + player.setStackInHand(Hand.MAIN_HAND, brush); world.spawnEntity(player); TestUtil.useBlock(context, BLOCK_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> context.assertTrue(player.isUsingItem(), "Expected player to have started using a Brush")); + context.addFinalTask(() -> Assert.isTrue( + context, + player.isUsingItem(), + () -> "Expected Player to have started using a Brush" + )); } - @GameTest(templateName = "itematic:item.brush.platform.short_grass") + @GameTest(structure = "itematic:item.brush.platform.short_grass") public void usingBrushOnIntangibleBlockDoesNotStartBrushing(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BRUSH); + ItemStack brush = world.itematic$createStack(ItemKeys.BRUSH); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + TestUtil.setEntityPos(context, player, SPAWN_POSITION); + player.setStackInHand(Hand.MAIN_HAND, brush); world.spawnEntity(player); TestUtil.useBlock(context, BLOCK_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> context.assertFalse(player.isUsingItem(), "Expected player to not have started using a Brush")); + context.addFinalTaskWithDuration(1, () -> Assert.isFalse( + context, + player.isUsingItem(), + () -> "Expected Player not to have started using a Brush" + )); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/BundleTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/BundleTestSuite.java index a59524f1..bfa27116 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/BundleTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/BundleTestSuite.java @@ -1,18 +1,17 @@ package net.errorcraft.itematic.gametest.item; -import net.errorcraft.itematic.gametest.Assert; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; import net.errorcraft.itematic.item.component.ItemComponentTypes; import net.errorcraft.itematic.mixin.component.type.BundleContentsComponentAccessor; -import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.component.DataComponentTypes; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.item.ItemStack; import net.minecraft.screen.slot.Slot; import net.minecraft.server.world.ServerWorld; -import net.minecraft.test.GameTest; import net.minecraft.test.TestContext; import net.minecraft.util.ClickType; import net.minecraft.world.GameMode; @@ -20,7 +19,7 @@ public class BundleTestSuite { private static final int SLOT_INDEX = 0; - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void addingNormalItemToBundleAddsIt(TestContext context) { ServerWorld world = context.getWorld(); ItemStack bundleStack = world.itematic$createStack(ItemKeys.BUNDLE); @@ -29,16 +28,24 @@ public void addingNormalItemToBundleAddsIt(TestContext context) { PlayerInventory inventory = player.getInventory(); inventory.insertStack(SLOT_INDEX, addedStack); Slot slot = new Slot(inventory, SLOT_INDEX, 0, 0); - context.addInstantFinalTask(() -> { - context.assertTrue(bundleStack.onStackClicked(slot, ClickType.RIGHT, player), "Expected right-clicking with Bundle to be successful"); - Assert.itemStackIsEmpty(slot.getStack()); - Assert.itemStackHasDataComponent(bundleStack, DataComponentTypes.BUNDLE_CONTENTS, bundleContents -> { - Assert.itemStackIsOf(bundleContents.get(0), ItemKeys.STICK); - }); + context.addFinalTask(() -> { + Assert.isTrue( + context, + bundleStack.onStackClicked(slot, ClickType.RIGHT, player), + () -> "Expected right clicking on slot with Bundle to be successful" + ); + Assert.itemStack(context, slot.getStack()) + .isEmpty(); + Assert.itemStack(context, bundleStack) + .hasComponent( + DataComponentTypes.BUNDLE_CONTENTS, + bundleContents -> Assert.itemStack(context, bundleContents.get(0)) + .is(ItemKeys.STICK) + ); }); } - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void addingShulkerBoxToBundleRejectsIt(TestContext context) { ServerWorld world = context.getWorld(); ItemStack bundleStack = world.itematic$createStack(ItemKeys.BUNDLE); @@ -47,32 +54,47 @@ public void addingShulkerBoxToBundleRejectsIt(TestContext context) { PlayerInventory inventory = player.getInventory(); inventory.insertStack(SLOT_INDEX, addedStack); Slot slot = new Slot(inventory, SLOT_INDEX, 0, 0); - context.addInstantFinalTask(() -> { - context.assertTrue(bundleStack.onStackClicked(slot, ClickType.RIGHT, player), "Expected right-clicking with Bundle to be successful"); - Assert.itemStackIsNotEmpty(slot.getStack()); - Assert.itemStackHasDataComponent(bundleStack, DataComponentTypes.BUNDLE_CONTENTS, bundleContents -> { - context.assertTrue(bundleContents.isEmpty(), "Expected Bundle to be empty"); - }); + context.addFinalTask(() -> { + Assert.isTrue( + context, + bundleStack.onStackClicked(slot, ClickType.RIGHT, player), + () -> "Expected right clicking on slot with Bundle to be successful" + ); + Assert.itemStack(context, slot.getStack()) + .isNotEmpty(); + Assert.itemStack(context, bundleStack) + .hasComponent( + DataComponentTypes.BUNDLE_CONTENTS, + bundleContents -> Assert.isTrue(context, bundleContents.isEmpty(), () -> "Expected Bundle to be empty") + ); }); } - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void addingBundleToBundleAddsItWithPenalty(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack bundleStack = world.itematic$createStack(ItemKeys.BUNDLE); - ItemStack addedStack = world.itematic$createStack(ItemKeys.BUNDLE); + ItemStack bundle = world.itematic$createStack(ItemKeys.BUNDLE); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); PlayerInventory inventory = player.getInventory(); - inventory.insertStack(SLOT_INDEX, addedStack); + inventory.insertStack(SLOT_INDEX, world.itematic$createStack(ItemKeys.BUNDLE)); Slot slot = new Slot(inventory, SLOT_INDEX, 0, 0); - context.addInstantFinalTask(() -> { - context.assertTrue(bundleStack.onStackClicked(slot, ClickType.RIGHT, player), "Expected right-clicking with Bundle to be successful"); - Assert.itemStackIsEmpty(slot.getStack()); - Assert.itemStackHasDataComponent(bundleStack, DataComponentTypes.BUNDLE_CONTENTS, bundleContents -> { - Assert.itemStackIsOf(bundleContents.get(0), ItemKeys.BUNDLE); - }); - context.assertEquals( - TestUtil.getItemBehavior(bundleStack, ItemComponentTypes.ITEM_HOLDER).occupancy(bundleStack), + context.addFinalTask(() -> { + Assert.isTrue( + context, + bundle.onStackClicked(slot, ClickType.RIGHT, player), + () -> "Expected right clicking on slot with Bundle to be successful" + ); + Assert.itemStack(context, slot.getStack()) + .isEmpty(); + Assert.itemStack(context, bundle) + .hasComponent( + DataComponentTypes.BUNDLE_CONTENTS, + bundleContents -> Assert.itemStack(context, bundleContents.get(0)) + .is(ItemKeys.BUNDLE) + ); + Assert.areEqual( + context, + TestUtil.getItemBehavior(context, bundle, ItemComponentTypes.ITEM_HOLDER).occupancy(bundle), BundleContentsComponentAccessor.nestedBundleOccupancy(), "occupancy" ); diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/CompassTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/CompassTestSuite.java new file mode 100644 index 00000000..85887bd2 --- /dev/null +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/CompassTestSuite.java @@ -0,0 +1,87 @@ +package net.errorcraft.itematic.gametest.item; + +import net.errorcraft.itematic.assertion.Assert; +import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.test.TestContext; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.GlobalPos; +import net.minecraft.world.GameMode; + +import java.util.Optional; + +public class CompassTestSuite { + private static final BlockPos LODESTONE_POSITION = new BlockPos(1, 1, 1); + + @GameTest(structure = "itematic:item.compass.platform.lodestone") + public void usingCompassOnLodestoneSetsTrackedDataFromBlock(TestContext context) { + ServerWorld world = context.getWorld(); + ItemStack compass = world.itematic$createStack(ItemKeys.COMPASS); + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + player.setStackInHand(Hand.MAIN_HAND, compass); + world.spawnEntity(player); + ItemStack resultStack = TestUtil.useStackOnBlockInside(context, player, compass, LODESTONE_POSITION, Direction.UP) + .orElseThrow(); + context.addFinalTask(() -> Assert.itemStack(context, resultStack) + .hasComponent(DataComponentTypes.LODESTONE_TRACKER, lodestoneTracker -> { + Assert.isTrue( + context, + lodestoneTracker.tracked(), + () -> "Expected Lodestone Compass to be tracked" + ); + Optional target = lodestoneTracker.target(); + Assert.isTrue( + context, + target.isPresent(), + () -> "Expected Lodestone Compass to have a target" + ); + Assert.areEqual( + context, + target.get().dimension(), + context.getWorld().getRegistryKey(), + "Lodestone dimension" + ); + Assert.areEqual( + context, + target.get().pos(), + context.getAbsolutePos(LODESTONE_POSITION), + "Lodestone position" + ); + })); + } + + @GameTest(structure = "itematic:item.compass.platform.lodestone") + public void destroyingLodestoneRemovesTrackedDataFromLodestoneCompass(TestContext context) { + ServerWorld world = context.getWorld(); + ItemStack compass = world.itematic$createStack(ItemKeys.COMPASS); + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + player.setStackInHand(Hand.MAIN_HAND, compass); + world.spawnEntity(player); + ItemStack resultStack = TestUtil.useStackOnBlockInside(context, player, compass, LODESTONE_POSITION, Direction.UP) + .orElseThrow(); + context.removeBlock(LODESTONE_POSITION); + context.createTimedTaskRunner() + .expectMinDurationAndRun(1, () -> Assert.itemStack(context, resultStack) + .hasComponent(DataComponentTypes.LODESTONE_TRACKER, lodestoneTracker -> { + Assert.isTrue( + context, + lodestoneTracker.tracked(), + () -> "Expected Lodestone Compass to be tracked" + ); + Assert.isTrue( + context, + lodestoneTracker.target().isEmpty(), + () -> "Expected Lodestone Compass not to have a target" + ); + }) + ) + .completeIfSuccessful(); + } +} diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/CrossbowTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/CrossbowTestSuite.java index 807858c9..f93ed78e 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/CrossbowTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/CrossbowTestSuite.java @@ -1,43 +1,45 @@ package net.errorcraft.itematic.gametest.item; -import net.errorcraft.itematic.gametest.Assert; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; -import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.component.DataComponentTypes; import net.minecraft.enchantment.Enchantments; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; -import net.minecraft.registry.RegistryKeys; 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 CrossbowTestSuite { - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest(maxTicks = 100) public void usingCrossbowWithInfinityChargesArrowFromInventoryButDoesNotConsumeTheArrow(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CROSSBOW); - stack.addEnchantment( - world.getRegistryManager() - .getOrThrow(RegistryKeys.ENCHANTMENT) - .getOrThrow(Enchantments.INFINITY), - 1 - ); - ItemStack ammunition = world.itematic$createStack(ItemKeys.ARROW); + ItemStack crossbow = TestUtil.createItemStackWithEnchantment(world, ItemKeys.CROSSBOW, Enchantments.INFINITY); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); - player.getInventory().insertStack(ammunition); + player.setStackInHand(Hand.MAIN_HAND, crossbow); + player.getInventory().insertStack(world.itematic$createStack(ItemKeys.ARROW)); world.spawnEntity(player); context.createTimedTaskRunner() - .createAndAddReported(() -> stack.use(world, player, Hand.MAIN_HAND)) - .expectMinDurationAndRun(stack.getMaxUseTime(player), () -> { + .createAndAddReported(() -> crossbow.use(world, player, Hand.MAIN_HAND)) + .expectMinDurationAndRun(crossbow.getMaxUseTime(player), () -> { player.stopUsingItem(); - Assert.itemStackHasDataComponent(player.getStackInHand(Hand.MAIN_HAND), DataComponentTypes.CHARGED_PROJECTILES, - component -> context.assertTrue(component.itematic$contains(ItemKeys.ARROW), "Expected item stack to have an Arrow as a charged projectile") + Assert.itemStack(context, player.getStackInHand(Hand.MAIN_HAND)) + .hasComponent( + DataComponentTypes.CHARGED_PROJECTILES, + component -> Assert.isTrue( + context, + component.itematic$contains(ItemKeys.ARROW), + () -> "Expected item stack to have an Arrow as a charged projectile" + ) + ); + Assert.isTrue( + context, + player.getInventory().contains(s -> s.itematic$isOf(ItemKeys.ARROW)), + () -> "Expected Player to have an Arrow in their inventory" ); - context.assertTrue(player.getInventory().contains(s -> s.itematic$isOf(ItemKeys.ARROW)), "Expected player to have an Arrow in their inventory"); }) .completeIfSuccessful(); } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/FishingRodTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/FishingRodTestSuite.java index 7698b8d8..29a2775e 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/FishingRodTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/FishingRodTestSuite.java @@ -1,35 +1,44 @@ package net.errorcraft.itematic.gametest.item; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; -import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.FishingBobberEntity; +import net.minecraft.entity.projectile.ProjectileEntity; 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 FishingRodTestSuite { - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void usingFishingRodCastsFishingRod(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.FISHING_ROD); - player.setStackInHand(Hand.MAIN_HAND, stack); - stack.use(world, player, Hand.MAIN_HAND); - context.addInstantFinalTask(() -> context.assertTrue(player.fishHook != null, "Expected player to have cast a fishing rod")); + ItemStack fishingRod = world.itematic$createStack(ItemKeys.FISHING_ROD); + player.setStackInHand(Hand.MAIN_HAND, fishingRod); + fishingRod.use(world, player, Hand.MAIN_HAND); + context.addFinalTask(() -> Assert.isTrue( + context, + player.fishHook != null, + () -> "Expected Player to have cast a Fishing Rod" + )); } - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void usingCastFishingRodRetractsFishingRod(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.FISHING_ROD); - player.setStackInHand(Hand.MAIN_HAND, stack); - world.spawnEntity(new FishingBobberEntity(player, world, 0, 0, stack)); - stack.use(world, player, Hand.MAIN_HAND); - context.addInstantFinalTask(() -> context.assertTrue(player.fishHook == null, "Expected player to have retracted a fishing rod")); + ItemStack fishingRod = world.itematic$createStack(ItemKeys.FISHING_ROD); + player.setStackInHand(Hand.MAIN_HAND, fishingRod); + ProjectileEntity.spawn(new FishingBobberEntity(player, world, 0, 0), world, fishingRod); + fishingRod.use(world, player, Hand.MAIN_HAND); + context.addFinalTask(() -> Assert.isTrue( + context, + player.fishHook == null, + () -> "Expected Player to have retracted a Fishing Rod" + )); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/FlowerPotItemTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/FlowerPotItemTestSuite.java index b33ebe48..d9e0921a 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/FlowerPotItemTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/FlowerPotItemTestSuite.java @@ -1,13 +1,13 @@ package net.errorcraft.itematic.gametest.item; -import net.errorcraft.itematic.gametest.Assert; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.block.Blocks; 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.util.math.BlockPos; @@ -17,1363 +17,1567 @@ public class FlowerPotItemTestSuite { private static final BlockPos FLOWER_POT_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingOakSaplingOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.OAK_SAPLING); + ItemStack oakSapling = world.itematic$createStack(ItemKeys.OAK_SAPLING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, oakSapling); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_OAK_SAPLING, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, oakSapling, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, oakSapling) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_OAK_SAPLING); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingOakSaplingOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.OAK_SAPLING); + ItemStack oakSapling = world.itematic$createStack(ItemKeys.OAK_SAPLING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, oakSapling); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.OAK_SAPLING); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, oakSapling, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.OAK_SAPLING); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingSpruceSaplingOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SPRUCE_SAPLING); + ItemStack spruceSapling = world.itematic$createStack(ItemKeys.SPRUCE_SAPLING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, spruceSapling); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_SPRUCE_SAPLING, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, spruceSapling, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, spruceSapling) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_SPRUCE_SAPLING); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingSpruceSaplingOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SPRUCE_SAPLING); + ItemStack spruceSapling = world.itematic$createStack(ItemKeys.SPRUCE_SAPLING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, spruceSapling); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.SPRUCE_SAPLING); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, spruceSapling, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.SPRUCE_SAPLING); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingBirchSaplingOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BIRCH_SAPLING); + ItemStack birchSapling = world.itematic$createStack(ItemKeys.BIRCH_SAPLING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, birchSapling); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_BIRCH_SAPLING, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, birchSapling, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, birchSapling) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_BIRCH_SAPLING); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingBirchSaplingOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BIRCH_SAPLING); + ItemStack birchSapling = world.itematic$createStack(ItemKeys.BIRCH_SAPLING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, birchSapling); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.BIRCH_SAPLING); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, birchSapling, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.BIRCH_SAPLING); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingJungleSaplingOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.JUNGLE_SAPLING); + ItemStack jungleSapling = world.itematic$createStack(ItemKeys.JUNGLE_SAPLING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, jungleSapling); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_JUNGLE_SAPLING, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, jungleSapling, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, jungleSapling) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_JUNGLE_SAPLING); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingJungleSaplingOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.JUNGLE_SAPLING); + ItemStack jungleSapling = world.itematic$createStack(ItemKeys.JUNGLE_SAPLING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, jungleSapling); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.JUNGLE_SAPLING); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, jungleSapling, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.JUNGLE_SAPLING); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingAcaciaSaplingOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.ACACIA_SAPLING); + ItemStack acaciaSapling = world.itematic$createStack(ItemKeys.ACACIA_SAPLING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, acaciaSapling); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_ACACIA_SAPLING, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, acaciaSapling, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, acaciaSapling) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_ACACIA_SAPLING); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingAcaciaSaplingOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.ACACIA_SAPLING); + ItemStack acaciaSapling = world.itematic$createStack(ItemKeys.ACACIA_SAPLING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, acaciaSapling); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.ACACIA_SAPLING); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, acaciaSapling, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.ACACIA_SAPLING); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingCherrySaplingOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CHERRY_SAPLING); + ItemStack cherrySapling = world.itematic$createStack(ItemKeys.CHERRY_SAPLING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, cherrySapling); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_CHERRY_SAPLING, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, cherrySapling, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, cherrySapling) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_CHERRY_SAPLING); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingCherrySaplingOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CHERRY_SAPLING); + ItemStack cherrySapling = world.itematic$createStack(ItemKeys.CHERRY_SAPLING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, cherrySapling); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.CHERRY_SAPLING); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, cherrySapling, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.CHERRY_SAPLING); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingDarkOakSaplingOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.DARK_OAK_SAPLING); + ItemStack darkOakSapling = world.itematic$createStack(ItemKeys.DARK_OAK_SAPLING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, darkOakSapling); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_DARK_OAK_SAPLING, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, darkOakSapling, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, darkOakSapling) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_DARK_OAK_SAPLING); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingDarkOakSaplingOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.DARK_OAK_SAPLING); + ItemStack darkOakSapling = world.itematic$createStack(ItemKeys.DARK_OAK_SAPLING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, darkOakSapling); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.DARK_OAK_SAPLING); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, darkOakSapling, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.DARK_OAK_SAPLING); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingCrimsonFungusOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CRIMSON_FUNGUS); + ItemStack crimsonFungus = world.itematic$createStack(ItemKeys.CRIMSON_FUNGUS); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, crimsonFungus); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_CRIMSON_FUNGUS, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, crimsonFungus, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, crimsonFungus) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_CRIMSON_FUNGUS); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingCrimsonFungusOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CRIMSON_FUNGUS); + ItemStack crimsonFungus = world.itematic$createStack(ItemKeys.CRIMSON_FUNGUS); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, crimsonFungus); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.CRIMSON_FUNGUS); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, crimsonFungus, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.CRIMSON_FUNGUS); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingWarpedFungusOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.WARPED_FUNGUS); + ItemStack warpedFungus = world.itematic$createStack(ItemKeys.WARPED_FUNGUS); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, warpedFungus); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_WARPED_FUNGUS, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, warpedFungus, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, warpedFungus) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_WARPED_FUNGUS); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingWarpedFungusOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.WARPED_FUNGUS); + ItemStack warpedFungus = world.itematic$createStack(ItemKeys.WARPED_FUNGUS); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, warpedFungus); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.WARPED_FUNGUS); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, warpedFungus, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.WARPED_FUNGUS); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingCrimsonRootsOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CRIMSON_ROOTS); + ItemStack crimsonRoots = world.itematic$createStack(ItemKeys.CRIMSON_ROOTS); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, crimsonRoots); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_CRIMSON_ROOTS, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, crimsonRoots, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, crimsonRoots) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_CRIMSON_ROOTS); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingCrimsonRootsOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CRIMSON_ROOTS); + ItemStack crimsonRoots = world.itematic$createStack(ItemKeys.CRIMSON_ROOTS); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, crimsonRoots); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.CRIMSON_ROOTS); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, crimsonRoots, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.CRIMSON_ROOTS); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingWarpedRootsOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.WARPED_ROOTS); + ItemStack warpedRoots = world.itematic$createStack(ItemKeys.WARPED_ROOTS); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, warpedRoots); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_WARPED_ROOTS, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, warpedRoots, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, warpedRoots) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_WARPED_ROOTS); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingWarpedRootsOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.WARPED_ROOTS); + ItemStack warpedRoots = world.itematic$createStack(ItemKeys.WARPED_ROOTS); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, warpedRoots); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.WARPED_ROOTS); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, warpedRoots, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.WARPED_ROOTS); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingAzaleaBushOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.AZALEA); + ItemStack azalea = world.itematic$createStack(ItemKeys.AZALEA); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, azalea); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_AZALEA_BUSH, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, azalea, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, azalea) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_AZALEA_BUSH); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingAzaleaBushOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.AZALEA); + ItemStack azalea = world.itematic$createStack(ItemKeys.AZALEA); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, azalea); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.AZALEA); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, azalea, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.AZALEA); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingFloweringAzaleaBushOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.FLOWERING_AZALEA); + ItemStack floweringAzalea = world.itematic$createStack(ItemKeys.FLOWERING_AZALEA); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, floweringAzalea); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_FLOWERING_AZALEA_BUSH, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, floweringAzalea, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, floweringAzalea) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_FLOWERING_AZALEA_BUSH); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingFloweringAzaleaBushOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.FLOWERING_AZALEA); + ItemStack floweringAzalea = world.itematic$createStack(ItemKeys.FLOWERING_AZALEA); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, floweringAzalea); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.FLOWERING_AZALEA); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, floweringAzalea, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.FLOWERING_AZALEA); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingMangrovePropaguleOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.MANGROVE_PROPAGULE); + ItemStack mangrovePropagule = world.itematic$createStack(ItemKeys.MANGROVE_PROPAGULE); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, mangrovePropagule); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_MANGROVE_PROPAGULE, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, mangrovePropagule, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, mangrovePropagule) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_MANGROVE_PROPAGULE); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingMangrovePropaguleOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.MANGROVE_PROPAGULE); + ItemStack mangrovePropagule = world.itematic$createStack(ItemKeys.MANGROVE_PROPAGULE); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, mangrovePropagule); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.MANGROVE_PROPAGULE); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, mangrovePropagule, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.MANGROVE_PROPAGULE); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingCactusOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CACTUS); + ItemStack cactus = world.itematic$createStack(ItemKeys.CACTUS); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, cactus); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_CACTUS, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, cactus, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, cactus) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_CACTUS); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingCactusOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CACTUS); + ItemStack cactus = world.itematic$createStack(ItemKeys.CACTUS); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, cactus); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.CACTUS); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, cactus, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.CACTUS); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingDeadBushOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.DEAD_BUSH); + ItemStack deadBush = world.itematic$createStack(ItemKeys.DEAD_BUSH); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, deadBush); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_DEAD_BUSH, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, deadBush, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, deadBush) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_DEAD_BUSH); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingDeadBushOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.DEAD_BUSH); + ItemStack deadBush = world.itematic$createStack(ItemKeys.DEAD_BUSH); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, deadBush); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.DEAD_BUSH); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, deadBush, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.DEAD_BUSH); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingBambooOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BAMBOO); + ItemStack bamboo = world.itematic$createStack(ItemKeys.BAMBOO); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, bamboo); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_BAMBOO, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, bamboo, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, bamboo) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_BAMBOO); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingBambooOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BAMBOO); + ItemStack bamboo = world.itematic$createStack(ItemKeys.BAMBOO); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, bamboo); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.BAMBOO); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, bamboo, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.BAMBOO); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingFernOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.FERN); + ItemStack fern = world.itematic$createStack(ItemKeys.FERN); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, fern); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_FERN, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, fern, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, fern) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_FERN); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingFernOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.FERN); + ItemStack fern = world.itematic$createStack(ItemKeys.FERN); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, fern); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.FERN); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, fern, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.FERN); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingDandelionOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.DANDELION); + ItemStack dandelion = world.itematic$createStack(ItemKeys.DANDELION); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, dandelion); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_DANDELION, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, dandelion, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, dandelion) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_DANDELION); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingDandelionOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.DANDELION); + ItemStack dandelion = world.itematic$createStack(ItemKeys.DANDELION); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, dandelion); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.DANDELION); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, dandelion, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.DANDELION); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingPoppyOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.POPPY); + ItemStack poppy = world.itematic$createStack(ItemKeys.POPPY); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, poppy); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, poppy, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, poppy) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_dandelion") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_dandelion") public void usingPoppyOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.POPPY); + ItemStack poppy = world.itematic$createStack(ItemKeys.POPPY); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, poppy); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.POPPY); - context.expectBlock(Blocks.POTTED_DANDELION, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, poppy, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.POPPY); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_DANDELION); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingBlueOrchidOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BLUE_ORCHID); + ItemStack blueOrchid = world.itematic$createStack(ItemKeys.BLUE_ORCHID); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, blueOrchid); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_BLUE_ORCHID, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, blueOrchid, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, blueOrchid) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_BLUE_ORCHID); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingBlueOrchidOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BLUE_ORCHID); + ItemStack blueOrchid = world.itematic$createStack(ItemKeys.BLUE_ORCHID); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, blueOrchid); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.BLUE_ORCHID); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, blueOrchid, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.BLUE_ORCHID); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingAlliumOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.ALLIUM); + ItemStack allium = world.itematic$createStack(ItemKeys.ALLIUM); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, allium); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_ALLIUM, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, allium, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, allium) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_ALLIUM); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingAlliumOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.ALLIUM); + ItemStack allium = world.itematic$createStack(ItemKeys.ALLIUM); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, allium); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.ALLIUM); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, allium, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.ALLIUM); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingAzureBluetOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.AZURE_BLUET); + ItemStack azureBluet = world.itematic$createStack(ItemKeys.AZURE_BLUET); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, azureBluet); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_AZURE_BLUET, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, azureBluet, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, azureBluet) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_AZURE_BLUET); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingAzureBluetOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.AZURE_BLUET); + ItemStack azureBluet = world.itematic$createStack(ItemKeys.AZURE_BLUET); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, azureBluet); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.AZURE_BLUET); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, azureBluet, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.AZURE_BLUET); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingRedTulipOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.RED_TULIP); + ItemStack redTulip = world.itematic$createStack(ItemKeys.RED_TULIP); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, redTulip); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_RED_TULIP, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, redTulip, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, redTulip) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_RED_TULIP); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingRedTulipOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.RED_TULIP); + ItemStack redTulip = world.itematic$createStack(ItemKeys.RED_TULIP); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, redTulip); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.RED_TULIP); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, redTulip, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.RED_TULIP); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingOrangeTulipOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.ORANGE_TULIP); + ItemStack orangeTulip = world.itematic$createStack(ItemKeys.ORANGE_TULIP); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, orangeTulip); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_ORANGE_TULIP, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, orangeTulip, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, orangeTulip) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_ORANGE_TULIP); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingOrangeTulipOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.ORANGE_TULIP); + ItemStack orangeTulip = world.itematic$createStack(ItemKeys.ORANGE_TULIP); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, orangeTulip); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.ORANGE_TULIP); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, orangeTulip, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.ORANGE_TULIP); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingWhiteTulipOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.WHITE_TULIP); + ItemStack whiteTulip = world.itematic$createStack(ItemKeys.WHITE_TULIP); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, whiteTulip); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_WHITE_TULIP, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, whiteTulip, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, whiteTulip) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_WHITE_TULIP); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingWhiteTulipOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.WHITE_TULIP); + ItemStack whiteTulip = world.itematic$createStack(ItemKeys.WHITE_TULIP); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, whiteTulip); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.WHITE_TULIP); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, whiteTulip, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.WHITE_TULIP); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingPinkTulipOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.PINK_TULIP); + ItemStack pinkTulip = world.itematic$createStack(ItemKeys.PINK_TULIP); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, pinkTulip); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_PINK_TULIP, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, pinkTulip, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, pinkTulip) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_PINK_TULIP); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingPinkTulipOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.PINK_TULIP); + ItemStack pinkTulip = world.itematic$createStack(ItemKeys.PINK_TULIP); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, pinkTulip); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.PINK_TULIP); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, pinkTulip, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.PINK_TULIP); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingOxeyeDaisyOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.OXEYE_DAISY); + ItemStack oxeyeDaisy = world.itematic$createStack(ItemKeys.OXEYE_DAISY); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, oxeyeDaisy); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_OXEYE_DAISY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, oxeyeDaisy, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, oxeyeDaisy) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_OXEYE_DAISY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingOxeyeDaisyOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.OXEYE_DAISY); + ItemStack oxeyeDaisy = world.itematic$createStack(ItemKeys.OXEYE_DAISY); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, oxeyeDaisy); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.OXEYE_DAISY); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, oxeyeDaisy, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.OXEYE_DAISY); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingCornflowerOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CORNFLOWER); + ItemStack cornflower = world.itematic$createStack(ItemKeys.CORNFLOWER); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, cornflower); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_CORNFLOWER, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, cornflower, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, cornflower) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_CORNFLOWER); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingCornflowerOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CORNFLOWER); + ItemStack cornflower = world.itematic$createStack(ItemKeys.CORNFLOWER); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, cornflower); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.CORNFLOWER); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, cornflower, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.CORNFLOWER); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingLilyOfTheValleyOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.LILY_OF_THE_VALLEY); + ItemStack lilyOfTheValley = world.itematic$createStack(ItemKeys.LILY_OF_THE_VALLEY); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, lilyOfTheValley); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_LILY_OF_THE_VALLEY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, lilyOfTheValley, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, lilyOfTheValley) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_LILY_OF_THE_VALLEY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingLilyOfTheValleyOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.LILY_OF_THE_VALLEY); + ItemStack lilyOfTheValley = world.itematic$createStack(ItemKeys.LILY_OF_THE_VALLEY); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, lilyOfTheValley); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.LILY_OF_THE_VALLEY); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, lilyOfTheValley, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.LILY_OF_THE_VALLEY); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingWitherRoseOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.WITHER_ROSE); + ItemStack witherRose = world.itematic$createStack(ItemKeys.WITHER_ROSE); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, witherRose); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_WITHER_ROSE, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, witherRose, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, witherRose) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_WITHER_ROSE); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingWitherRoseOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.WITHER_ROSE); + ItemStack witherRose = world.itematic$createStack(ItemKeys.WITHER_ROSE); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, witherRose); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.WITHER_ROSE); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, witherRose, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.WITHER_ROSE); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingTorchflowerOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.TORCHFLOWER); + ItemStack torchflower = world.itematic$createStack(ItemKeys.TORCHFLOWER); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, torchflower); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_TORCHFLOWER, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, torchflower, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, torchflower) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_TORCHFLOWER); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingTorchflowerOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.TORCHFLOWER); + ItemStack torchflower = world.itematic$createStack(ItemKeys.TORCHFLOWER); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, torchflower); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.TORCHFLOWER); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, torchflower, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.TORCHFLOWER); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingRedMushroomOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.RED_MUSHROOM); + ItemStack redMushroom = world.itematic$createStack(ItemKeys.RED_MUSHROOM); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, redMushroom); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_RED_MUSHROOM, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, redMushroom, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, redMushroom) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_RED_MUSHROOM); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingRedMushroomOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.RED_MUSHROOM); + ItemStack redMushroom = world.itematic$createStack(ItemKeys.RED_MUSHROOM); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, redMushroom); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.RED_MUSHROOM); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, redMushroom, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.RED_MUSHROOM); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.flower_pot") + @GameTest(structure = "itematic:item.flower_pot.platform.flower_pot") public void usingBrownMushroomOnFlowerPotReplacesFlowerPot(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BROWN_MUSHROOM); + ItemStack brownMushroom = world.itematic$createStack(ItemKeys.BROWN_MUSHROOM); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, brownMushroom); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsEmpty(stack); - context.expectBlock(Blocks.POTTED_BROWN_MUSHROOM, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, brownMushroom, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, brownMushroom) + .isEmpty(); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_BROWN_MUSHROOM); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingBrownMushroomOnPottedFlowerPotDoesNotReplacePottedFlower(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.BROWN_MUSHROOM); + ItemStack brownMushroom = world.itematic$createStack(ItemKeys.BROWN_MUSHROOM); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, brownMushroom); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, FLOWER_POT_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.BROWN_MUSHROOM); - context.expectBlock(Blocks.POTTED_POPPY, FLOWER_POT_POSITION); + TestUtil.useStackOnBlockInside(context, player, brownMushroom, FLOWER_POT_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.BROWN_MUSHROOM); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.POTTED_POPPY); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_oak_sapling") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_oak_sapling") public void usingHandOnPottedOakSaplingEmptiesPottedOakSaplingAndGivesOakSapling(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.OAK_SAPLING); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.OAK_SAPLING); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_spruce_sapling") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_spruce_sapling") public void usingHandOnPottedSpruceSaplingEmptiesPottedSpruceSaplingAndGivesSpruceSapling(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.SPRUCE_SAPLING); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.SPRUCE_SAPLING); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_birch_sapling") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_birch_sapling") public void usingHandOnPottedBirchSaplingEmptiesPottedBirchSaplingAndGivesBirchSapling(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.BIRCH_SAPLING); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.BIRCH_SAPLING); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_jungle_sapling") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_jungle_sapling") public void usingHandOnPottedJungleSaplingEmptiesPottedJungleSaplingAndGivesJungleSapling(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.JUNGLE_SAPLING); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.JUNGLE_SAPLING); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_acacia_sapling") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_acacia_sapling") public void usingHandOnPottedAcaciaSaplingEmptiesPottedAcaciaSaplingAndGivesAcaciaSapling(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.ACACIA_SAPLING); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.ACACIA_SAPLING); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_cherry_sapling") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_cherry_sapling") public void usingHandOnPottedCherrySaplingEmptiesPottedCherrySaplingAndGivesCherrySapling(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.CHERRY_SAPLING); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.CHERRY_SAPLING); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_dark_oak_sapling") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_dark_oak_sapling") public void usingHandOnPottedDarkOakSaplingEmptiesPottedDarkOakSaplingAndGivesDarkOakSapling(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.DARK_OAK_SAPLING); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.DARK_OAK_SAPLING); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_crimson_fungus") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_crimson_fungus") public void usingHandOnPottedCrimsonFungusEmptiesPottedCrimsonFungusAndGivesCrimsonFungus(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.CRIMSON_FUNGUS); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.CRIMSON_FUNGUS); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_warped_fungus") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_warped_fungus") public void usingHandOnPottedWarpedFungusEmptiesPottedWarpedFungusAndGivesWarpedFungus(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.WARPED_FUNGUS); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.WARPED_FUNGUS); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_crimson_roots") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_crimson_roots") public void usingHandOnPottedCrimsonRootsEmptiesPottedCrimsonRootsAndGivesCrimsonRoots(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.CRIMSON_ROOTS); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.CRIMSON_ROOTS); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_warped_roots") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_warped_roots") public void usingHandOnPottedWarpedRootsEmptiesPottedWarpedRootsAndGivesWarpedRoots(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.WARPED_ROOTS); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.WARPED_ROOTS); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_azalea_bush") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_azalea_bush") public void usingHandOnPottedAzaleaEmptiesPottedAzaleaAndGivesAzalea(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.AZALEA); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.AZALEA); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_flowering_azalea_bush") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_flowering_azalea_bush") public void usingHandOnPottedFloweringAzaleaEmptiesPottedFloweringAzaleaAndGivesFloweringAzalea(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.FLOWERING_AZALEA); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.FLOWERING_AZALEA); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_mangrove_propagule") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_mangrove_propagule") public void usingHandOnPottedMangrovePropaguleEmptiesPottedMangrovePropaguleAndGivesMangrovePropagule(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.MANGROVE_PROPAGULE); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.MANGROVE_PROPAGULE); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_cactus") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_cactus") public void usingHandOnPottedCactusEmptiesPottedCactusAndGivesCactus(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.CACTUS); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.CACTUS); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_dead_bush") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_dead_bush") public void usingHandOnPottedDeadBushEmptiesPottedDeadBushAndGivesDeadBush(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.DEAD_BUSH); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.DEAD_BUSH); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_bamboo") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_bamboo") public void usingHandOnPottedBambooEmptiesPottedBambooAndGivesBamboo(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.BAMBOO); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.BAMBOO); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_fern") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_fern") public void usingHandOnPottedFernEmptiesPottedFernAndGivesFern(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.FERN); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.FERN); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_dandelion") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_dandelion") public void usingHandOnPottedDandelionEmptiesPottedDandelionAndGivesDandelion(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.DANDELION); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.DANDELION); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_poppy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_poppy") public void usingHandOnPottedPoppyEmptiesPottedPoppyAndGivesPoppy(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.POPPY); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.POPPY); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_blue_orchid") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_blue_orchid") public void usingHandOnPottedBlueOrchidEmptiesPottedBlueOrchidAndGivesBlueOrchid(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.BLUE_ORCHID); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.BLUE_ORCHID); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_allium") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_allium") public void usingHandOnPottedAlliumEmptiesPottedAlliumAndGivesAllium(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.ALLIUM); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.ALLIUM); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_azure_bluet") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_azure_bluet") public void usingHandOnPottedAzureBluetEmptiesPottedAzureBluetAndGivesAzureBluet(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.AZURE_BLUET); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.AZURE_BLUET); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_red_tulip") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_red_tulip") public void usingHandOnPottedRedTulipEmptiesPottedRedTulipAndGivesRedTulip(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.RED_TULIP); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.RED_TULIP); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_orange_tulip") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_orange_tulip") public void usingHandOnPottedOrangeTulipEmptiesPottedOrangeTulipAndGivesOrangeTulip(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.ORANGE_TULIP); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.ORANGE_TULIP); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_white_tulip") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_white_tulip") public void usingHandOnPottedWhiteTulipEmptiesPottedWhiteTulipAndGivesWhiteTulip(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.WHITE_TULIP); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.WHITE_TULIP); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_pink_tulip") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_pink_tulip") public void usingHandOnPottedPinkTulipEmptiesPottedPinkTulipAndGivesPinkTulip(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.PINK_TULIP); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.PINK_TULIP); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_oxeye_daisy") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_oxeye_daisy") public void usingHandOnPottedOxeyeDaisyEmptiesPottedOxeyeDaisyAndGivesOxeyeDaisy(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.OXEYE_DAISY); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.OXEYE_DAISY); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_cornflower") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_cornflower") public void usingHandOnPottedCornflowerEmptiesPottedCornflowerAndGivesCornflower(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.CORNFLOWER); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.CORNFLOWER); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_lily_of_the_valley") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_lily_of_the_valley") public void usingHandOnPottedLilyOfTheValleyEmptiesPottedLilyOfTheValleyAndGivesLilyOfTheValley(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.LILY_OF_THE_VALLEY); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.LILY_OF_THE_VALLEY); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_wither_rose") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_wither_rose") public void usingHandOnPottedWitherRoseEmptiesPottedWitherRoseAndGivesWitherRose(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.WITHER_ROSE); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.WITHER_ROSE); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_torchflower") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_torchflower") public void usingHandOnPottedTorchflowerEmptiesPottedTorchflowerAndGivesTorchflower(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.TORCHFLOWER); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.TORCHFLOWER); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_red_mushroom") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_red_mushroom") public void usingHandOnPottedRedMushroomEmptiesPottedRedMushroomAndGivesRedMushroom(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.RED_MUSHROOM); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.RED_MUSHROOM); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } - @GameTest(templateName = "itematic:item.flower_pot.platform.potted_brown_mushroom") + @GameTest(structure = "itematic:item.flower_pot.platform.potted_brown_mushroom") public void usingHandOnPottedBrownMushroomEmptiesPottedBrownMushroomAndGivesBrownMushroom(TestContext context) { ServerWorld world = context.getWorld(); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); world.spawnEntity(player); TestUtil.useBlock(context, FLOWER_POT_POSITION, player, Direction.UP); - context.addInstantFinalTask(() -> { - Assert.itemStackIsOf(player.getMainHandStack(), ItemKeys.BROWN_MUSHROOM); - context.expectBlock(Blocks.FLOWER_POT, FLOWER_POT_POSITION); + context.addFinalTask(() -> { + Assert.itemStack(context, player.getMainHandStack()) + .is(ItemKeys.BROWN_MUSHROOM); + Assert.blockState(context, FLOWER_POT_POSITION) + .is(Blocks.FLOWER_POT); }); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/HoneyBottleTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/HoneyBottleTestSuite.java index 8ea63d9f..465307f3 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/HoneyBottleTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/HoneyBottleTestSuite.java @@ -1,33 +1,33 @@ package net.errorcraft.itematic.gametest.item; -import net.errorcraft.itematic.gametest.Assert; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; -import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.entity.effect.StatusEffectInstance; 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 HoneyBottleTestSuite { - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest(maxTicks = 100) public void consumingHoneyBottleRemovesPoisonStatusEffect(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); player.getHungerManager().setFoodLevel(0); player.addStatusEffect(new StatusEffectInstance(StatusEffects.POISON, StatusEffectInstance.INFINITE)); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.HONEY_BOTTLE); - player.setStackInHand(Hand.MAIN_HAND, stack); + ItemStack honeyBottle = world.itematic$createStack(ItemKeys.HONEY_BOTTLE); + player.setStackInHand(Hand.MAIN_HAND, honeyBottle); world.spawnEntity(player); context.createTimedTaskRunner() - .createAndAddReported(() -> stack.use(world, player, Hand.MAIN_HAND)) + .createAndAddReported(() -> honeyBottle.use(world, player, Hand.MAIN_HAND)) .expectMinDurationAndRun( - stack.getMaxUseTime(player) + 1, - () -> Assert.entityDoesNotHaveStatusEffect(player, StatusEffects.POISON) + honeyBottle.getMaxUseTime(player) + 1, + () -> Assert.livingEntity(context, player) + .doesNotHaveEffect(StatusEffects.POISON) ) .completeIfSuccessful(); } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/LeadTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/LeadTestSuite.java index 55f4bd27..7e0370bb 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/LeadTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/LeadTestSuite.java @@ -1,14 +1,15 @@ package net.errorcraft.itematic.gametest.item; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.entity.EntityType; import net.minecraft.entity.passive.HorseEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.vehicle.BoatEntity; 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.ActionResult; import net.minecraft.util.Hand; @@ -18,33 +19,49 @@ public class LeadTestSuite { private static final BlockPos PLACED_ENTITY_POSITION = new BlockPos(1, 1, 0); - @GameTest(templateName = "itematic:item.lead.platform") + @GameTest(structure = "itematic:item.lead.platform") public void usingLeadOnHorseLeashesHorse(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.LEAD); + ItemStack lead = world.itematic$createStack(ItemKeys.LEAD); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, lead); world.spawnEntity(player); HorseEntity horse = TestUtil.createEntityAt(context, EntityType.HORSE, PLACED_ENTITY_POSITION, entity -> {}); - context.addInstantFinalTask(() -> { + context.addFinalTask(() -> { ActionResult result = horse.interact(player, Hand.MAIN_HAND); - context.assertTrue(result.isAccepted(), "Expected interaction with Horse to be successful"); - context.assertTrue(horse.isLeashed(), "Expected Horse to be leashed"); + Assert.isTrue( + context, + result.isAccepted(), + () -> "Expected interaction with Horse to be successful" + ); + Assert.isTrue( + context, + horse.isLeashed(), + () -> "Expected Horse to be leashed" + ); }); } - @GameTest(templateName = "itematic:item.lead.platform") + @GameTest(structure = "itematic:item.lead.platform") public void usingLeadOnBoatLeashesBoat(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.LEAD); + ItemStack lead = world.itematic$createStack(ItemKeys.LEAD); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, lead); world.spawnEntity(player); BoatEntity boat = TestUtil.createEntityAt(context, EntityType.OAK_BOAT, PLACED_ENTITY_POSITION, entity -> {}); - context.addInstantFinalTask(() -> { + context.addFinalTask(() -> { ActionResult result = boat.interact(player, Hand.MAIN_HAND); - context.assertTrue(result.isAccepted(), "Expected interaction with Oak Boat to be successful"); - context.assertTrue(boat.isLeashed(), "Expected Oak Boat to be leashed"); + Assert.isTrue( + context, + result.isAccepted(), + () -> "Expected interaction with Oak Boat to be successful" + ); + Assert.isTrue( + context, + boat.isLeashed(), + () -> "Expected Oak Boat to be leashed" + ); }); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/SignTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/SignTestSuite.java index 31ebf408..668bdb9f 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/SignTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/SignTestSuite.java @@ -1,8 +1,9 @@ package net.errorcraft.itematic.gametest.item; -import net.errorcraft.itematic.gametest.Assert; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.block.Blocks; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.component.DataComponentTypes; @@ -12,8 +13,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.registry.Registries; import net.minecraft.server.world.ServerWorld; -import net.minecraft.test.GameTest; -import net.minecraft.test.GameTestException; import net.minecraft.test.TestContext; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; @@ -25,77 +24,91 @@ public class SignTestSuite { private static final BlockPos PLACED_BLOCK_POSITION = GROUND_POSITION.add(0, 1, 0); private static final BlockPos ABOVE_PLACED_BLOCK_POSITION = PLACED_BLOCK_POSITION.add(0, 1, 0); - @GameTest(templateName = "itematic:item.sign.platform") + @GameTest(structure = "itematic:item.sign.platform") public void placingSignOpensSignMenu(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.OAK_SIGN); + ItemStack oakSign = world.itematic$createStack(ItemKeys.OAK_SIGN); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, oakSign); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, GROUND_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - context.expectBlock(Blocks.OAK_SIGN, PLACED_BLOCK_POSITION); - Assert.blockEntityExists(context, PLACED_BLOCK_POSITION, BlockEntityType.SIGN, blockEntity -> { - if (!player.getUuid().equals(blockEntity.getEditor())) { - throw new GameTestException("Sign menu was not opened by the player"); - } - }); + TestUtil.useStackOnBlockInside(context, player, oakSign, GROUND_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.blockState(context, PLACED_BLOCK_POSITION) + .is(Blocks.OAK_SIGN); + Assert.blockEntity(context, PLACED_BLOCK_POSITION, BlockEntityType.SIGN, + blockEntity -> Assert.isTrue( + context, + player.getUuid().equals(blockEntity.getEditor()), + () -> "Sign menu was not opened by the Player" + ) + ); }); } - @GameTest(templateName = "itematic:item.sign.platform") + @GameTest(structure = "itematic:item.sign.platform") + @SuppressWarnings("DataFlowIssue") public void placingSignWithBlockEntityDataDoesNotOpenSignMenu(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.OAK_SIGN); - NbtComponent.set(DataComponentTypes.BLOCK_ENTITY_DATA, stack, nbt -> nbt.putString(Entity.ID_KEY, Registries.BLOCK_ENTITY_TYPE.getId(BlockEntityType.SIGN).toString())); + ItemStack oakSign = world.itematic$createStack(ItemKeys.OAK_SIGN); + NbtComponent.set(DataComponentTypes.BLOCK_ENTITY_DATA, oakSign, nbt -> nbt.putString(Entity.ID_KEY, Registries.BLOCK_ENTITY_TYPE.getId(BlockEntityType.SIGN).toString())); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, oakSign); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, GROUND_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - context.expectBlock(Blocks.OAK_SIGN, PLACED_BLOCK_POSITION); - Assert.blockEntityExists(context, PLACED_BLOCK_POSITION, BlockEntityType.SIGN, blockEntity -> { - if (player.getUuid().equals(blockEntity.getEditor())) { - throw new GameTestException("Sign menu was opened by the player"); - } - }); + TestUtil.useStackOnBlockInside(context, player, oakSign, GROUND_POSITION, Direction.UP); + context.addFinalTaskWithDuration(1, () -> { + Assert.blockState(context, PLACED_BLOCK_POSITION) + .is(Blocks.OAK_SIGN); + Assert.blockEntity(context, PLACED_BLOCK_POSITION, BlockEntityType.SIGN, + blockEntity -> Assert.isFalse( + context, + player.getUuid().equals(blockEntity.getEditor()), + () -> "Sign menu was opened by the Player" + ) + ); }); } - @GameTest(templateName = "itematic:item.sign.platform.ceiling") + @GameTest(structure = "itematic:item.sign.platform.ceiling") public void placingHangingSignOpensSignMenu(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.OAK_HANGING_SIGN); + ItemStack oakHangingSign = world.itematic$createStack(ItemKeys.OAK_HANGING_SIGN); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, oakHangingSign); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, ABOVE_PLACED_BLOCK_POSITION, Direction.DOWN); - context.addInstantFinalTask(() -> { - context.expectBlock(Blocks.OAK_HANGING_SIGN, PLACED_BLOCK_POSITION); - Assert.blockEntityExists(context, PLACED_BLOCK_POSITION, BlockEntityType.HANGING_SIGN, blockEntity -> { - if (!player.getUuid().equals(blockEntity.getEditor())) { - throw new GameTestException("Sign menu was not opened by the player"); - } - }); + TestUtil.useStackOnBlockInside(context, player, oakHangingSign, ABOVE_PLACED_BLOCK_POSITION, Direction.DOWN); + context.addFinalTask(() -> { + Assert.blockState(context, PLACED_BLOCK_POSITION) + .is(Blocks.OAK_HANGING_SIGN); + Assert.blockEntity(context, PLACED_BLOCK_POSITION, BlockEntityType.HANGING_SIGN, + blockEntity -> Assert.isTrue( + context, + player.getUuid().equals(blockEntity.getEditor()), + () -> "Sign menu was not opened by the Player" + ) + ); }); } - @GameTest(templateName = "itematic:item.sign.platform.ceiling") + @GameTest(structure = "itematic:item.sign.platform.ceiling") + @SuppressWarnings("DataFlowIssue") public void placingHangingSignWithBlockEntityDataDoesNotOpenSignMenu(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.OAK_HANGING_SIGN); - NbtComponent.set(DataComponentTypes.BLOCK_ENTITY_DATA, stack, nbt -> nbt.putString(Entity.ID_KEY, Registries.BLOCK_ENTITY_TYPE.getId(BlockEntityType.SIGN).toString())); + ItemStack oakHangingSign = world.itematic$createStack(ItemKeys.OAK_HANGING_SIGN); + NbtComponent.set(DataComponentTypes.BLOCK_ENTITY_DATA, oakHangingSign, nbt -> nbt.putString(Entity.ID_KEY, Registries.BLOCK_ENTITY_TYPE.getId(BlockEntityType.SIGN).toString())); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, oakHangingSign); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, ABOVE_PLACED_BLOCK_POSITION, Direction.DOWN); - context.addInstantFinalTask(() -> { - context.expectBlock(Blocks.OAK_HANGING_SIGN, PLACED_BLOCK_POSITION); - Assert.blockEntityExists(context, PLACED_BLOCK_POSITION, BlockEntityType.HANGING_SIGN, blockEntity -> { - if (player.getUuid().equals(blockEntity.getEditor())) { - throw new GameTestException("Sign menu was opened by the player"); - } - }); + TestUtil.useStackOnBlockInside(context, player, oakHangingSign, ABOVE_PLACED_BLOCK_POSITION, Direction.DOWN); + context.addFinalTaskWithDuration(1, () -> { + Assert.blockState(context, PLACED_BLOCK_POSITION) + .is(Blocks.OAK_HANGING_SIGN); + Assert.blockEntity(context, PLACED_BLOCK_POSITION, BlockEntityType.HANGING_SIGN, + blockEntity -> Assert.isFalse( + context, + player.getUuid().equals(blockEntity.getEditor()), + () -> "Sign menu was opened by the Player" + ) + ); }); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/TotemOfUndyingTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/TotemOfUndyingTestSuite.java index 2fc0a359..922b2152 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/TotemOfUndyingTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/TotemOfUndyingTestSuite.java @@ -1,31 +1,30 @@ package net.errorcraft.itematic.gametest.item; -import net.errorcraft.itematic.gametest.Assert; +import net.errorcraft.itematic.assertion.Assert; +import net.errorcraft.itematic.assertion.ItemStackAssert; import net.errorcraft.itematic.item.ItemKeys; -import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.fabricmc.fabric.api.gametest.v1.GameTest; 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) + @GameTest 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); + ItemStack totemOfUndying = world.itematic$createStack(ItemKeys.TOTEM_OF_UNDYING); + player.setStackInHand(Hand.MAIN_HAND, totemOfUndying); player.damage(world, 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)); - }); + context.addFinalTask(() -> Assert.livingEntity(context, player) + .hasHealth(health -> health.equals(1.0f)) + .hasEffect(StatusEffects.REGENERATION, 1) + .hasEffect(StatusEffects.ABSORPTION, 1) + .hasEffect(StatusEffects.FIRE_RESISTANCE, 0) + .hasStackInHand(Hand.MAIN_HAND, ItemStackAssert::isEmpty)); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/BlockItemComponentTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/BlockItemComponentTestSuite.java index b5b97399..ed9ff439 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/BlockItemComponentTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/BlockItemComponentTestSuite.java @@ -1,7 +1,9 @@ package net.errorcraft.itematic.gametest.item.component; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.block.Blocks; import net.minecraft.block.ScaffoldingBlock; import net.minecraft.block.enums.DoubleBlockHalf; @@ -10,7 +12,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.server.world.ServerWorld; import net.minecraft.state.property.Properties; -import net.minecraft.test.GameTest; import net.minecraft.test.TestContext; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; @@ -22,201 +23,218 @@ public class BlockItemComponentTestSuite { private static final BlockPos PLACED_BLOCK_POSITION = GROUND_POSITION.add(0, 1, 0); private static final BlockPos ABOVE_PLACED_BLOCK_POSITION = PLACED_BLOCK_POSITION.add(0, 1, 0); private static final BlockPos WALL_POSITION = GROUND_POSITION.add(0, 1, 1); - private static final int BEYOND_MAX_SCAFFOLDING_DISTANCE = ScaffoldingBlock.MAX_DISTANCE + 1; private static final BlockPos HORIZONTAL_SCAFFOLDING_OFFSET = PLACED_BLOCK_POSITION.add(0, 0, 1); private static final BlockPos VERTICAL_SCAFFOLDING_OFFSET = PLACED_BLOCK_POSITION.add(0, 1, 0); private static final BlockPos HORIZONTAL_SCAFFOLDING_BEYOND_MAX_DISTANCE_OFFSET = PLACED_BLOCK_POSITION.add(0, 0, BEYOND_MAX_SCAFFOLDING_DISTANCE); private static final BlockPos VERTICAL_SCAFFOLDING_BEYOND_MAX_DISTANCE_OFFSET = PLACED_BLOCK_POSITION.add(0, BEYOND_MAX_SCAFFOLDING_DISTANCE, 0); - @GameTest(templateName = "itematic:item.component.block.platform") + @GameTest(structure = "itematic:item.component.block.platform") public void usingStoneOnGroundPlacesStone(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.STONE); + ItemStack stone = world.itematic$createStack(ItemKeys.STONE); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, stone); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, GROUND_POSITION, Direction.UP); - context.addInstantFinalTask(() -> context.expectBlock(Blocks.STONE, PLACED_BLOCK_POSITION)); + TestUtil.useStackOnBlockInside(context, player, stone, GROUND_POSITION, Direction.UP); + context.addFinalTask(() -> Assert.blockState(context, PLACED_BLOCK_POSITION) + .is(Blocks.STONE)); } - @GameTest(templateName = "itematic:item.component.block.platform") + @GameTest(structure = "itematic:item.component.block.platform") public void usingOakSlabOnGroundPlacesOakSlab(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.OAK_SLAB); + ItemStack oakSlab = world.itematic$createStack(ItemKeys.OAK_SLAB); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, oakSlab); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, GROUND_POSITION, Direction.UP); - context.addInstantFinalTask(() -> context.checkBlockState(PLACED_BLOCK_POSITION, state -> state.get(Properties.SLAB_TYPE) == SlabType.BOTTOM, () -> "Expected placed oak slab to be of bottom type")); + TestUtil.useStackOnBlockInside(context, player, oakSlab, GROUND_POSITION, Direction.UP); + context.addFinalTask(() -> Assert.blockState(context, PLACED_BLOCK_POSITION) + .hasProperty(Properties.SLAB_TYPE, SlabType.BOTTOM, () -> "Expected placed Oak Slab to be of bottom type")); } - @GameTest(templateName = "itematic:item.component.block.oak_slab.lower") + @GameTest(structure = "itematic:item.component.block.oak_slab.lower") public void usingOakSlabOnLowerOakSlabPlacesDoubleOakSlab(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.OAK_SLAB); + ItemStack oakSlab = world.itematic$createStack(ItemKeys.OAK_SLAB); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, oakSlab); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, PLACED_BLOCK_POSITION, Direction.DOWN); - context.addInstantFinalTask(() -> context.checkBlockState(PLACED_BLOCK_POSITION, state -> state.get(Properties.SLAB_TYPE) == SlabType.DOUBLE, () -> "Expected placed oak slab to be of double type")); + TestUtil.useStackOnBlockInside(context, player, oakSlab, PLACED_BLOCK_POSITION, Direction.DOWN); + context.addFinalTask(() -> Assert.blockState(context, PLACED_BLOCK_POSITION) + .hasProperty(Properties.SLAB_TYPE, SlabType.DOUBLE, () -> "Expected placed Oak Slab to be of double type")); } - @GameTest(templateName = "itematic:item.component.block.oak_slab.upper") + @GameTest(structure = "itematic:item.component.block.oak_slab.upper") public void usingOakSlabOnUpperOakSlabPlacesDoubleOakSlab(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.OAK_SLAB); + ItemStack oakSlab = world.itematic$createStack(ItemKeys.OAK_SLAB); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, oakSlab); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, PLACED_BLOCK_POSITION, Direction.DOWN); - context.addInstantFinalTask(() -> context.checkBlockState(PLACED_BLOCK_POSITION, state -> state.get(Properties.SLAB_TYPE) == SlabType.DOUBLE, () -> "Expected placed oak slab to be of double type")); + TestUtil.useStackOnBlockInside(context, player, oakSlab, PLACED_BLOCK_POSITION, Direction.DOWN); + context.addFinalTask(() -> Assert.blockState(context, PLACED_BLOCK_POSITION) + .hasProperty(Properties.SLAB_TYPE, SlabType.DOUBLE, () -> "Expected placed Oak Slab to be of double type")); } - @GameTest(templateName = "itematic:item.component.block.platform.grass_block") + @GameTest(structure = "itematic:item.component.block.platform.grass_block") public void usingTallGrassOnGroundPlacesTallGrass(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.TALL_GRASS); + ItemStack tallGrass = world.itematic$createStack(ItemKeys.TALL_GRASS); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, tallGrass); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, GROUND_POSITION, Direction.UP); - context.addInstantFinalTask(() -> { - context.checkBlockState(PLACED_BLOCK_POSITION, state -> state.get(Properties.DOUBLE_BLOCK_HALF) == DoubleBlockHalf.LOWER, () -> "Expected lower half of tall grass to be placed"); - context.checkBlockState(ABOVE_PLACED_BLOCK_POSITION, state -> state.get(Properties.DOUBLE_BLOCK_HALF) == DoubleBlockHalf.UPPER, () -> "Expected upper half of tall grass to be placed"); + TestUtil.useStackOnBlockInside(context, player, tallGrass, GROUND_POSITION, Direction.UP); + context.addFinalTask(() -> { + Assert.blockState(context, PLACED_BLOCK_POSITION) + .hasProperty(Properties.DOUBLE_BLOCK_HALF, DoubleBlockHalf.LOWER, () -> "Expected lower half of Tall Grass to be placed"); + Assert.blockState(context, ABOVE_PLACED_BLOCK_POSITION) + .hasProperty(Properties.DOUBLE_BLOCK_HALF, DoubleBlockHalf.UPPER, () -> "Expected upper half of Tall Grass to be placed"); }); } - @GameTest(templateName = "itematic:item.component.block.platform.grass_block.blocked_off_above") + @GameTest(structure = "itematic:item.component.block.platform.grass_block.blocked_off_above") public void usingTallGrassOnGroundWhileBlockedOffDoesNotPlaceTallGrass(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.TALL_GRASS); + ItemStack tallGrass = world.itematic$createStack(ItemKeys.TALL_GRASS); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, tallGrass); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, GROUND_POSITION, Direction.UP); - context.addInstantFinalTask(() -> context.dontExpectBlock(Blocks.TALL_GRASS, PLACED_BLOCK_POSITION)); + TestUtil.useStackOnBlockInside(context, player, tallGrass, GROUND_POSITION, Direction.UP); + context.addFinalTask(() -> Assert.blockState(context, PLACED_BLOCK_POSITION) + .isNot(Blocks.TALL_GRASS)); } - @GameTest(templateName = "itematic:item.component.block.platform") + @GameTest(structure = "itematic:item.component.block.platform") public void usingSkeletonSkullOnGroundPlacesSkeletonSkull(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SKELETON_SKULL); + ItemStack skeletonSkull = world.itematic$createStack(ItemKeys.SKELETON_SKULL); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, skeletonSkull); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, GROUND_POSITION, Direction.UP); - context.addInstantFinalTask(() -> context.expectBlock(Blocks.SKELETON_SKULL, PLACED_BLOCK_POSITION)); + TestUtil.useStackOnBlockInside(context, player, skeletonSkull, GROUND_POSITION, Direction.UP); + context.addFinalTask(() -> Assert.blockState(context, PLACED_BLOCK_POSITION) + .is(Blocks.SKELETON_SKULL)); } - @GameTest(templateName = "itematic:item.component.block.platform.wall") + @GameTest(structure = "itematic:item.component.block.platform.wall") public void usingSkeletonSkullOnWallPlacesSkeletonWallSkull(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SKELETON_SKULL); + ItemStack skeletonSkull = world.itematic$createStack(ItemKeys.SKELETON_SKULL); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, skeletonSkull); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, WALL_POSITION, Direction.NORTH); - context.addInstantFinalTask(() -> context.expectBlock(Blocks.SKELETON_WALL_SKULL, PLACED_BLOCK_POSITION)); + TestUtil.useStackOnBlockInside(context, player, skeletonSkull, WALL_POSITION, Direction.NORTH); + context.addFinalTask(() -> Assert.blockState(context, PLACED_BLOCK_POSITION) + .is(Blocks.SKELETON_WALL_SKULL)); } - @GameTest(templateName = "itematic:item.component.block.platform.ceiling") + @GameTest(structure = "itematic:item.component.block.platform.ceiling") public void usingOakHangingSignOnCeilingPlacesOakHangingSign(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.OAK_HANGING_SIGN); + ItemStack oakHangingSign = world.itematic$createStack(ItemKeys.OAK_HANGING_SIGN); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, oakHangingSign); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, ABOVE_PLACED_BLOCK_POSITION, Direction.DOWN); - context.addInstantFinalTask(() -> context.expectBlock(Blocks.OAK_HANGING_SIGN, PLACED_BLOCK_POSITION)); + TestUtil.useStackOnBlockInside(context, player, oakHangingSign, ABOVE_PLACED_BLOCK_POSITION, Direction.DOWN); + context.addFinalTask(() -> Assert.blockState(context, PLACED_BLOCK_POSITION) + .is(Blocks.OAK_HANGING_SIGN)); } - @GameTest(templateName = "itematic:item.component.block.platform.wall") + @GameTest(structure = "itematic:item.component.block.platform.wall") public void usingOakHangingSignOnWallPlacesOakWallHangingSign(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.OAK_HANGING_SIGN); + ItemStack oakHangingSign = world.itematic$createStack(ItemKeys.OAK_HANGING_SIGN); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, oakHangingSign); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, WALL_POSITION, Direction.NORTH); - context.addInstantFinalTask(() -> context.expectBlock(Blocks.OAK_WALL_HANGING_SIGN, PLACED_BLOCK_POSITION)); + TestUtil.useStackOnBlockInside(context, player, oakHangingSign, WALL_POSITION, Direction.NORTH); + context.addFinalTask(() -> Assert.blockState(context, PLACED_BLOCK_POSITION) + .is(Blocks.OAK_WALL_HANGING_SIGN)); } - @GameTest(templateName = "itematic:item.component.block.platform") + @GameTest(structure = "itematic:item.component.block.platform") public void usingScaffoldingOnGroundPlacesScaffolding(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SCAFFOLDING); + ItemStack scaffolding = world.itematic$createStack(ItemKeys.SCAFFOLDING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, scaffolding); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, GROUND_POSITION, Direction.UP); - context.addInstantFinalTask(() -> context.expectBlock(Blocks.SCAFFOLDING, PLACED_BLOCK_POSITION)); + TestUtil.useStackOnBlockInside(context, player, scaffolding, GROUND_POSITION, Direction.UP); + context.addFinalTask(() -> Assert.blockState(context, PLACED_BLOCK_POSITION) + .is(Blocks.SCAFFOLDING)); } - @GameTest(templateName = "itematic:item.component.block.scaffolding.single_block") + @GameTest(structure = "itematic:item.component.block.scaffolding.single_block") public void usingScaffoldingOnTopFaceOfScaffoldingPlacesScaffoldingHorizontally(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SCAFFOLDING); + ItemStack scaffolding = world.itematic$createStack(ItemKeys.SCAFFOLDING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, scaffolding); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, PLACED_BLOCK_POSITION, Direction.UP); - context.addInstantFinalTask(() -> context.expectBlock(Blocks.SCAFFOLDING, HORIZONTAL_SCAFFOLDING_OFFSET)); + TestUtil.useStackOnBlockInside(context, player, scaffolding, PLACED_BLOCK_POSITION, Direction.UP); + context.addFinalTask(() -> Assert.blockState(context, HORIZONTAL_SCAFFOLDING_OFFSET) + .is(Blocks.SCAFFOLDING)); } - @GameTest(templateName = "itematic:item.component.block.scaffolding.single_block") + @GameTest(structure = "itematic:item.component.block.scaffolding.single_block") public void usingScaffoldingOnTopFaceOfBlockBelowScaffoldingPlacesScaffoldingHorizontally(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SCAFFOLDING); + ItemStack scaffolding = world.itematic$createStack(ItemKeys.SCAFFOLDING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, scaffolding); player.setYaw(0.0f); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, GROUND_POSITION, Direction.UP); - context.addInstantFinalTask(() -> context.expectBlock(Blocks.SCAFFOLDING, HORIZONTAL_SCAFFOLDING_OFFSET)); + TestUtil.useStackOnBlockInside(context, player, scaffolding, GROUND_POSITION, Direction.UP); + context.addFinalTask(() -> Assert.blockState(context, HORIZONTAL_SCAFFOLDING_OFFSET) + .is(Blocks.SCAFFOLDING)); } - @GameTest(templateName = "itematic:item.component.block.scaffolding.single_block") + @GameTest(structure = "itematic:item.component.block.scaffolding.single_block") public void usingScaffoldingOnSideFaceOfScaffoldingPlacesScaffoldingVertically(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SCAFFOLDING); + ItemStack scaffolding = world.itematic$createStack(ItemKeys.SCAFFOLDING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, scaffolding); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, PLACED_BLOCK_POSITION, Direction.SOUTH); - context.addInstantFinalTask(() -> context.expectBlock(Blocks.SCAFFOLDING, VERTICAL_SCAFFOLDING_OFFSET)); + TestUtil.useStackOnBlockInside(context, player, scaffolding, PLACED_BLOCK_POSITION, Direction.SOUTH); + context.addFinalTask(() -> Assert.blockState(context, VERTICAL_SCAFFOLDING_OFFSET) + .is(Blocks.SCAFFOLDING)); } - @GameTest(templateName = "itematic:item.component.block.scaffolding.horizontal.max_distance") + @GameTest(structure = "itematic:item.component.block.scaffolding.horizontal.max_distance") public void usingScaffoldingForHorizontalPlacementFailsAfterReachingMaxDistance(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SCAFFOLDING); + ItemStack scaffolding = world.itematic$createStack(ItemKeys.SCAFFOLDING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, scaffolding); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, PLACED_BLOCK_POSITION, Direction.UP); - context.addInstantFinalTask(() -> context.dontExpectBlock(Blocks.SCAFFOLDING, HORIZONTAL_SCAFFOLDING_BEYOND_MAX_DISTANCE_OFFSET)); + TestUtil.useStackOnBlockInside(context, player, scaffolding, PLACED_BLOCK_POSITION, Direction.UP); + context.addFinalTask(() -> Assert.blockState(context, HORIZONTAL_SCAFFOLDING_BEYOND_MAX_DISTANCE_OFFSET) + .isNot(Blocks.SCAFFOLDING)); } - @GameTest(templateName = "itematic:item.component.block.scaffolding.vertical.max_distance") + @GameTest(structure = "itematic:item.component.block.scaffolding.vertical.max_distance") public void usingScaffoldingForVerticalPlacementIgnoresMaxDistance(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SCAFFOLDING); + ItemStack scaffolding = world.itematic$createStack(ItemKeys.SCAFFOLDING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, scaffolding); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, PLACED_BLOCK_POSITION, Direction.SOUTH); - context.addInstantFinalTask(() -> context.expectBlock(Blocks.SCAFFOLDING, VERTICAL_SCAFFOLDING_BEYOND_MAX_DISTANCE_OFFSET)); + TestUtil.useStackOnBlockInside(context, player, scaffolding, PLACED_BLOCK_POSITION, Direction.SOUTH); + context.addFinalTask(() -> Assert.blockState(context, VERTICAL_SCAFFOLDING_BEYOND_MAX_DISTANCE_OFFSET) + .is(Blocks.SCAFFOLDING)); } - @GameTest(templateName = "itematic:item.component.block.platform") + @GameTest(structure = "itematic:item.component.block.platform") public void usingCommandBlockInSurvivalModeOnGroundDoesNotPlaceCommandBlock(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.COMMAND_BLOCK); + ItemStack commandBlock = world.itematic$createStack(ItemKeys.COMMAND_BLOCK); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, commandBlock); world.spawnEntity(player); - TestUtil.useStackOnBlockInside(context, player, stack, GROUND_POSITION, Direction.UP); - context.addInstantFinalTask(() -> context.dontExpectBlock(Blocks.COMMAND_BLOCK, PLACED_BLOCK_POSITION)); + TestUtil.useStackOnBlockInside(context, player, commandBlock, GROUND_POSITION, Direction.UP); + context.addFinalTask(() -> Assert.blockState(context, PLACED_BLOCK_POSITION) + .isNot(Blocks.COMMAND_BLOCK)); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/BucketItemComponentTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/BucketItemComponentTestSuite.java new file mode 100644 index 00000000..e7d4adb8 --- /dev/null +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/BucketItemComponentTestSuite.java @@ -0,0 +1,118 @@ +package net.errorcraft.itematic.gametest.item.component; + +import net.errorcraft.itematic.assertion.Assert; +import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; +import net.minecraft.block.Blocks; +import net.minecraft.command.argument.EntityAnchorArgumentType; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.fluid.Fluids; +import net.minecraft.item.ItemStack; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.test.TestContext; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.GameMode; + +public class BucketItemComponentTestSuite { + private static final BlockPos SPAWN_POSITION = new BlockPos(1, 2, 0); + private static final BlockPos FACE_POSITION = new BlockPos(1, 1, 1); + private static final BlockPos PLACED_POSITION = FACE_POSITION; + + @GameTest(structure = "itematic:item.component.bucket.platform.water") + public void usingBucketOnWaterTakesWaterAndGivesWaterBucket(TestContext context) { + ServerWorld world = context.getWorld(); + ItemStack bucket = world.itematic$createStack(ItemKeys.BUCKET); + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + TestUtil.setEntityPos(context, player, SPAWN_POSITION); + player.lookAt(EntityAnchorArgumentType.EntityAnchor.EYES, Vec3d.ofBottomCenter(context.getAbsolutePos(FACE_POSITION))); + player.setStackInHand(Hand.MAIN_HAND, bucket); + world.spawnEntity(player); + ActionResult result = bucket.use(world, player, Hand.MAIN_HAND); + context.addFinalTask(() -> { + Assert.fluidState(context, PLACED_POSITION) + .is(Fluids.EMPTY); + Assert.isInstance( + context, + result, + ActionResult.Success.class, + () -> "Expected Bucket usage to be successful", + success -> Assert.itemStack(context, success.getNewHandStack()) + .is(ItemKeys.WATER_BUCKET) + ); + }); + } + + @GameTest(structure = "itematic:item.component.bucket.platform.powder_snow") + public void usingBucketOnPowderSnowTakesWaterAndGivesPowderSnowBucket(TestContext context) { + ServerWorld world = context.getWorld(); + ItemStack bucket = world.itematic$createStack(ItemKeys.BUCKET); + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + TestUtil.setEntityPos(context, player, SPAWN_POSITION); + player.lookAt(EntityAnchorArgumentType.EntityAnchor.EYES, Vec3d.ofBottomCenter(context.getAbsolutePos(FACE_POSITION))); + player.setStackInHand(Hand.MAIN_HAND, bucket); + world.spawnEntity(player); + ActionResult result = bucket.use(world, player, Hand.MAIN_HAND); + context.addFinalTask(() -> { + Assert.fluidState(context, PLACED_POSITION) + .is(Fluids.EMPTY); + Assert.isInstance( + context, + result, + ActionResult.Success.class, + () -> "Expected Bucket usage to be successful", + success -> Assert.itemStack(context, success.getNewHandStack()) + .is(ItemKeys.POWDER_SNOW_BUCKET) + ); + }); + } + + @GameTest(structure = "itematic:item.component.bucket.platform") + public void usingWaterBucketOnGroundPlacesWater(TestContext context) { + ServerWorld world = context.getWorld(); + ItemStack waterBucket = world.itematic$createStack(ItemKeys.WATER_BUCKET); + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + TestUtil.setEntityPos(context, player, SPAWN_POSITION); + player.lookAt(EntityAnchorArgumentType.EntityAnchor.EYES, Vec3d.ofBottomCenter(context.getAbsolutePos(FACE_POSITION))); + player.setStackInHand(Hand.MAIN_HAND, waterBucket); + world.spawnEntity(player); + waterBucket.use(world, player, Hand.MAIN_HAND); + context.addFinalTask(() -> Assert.fluidState(context, PLACED_POSITION) + .is(Fluids.WATER)); + } + + @GameTest(structure = "itematic:item.component.bucket.platform") + public void usingPowderSnowBucketOnGroundPlacesPowderSnow(TestContext context) { + ServerWorld world = context.getWorld(); + ItemStack powderSnowBucket = world.itematic$createStack(ItemKeys.POWDER_SNOW_BUCKET); + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + TestUtil.setEntityPos(context, player, SPAWN_POSITION); + player.lookAt(EntityAnchorArgumentType.EntityAnchor.EYES, Vec3d.ofBottomCenter(context.getAbsolutePos(FACE_POSITION))); + player.setStackInHand(Hand.MAIN_HAND, powderSnowBucket); + world.spawnEntity(player); + powderSnowBucket.use(world, player, Hand.MAIN_HAND); + context.addFinalTask(() -> Assert.blockState(context, PLACED_POSITION) + .is(Blocks.POWDER_SNOW)); + } + + @GameTest(structure = "itematic:item.component.bucket.platform") + public void usingPufferfishBucketOnGroundPlacesWaterAndPufferfish(TestContext context) { + ServerWorld world = context.getWorld(); + ItemStack pufferfishBucket = world.itematic$createStack(ItemKeys.PUFFERFISH_BUCKET); + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + TestUtil.setEntityPos(context, player, SPAWN_POSITION); + player.lookAt(EntityAnchorArgumentType.EntityAnchor.EYES, Vec3d.ofBottomCenter(context.getAbsolutePos(FACE_POSITION))); + player.setStackInHand(Hand.MAIN_HAND, pufferfishBucket); + world.spawnEntity(player); + pufferfishBucket.use(world, player, Hand.MAIN_HAND); + context.addFinalTask(() -> { + Assert.fluidState(context, PLACED_POSITION) + .is(Fluids.WATER); + context.expectEntityAt(EntityType.PUFFERFISH, PLACED_POSITION); + }); + } +} diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ConsumableItemComponentTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ConsumableItemComponentTestSuite.java index 97ceb116..ef818e0c 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ConsumableItemComponentTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ConsumableItemComponentTestSuite.java @@ -1,31 +1,31 @@ package net.errorcraft.itematic.gametest.item.component; -import net.errorcraft.itematic.component.ItematicDataComponentTypes; -import net.errorcraft.itematic.gametest.Assert; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; -import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.fabricmc.fabric.api.gametest.v1.GameTest; 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 ConsumableItemComponentTestSuite { - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest(maxTicks = 100) public void consumingHoneyBottleReplacesItemWithGlassBottle(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); player.getHungerManager().setFoodLevel(0); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.HONEY_BOTTLE); - player.setStackInHand(Hand.MAIN_HAND, stack); + ItemStack honeyBottle = world.itematic$createStack(ItemKeys.HONEY_BOTTLE); + player.setStackInHand(Hand.MAIN_HAND, honeyBottle); world.spawnEntity(player); - stack.use(world, player, Hand.MAIN_HAND); - context.createTimedTaskRunner().expectMinDurationAndRun( - TestUtil.getDataComponent(stack, ItematicDataComponentTypes.USE_DURATION).ticks(stack, player), - () -> Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.GLASS_BOTTLE) - ).completeIfSuccessful(); + context.createTimedTaskRunner() + .createAndAddReported(() -> honeyBottle.use(world, player, Hand.MAIN_HAND)) + .expectMinDurationAndRun( + honeyBottle.getMaxUseTime(player), + () -> Assert.itemStack(context, player.getStackInHand(Hand.MAIN_HAND)) + .is(ItemKeys.GLASS_BOTTLE) + ) + .completeIfSuccessful(); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/EntityItemComponentTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/EntityItemComponentTestSuite.java new file mode 100644 index 00000000..5d037db5 --- /dev/null +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/EntityItemComponentTestSuite.java @@ -0,0 +1,41 @@ +package net.errorcraft.itematic.gametest.item.component; + +import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.test.TestContext; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.GameMode; + +public class EntityItemComponentTestSuite { + private static final BlockPos GROUND_POSITION = new BlockPos(1, 0, 0); + private static final BlockPos PLACED_ENTITY_POSITION = GROUND_POSITION.add(0, 1, 0); + + @GameTest(structure = "itematic:item.component.entity.platform") + public void usingOakBoatOnGroundPlacesOakBoat(TestContext context) { + ServerWorld world = context.getWorld(); + ItemStack oakBoat = world.itematic$createStack(ItemKeys.OAK_BOAT); + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + player.setStackInHand(Hand.MAIN_HAND, oakBoat); + world.spawnEntity(player); + TestUtil.useStackOnBlockInside(context, player, oakBoat, GROUND_POSITION, Direction.UP); + context.addFinalTask(() -> context.expectEntityAt(EntityType.OAK_BOAT, PLACED_ENTITY_POSITION)); + } + + @GameTest(structure = "itematic:item.component.entity.platform") + public void usingPigSpawnEggOnGroundPlacesPig(TestContext context) { + ServerWorld world = context.getWorld(); + ItemStack pigSpawnEgg = world.itematic$createStack(ItemKeys.PIG_SPAWN_EGG); + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + player.setStackInHand(Hand.MAIN_HAND, pigSpawnEgg); + world.spawnEntity(player); + TestUtil.useStackOnBlockInside(context, player, pigSpawnEgg, GROUND_POSITION, Direction.UP); + context.addFinalTask(() -> context.expectEntityAt(EntityType.PIG, PLACED_ENTITY_POSITION)); + } +} diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/EquipmentItemComponentTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/EquipmentItemComponentTestSuite.java index 854f11e2..42fb3591 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/EquipmentItemComponentTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/EquipmentItemComponentTestSuite.java @@ -1,60 +1,66 @@ package net.errorcraft.itematic.gametest.item.component; -import net.errorcraft.itematic.gametest.Assert; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; -import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.EquippableComponent; import net.minecraft.entity.EquipmentSlot; 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.GameTestException; import net.minecraft.test.TestContext; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.world.GameMode; public class EquipmentItemComponentTestSuite { - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void usingItemEquipsStack(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.LEATHER_HELMET); - player.setStackInHand(Hand.MAIN_HAND, stack); - EquippableComponent equippable = TestUtil.getDataComponent(stack, DataComponentTypes.EQUIPPABLE); - stack.use(world, player, Hand.MAIN_HAND); - context.addInstantFinalTask(() -> Assert.itemStackIsOf(player.getEquippedStack(equippable.slot()), ItemKeys.LEATHER_HELMET)); + ItemStack leatherHelmet = world.itematic$createStack(ItemKeys.LEATHER_HELMET); + player.setStackInHand(Hand.MAIN_HAND, leatherHelmet); + EquippableComponent equippable = TestUtil.getDataComponent(context, leatherHelmet, DataComponentTypes.EQUIPPABLE); + leatherHelmet.use(world, player, Hand.MAIN_HAND); + context.addFinalTask(() -> Assert.itemStack(context, player.getEquippedStack(equippable.slot())) + .is(ItemKeys.LEATHER_HELMET) + ); } - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void usingItemThatIsNotSwappableDoesNotEquipStack(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SHIELD); - player.setStackInHand(Hand.MAIN_HAND, stack); - EquippableComponent equippable = TestUtil.getDataComponent(stack, DataComponentTypes.EQUIPPABLE); - stack.use(world, player, Hand.MAIN_HAND); - context.addInstantFinalTask(() -> Assert.itemStackIsEmpty(player.getEquippedStack(equippable.slot()))); + ItemStack shield = world.itematic$createStack(ItemKeys.SHIELD); + player.setStackInHand(Hand.MAIN_HAND, shield); + EquippableComponent equippable = TestUtil.getDataComponent(context, shield, DataComponentTypes.EQUIPPABLE); + shield.use(world, player, Hand.MAIN_HAND); + context.addFinalTask(() -> Assert.itemStack(context, player.getEquippedStack(equippable.slot())) + .isEmpty() + ); } - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void usingItemWithAlreadyEquippedStackSwapsStacks(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); ServerWorld world = context.getWorld(); player.equipStack(EquipmentSlot.HEAD, world.itematic$createStack(ItemKeys.IRON_HELMET)); - ItemStack stack = world.itematic$createStack(ItemKeys.LEATHER_HELMET); - player.setStackInHand(Hand.MAIN_HAND, stack); - ActionResult result = stack.use(world, player, Hand.MAIN_HAND); - context.addInstantFinalTask(() -> { - if (!(result instanceof ActionResult.Success successResult)) { - throw new GameTestException("Expected equipment usage to be successful"); - } - - Assert.itemStackIsOf(player.getEquippedStack(EquipmentSlot.HEAD), ItemKeys.LEATHER_HELMET); - Assert.itemStackIsOf(successResult.getNewHandStack(), ItemKeys.IRON_HELMET); + ItemStack leatherHelmet = world.itematic$createStack(ItemKeys.LEATHER_HELMET); + player.setStackInHand(Hand.MAIN_HAND, leatherHelmet); + context.addFinalTask(() -> { + ActionResult result = leatherHelmet.use(world, player, Hand.MAIN_HAND); + Assert.isInstance( + context, + result, + ActionResult.Success.class, + () -> "Expected equipment item usage to be successful", + success -> Assert.itemStack(context, success.getNewHandStack()) + .is(ItemKeys.IRON_HELMET) + ); + Assert.itemStack(context, player.getEquippedStack(EquipmentSlot.HEAD)) + .is(ItemKeys.LEATHER_HELMET); }); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/FoodItemComponentTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/FoodItemComponentTestSuite.java index 67b24653..e59d257e 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/FoodItemComponentTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/FoodItemComponentTestSuite.java @@ -1,18 +1,16 @@ package net.errorcraft.itematic.gametest.item.component; -import net.errorcraft.itematic.component.ItematicDataComponentTypes; -import net.errorcraft.itematic.gametest.Assert; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; import net.errorcraft.itematic.item.component.ItemComponentTypes; import net.errorcraft.itematic.item.component.components.FoodItemComponent; -import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.SuspiciousStewEffectsComponent; 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; @@ -20,46 +18,43 @@ import java.util.List; public class FoodItemComponentTestSuite { - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest(maxTicks = 100) public void eatingFoodItemAddsNutrition(TestContext context) { + ServerWorld world = context.getWorld(); + ItemStack apple = world.itematic$createStack(ItemKeys.APPLE); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); player.getHungerManager().setFoodLevel(0); - ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.APPLE); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, apple); world.spawnEntity(player); - FoodItemComponent component = TestUtil.getItemBehavior(stack, ItemComponentTypes.FOOD); - stack.use(world, player, Hand.MAIN_HAND); + FoodItemComponent component = TestUtil.getItemBehavior(context, apple, ItemComponentTypes.FOOD); + apple.use(world, player, Hand.MAIN_HAND); context.createTimedTaskRunner().expectMinDurationAndRun( - TestUtil.getDataComponent(stack, ItematicDataComponentTypes.USE_DURATION).ticks(stack, player), + apple.getMaxUseTime(player), () -> { - Assert.itemStackIsEmpty(player.getStackInHand(Hand.MAIN_HAND)); - Assert.areIntsEqual( - player.getHungerManager().getFoodLevel(), - component.nutrition(), - (value, expected) -> "Expected nutrition to be " + expected + ", got " + value + " instead" - ); + Assert.itemStack(context, player.getStackInHand(Hand.MAIN_HAND)) + .isEmpty(); + Assert.ints(context, player.getHungerManager().getFoodLevel(), "nutrition") + .equals(component.nutrition()); } ).completeIfSuccessful(); } - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest(maxTicks = 100) public void eatingSuspiciousStewAddsSuspiciousEffects(TestContext context) { - PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SUSPICIOUS_STEW); - List effects = TestUtil.getItemBehavior(world.itematic$createStack(ItemKeys.DANDELION), ItemComponentTypes.SUSPICIOUS_EFFECT_INGREDIENT) + ItemStack suspiciousStew = world.itematic$createStack(ItemKeys.SUSPICIOUS_STEW); + List effects = TestUtil.getItemBehavior(context, world.itematic$createStack(ItemKeys.DANDELION), ItemComponentTypes.SUSPICIOUS_EFFECT_INGREDIENT) .effects(); - stack.set(DataComponentTypes.SUSPICIOUS_STEW_EFFECTS, new SuspiciousStewEffectsComponent(effects)); - player.setStackInHand(Hand.MAIN_HAND, stack); + suspiciousStew.set(DataComponentTypes.SUSPICIOUS_STEW_EFFECTS, new SuspiciousStewEffectsComponent(effects)); + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + player.setStackInHand(Hand.MAIN_HAND, suspiciousStew); world.spawnEntity(player); - stack.use(world, player, Hand.MAIN_HAND); + suspiciousStew.use(world, player, Hand.MAIN_HAND); context.createTimedTaskRunner().expectMinDurationAndRun( - TestUtil.getDataComponent(stack, ItematicDataComponentTypes.USE_DURATION).ticks(stack, player), - () -> { - Assert.forAll(effects, effect -> context.expectEntityHasEffect(player, effect.effect(), effect.createStatusEffectInstance().getAmplifier())); - Assert.itemStackIsOf(player.getStackInHand(Hand.MAIN_HAND), ItemKeys.BOWL); - } + suspiciousStew.getMaxUseTime(player), + () -> Assert.livingEntity(context, player) + .hasEffects(effects) + .hasStackInHand(Hand.MAIN_HAND, stack -> stack.is(ItemKeys.BOWL)) ).completeIfSuccessful(); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ImmuneToDamageItemComponentTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ImmuneToDamageItemComponentTestSuite.java index c8f552e6..149ebd7b 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ImmuneToDamageItemComponentTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ImmuneToDamageItemComponentTestSuite.java @@ -1,56 +1,74 @@ package net.errorcraft.itematic.gametest.item.component; -import net.errorcraft.itematic.gametest.TestUtil; import net.errorcraft.itematic.item.ItemKeys; -import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.entity.EntityType; import net.minecraft.entity.ItemEntity; -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.math.BlockPos; public class ImmuneToDamageItemComponentTestSuite { private static final BlockPos SPAWN_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void explodingNetherStarKeepsItemAlive(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.NETHER_STAR); - ItemEntity item = new ItemEntity(world, 0.0d, 0.0d, 0.0d, stack); - TestUtil.spawnEntity(context, item, SPAWN_POSITION); - item.damage(world, world.getDamageSources().explosion(null), Float.MAX_VALUE); - context.addInstantFinalTask(() -> context.expectEntity(EntityType.ITEM)); + ItemEntity netherStar = new ItemEntity( + world, + 0.0d, + 0.0d, + 0.0d, + world.itematic$createStack(ItemKeys.NETHER_STAR) + ); + TestUtil.spawnEntity(context, netherStar, SPAWN_POSITION); + netherStar.damage(world, world.getDamageSources().explosion(null), Float.MAX_VALUE); + context.addFinalTask(() -> context.expectEntity(EntityType.ITEM)); } - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void explodingStickDestroysItem(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.STICK); - ItemEntity item = new ItemEntity(world, 0.0d, 0.0d, 0.0d, stack); - TestUtil.spawnEntity(context, item, SPAWN_POSITION); - item.damage(world, world.getDamageSources().explosion(null), Float.MAX_VALUE); - context.addInstantFinalTask(() -> context.dontExpectEntity(EntityType.ITEM)); + ItemEntity stick = new ItemEntity( + world, + 0.0d, + 0.0d, + 0.0d, + world.itematic$createStack(ItemKeys.STICK) + ); + TestUtil.spawnEntity(context, stick, SPAWN_POSITION); + stick.damage(world, world.getDamageSources().explosion(null), Float.MAX_VALUE); + context.addFinalTask(() -> context.dontExpectEntity(EntityType.ITEM)); } - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void settingNetheriteIngotOnFireKeepsItemAlive(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.NETHERITE_INGOT); - ItemEntity item = new ItemEntity(world, 0.0d, 0.0d, 0.0d, stack); - TestUtil.spawnEntity(context, item, SPAWN_POSITION); - item.damage(world, world.getDamageSources().inFire(), Float.MAX_VALUE); - context.addInstantFinalTask(() -> context.expectEntity(EntityType.ITEM)); + ItemEntity netheriteIngot = new ItemEntity( + world, + 0.0d, + 0.0d, + 0.0d, + world.itematic$createStack(ItemKeys.NETHERITE_INGOT) + ); + TestUtil.spawnEntity(context, netheriteIngot, SPAWN_POSITION); + netheriteIngot.damage(world, world.getDamageSources().inFire(), Float.MAX_VALUE); + context.addFinalTask(() -> context.expectEntity(EntityType.ITEM)); } - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void settingStickOnFireDestroysItem(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.STICK); - ItemEntity item = new ItemEntity(world, 0.0d, 0.0d, 0.0d, stack); - TestUtil.spawnEntity(context, item, SPAWN_POSITION); - item.damage(world, world.getDamageSources().inFire(), Float.MAX_VALUE); - context.addInstantFinalTask(() -> context.dontExpectEntity(EntityType.ITEM)); + ItemEntity stick = new ItemEntity( + world, + 0.0d, + 0.0d, + 0.0d, + world.itematic$createStack(ItemKeys.STICK) + ); + TestUtil.spawnEntity(context, stick, SPAWN_POSITION); + stick.damage(world, world.getDamageSources().inFire(), Float.MAX_VALUE); + context.addFinalTask(() -> context.dontExpectEntity(EntityType.ITEM)); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ItemHolderItemComponentTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ItemHolderItemComponentTestSuite.java index a5d53dbe..3ba7ac14 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ItemHolderItemComponentTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ItemHolderItemComponentTestSuite.java @@ -1,11 +1,11 @@ package net.errorcraft.itematic.gametest.item.component; -import net.errorcraft.itematic.gametest.Assert; -import net.errorcraft.itematic.gametest.TestUtil; -import net.errorcraft.itematic.inventory.StackReferenceUtil; +import net.errorcraft.itematic.assertion.Assert; +import net.errorcraft.itematic.inventory.SimpleStackReference; import net.errorcraft.itematic.item.ItemKeys; import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.BundleContentsComponent; import net.minecraft.entity.player.PlayerEntity; @@ -14,7 +14,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.screen.slot.Slot; import net.minecraft.server.world.ServerWorld; -import net.minecraft.test.GameTest; import net.minecraft.test.TestContext; import net.minecraft.util.ClickType; import net.minecraft.world.GameMode; @@ -24,94 +23,126 @@ public class ItemHolderItemComponentTestSuite { private static final int SLOT = 0; - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void rightClickingOnStackWithItemHolderAddsStackToItemHolder(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); ServerWorld world = context.getWorld(); PlayerInventory inventory = player.getInventory(); - ItemStack stack = world.itematic$createStack(ItemKeys.BUNDLE); + ItemStack bundle = world.itematic$createStack(ItemKeys.BUNDLE); inventory.insertStack(SLOT, world.itematic$createStack(ItemKeys.STICK)); Slot slot = new Slot(inventory, SLOT, 0, 0); world.spawnEntity(player); - boolean success = stack.onStackClicked(slot, ClickType.RIGHT, player); - context.addInstantFinalTask(() -> { - context.assertTrue(success, "Expected right clicking with item holder to be successful"); - Assert.itemStackIsEmpty(inventory.getStack(SLOT)); - Assert.itemStackHasDataComponent(stack, DataComponentTypes.BUNDLE_CONTENTS, - component -> Assert.itemStackIsOf(component.get(0), ItemKeys.STICK) + context.addFinalTask(() -> { + boolean success = bundle.onStackClicked(slot, ClickType.RIGHT, player); + Assert.isTrue( + context, + success, + () -> "Expected right clicking on slot with item holder to be successful" ); + Assert.itemStack(context, inventory.getStack(SLOT)) + .isEmpty(); + Assert.itemStack(context, bundle) + .hasComponent( + DataComponentTypes.BUNDLE_CONTENTS, + component -> Assert.itemStack(context, component.get(0)) + .is(ItemKeys.STICK) + ); }); } - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void rightClickingOnEmptySlotPlacesLastStackFromItemHolderInSlot(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); ServerWorld world = context.getWorld(); PlayerInventory inventory = player.getInventory(); - ItemStack stack = world.itematic$createStack(ItemKeys.BUNDLE); - ItemStack stackToRemove = world.itematic$createStack(ItemKeys.STICK); - addToBundleContentsComponent(stack, stackToRemove); + ItemStack bundle = world.itematic$createStack(ItemKeys.BUNDLE); + addToBundleContentsComponent(context, bundle, world.itematic$createStack(ItemKeys.STICK)); Slot slot = new Slot(inventory, SLOT, 0, 0); world.spawnEntity(player); - boolean success = stack.onStackClicked(slot, ClickType.RIGHT, player); - context.addInstantFinalTask(() -> { - context.assertTrue(success, "Expected right clicking with item holder to be successful"); - Assert.itemStackIsOf(inventory.getStack(SLOT), ItemKeys.STICK); - Assert.itemStackHasDataComponent(stack, DataComponentTypes.BUNDLE_CONTENTS, - component -> context.assertTrue(component.isEmpty(), "Expected item holder to be empty") + context.addFinalTask(() -> { + boolean success = bundle.onStackClicked(slot, ClickType.RIGHT, player); + Assert.isTrue( + context, + success, + () -> "Expected right clicking on slot with item holder to be successful" ); + Assert.itemStack(context, inventory.getStack(SLOT)) + .is(ItemKeys.STICK); + Assert.itemStack(context, bundle) + .hasComponent(DataComponentTypes.BUNDLE_CONTENTS, component -> Assert.isTrue( + context, + component.isEmpty(), + () -> "Expected item holder contents to be empty" + )); }); } - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void rightClickingOnItemHolderWithStackAddsStackToItemHolder(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); ServerWorld world = context.getWorld(); PlayerInventory inventory = player.getInventory(); inventory.insertStack(SLOT, world.itematic$createStack(ItemKeys.BUNDLE)); - ItemStack stack = inventory.getStack(SLOT); + ItemStack bundle = inventory.getStack(SLOT); ItemStack stackToAdd = world.itematic$createStack(ItemKeys.STICK); - StackReference cursorStack = StackReferenceUtil.of(stackToAdd); + StackReference cursorStack = SimpleStackReference.of(stackToAdd); Slot slot = new Slot(inventory, SLOT, 0, 0); world.spawnEntity(player); - boolean success = stack.onClicked(stackToAdd, slot, ClickType.RIGHT, player, cursorStack); - context.addInstantFinalTask(() -> { - context.assertTrue(success, "Expected right clicking on item holder to be successful"); - Assert.itemStackIsEmpty(cursorStack.get()); - Assert.itemStackHasDataComponent(inventory.getStack(SLOT), DataComponentTypes.BUNDLE_CONTENTS, - component -> Assert.itemStackIsOf(component.get(0), ItemKeys.STICK) + context.addFinalTask(() -> { + boolean success = bundle.onClicked(stackToAdd, slot, ClickType.RIGHT, player, cursorStack); + Assert.isTrue( + context, + success, + () -> "Expected right clicking on item holder to be successful" ); + Assert.itemStack(context, cursorStack.get()) + .isEmpty(); + Assert.itemStack(context, inventory.getStack(SLOT)) + .hasComponent( + DataComponentTypes.BUNDLE_CONTENTS, + component -> Assert.itemStack(context, component.get(0)) + .is(ItemKeys.STICK) + ); }); } - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void rightClickingOnItemHolderRemovesStackFromItemHolder(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); ServerWorld world = context.getWorld(); PlayerInventory inventory = player.getInventory(); - ItemStack stack = world.itematic$createStack(ItemKeys.BUNDLE); - ItemStack stackToRemove = world.itematic$createStack(ItemKeys.STICK); - addToBundleContentsComponent(stack, stackToRemove); - inventory.insertStack(SLOT, stack); - stack = inventory.getStack(SLOT); - StackReference cursorStack = StackReferenceUtil.of(ItemStack.EMPTY); + inventory.insertStack(SLOT, world.itematic$createStack(ItemKeys.BUNDLE)); + ItemStack bundle = inventory.getStack(SLOT); + addToBundleContentsComponent(context, bundle, world.itematic$createStack(ItemKeys.STICK)); + StackReference cursorStack = SimpleStackReference.of(ItemStack.EMPTY); Slot slot = new Slot(inventory, SLOT, 0, 0); world.spawnEntity(player); - boolean success = stack.onClicked(ItemStack.EMPTY, slot, ClickType.RIGHT, player, cursorStack); - context.addInstantFinalTask(() -> { - context.assertTrue(success, "Expected right clicking on item holder to be successful"); - Assert.itemStackIsOf(cursorStack.get(), ItemKeys.STICK); - Assert.itemStackHasDataComponent(inventory.getStack(SLOT), DataComponentTypes.BUNDLE_CONTENTS, - component -> context.assertTrue(component.isEmpty(), "Expected item holder to be empty") + context.addFinalTask(() -> { + boolean success = bundle.onClicked(ItemStack.EMPTY, slot, ClickType.RIGHT, player, cursorStack); + Assert.isTrue( + context, + success, + () -> "Expected right clicking on item holder to be successful" ); + Assert.itemStack(context, cursorStack.get()) + .is(ItemKeys.STICK); + Assert.itemStack(context, inventory.getStack(SLOT)) + .hasComponent( + DataComponentTypes.BUNDLE_CONTENTS, + component -> Assert.isTrue( + context, + component.isEmpty(), + () -> "Expected item holder to be empty" + ) + ); }); } - private static void addToBundleContentsComponent(ItemStack origin, ItemStack stackToAdd) { + private static void addToBundleContentsComponent(TestContext helper, ItemStack bundle, ItemStack stackToAdd) { BundleContentsComponent.Builder builder = Objects.requireNonNull( - TestUtil.getItemBehavior(origin, ItemComponentTypes.ITEM_HOLDER).createBuilder(origin) + TestUtil.getItemBehavior(helper, bundle, ItemComponentTypes.ITEM_HOLDER).createBuilder(bundle) ); builder.add(stackToAdd); - origin.set(DataComponentTypes.BUNDLE_CONTENTS, builder.build()); + bundle.set(DataComponentTypes.BUNDLE_CONTENTS, builder.build()); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/LifeSavingItemComponentTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/LifeSavingItemComponentTestSuite.java index 9d541b0c..c1b1b764 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/LifeSavingItemComponentTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/LifeSavingItemComponentTestSuite.java @@ -1,40 +1,39 @@ package net.errorcraft.itematic.gametest.item.component; -import net.errorcraft.itematic.gametest.Assert; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; -import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.fabricmc.fabric.api.gametest.v1.GameTest; 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 LifeSavingItemComponentTestSuite { - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void dyingWhileHoldingTotemOfUndyingKeepsPlayerAlive(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.TOTEM_OF_UNDYING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, world.itematic$createStack(ItemKeys.TOTEM_OF_UNDYING)); player.damage(world, 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); - }); + context.addFinalTask(() -> Assert.livingEntity(context, player) + .hasHealth(health -> health.equals(1.0f)) + .hasEffect(StatusEffects.REGENERATION, 1) + .hasEffect(StatusEffects.ABSORPTION, 1) + .hasEffect(StatusEffects.FIRE_RESISTANCE, 0)); } - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void dyingFromBypassedInvulnerabilityDamageWhileHoldingTotemOfUndyingKillsPlayer(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.TOTEM_OF_UNDYING); PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, world.itematic$createStack(ItemKeys.TOTEM_OF_UNDYING)); player.damage(world, world.getDamageSources().genericKill(), Float.MAX_VALUE); - context.addInstantFinalTask(() -> context.assertTrue(player.isDead(), "Expected player to be dead")); + context.addFinalTask(() -> Assert.isTrue( + context, + player.isDead(), + () -> "Expected Player to be dead" + )); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/MappableItemComponentTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/MappableItemComponentTestSuite.java index c2b52190..8a92b426 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/MappableItemComponentTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/MappableItemComponentTestSuite.java @@ -1,36 +1,34 @@ package net.errorcraft.itematic.gametest.item.component; -import net.errorcraft.itematic.gametest.Assert; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; -import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.component.DataComponentTypes; 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.GameTestException; import net.minecraft.test.TestContext; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.world.GameMode; public class MappableItemComponentTestSuite { - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void usingMapFillsMap(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.MAP); - player.setStackInHand(Hand.MAIN_HAND, stack); + ItemStack map = world.itematic$createStack(ItemKeys.MAP); + player.setStackInHand(Hand.MAIN_HAND, map); world.spawnEntity(player); - ActionResult result = stack.use(world, player, Hand.MAIN_HAND); - context.addInstantFinalTask(() -> { - if (!(result instanceof ActionResult.Success successResult)) { - throw new GameTestException("Expected mappable usage to be successful"); - } - - ItemStack resultStack = successResult.getNewHandStack(); - Assert.itemStackIsOf(resultStack, ItemKeys.FILLED_MAP); - Assert.itemStackHasDataComponent(resultStack, DataComponentTypes.MAP_ID); - }); + ActionResult result = map.use(world, player, Hand.MAIN_HAND); + context.addFinalTask(() -> Assert.isInstance( + context, + result, + ActionResult.Success.class, + () -> "Expected mappable item usage to be successful", + success -> Assert.itemStack(context, success.getNewHandStack()) + .is(ItemKeys.FILLED_MAP) + .hasComponent(DataComponentTypes.MAP_ID) + )); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/PotionItemComponentTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/PotionItemComponentTestSuite.java index 6c5790d1..2622c384 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/PotionItemComponentTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/PotionItemComponentTestSuite.java @@ -1,35 +1,33 @@ package net.errorcraft.itematic.gametest.item.component; -import net.errorcraft.itematic.component.ItematicDataComponentTypes; +import net.errorcraft.itematic.assertion.Assert; 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.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.fabricmc.fabric.api.gametest.v1.GameTest; 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.Hand; import net.minecraft.world.GameMode; public class PotionItemComponentTestSuite { - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest(maxTicks = 100) public void drinkingPotionItemAddsEffects(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); ServerWorld world = context.getWorld(); - ItemStack stack = PotionContentsComponentUtil.setPotion(world.itematic$createStack(ItemKeys.POTION), Potions.LEAPING); - player.setStackInHand(Hand.MAIN_HAND, stack); + ItemStack potion = PotionContentsComponentUtil.setPotion( + world.itematic$createStack(ItemKeys.POTION), + Potions.LEAPING + ); + player.setStackInHand(Hand.MAIN_HAND, potion); world.spawnEntity(player); - stack.use(world, player, Hand.MAIN_HAND); + potion.use(world, player, Hand.MAIN_HAND); context.createTimedTaskRunner().expectMinDurationAndRun( - TestUtil.getDataComponent(stack, ItematicDataComponentTypes.USE_DURATION).ticks(stack, player), - () -> Assert.forAll( - Potions.LEAPING.value().getEffects(), - effectInstance -> context.expectEntityHasEffect(player, effectInstance.getEffectType(), effectInstance.getAmplifier()) - ) + potion.getMaxUseTime(player), + () -> Assert.livingEntity(context, player) + .hasEffects(Potions.LEAPING) ).completeIfSuccessful(); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ShooterItemComponentTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ShooterItemComponentTestSuite.java index 4934d321..57655f23 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ShooterItemComponentTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ShooterItemComponentTestSuite.java @@ -1,58 +1,74 @@ package net.errorcraft.itematic.gametest.item.component; -import net.errorcraft.itematic.gametest.Assert; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; -import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.component.DataComponentTypes; 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 ShooterItemComponentTestSuite { - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest(maxTicks = 100) public void usingCrossbowChargesArrowFromInventory(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CROSSBOW); + ItemStack crossbow = world.itematic$createStack(ItemKeys.CROSSBOW); ItemStack ammunition = world.itematic$createStack(ItemKeys.ARROW); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, crossbow); player.getInventory().insertStack(ammunition); world.spawnEntity(player); - stack.use(world, player, Hand.MAIN_HAND); + crossbow.use(world, player, Hand.MAIN_HAND); context.createTimedTaskRunner().expectMinDurationAndRun( - stack.getMaxUseTime(player), + crossbow.getMaxUseTime(player), () -> { - stack.onStoppedUsing(world, player, player.getItemUseTimeLeft()); - Assert.itemStackHasDataComponent(player.getStackInHand(Hand.MAIN_HAND), DataComponentTypes.CHARGED_PROJECTILES, - component -> context.assertTrue(component.itematic$contains(ItemKeys.ARROW), "Expected item stack to have an Arrow as a charged projectile") + crossbow.onStoppedUsing(world, player, player.getItemUseTimeLeft()); + Assert.itemStack(context, player.getStackInHand(Hand.MAIN_HAND)) + .hasComponent( + DataComponentTypes.CHARGED_PROJECTILES, + chargedProjectiles -> Assert.isTrue( + context, + chargedProjectiles.itematic$contains(ItemKeys.ARROW), + () -> "Expected item stack to have an Arrow as a charged projectile" + ) + ); + Assert.isFalse( + context, + player.getInventory().contains(s -> s.itematic$isOf(ItemKeys.ARROW)), + () -> "Expected Player not to have any Arrows in their inventory" ); - context.assertTrue(!player.getInventory().contains(s -> s.itematic$isOf(ItemKeys.ARROW)), "Expected player to have no Arrows in their inventory"); } ).completeIfSuccessful(); } - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest(maxTicks = 100) public void usingCrossbowChargesFireworkRocketFromOffhand(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.CROSSBOW); + ItemStack crossbow = world.itematic$createStack(ItemKeys.CROSSBOW); ItemStack ammunition = world.itematic$createStack(ItemKeys.FIREWORK_ROCKET); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, crossbow); player.setStackInHand(Hand.OFF_HAND, ammunition); world.spawnEntity(player); - stack.use(world, player, Hand.MAIN_HAND); + crossbow.use(world, player, Hand.MAIN_HAND); context.createTimedTaskRunner().expectMinDurationAndRun( - stack.getMaxUseTime(player), + crossbow.getMaxUseTime(player), () -> { - stack.onStoppedUsing(world, player, player.getItemUseTimeLeft()); - Assert.itemStackHasDataComponent(player.getStackInHand(Hand.MAIN_HAND), DataComponentTypes.CHARGED_PROJECTILES, - component -> context.assertTrue(component.itematic$contains(ItemKeys.FIREWORK_ROCKET), "Expected item stack to have a Firework Rocket as a charged projectile") - ); - Assert.itemStackIsEmpty(player.getStackInHand(Hand.OFF_HAND)); + crossbow.onStoppedUsing(world, player, player.getItemUseTimeLeft()); + Assert.itemStack(context, player.getStackInHand(Hand.MAIN_HAND)) + .hasComponent( + DataComponentTypes.CHARGED_PROJECTILES, + chargedProjectiles -> Assert.isTrue( + context, + chargedProjectiles.itematic$contains(ItemKeys.FIREWORK_ROCKET), + () -> "Expected item stack to have a Firework Rocket as a charged projectile" + ) + ); + Assert.itemStack(context, player.getStackInHand(Hand.OFF_HAND)) + .isEmpty(); } ).completeIfSuccessful(); } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ThrowableItemComponentTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ThrowableItemComponentTestSuite.java index 4d95c1a0..4ad97366 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ThrowableItemComponentTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/ThrowableItemComponentTestSuite.java @@ -1,16 +1,17 @@ package net.errorcraft.itematic.gametest.item.component; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; import net.errorcraft.itematic.item.component.ItemComponentTypes; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.entity.EntityType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.predicate.NumberRange; import net.minecraft.server.world.ServerWorld; -import net.minecraft.test.GameTest; -import net.minecraft.test.GameTestException; import net.minecraft.test.TestContext; +import net.minecraft.text.Text; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; @@ -19,106 +20,138 @@ public class ThrowableItemComponentTestSuite { private static final BlockPos SPAWN_POSITION = new BlockPos(1, 1, 1); - @GameTest(templateName = "itematic:item.component.throwable.platform") + @GameTest(structure = "itematic:item.component.throwable.platform") public void throwingEggSpawnsEggAtEyePosition(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.EGG); + ItemStack egg = world.itematic$createStack(ItemKeys.EGG); PlayerEntity player = TestUtil.createMockPlayer(context, GameMode.SURVIVAL, SPAWN_POSITION); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, egg); world.spawnEntity(player); - ActionResult result = stack.use(world, player, Hand.MAIN_HAND); context.addFinalTask(() -> { - context.assertTrue(result.isAccepted(), "Expected Egg usage to be successful"); + ActionResult result = egg.use(world, player, Hand.MAIN_HAND); + Assert.isTrue( + context, + result.isAccepted(), + () -> "Expected Egg usage to be successful" + ); context.expectEntityAt(EntityType.EGG, SPAWN_POSITION.add(0, (int)player.getStandingEyeHeight(), 0)); }); } - @GameTest(templateName = "itematic:item.component.throwable.platform") + @GameTest(structure = "itematic:item.component.throwable.platform") public void throwingEnderPearlSpawnsEnderPearlAtEyePosition(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.ENDER_PEARL); + ItemStack enderPearl = world.itematic$createStack(ItemKeys.ENDER_PEARL); PlayerEntity player = TestUtil.createMockPlayer(context, GameMode.SURVIVAL, SPAWN_POSITION); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, enderPearl); world.spawnEntity(player); - ActionResult result = stack.use(world, player, Hand.MAIN_HAND); context.addFinalTask(() -> { - context.assertTrue(result.isAccepted(), "Expected Ender Pearl usage to be successful"); + ActionResult result = enderPearl.use(world, player, Hand.MAIN_HAND); + Assert.isTrue( + context, + result.isAccepted(), + () -> "Expected Ender Pearl usage to be successful" + ); context.expectEntityAt(EntityType.ENDER_PEARL, SPAWN_POSITION.add(0, (int)player.getStandingEyeHeight(), 0)); }); } - @GameTest(templateName = "itematic:item.component.throwable.platform") + @GameTest(structure = "itematic:item.component.throwable.platform") public void throwingSnowballSpawnsSnowballAtEyePosition(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SNOWBALL); + ItemStack snowball = world.itematic$createStack(ItemKeys.SNOWBALL); PlayerEntity player = TestUtil.createMockPlayer(context, GameMode.SURVIVAL, SPAWN_POSITION); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, snowball); world.spawnEntity(player); - ActionResult result = stack.use(world, player, Hand.MAIN_HAND); context.addFinalTask(() -> { - context.assertTrue(result.isAccepted(), "Expected Snowball usage to be successful"); + ActionResult result = snowball.use(world, player, Hand.MAIN_HAND); + Assert.isTrue( + context, + result.isAccepted(), + () -> "Expected Snowball usage to be successful" + ); context.expectEntityAt(EntityType.SNOWBALL, SPAWN_POSITION.add(0, (int)player.getStandingEyeHeight(), 0)); }); } - @GameTest(templateName = "itematic:item.component.throwable.platform") + @GameTest(structure = "itematic:item.component.throwable.platform") public void throwingExperienceBottleSpawnsExperienceBottleAtEyePosition(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.EXPERIENCE_BOTTLE); + ItemStack experienceBottle = world.itematic$createStack(ItemKeys.EXPERIENCE_BOTTLE); PlayerEntity player = TestUtil.createMockPlayer(context, GameMode.SURVIVAL, SPAWN_POSITION); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, experienceBottle); world.spawnEntity(player); - ActionResult result = stack.use(world, player, Hand.MAIN_HAND); context.addFinalTask(() -> { - context.assertTrue(result.isAccepted(), "Expected Experience Bottle usage to be successful"); + ActionResult result = experienceBottle.use(world, player, Hand.MAIN_HAND); + Assert.isTrue( + context, + result.isAccepted(), + () -> "Expected Experience Bottle usage to be successful" + ); context.expectEntityAt(EntityType.EXPERIENCE_BOTTLE, SPAWN_POSITION.add(0, (int)player.getStandingEyeHeight(), 0)); }); } - @GameTest(templateName = "itematic:item.component.throwable.platform") + @GameTest(structure = "itematic:item.component.throwable.platform") public void throwingSplashPotionSpawnsPotionAtEyePosition(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.SPLASH_POTION); + ItemStack splashPotion = world.itematic$createStack(ItemKeys.SPLASH_POTION); PlayerEntity player = TestUtil.createMockPlayer(context, GameMode.SURVIVAL, SPAWN_POSITION); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, splashPotion); world.spawnEntity(player); - ActionResult result = stack.use(world, player, Hand.MAIN_HAND); context.addFinalTask(() -> { - context.assertTrue(result.isAccepted(), "Expected Splash Potion usage to be successful"); - context.expectEntityAt(EntityType.POTION, SPAWN_POSITION.add(0, (int)player.getStandingEyeHeight(), 0)); + ActionResult result = splashPotion.use(world, player, Hand.MAIN_HAND); + Assert.isTrue( + context, + result.isAccepted(), + () -> "Expected Splash Potion usage to be successful" + ); + context.expectEntityAt(EntityType.SPLASH_POTION, SPAWN_POSITION.add(0, (int)player.getStandingEyeHeight(), 0)); }); } - @GameTest(templateName = "itematic:item.component.throwable.platform") + @GameTest(structure = "itematic:item.component.throwable.platform") public void throwingLingeringPotionSpawnsPotionAtEyePosition(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.LINGERING_POTION); + ItemStack lingeringPotion = world.itematic$createStack(ItemKeys.LINGERING_POTION); PlayerEntity player = TestUtil.createMockPlayer(context, GameMode.SURVIVAL, SPAWN_POSITION); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, lingeringPotion); world.spawnEntity(player); - ActionResult result = stack.use(world, player, Hand.MAIN_HAND); context.addFinalTask(() -> { - context.assertTrue(result.isAccepted(), "Expected Lingering Potion usage to be successful"); - context.expectEntityAt(EntityType.POTION, SPAWN_POSITION.add(0, (int)player.getStandingEyeHeight(), 0)); + ActionResult result = lingeringPotion.use(world, player, Hand.MAIN_HAND); + Assert.isTrue( + context, + result.isAccepted(), + () -> "Expected Lingering Potion usage to be successful" + ); + context.expectEntityAt(EntityType.LINGERING_POTION, SPAWN_POSITION.add(0, (int)player.getStandingEyeHeight(), 0)); }); } - @GameTest(templateName = "itematic:item.component.throwable.platform") + @GameTest(structure = "itematic:item.component.throwable.platform") public void throwingTridentSpawnsTridentAtEyePosition(TestContext context) { ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.TRIDENT); - int minDrawDuration = TestUtil.getItemBehavior(stack, ItemComponentTypes.THROWABLE) + ItemStack trident = world.itematic$createStack(ItemKeys.TRIDENT); + int minDrawDuration = TestUtil.getItemBehavior(context, trident, ItemComponentTypes.THROWABLE) .drawDuration() .flatMap(NumberRange.IntRange::min) - .orElseThrow(() -> new GameTestException("Trident does not have a minimum draw duration")); + .orElseThrow(() -> context.createError(Text.literal("Trident does not have a minimum draw duration"))); PlayerEntity player = TestUtil.createMockPlayer(context, GameMode.SURVIVAL, SPAWN_POSITION); - player.setStackInHand(Hand.MAIN_HAND, stack); + player.setStackInHand(Hand.MAIN_HAND, trident); world.spawnEntity(player); - ActionResult result = stack.use(world, player, Hand.MAIN_HAND); - context.assertTrue(result.isAccepted(), "Expected Trident usage to be successful"); - context.runAtTick(minDrawDuration, () -> context.addFinalTask(() -> { - stack.onStoppedUsing(world, player, player.getItemUseTimeLeft()); - context.expectEntityAt(EntityType.TRIDENT, SPAWN_POSITION.add(0, (int)player.getStandingEyeHeight(), 0)); - })); + context.createTimedTaskRunner() + .createAndAddReported(() -> { + ActionResult result = trident.use(world, player, Hand.MAIN_HAND); + Assert.isTrue( + context, + result.isAccepted(), + () -> "Expected Trident usage to be successful" + ); + }) + .expectMinDurationAndRun(minDrawDuration, () -> { + trident.onStoppedUsing(world, player, player.getItemUseTimeLeft()); + context.expectEntityAt(EntityType.TRIDENT, SPAWN_POSITION.add(0, (int)player.getStandingEyeHeight(), 0)); + }) + .completeIfSuccessful(); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/UseableOnFluidItemComponentTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/UseableOnFluidItemComponentTestSuite.java index 982307a4..3ff68041 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/UseableOnFluidItemComponentTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/UseableOnFluidItemComponentTestSuite.java @@ -1,14 +1,15 @@ package net.errorcraft.itematic.gametest.item.component; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.block.Blocks; import net.minecraft.command.argument.EntityAnchorArgumentType; import net.minecraft.entity.EntityType; 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.ActionResult; import net.minecraft.util.Hand; @@ -27,74 +28,91 @@ public class UseableOnFluidItemComponentTestSuite { private static final BlockPos ABOVE_LOOK_AT_WATER_POSITION_IN_WATER = LOOK_AT_WATER_POSITION_IN_WATER.add(0, 1, 0); private static final BlockPos LOOK_AT_AIR_POSITION_IN_WATER = SPAWN_POSITION_IN_WATER.add(0, 3, 0); - @GameTest(templateName = "itematic:item.component.useable_on_fluid.water_hole") + @GameTest(structure = "itematic:item.component.useable_on_fluid.water_hole") public void usingLilyPadWhileLookingAtWaterPlacesLilyPad(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); TestUtil.setEntityPos(context, player, SPAWN_POSITION_ON_LAND); player.lookAt(EntityAnchorArgumentType.EntityAnchor.EYES, Vec3d.ofBottomCenter(context.getAbsolutePos(LOOK_AT_WATER_POSITION_ON_LAND))); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.LILY_PAD); - player.setStackInHand(Hand.MAIN_HAND, stack); - ActionResult result = stack.use(world, player, Hand.MAIN_HAND); - context.addInstantFinalTask(() -> { - context.assertTrue(result.isAccepted(), "Expected Lily Pad usage to be successful"); - context.expectBlock(Blocks.LILY_PAD, ABOVE_LOOK_AT_WATER_POSITION_ON_LAND); + ItemStack lilyPad = world.itematic$createStack(ItemKeys.LILY_PAD); + player.setStackInHand(Hand.MAIN_HAND, lilyPad); + context.addFinalTask(() -> { + ActionResult result = lilyPad.use(world, player, Hand.MAIN_HAND); + Assert.isTrue( + context, + result.isAccepted(), + () -> "Expected Lily Pad usage to be successful" + ); + Assert.blockState(context, ABOVE_LOOK_AT_WATER_POSITION_ON_LAND) + .is(Blocks.LILY_PAD); }); } - @GameTest(templateName = "itematic:item.component.useable_on_fluid.water_hole") + @GameTest(structure = "itematic:item.component.useable_on_fluid.water_hole") public void usingPigSpawnEggWhileLookingAtWaterSpawnsPigAtWater(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); TestUtil.setEntityPos(context, player, SPAWN_POSITION_ON_LAND); player.lookAt(EntityAnchorArgumentType.EntityAnchor.EYES, Vec3d.ofBottomCenter(context.getAbsolutePos(LOOK_AT_WATER_POSITION_ON_LAND))); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.PIG_SPAWN_EGG); - player.setStackInHand(Hand.MAIN_HAND, stack); - ActionResult result = stack.use(world, player, Hand.MAIN_HAND); - context.addInstantFinalTask(() -> { - context.assertTrue(result.isAccepted(), "Expected Pig Spawn Egg usage to be successful"); + ItemStack pigSpawnEgg = world.itematic$createStack(ItemKeys.PIG_SPAWN_EGG); + player.setStackInHand(Hand.MAIN_HAND, pigSpawnEgg); + context.addFinalTask(() -> { + ActionResult result = pigSpawnEgg.use(world, player, Hand.MAIN_HAND); + Assert.isTrue( + context, + result.isAccepted(), + () -> "Expected Pig Spawn Egg usage to be successful" + ); context.expectEntityAt(EntityType.PIG, LOOK_AT_WATER_POSITION_ON_LAND); }); } - @GameTest(templateName = "itematic:item.component.useable_on_fluid.water_hole") + @GameTest(structure = "itematic:item.component.useable_on_fluid.water_hole") public void usingPigSpawnEggWhileLookingAtAirDoesNotSpawnPig(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); TestUtil.setEntityPos(context, player, SPAWN_POSITION_ON_LAND); player.lookAt(EntityAnchorArgumentType.EntityAnchor.EYES, Vec3d.ofBottomCenter(context.getAbsolutePos(LOOK_AT_AIR_POSITION_ON_LAND))); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.PIG_SPAWN_EGG); - player.setStackInHand(Hand.MAIN_HAND, stack); - ActionResult result = stack.use(world, player, Hand.MAIN_HAND); - context.addInstantFinalTask(() -> { - context.assertFalse(result.isAccepted(), "Expected Pig Spawn Egg usage to be unsuccessful"); + ItemStack pigSpawnEgg = world.itematic$createStack(ItemKeys.PIG_SPAWN_EGG); + player.setStackInHand(Hand.MAIN_HAND, pigSpawnEgg); + context.addFinalTask(() -> { + ActionResult result = pigSpawnEgg.use(world, player, Hand.MAIN_HAND); + Assert.isFalse( + context, + result.isAccepted(), + () -> "Expected Pig Spawn Egg usage to be unsuccessful" + ); context.dontExpectEntity(EntityType.PIG); }); } - @GameTest(templateName = "itematic:item.component.useable_on_fluid.water_hole") + @GameTest(structure = "itematic:item.component.useable_on_fluid.water_hole") public void usingPigSpawnEggWhileLookingAtGroundUnderWaterSpawnsPigOnGroundUnderWater(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); TestUtil.setEntityPos(context, player, SPAWN_POSITION_IN_WATER); player.lookAt(EntityAnchorArgumentType.EntityAnchor.EYES, Vec3d.ofBottomCenter(context.getAbsolutePos(LOOK_AT_WATER_POSITION_IN_WATER))); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.PIG_SPAWN_EGG); - player.setStackInHand(Hand.MAIN_HAND, stack); - TestUtil.useStackOnBlockInside(context, player, stack, ABOVE_LOOK_AT_WATER_POSITION_IN_WATER, Direction.DOWN); - context.addInstantFinalTask(() -> context.expectEntityAt(EntityType.PIG, ABOVE_LOOK_AT_WATER_POSITION_IN_WATER)); + ItemStack pigSpawnEgg = world.itematic$createStack(ItemKeys.PIG_SPAWN_EGG); + player.setStackInHand(Hand.MAIN_HAND, pigSpawnEgg); + TestUtil.useStackOnBlockInside(context, player, pigSpawnEgg, ABOVE_LOOK_AT_WATER_POSITION_IN_WATER, Direction.DOWN); + context.addFinalTask(() -> context.expectEntityAt(EntityType.PIG, ABOVE_LOOK_AT_WATER_POSITION_IN_WATER)); } - @GameTest(templateName = "itematic:item.component.useable_on_fluid.water_hole") + @GameTest(structure = "itematic:item.component.useable_on_fluid.water_hole") public void usingPigSpawnEggWhileLookingAtWaterUnderWaterSpawnsPigAtPlayerEyes(TestContext context) { PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); TestUtil.setEntityPos(context, player, SPAWN_POSITION_IN_WATER); player.lookAt(EntityAnchorArgumentType.EntityAnchor.EYES, Vec3d.ofBottomCenter(context.getAbsolutePos(LOOK_AT_AIR_POSITION_IN_WATER))); ServerWorld world = context.getWorld(); - ItemStack stack = world.itematic$createStack(ItemKeys.PIG_SPAWN_EGG); - player.setStackInHand(Hand.MAIN_HAND, stack); - ActionResult result = stack.use(world, player, Hand.MAIN_HAND); - context.addInstantFinalTask(() -> { - context.assertTrue(result.isAccepted(), "Expected Pig Spawn Egg usage to be successful"); + ItemStack pigSpawnEgg = world.itematic$createStack(ItemKeys.PIG_SPAWN_EGG); + player.setStackInHand(Hand.MAIN_HAND, pigSpawnEgg); + ActionResult result = pigSpawnEgg.use(world, player, Hand.MAIN_HAND); + context.addFinalTask(() -> { + Assert.isTrue( + context, + result.isAccepted(), + () -> "Expected Pig Spawn Egg usage to be successful" + ); BlockPos eyeBlockPos = SPAWN_POSITION_IN_WATER.add(0, (int) player.getStandingEyeHeight(), 0); context.expectEntityAt(EntityType.PIG, eyeBlockPos); }); 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 e1c26436..e6fd467d 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 @@ -1,18 +1,15 @@ package net.errorcraft.itematic.gametest.item.component; -import net.errorcraft.itematic.gametest.Assert; -import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.assertion.Assert; import net.errorcraft.itematic.item.ItemKeys; -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.errorcraft.itematic.util.TestUtil; +import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.entity.EntityType; import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.entity.mob.PiglinEntity; import net.minecraft.entity.mob.ZombieEntity; import net.minecraft.entity.passive.PigEntity; -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; @@ -21,70 +18,83 @@ public class WeaponItemComponentTestSuite { private static final double MAX_HEALTH_VICTIM = 100.0d; - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest public void zombieAttackingUnarmedDealsDamageFromTrueBaseValueAttackDamageAttribute(TestContext context) { ServerWorld world = context.getWorld(); ZombieEntity zombie = TestUtil.createEntity(context, EntityType.ZOMBIE, entity -> {}); world.spawnEntity(zombie); PigEntity victim = spawnVictim(context); context.createTimedTaskRunner().expectMinDurationAndRun(1, () -> { - context.assertTrue(zombie.tryAttack(world, victim), "Expected attack to be successful"); - Assert.areDoublesEqual( - victim.getHealth(), - MAX_HEALTH_VICTIM - zombie.getAttributeBaseValue(EntityAttributes.ATTACK_DAMAGE), - (value, expected) -> "Expected health to be " + expected + ", got " + value + " instead" + Assert.isTrue( + context, + zombie.tryAttack(world, victim), + () -> "Expected attack to be successful" ); + Assert.doubles(context, victim.getHealth(), "health") + .equals(MAX_HEALTH_VICTIM - zombie.itematic$getAttackDamage()); }).completeIfSuccessful(); } - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest 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)); + ZombieEntity zombie = TestUtil.createEntity( + context, + EntityType.ZOMBIE, + entity -> entity.setStackInHand(Hand.MAIN_HAND, world.itematic$createStack(ItemKeys.IRON_SWORD)) + ); world.spawnEntity(zombie); PigEntity victim = spawnVictim(context); context.createTimedTaskRunner().expectMinDurationAndRun(1, () -> { - context.assertTrue(zombie.tryAttack(world, victim), "Expected attack to be successful"); - Assert.areDoublesEqual( - victim.getHealth(), - MAX_HEALTH_VICTIM - zombie.getAttributeBaseValue(EntityAttributes.ATTACK_DAMAGE) - TestUtil.getItemBehavior(stack, ItemComponentTypes.WEAPON).attackDamage().defaultDamage(), - (value, expected) -> "Expected health to be " + expected + ", got " + value + " instead" + Assert.isTrue( + context, + zombie.tryAttack(world, victim), + () -> "Expected attack to be successful" ); + Assert.doubles(context, victim.getHealth(), "health") + .equals(MAX_HEALTH_VICTIM - zombie.itematic$getAttackDamage()); }).completeIfSuccessful(); } - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest 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)); + PiglinEntity piglin = TestUtil.createEntity( + context, + EntityType.PIGLIN, + entity -> world.itematic$createStack(ItemKeys.IRON_SWORD) + ); world.spawnEntity(piglin); PigEntity victim = spawnVictim(context); context.createTimedTaskRunner().expectMinDurationAndRun(1, () -> { - context.assertTrue(piglin.tryAttack(world, victim), "Expected attack to be successful"); - Assert.areDoublesEqual( - victim.getHealth(), - MAX_HEALTH_VICTIM - piglin.getAttributeBaseValue(EntityAttributes.ATTACK_DAMAGE) - TestUtil.getItemBehavior(stack, ItemComponentTypes.WEAPON).attackDamage().defaultDamage(), - (value, expected) -> "Expected health to be " + expected + ", got " + value + " instead" + Assert.isTrue( + context, + piglin.tryAttack(world, victim), + () -> "Expected attack to be successful" ); + Assert.doubles(context, victim.getHealth(), "health") + .equals(MAX_HEALTH_VICTIM - piglin.itematic$getAttackDamage()); }).completeIfSuccessful(); } - @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + @GameTest 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)); + PiglinEntity piglin = TestUtil.createEntity( + context, + EntityType.PIGLIN, + entity -> entity.setStackInHand(Hand.MAIN_HAND, world.itematic$createStack(ItemKeys.GOLDEN_SWORD)) + ); world.spawnEntity(piglin); PigEntity victim = spawnVictim(context); context.createTimedTaskRunner().expectMinDurationAndRun(1, () -> { - context.assertTrue(piglin.tryAttack(world, victim), "Expected attack to be successful"); - Assert.areDoublesEqual( - victim.getHealth(), - MAX_HEALTH_VICTIM - piglin.getAttributeBaseValue(EntityAttributes.ATTACK_DAMAGE) - TestUtil.getItemBehavior(stack, ItemComponentTypes.WEAPON).attackDamage().defaultDamage(), - (value, expected) -> "Expected health to be " + expected + ", got " + value + " instead" + Assert.isTrue( + context, + piglin.tryAttack(world, victim), + () -> "Expected attack to be successful" ); + Assert.doubles(context, victim.getHealth(), "health") + .equals(MAX_HEALTH_VICTIM - piglin.itematic$getAttackDamage()); }).completeIfSuccessful(); } diff --git a/src/gametest/java/net/errorcraft/itematic/mixin/gametest/StructureTestListenerExtender.java b/src/gametest/java/net/errorcraft/itematic/mixin/gametest/StructureTestListenerExtender.java deleted file mode 100644 index 31d4ded9..00000000 --- a/src/gametest/java/net/errorcraft/itematic/mixin/gametest/StructureTestListenerExtender.java +++ /dev/null @@ -1,53 +0,0 @@ -package net.errorcraft.itematic.mixin.gametest; - -import net.errorcraft.itematic.item.ItemKeys; -import net.minecraft.item.ItemConvertible; -import net.minecraft.item.ItemStack; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.test.GameTestState; -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.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(targets = "net.minecraft.test.StructureTestListener") -public class StructureTestListenerExtender { - @Unique - private static ServerWorld world; - - @Inject( - method = "createTestOutputLectern", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/test/StructureTestListener;createBookWithText(Ljava/lang/String;ZLjava/lang/String;)Lnet/minecraft/item/ItemStack;" - ) - ) - private static void storeWorld(GameTestState test, String output, CallbackInfo info) { - world = test.getWorld(); - } - - @Inject( - method = "createTestOutputLectern", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/test/StructureTestListener;createBookWithText(Ljava/lang/String;ZLjava/lang/String;)Lnet/minecraft/item/ItemStack;", - shift = At.Shift.AFTER - ) - ) - private static void resetWorld(GameTestState test, String output, CallbackInfo info) { - world = null; - } - - @Redirect( - method = "createBookWithText", - at = @At( - value = "NEW", - target = "(Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/item/ItemStack;" - ) - ) - private static ItemStack newItemStackForWritableBookUseCreateStack(ItemConvertible item) { - return world.itematic$createStack(ItemKeys.WRITABLE_BOOK); - } -} diff --git a/src/gametest/java/net/errorcraft/itematic/mixin/gametest/TestContextExtender.java b/src/gametest/java/net/errorcraft/itematic/mixin/gametest/TestContextExtender.java index bd4b8bc2..ad498e73 100644 --- a/src/gametest/java/net/errorcraft/itematic/mixin/gametest/TestContextExtender.java +++ b/src/gametest/java/net/errorcraft/itematic/mixin/gametest/TestContextExtender.java @@ -2,21 +2,37 @@ import com.llamalad7.mixinextras.injector.ModifyReturnValue; import net.errorcraft.itematic.access.gametest.GameTestStateAccess; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.test.GameTestState; import net.minecraft.test.TestContext; import net.minecraft.text.Text; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.GameMode; 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; @Mixin(TestContext.class) -public class TestContextExtender { +public abstract class TestContextExtender { @Shadow @Final private GameTestState test; + @Shadow + public abstract Vec3d getAbsolute(Vec3d pos); + + @ModifyReturnValue( + method = "createMockPlayer", + at = @At("TAIL") + ) + private PlayerEntity setPlayerData(PlayerEntity original, GameMode gameMode) { + original.setPosition(this.getAbsolute(Vec3d.ZERO)); + gameMode.setAbilities(original.getAbilities()); + return original; + } + @ModifyReturnValue( method = "createMockCreativeServerPlayerInWorld", at = @At("TAIL") diff --git a/src/gametest/java/net/errorcraft/itematic/mixin/gametest/structure/StructureTemplateManagerExtender.java b/src/gametest/java/net/errorcraft/itematic/mixin/gametest/structure/StructureTemplateManagerExtender.java new file mode 100644 index 00000000..c936ae8c --- /dev/null +++ b/src/gametest/java/net/errorcraft/itematic/mixin/gametest/structure/StructureTemplateManagerExtender.java @@ -0,0 +1,45 @@ +package net.errorcraft.itematic.mixin.gametest.structure; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import net.minecraft.structure.StructureTemplateManager; +import org.objectweb.asm.Opcodes; +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.Constant; +import org.spongepowered.asm.mixin.injection.ModifyConstant; + +import java.nio.file.Path; +import java.nio.file.Paths; + +@Mixin(StructureTemplateManager.class) +public class StructureTemplateManagerExtender { + @Unique + private static final String STRUCTURE_OUTPUT_DIRECTORY = System.getProperty("itematic.gametest.structure-output-directory"); + + @ModifyExpressionValue( + method = "getTemplatePath", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/structure/StructureTemplateManager;generatedPath:Ljava/nio/file/Path;", + opcode = Opcodes.GETFIELD + ) + ) + private Path useCustomStructureOutputDirectory(Path original) { + if (STRUCTURE_OUTPUT_DIRECTORY != null) { + return Paths.get(STRUCTURE_OUTPUT_DIRECTORY); + } + + return original; + } + + @ModifyConstant( + method = "getTemplatePath", + constant = @Constant( + stringValue = "structures" + ) + ) + private String useSingularNameForStructureOutputDirectory(String constant) { + return "structure"; + } +} diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/TestUtil.java b/src/gametest/java/net/errorcraft/itematic/util/TestUtil.java similarity index 73% rename from src/gametest/java/net/errorcraft/itematic/gametest/TestUtil.java rename to src/gametest/java/net/errorcraft/itematic/util/TestUtil.java index 5edd8093..828a1fa8 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/TestUtil.java +++ b/src/gametest/java/net/errorcraft/itematic/util/TestUtil.java @@ -1,4 +1,4 @@ -package net.errorcraft.itematic.gametest; +package net.errorcraft.itematic.util; import net.errorcraft.itematic.item.component.ItemComponent; import net.errorcraft.itematic.item.component.ItemComponentType; @@ -22,9 +22,8 @@ import net.minecraft.screen.ScreenHandler; import net.minecraft.screen.ScreenHandlerType; import net.minecraft.server.world.ServerWorld; -import net.minecraft.test.GameTestException; -import net.minecraft.test.PositionedException; import net.minecraft.test.TestContext; +import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; @@ -32,6 +31,7 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.GameMode; +import java.util.Optional; import java.util.function.Consumer; public class TestUtil { @@ -56,23 +56,34 @@ public static ItemStack createItemStackWithEnchantment(ServerWorld world, Regist return stack; } - public static > T getItemBehavior(ItemStack stack, ItemComponentType type) { + public static > T getItemBehavior(TestContext helper, ItemStack stack, ItemComponentType type) { return stack.itematic$getBehavior(type) - .orElseThrow(() -> new GameTestException("Item " + stack.itematic$key() + " does not have the " + ItematicRegistries.ITEM_COMPONENT_TYPE.getKey(type).orElseThrow() + " behavior")); + .orElseThrow(() -> helper.createError( + "test.error.item.expected_item_behavior", + ItematicRegistries.ITEM_COMPONENT_TYPE.getId(type) + )); } - public static T getDataComponent(ItemStack stack, ComponentType type) { + public static T getDataComponent(TestContext helper, ItemStack stack, ComponentType type) { T component = stack.get(type); - if (component == null) { - throw new GameTestException("Item stack does not contain the " + type + " data component"); + if (component != null) { + return component; } - return component; + throw helper.createError( + "test.error.item_stack.expected_data_component", + "item stack", + type + ); } public static T getBlockEntity(TestContext context, BlockPos pos, BlockEntityType type) { return context.getWorld().getBlockEntity(context.getAbsolutePos(pos), type) - .orElseThrow(() -> new GameTestException("Block entity at position " + pos + " was not of type " + Registries.BLOCK_ENTITY_TYPE.getKey(type).orElseThrow())); + .orElseThrow(() -> context.createError( + pos, + "test.error.block_entity.expected_block_entity_type", + Registries.BLOCK_ENTITY_TYPE.getId(type) + )); } public static PlayerEntity createMockPlayer(TestContext context, GameMode gameMode, BlockPos pos) { @@ -88,7 +99,10 @@ public static T createEntity(TestContext context, EntityType< public static T createEntityAt(TestContext context, EntityType type, BlockPos pos, Consumer initializer) { T entity = type.create(context.getWorld(), SpawnReason.COMMAND); if (entity == null) { - throw new GameTestException("Entity is null"); + throw context.createError( + "test.error.entity_type.cannot_create_entity", + type.getName() + ); } setEntityPos(context, entity, pos); @@ -111,10 +125,15 @@ public static void setEntityPos(TestContext context, Entity entity, BlockPos pos entity.setPosition(Vec3d.ofBottomCenter(absolutePos)); } - public static void useStackOnBlockInside(TestContext context, PlayerEntity player, ItemStack stack, BlockPos pos, Direction direction) { + public static Optional useStackOnBlockInside(TestContext context, PlayerEntity player, ItemStack stack, BlockPos pos, Direction direction) { BlockPos absolutePos = context.getAbsolutePos(pos); BlockHitResult hitResult = new BlockHitResult(Vec3d.ofCenter(absolutePos), direction, absolutePos, true); - stack.useOnBlock(new ItemUsageContext(player, Hand.MAIN_HAND, hitResult)); + ActionResult result = stack.useOnBlock(new ItemUsageContext(player, Hand.MAIN_HAND, hitResult)); + if (result instanceof ActionResult.Success success) { + return Optional.ofNullable(success.getNewHandStack()); + } + + return Optional.empty(); } public static void useBlock(TestContext context, BlockPos pos, PlayerEntity player, Direction direction) { @@ -127,12 +146,12 @@ public static T getMenuFromBlock(TestContext context, BlockPos absolutePos = context.getAbsolutePos(pos); NamedScreenHandlerFactory factory = context.getBlockState(pos).createScreenHandlerFactory(context.getWorld(), absolutePos); if (factory == null) { - throw new PositionedException("Block does not provide a menu", absolutePos, pos, context.getTick()); + throw context.createError(pos, "test.error.menu.does_not_provide_menu"); } ScreenHandler menu = factory.createMenu(-1, player.getInventory(), player); if (menu == null) { - throw new PositionedException("Block does not create a menu", absolutePos, pos, context.getTick()); + throw context.createError(pos, "test.error.menu.does_not_create_menu"); } try { @@ -141,14 +160,14 @@ public static T getMenuFromBlock(TestContext context, return (T) menu; } - throw new PositionedException( - "Block has the incorrect menu type " + Registries.SCREEN_HANDLER.getId(actualType) + ", expected " + Registries.SCREEN_HANDLER.getId(type), - absolutePos, + throw context.createError( pos, - context.getTick() + "test.error.menu.has_incorrect_menu_type", + Registries.SCREEN_HANDLER.getId(actualType), + Registries.SCREEN_HANDLER.getId(type) ); } catch (UnsupportedOperationException ignored) { - throw new PositionedException("Block does not create a menu by type", absolutePos, pos, context.getTick()); + throw context.createError(pos, "test.error.menu.does_not_create_menu_by_type"); } } } diff --git a/src/gametest/resources/assets/itematic/lang/en_us.json b/src/gametest/resources/assets/itematic/lang/en_us.json new file mode 100644 index 00000000..72c9d294 --- /dev/null +++ b/src/gametest/resources/assets/itematic/lang/en_us.json @@ -0,0 +1,27 @@ +{ + "test.error.expected_not_null": "Expected %s to exist", + "test.error.expected_value_greater_than": "Expected %s to be greater than %s, got %s instead", + "test.error.expected_type": "Expected %s to be %s, got %s instead", + "test.error.did_not_expect_type": "Expected %s not to be %s", + "test.error.expected_tag": "Expected %s to be #%s", + "test.error.block_entity.expected_block_entity_type": "Expected block entity type to be %s", + "test.error.entity.expected_effect": "Expected entity %s to have effect %s", + "test.error.entity.did_not_expect_effect": "Expected entity %s not to have effect %s", + "test.error.entity_type.cannot_create_entity": "Cannot create entity with type %s", + "test.error.item.expected_item_behavior": "Expected item to have the %s behavior", + "test.error.item_stack.expected_damaged": "Expected %s to be damaged", + "test.error.item_stack.expected_not_damaged": "Expected %s not to be damaged", + "test.error.item_stack.expected_potion": "Expected %s to have potion %s", + "test.error.item_stack.expected_other_potion": "Expected %s to have potion %s, got %s instead", + "test.error.item_stack.expected_data_component": "Expected %s to have the %s data component", + "test.error.item_stack.did_not_expect_data_component": "Expected %s not to have the %s data component", + "test.error.item_stack.expected_empty": "Expected %s to be empty, got %s instead", + "test.error.item_stack.expected_not_empty": "Expected %s not to be empty", + "test.error.item_stack.expected_enchantments": "Expected %s to have enchantments", + "test.error.item_stack.expected_no_enchantments": "Expected %s not to have enchantments", + "test.error.item_stack.expected_specified_enchantments": "Expected %s to have enchantments: %s", + "test.error.menu.does_not_provide_menu": "Block does not provide a menu", + "test.error.menu.does_not_create_menu": "Block does not create a menu", + "test.error.menu.has_incorrect_menu_type": "Block has the incorrect menu type %s, expected %s", + "test.error.menu.does_not_create_menu_by_type": "Block does not create a menu by type" +} diff --git a/src/gametest/resources/data/itematic/gametest/structure/block.pale_oak_wall_hanging_sign.snbt b/src/gametest/resources/data/itematic/gametest/structure/block.pale_oak_wall_hanging_sign.snbt new file mode 100644 index 00000000..5215a32b --- /dev/null +++ b/src/gametest/resources/data/itematic/gametest/structure/block.pale_oak_wall_hanging_sign.snbt @@ -0,0 +1,39 @@ +{ + DataVersion: 4174, + 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:bedrock"}, + {pos: [0, 1, 2], state: "minecraft:air"}, + {pos: [1, 1, 0], state: "minecraft:air"}, + {pos: [1, 1, 1], state: "minecraft:pale_oak_wall_hanging_sign{facing:north,waterlogged:false}", nbt: {back_text: {color: "black", has_glowing_text: 0b, messages: ['""', '""', '""', '""']}, front_text: {color: "black", has_glowing_text: 0b, messages: ['""', '""', '""', '""']}, id: "minecraft:hanging_sign", is_waxed: 0b}}, + {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:pale_oak_wall_hanging_sign{facing:north,waterlogged:false}" + ] +} diff --git a/src/gametest/resources/data/itematic/gametest/structure/block.pale_oak_wall_sign.snbt b/src/gametest/resources/data/itematic/gametest/structure/block.pale_oak_wall_sign.snbt new file mode 100644 index 00000000..2ee80c11 --- /dev/null +++ b/src/gametest/resources/data/itematic/gametest/structure/block.pale_oak_wall_sign.snbt @@ -0,0 +1,39 @@ +{ + DataVersion: 4174, + 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:pale_oak_wall_sign{facing:north,waterlogged:false}", nbt: {back_text: {color: "black", has_glowing_text: 0b, messages: ['""', '""', '""', '""']}, front_text: {color: "black", has_glowing_text: 0b, messages: ['""', '""', '""', '""']}, id: "minecraft:sign", is_waxed: 0b}}, + {pos: [1, 1, 2], state: "minecraft:bedrock"}, + {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:pale_oak_wall_sign{facing:north,waterlogged:false}" + ] +} diff --git a/src/gametest/resources/data/itematic/gametest/structure/item.brush.platform.suspicious_sand.snbt b/src/gametest/resources/data/itematic/gametest/structure/block.potted_closed_eyeblossom.snbt similarity index 89% rename from src/gametest/resources/data/itematic/gametest/structure/item.brush.platform.suspicious_sand.snbt rename to src/gametest/resources/data/itematic/gametest/structure/block.potted_closed_eyeblossom.snbt index 1db6483e..9857f93b 100644 --- a/src/gametest/resources/data/itematic/gametest/structure/item.brush.platform.suspicious_sand.snbt +++ b/src/gametest/resources/data/itematic/gametest/structure/block.potted_closed_eyeblossom.snbt @@ -1,5 +1,5 @@ { - DataVersion: 3839, + DataVersion: 4174, size: [3, 3, 3], data: [ {pos: [0, 0, 0], state: "minecraft:bedrock"}, @@ -15,7 +15,7 @@ {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:suspicious_sand{dusted:0}", nbt: {id: "minecraft:brushable_block"}}, + {pos: [1, 1, 1], state: "minecraft:potted_closed_eyeblossom"}, {pos: [1, 1, 2], state: "minecraft:air"}, {pos: [2, 1, 0], state: "minecraft:air"}, {pos: [2, 1, 1], state: "minecraft:air"}, @@ -34,6 +34,6 @@ palette: [ "minecraft:bedrock", "minecraft:air", - "minecraft:suspicious_sand{dusted:0}" + "minecraft:potted_closed_eyeblossom" ] } diff --git a/src/gametest/resources/data/itematic/gametest/structure/item.brush.platform.short_grass.snbt b/src/gametest/resources/data/itematic/gametest/structure/block.potted_open_eyeblossom.snbt similarity index 86% rename from src/gametest/resources/data/itematic/gametest/structure/item.brush.platform.short_grass.snbt rename to src/gametest/resources/data/itematic/gametest/structure/block.potted_open_eyeblossom.snbt index a41a4449..f03bfa2c 100644 --- a/src/gametest/resources/data/itematic/gametest/structure/item.brush.platform.short_grass.snbt +++ b/src/gametest/resources/data/itematic/gametest/structure/block.potted_open_eyeblossom.snbt @@ -1,12 +1,12 @@ { - DataVersion: 3839, + DataVersion: 4174, 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:grass_block{snowy:false}"}, + {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"}, @@ -15,7 +15,7 @@ {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:short_grass"}, + {pos: [1, 1, 1], state: "minecraft:potted_open_eyeblossom"}, {pos: [1, 1, 2], state: "minecraft:air"}, {pos: [2, 1, 0], state: "minecraft:air"}, {pos: [2, 1, 1], state: "minecraft:air"}, @@ -33,8 +33,7 @@ entities: [], palette: [ "minecraft:bedrock", - "minecraft:grass_block{snowy:false}", "minecraft:air", - "minecraft:short_grass" + "minecraft:potted_open_eyeblossom" ] } diff --git a/src/gametest/resources/data/itematic/gametest/structure/item.compass.platform.lodestone.snbt b/src/gametest/resources/data/itematic/gametest/structure/item.compass.platform.lodestone.snbt new file mode 100644 index 00000000..553e4f57 --- /dev/null +++ b/src/gametest/resources/data/itematic/gametest/structure/item.compass.platform.lodestone.snbt @@ -0,0 +1,39 @@ +{ + DataVersion: 4179, + 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:lodestone"}, + {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:lodestone", + "minecraft:air" + ] +} diff --git a/src/gametest/resources/data/itematic/gametest/structure/item.component.bucket.platform.powder_snow.snbt b/src/gametest/resources/data/itematic/gametest/structure/item.component.bucket.platform.powder_snow.snbt index 2c044c60..8cf932c7 100644 --- a/src/gametest/resources/data/itematic/gametest/structure/item.component.bucket.platform.powder_snow.snbt +++ b/src/gametest/resources/data/itematic/gametest/structure/item.component.bucket.platform.powder_snow.snbt @@ -1,6 +1,6 @@ { - DataVersion: 3826, - size: [3, 3, 3], + DataVersion: 4189, + size: [3, 4, 3], data: [ {pos: [0, 0, 0], state: "minecraft:bedrock"}, {pos: [0, 0, 1], state: "minecraft:bedrock"}, @@ -28,7 +28,16 @@ {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"} + {pos: [2, 2, 2], state: "minecraft:air"}, + {pos: [0, 3, 0], state: "minecraft:air"}, + {pos: [0, 3, 1], state: "minecraft:air"}, + {pos: [0, 3, 2], state: "minecraft:air"}, + {pos: [1, 3, 0], state: "minecraft:air"}, + {pos: [1, 3, 1], state: "minecraft:air"}, + {pos: [1, 3, 2], state: "minecraft:air"}, + {pos: [2, 3, 0], state: "minecraft:air"}, + {pos: [2, 3, 1], state: "minecraft:air"}, + {pos: [2, 3, 2], state: "minecraft:air"} ], entities: [], palette: [ diff --git a/src/gametest/resources/data/itematic/gametest/structure/item.component.bucket.platform.snbt b/src/gametest/resources/data/itematic/gametest/structure/item.component.bucket.platform.snbt index 7a943bf7..8482c05e 100644 --- a/src/gametest/resources/data/itematic/gametest/structure/item.component.bucket.platform.snbt +++ b/src/gametest/resources/data/itematic/gametest/structure/item.component.bucket.platform.snbt @@ -1,6 +1,6 @@ { - DataVersion: 3826, - size: [3, 3, 3], + DataVersion: 4189, + size: [3, 4, 3], data: [ {pos: [0, 0, 0], state: "minecraft:bedrock"}, {pos: [0, 0, 1], state: "minecraft:bedrock"}, @@ -11,15 +11,15 @@ {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: [0, 1, 0], state: "minecraft:bedrock"}, + {pos: [0, 1, 1], state: "minecraft:bedrock"}, + {pos: [0, 1, 2], state: "minecraft:bedrock"}, + {pos: [1, 1, 0], state: "minecraft:bedrock"}, {pos: [1, 1, 1], state: "minecraft:air"}, - {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: [1, 1, 2], state: "minecraft:bedrock"}, + {pos: [2, 1, 0], state: "minecraft:bedrock"}, + {pos: [2, 1, 1], state: "minecraft:bedrock"}, + {pos: [2, 1, 2], state: "minecraft:bedrock"}, {pos: [0, 2, 0], state: "minecraft:air"}, {pos: [0, 2, 1], state: "minecraft:air"}, {pos: [0, 2, 2], state: "minecraft:air"}, @@ -28,7 +28,16 @@ {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"} + {pos: [2, 2, 2], state: "minecraft:air"}, + {pos: [0, 3, 0], state: "minecraft:air"}, + {pos: [0, 3, 1], state: "minecraft:air"}, + {pos: [0, 3, 2], state: "minecraft:air"}, + {pos: [1, 3, 0], state: "minecraft:air"}, + {pos: [1, 3, 1], state: "minecraft:air"}, + {pos: [1, 3, 2], state: "minecraft:air"}, + {pos: [2, 3, 0], state: "minecraft:air"}, + {pos: [2, 3, 1], state: "minecraft:air"}, + {pos: [2, 3, 2], state: "minecraft:air"} ], entities: [], palette: [ diff --git a/src/gametest/resources/data/itematic/gametest/structure/item.component.bucket.platform.water.snbt b/src/gametest/resources/data/itematic/gametest/structure/item.component.bucket.platform.water.snbt index 67916f27..42fa6933 100644 --- a/src/gametest/resources/data/itematic/gametest/structure/item.component.bucket.platform.water.snbt +++ b/src/gametest/resources/data/itematic/gametest/structure/item.component.bucket.platform.water.snbt @@ -1,6 +1,6 @@ { - DataVersion: 3826, - size: [3, 3, 3], + DataVersion: 4189, + size: [3, 4, 3], data: [ {pos: [0, 0, 0], state: "minecraft:bedrock"}, {pos: [0, 0, 1], state: "minecraft:bedrock"}, @@ -28,7 +28,16 @@ {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"} + {pos: [2, 2, 2], state: "minecraft:air"}, + {pos: [0, 3, 0], state: "minecraft:air"}, + {pos: [0, 3, 1], state: "minecraft:air"}, + {pos: [0, 3, 2], state: "minecraft:air"}, + {pos: [1, 3, 0], state: "minecraft:air"}, + {pos: [1, 3, 1], state: "minecraft:air"}, + {pos: [1, 3, 2], state: "minecraft:air"}, + {pos: [2, 3, 0], state: "minecraft:air"}, + {pos: [2, 3, 1], state: "minecraft:air"}, + {pos: [2, 3, 2], state: "minecraft:air"} ], entities: [], palette: [ diff --git a/src/gametest/resources/data/itematic/gametest/structure/item.brush.platform.snbt b/src/gametest/resources/data/itematic/gametest/structure/item.component.entity.platform.snbt similarity index 98% rename from src/gametest/resources/data/itematic/gametest/structure/item.brush.platform.snbt rename to src/gametest/resources/data/itematic/gametest/structure/item.component.entity.platform.snbt index 5693ba04..0dd4600e 100644 --- a/src/gametest/resources/data/itematic/gametest/structure/item.brush.platform.snbt +++ b/src/gametest/resources/data/itematic/gametest/structure/item.component.entity.platform.snbt @@ -1,5 +1,5 @@ { - DataVersion: 3839, + DataVersion: 4189, size: [3, 3, 3], data: [ {pos: [0, 0, 0], state: "minecraft:bedrock"}, diff --git a/src/gametest/resources/data/itematic/structure/item.brush.platform.nbt b/src/gametest/resources/data/itematic/structure/item.brush.platform.nbt new file mode 100644 index 00000000..47ef87c2 Binary files /dev/null and b/src/gametest/resources/data/itematic/structure/item.brush.platform.nbt differ diff --git a/src/gametest/resources/data/itematic/structure/item.brush.platform.short_grass.nbt b/src/gametest/resources/data/itematic/structure/item.brush.platform.short_grass.nbt new file mode 100644 index 00000000..09b27d21 Binary files /dev/null and b/src/gametest/resources/data/itematic/structure/item.brush.platform.short_grass.nbt differ diff --git a/src/gametest/resources/data/itematic/structure/item.brush.platform.suspicious_sand.nbt b/src/gametest/resources/data/itematic/structure/item.brush.platform.suspicious_sand.nbt new file mode 100644 index 00000000..fe705978 Binary files /dev/null and b/src/gametest/resources/data/itematic/structure/item.brush.platform.suspicious_sand.nbt differ diff --git a/src/gametest/resources/fabric.mod.json b/src/gametest/resources/fabric.mod.json index 22c20bef..efb40780 100644 --- a/src/gametest/resources/fabric.mod.json +++ b/src/gametest/resources/fabric.mod.json @@ -32,6 +32,7 @@ "net.errorcraft.itematic.gametest.item.BowTestSuite", "net.errorcraft.itematic.gametest.item.BrushTestSuite", "net.errorcraft.itematic.gametest.item.BundleTestSuite", + "net.errorcraft.itematic.gametest.item.CompassTestSuite", "net.errorcraft.itematic.gametest.item.CrossbowTestSuite", "net.errorcraft.itematic.gametest.item.FishingRodTestSuite", "net.errorcraft.itematic.gametest.item.FlowerPotItemTestSuite", @@ -40,7 +41,9 @@ "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.BucketItemComponentTestSuite", "net.errorcraft.itematic.gametest.item.component.ConsumableItemComponentTestSuite", + "net.errorcraft.itematic.gametest.item.component.EntityItemComponentTestSuite", "net.errorcraft.itematic.gametest.item.component.EquipmentItemComponentTestSuite", "net.errorcraft.itematic.gametest.item.component.FoodItemComponentTestSuite", "net.errorcraft.itematic.gametest.item.component.ImmuneToDamageItemComponentTestSuite", diff --git a/src/gametest/resources/itematic-gametest.mixins.json b/src/gametest/resources/itematic-gametest.mixins.json index 23487eb3..046215aa 100644 --- a/src/gametest/resources/itematic-gametest.mixins.json +++ b/src/gametest/resources/itematic-gametest.mixins.json @@ -8,9 +8,9 @@ }, "mixins": [ "GameTestStateExtender", - "StructureTestListenerExtender", "TestContextExtender", - "TestServerExtender" + "TestServerExtender", + "structure.StructureTemplateManagerExtender" ], "injectors": { "defaultRequire": 1 diff --git a/src/main/generated/data/minecraft/action/extinguish_campfire.json b/src/main/generated/data/minecraft/action/extinguish_campfire.json index 486b1f74..c75316ef 100644 --- a/src/main/generated/data/minecraft/action/extinguish_campfire.json +++ b/src/main/generated/data/minecraft/action/extinguish_campfire.json @@ -6,7 +6,7 @@ { "action": { "type": "minecraft:modify_block_state", - "position": "target", + "position": "interacted", "properties": { "lit": "false" } @@ -20,7 +20,7 @@ "max": 3.4, "min": 1.8 }, - "position": "target", + "position": "interacted", "sound": "minecraft:block.fire.extinguish", "volume": 0.5 } @@ -59,7 +59,7 @@ "particle": { "type": "minecraft:campfire_signal_smoke" }, - "position": "target", + "position": "interacted", "speed": 0.0 } }, @@ -86,25 +86,20 @@ "particle": { "type": "minecraft:campfire_signal_smoke" }, - "position": "target", + "position": "interacted", "speed": 0.0 } } ], "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "state": { - "signal_fire": "true" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "state": { + "signal_fire": "true" } } - }, - "context": { - "entity": "this", - "position": "target" } } }, @@ -137,7 +132,7 @@ "particle": { "type": "minecraft:campfire_cosy_smoke" }, - "position": "target", + "position": "interacted", "speed": 0.0 } }, @@ -164,7 +159,7 @@ "particle": { "type": "minecraft:campfire_cosy_smoke" }, - "position": "target", + "position": "interacted", "speed": 0.0 } } @@ -176,20 +171,15 @@ ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "#minecraft:campfires", - "state": { - "lit": "true" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "#minecraft:campfires", + "state": { + "lit": "true" } } - }, - "context": { - "entity": "this", - "position": "target" } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/action/flatten_ground.json b/src/main/generated/data/minecraft/action/flatten_ground.json index a93c9c1d..af124173 100644 --- a/src/main/generated/data/minecraft/action/flatten_ground.json +++ b/src/main/generated/data/minecraft/action/flatten_ground.json @@ -6,7 +6,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:dirt_path" } @@ -17,7 +17,7 @@ "type": "minecraft:play_sound", "category": "block", "pitch": 1.0, - "position": "target", + "position": "interacted", "sound": "minecraft:item.shovel.flatten", "volume": 1.0 } @@ -25,40 +25,36 @@ ] }, "requirements": { - "conditions": { - "condition": "minecraft:all_of", - "terms": [ - { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "#minecraft:flattenable_into_dirt_path" - } - } - }, - { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:side_check", - "sides": [ - "down" - ] + "condition": "minecraft:all_of", + "terms": [ + { + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "#minecraft:flattenable_into_dirt_path" } - }, - { - "condition": "minecraft:location_check", - "offsetY": 1, - "predicate": { - "block": { - "blocks": "#minecraft:air" - } + } + }, + { + "condition": "minecraft:inverted", + "term": { + "condition": "minecraft:side_check", + "sides": [ + "down" + ] + } + }, + { + "condition": "minecraft:location_check", + "offsetY": 1, + "position": "interacted", + "predicate": { + "block": { + "blocks": "#minecraft:air" } } - ] - }, - "context": { - "entity": "this", - "position": "target" - } + } + ] } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/action/light_block.json b/src/main/generated/data/minecraft/action/light_block.json index 317ea6fe..2bb2d3d1 100644 --- a/src/main/generated/data/minecraft/action/light_block.json +++ b/src/main/generated/data/minecraft/action/light_block.json @@ -11,63 +11,72 @@ { "action": { "type": "minecraft:modify_block_state", - "position": "target", + "position": "interacted", "properties": { "lit": "true" } }, "requirements": { - "conditions": { - "condition": "minecraft:all_of", - "terms": [ - { + "condition": "minecraft:all_of", + "terms": [ + { + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "state": { + "lit": "false" + } + } + } + }, + { + "condition": "minecraft:inverted", + "term": { "condition": "minecraft:location_check", + "position": "interacted", "predicate": { "block": { "state": { - "lit": "false" - } - } - } - }, - { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "state": { - "waterlogged": "true" - } + "waterlogged": "true" } } } } - ] - }, - "context": { - "entity": "this", - "position": "target" - } + } + ] } }, { "action": { - "type": "minecraft:prime_tnt", - "position": "target" + "type": "minecraft:sequence", + "handler": "minecraft:passing", + "entries": [ + { + "action": { + "type": "minecraft:prime_tnt", + "position": "interacted" + } + }, + { + "action": { + "type": "minecraft:play_sound", + "category": "block", + "pitch": 1.0, + "position": "interacted", + "sound": "minecraft:entity.tnt.primed", + "volume": 1.0 + } + } + ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:tnt" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:tnt" } - }, - "context": { - "entity": "this", - "position": "target" } } }, @@ -76,7 +85,7 @@ "type": "minecraft:place_block", "block": "minecraft:fire", "decrement_count": false, - "position": "target" + "position": "interacted" } } ] @@ -85,7 +94,8 @@ { "entry": { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } }, "optional": true diff --git a/src/main/generated/data/minecraft/action/till_coarse_dirt.json b/src/main/generated/data/minecraft/action/till_coarse_dirt.json index b1af28f5..2ceb80c0 100644 --- a/src/main/generated/data/minecraft/action/till_coarse_dirt.json +++ b/src/main/generated/data/minecraft/action/till_coarse_dirt.json @@ -1,46 +1,42 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:dirt" } }, "requirements": { - "conditions": { - "condition": "minecraft:all_of", - "terms": [ - { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:coarse_dirt" - } + "condition": "minecraft:all_of", + "terms": [ + { + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:coarse_dirt" } - }, - { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:side_check", - "sides": [ - "down" - ] - } - }, - { - "condition": "minecraft:location_check", - "offsetY": 1, - "predicate": { - "block": { - "blocks": "#minecraft:air" - } + } + }, + { + "condition": "minecraft:inverted", + "term": { + "condition": "minecraft:side_check", + "sides": [ + "down" + ] + } + }, + { + "condition": "minecraft:location_check", + "offsetY": 1, + "position": "interacted", + "predicate": { + "block": { + "blocks": "#minecraft:air" } } - ] - }, - "context": { - "entity": "this", - "position": "target" - } + } + ] } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/action/till_dirt.json b/src/main/generated/data/minecraft/action/till_dirt.json index a73ab69c..aa0fe1c3 100644 --- a/src/main/generated/data/minecraft/action/till_dirt.json +++ b/src/main/generated/data/minecraft/action/till_dirt.json @@ -1,7 +1,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:farmland", "Properties": { @@ -10,40 +10,36 @@ } }, "requirements": { - "conditions": { - "condition": "minecraft:all_of", - "terms": [ - { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "#minecraft:tillable_into_farmland" - } + "condition": "minecraft:all_of", + "terms": [ + { + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "#minecraft:tillable_into_farmland" } - }, - { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:side_check", - "sides": [ - "down" - ] - } - }, - { - "condition": "minecraft:location_check", - "offsetY": 1, - "predicate": { - "block": { - "blocks": "#minecraft:air" - } + } + }, + { + "condition": "minecraft:inverted", + "term": { + "condition": "minecraft:side_check", + "sides": [ + "down" + ] + } + }, + { + "condition": "minecraft:location_check", + "offsetY": 1, + "position": "interacted", + "predicate": { + "block": { + "blocks": "#minecraft:air" } } - ] - }, - "context": { - "entity": "this", - "position": "target" - } + } + ] } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/action/till_rooted_dirt.json b/src/main/generated/data/minecraft/action/till_rooted_dirt.json index 7a25626e..257d6e50 100644 --- a/src/main/generated/data/minecraft/action/till_rooted_dirt.json +++ b/src/main/generated/data/minecraft/action/till_rooted_dirt.json @@ -6,7 +6,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:dirt" } @@ -15,24 +15,22 @@ { "action": { "type": "minecraft:drop_item_from_block", - "item": "minecraft:hanging_roots", - "position": "target" + "item": { + "id": "minecraft:hanging_roots", + "count": 1 + }, + "position": "interacted" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:rooted_dirt" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:rooted_dirt" } - }, - "context": { - "entity": "this", - "position": "target" } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/action/use_hoe_on_block.json b/src/main/generated/data/minecraft/action/use_hoe_on_block.json index ede067a1..51147ccc 100644 --- a/src/main/generated/data/minecraft/action/use_hoe_on_block.json +++ b/src/main/generated/data/minecraft/action/use_hoe_on_block.json @@ -18,7 +18,8 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } }, { @@ -26,7 +27,7 @@ "type": "minecraft:play_sound", "category": "block", "pitch": 1.0, - "position": "target", + "position": "interacted", "sound": "minecraft:item.hoe.till", "volume": 1.0 } diff --git a/src/main/generated/data/minecraft/action/use_shovel_on_block.json b/src/main/generated/data/minecraft/action/use_shovel_on_block.json index 32857484..691bcea9 100644 --- a/src/main/generated/data/minecraft/action/use_shovel_on_block.json +++ b/src/main/generated/data/minecraft/action/use_shovel_on_block.json @@ -18,24 +18,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:side_check", - "sides": [ - "down" - ] - } - }, - "context": { - "entity": "this", - "position": "target" + "condition": "minecraft:inverted", + "term": { + "condition": "minecraft:side_check", + "sides": [ + "down" + ] } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/dispense_behavior/brush.json b/src/main/generated/data/minecraft/dispense_behavior/brush.json index 3de32136..d724c6d9 100644 --- a/src/main/generated/data/minecraft/dispense_behavior/brush.json +++ b/src/main/generated/data/minecraft/dispense_behavior/brush.json @@ -8,7 +8,7 @@ { "action": { "type": "minecraft:brush_armadillo_at_position", - "position": "target" + "position": "interacted" } }, { diff --git a/src/main/generated/data/minecraft/dispense_behavior/charge_respawn_anchor.json b/src/main/generated/data/minecraft/dispense_behavior/charge_respawn_anchor.json index e3b85291..f303a32b 100644 --- a/src/main/generated/data/minecraft/dispense_behavior/charge_respawn_anchor.json +++ b/src/main/generated/data/minecraft/dispense_behavior/charge_respawn_anchor.json @@ -8,7 +8,7 @@ { "action": { "type": "minecraft:charge_respawn_anchor", - "position": "target" + "position": "interacted" } }, { @@ -20,17 +20,12 @@ ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:respawn_anchor" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:respawn_anchor" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/dispense_behavior/equip_chest.json b/src/main/generated/data/minecraft/dispense_behavior/equip_chest.json index e87e17c3..b319c414 100644 --- a/src/main/generated/data/minecraft/dispense_behavior/equip_chest.json +++ b/src/main/generated/data/minecraft/dispense_behavior/equip_chest.json @@ -7,7 +7,7 @@ { "action": { "type": "minecraft:equip_horse_with_chest_at_position", - "position": "target" + "position": "interacted" } }, { diff --git a/src/main/generated/data/minecraft/dispense_behavior/equip_entity.json b/src/main/generated/data/minecraft/dispense_behavior/equip_entity.json index d02ab4c5..6f2487e7 100644 --- a/src/main/generated/data/minecraft/dispense_behavior/equip_entity.json +++ b/src/main/generated/data/minecraft/dispense_behavior/equip_entity.json @@ -7,7 +7,7 @@ { "action": { "type": "minecraft:equip_entity_at_position", - "position": "target" + "position": "interacted" } }, { diff --git a/src/main/generated/data/minecraft/dispense_behavior/equip_entity_head.json b/src/main/generated/data/minecraft/dispense_behavior/equip_entity_head.json index 391f9566..cf679d52 100644 --- a/src/main/generated/data/minecraft/dispense_behavior/equip_entity_head.json +++ b/src/main/generated/data/minecraft/dispense_behavior/equip_entity_head.json @@ -8,7 +8,7 @@ { "action": { "type": "minecraft:equip_entity_at_position", - "position": "target" + "position": "interacted" } }, { diff --git a/src/main/generated/data/minecraft/dispense_behavior/glass_bottle.json b/src/main/generated/data/minecraft/dispense_behavior/glass_bottle.json index 3fe6f8c7..486ef0f0 100644 --- a/src/main/generated/data/minecraft/dispense_behavior/glass_bottle.json +++ b/src/main/generated/data/minecraft/dispense_behavior/glass_bottle.json @@ -9,30 +9,28 @@ { "action": { "type": "minecraft:take_honey", - "position": "target" + "position": "interacted" } }, { "action": { "type": "minecraft:exchange_item", - "item": "minecraft:honey_bottle" + "item": { + "id": "minecraft:honey_bottle", + "count": 1 + } } } ], "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "state": { - "honey_level": "5" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "state": { + "honey_level": "5" } } - }, - "context": { - "entity": "this", - "position": "target" } } }, diff --git a/src/main/generated/data/minecraft/dispense_behavior/place_block_from_item.json b/src/main/generated/data/minecraft/dispense_behavior/place_block_from_item.json index 785d100c..35e6258f 100644 --- a/src/main/generated/data/minecraft/dispense_behavior/place_block_from_item.json +++ b/src/main/generated/data/minecraft/dispense_behavior/place_block_from_item.json @@ -3,7 +3,7 @@ "entry": { "action": { "type": "minecraft:place_block_from_item", - "position": "target" + "position": "interacted" } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/dispense_behavior/place_carved_pumpkin.json b/src/main/generated/data/minecraft/dispense_behavior/place_carved_pumpkin.json index 90aa4092..6e6755c5 100644 --- a/src/main/generated/data/minecraft/dispense_behavior/place_carved_pumpkin.json +++ b/src/main/generated/data/minecraft/dispense_behavior/place_carved_pumpkin.json @@ -13,13 +13,13 @@ { "action": { "type": "minecraft:place_carved_pumpkin", - "position": "target" + "position": "interacted" } }, { "action": { "type": "minecraft:equip_entity_at_position", - "position": "target" + "position": "interacted" } } ] diff --git a/src/main/generated/data/minecraft/dispense_behavior/saddle.json b/src/main/generated/data/minecraft/dispense_behavior/saddle.json deleted file mode 100644 index 2ce973ee..00000000 --- a/src/main/generated/data/minecraft/dispense_behavior/saddle.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "entry": { - "action": { - "type": "minecraft:saddle_entity_at_position", - "position": "target" - } - } -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/dispense_behavior/shear.json b/src/main/generated/data/minecraft/dispense_behavior/shear.json index 1cef7189..230bce80 100644 --- a/src/main/generated/data/minecraft/dispense_behavior/shear.json +++ b/src/main/generated/data/minecraft/dispense_behavior/shear.json @@ -8,7 +8,7 @@ { "action": { "type": "minecraft:shear_at_position", - "position": "target" + "position": "interacted" } }, { diff --git a/src/main/generated/data/minecraft/dispense_behavior/shoot_bottle.json b/src/main/generated/data/minecraft/dispense_behavior/shoot_bottle.json index 9f4284c3..aafa7cfb 100644 --- a/src/main/generated/data/minecraft/dispense_behavior/shoot_bottle.json +++ b/src/main/generated/data/minecraft/dispense_behavior/shoot_bottle.json @@ -7,7 +7,7 @@ { "action": { "type": "minecraft:shoot_projectile_from_item", - "position": "target", + "position": "interacted", "power": 1.375, "uncertainty": 3.0 } diff --git a/src/main/generated/data/minecraft/dispense_behavior/shoot_charge.json b/src/main/generated/data/minecraft/dispense_behavior/shoot_charge.json index b5b748f3..ecf1c8d2 100644 --- a/src/main/generated/data/minecraft/dispense_behavior/shoot_charge.json +++ b/src/main/generated/data/minecraft/dispense_behavior/shoot_charge.json @@ -7,7 +7,7 @@ { "action": { "type": "minecraft:shoot_projectile_from_item", - "position": "target", + "position": "interacted", "power": 1.0, "uncertainty": 6.6666665 } diff --git a/src/main/generated/data/minecraft/dispense_behavior/shoot_firework_rocket.json b/src/main/generated/data/minecraft/dispense_behavior/shoot_firework_rocket.json index 30969c1e..860e4b7d 100644 --- a/src/main/generated/data/minecraft/dispense_behavior/shoot_firework_rocket.json +++ b/src/main/generated/data/minecraft/dispense_behavior/shoot_firework_rocket.json @@ -7,7 +7,7 @@ { "action": { "type": "minecraft:shoot_projectile_from_item", - "position": "target", + "position": "interacted", "power": 1.0, "uncertainty": 0.5 } diff --git a/src/main/generated/data/minecraft/dispense_behavior/shoot_projectile.json b/src/main/generated/data/minecraft/dispense_behavior/shoot_projectile.json index d3f990eb..71040051 100644 --- a/src/main/generated/data/minecraft/dispense_behavior/shoot_projectile.json +++ b/src/main/generated/data/minecraft/dispense_behavior/shoot_projectile.json @@ -7,7 +7,7 @@ { "action": { "type": "minecraft:shoot_projectile_from_item", - "position": "target", + "position": "interacted", "power": 1.1, "uncertainty": 6.0 } diff --git a/src/main/generated/data/minecraft/dispense_behavior/spawn_entity_from_item.json b/src/main/generated/data/minecraft/dispense_behavior/spawn_entity_from_item.json index f2bade44..c1bd2d28 100644 --- a/src/main/generated/data/minecraft/dispense_behavior/spawn_entity_from_item.json +++ b/src/main/generated/data/minecraft/dispense_behavior/spawn_entity_from_item.json @@ -2,7 +2,7 @@ "entry": { "action": { "type": "minecraft:spawn_entity_from_item", - "position": "target" + "position": "interacted" } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/dispense_behavior/spawn_tnt.json b/src/main/generated/data/minecraft/dispense_behavior/spawn_tnt.json index 3bc62a74..9eee9b1f 100644 --- a/src/main/generated/data/minecraft/dispense_behavior/spawn_tnt.json +++ b/src/main/generated/data/minecraft/dispense_behavior/spawn_tnt.json @@ -7,10 +7,8 @@ { "action": { "type": "minecraft:spawn_entity", - "entity": { - "type": "minecraft:tnt" - }, - "position": "target" + "entity": "minecraft:tnt", + "position": "interacted" } }, { @@ -18,7 +16,7 @@ "type": "minecraft:play_sound", "category": "block", "pitch": 1.0, - "position": "target", + "position": "interacted", "sound": "minecraft:entity.tnt.primed", "volume": 1.0 } diff --git a/src/main/generated/data/minecraft/dispense_behavior/use_bucket.json b/src/main/generated/data/minecraft/dispense_behavior/use_bucket.json index b1f21ec9..dd56a46a 100644 --- a/src/main/generated/data/minecraft/dispense_behavior/use_bucket.json +++ b/src/main/generated/data/minecraft/dispense_behavior/use_bucket.json @@ -2,7 +2,7 @@ "entry": { "action": { "type": "minecraft:use_bucket", - "position": "target" + "position": "interacted" } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/dispense_behavior/wax_block.json b/src/main/generated/data/minecraft/dispense_behavior/wax_block.json index 9d7536fb..26c6abf8 100644 --- a/src/main/generated/data/minecraft/dispense_behavior/wax_block.json +++ b/src/main/generated/data/minecraft/dispense_behavior/wax_block.json @@ -7,7 +7,7 @@ { "action": { "type": "minecraft:wax_block", - "position": "target" + "position": "interacted" } }, { diff --git a/src/main/generated/data/minecraft/item/acacia_boat.json b/src/main/generated/data/minecraft/item/acacia_boat.json index 442dc0ca..d4d44ce2 100644 --- a/src/main/generated/data/minecraft/item/acacia_boat.json +++ b/src/main/generated/data/minecraft/item/acacia_boat.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:acacia_boat" - } + "entity": "minecraft:acacia_boat" }, "minecraft:fuel": { "ticks": 1200 diff --git a/src/main/generated/data/minecraft/item/acacia_chest_boat.json b/src/main/generated/data/minecraft/item/acacia_chest_boat.json index a2880e9d..f8889102 100644 --- a/src/main/generated/data/minecraft/item/acacia_chest_boat.json +++ b/src/main/generated/data/minecraft/item/acacia_chest_boat.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:acacia_chest_boat" - } + "entity": "minecraft:acacia_chest_boat" }, "minecraft:fuel": { "ticks": 1200 diff --git a/src/main/generated/data/minecraft/item/acacia_leaves.json b/src/main/generated/data/minecraft/item/acacia_leaves.json index 97991911..3226e553 100644 --- a/src/main/generated/data/minecraft/item/acacia_leaves.json +++ b/src/main/generated/data/minecraft/item/acacia_leaves.json @@ -6,13 +6,7 @@ "minecraft:compostable": { "level_increase_chance": 0.3 }, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:foliage", - "biome": "minecraft:plains" - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:acacia_leaves", diff --git a/src/main/generated/data/minecraft/item/acacia_sapling.json b/src/main/generated/data/minecraft/item/acacia_sapling.json index 00010045..9e36ffb8 100644 --- a/src/main/generated/data/minecraft/item/acacia_sapling.json +++ b/src/main/generated/data/minecraft/item/acacia_sapling.json @@ -24,7 +24,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_acacia_sapling" } @@ -35,7 +35,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -56,23 +56,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } 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 c876d9a9..74c8cb00 100644 --- a/src/main/generated/data/minecraft/item/allay_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/allay_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:allay" - }, + "entity": "minecraft:allay", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 56063, - 44543 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:allay_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/allium.json b/src/main/generated/data/minecraft/item/allium.json index 7d7d81d9..b6fdb57f 100644 --- a/src/main/generated/data/minecraft/item/allium.json +++ b/src/main/generated/data/minecraft/item/allium.json @@ -29,7 +29,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_allium" } @@ -40,7 +40,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -61,23 +61,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/amethyst_shard.json b/src/main/generated/data/minecraft/item/amethyst_shard.json index 4a8fb6e5..880abb5d 100644 --- a/src/main/generated/data/minecraft/item/amethyst_shard.json +++ b/src/main/generated/data/minecraft/item/amethyst_shard.json @@ -1,6 +1,7 @@ { "behavior": { - "minecraft:stackable": 64 + "minecraft:stackable": 64, + "minecraft:trim_material_provider": "minecraft:amethyst" }, "display": { "model": "minecraft:amethyst_shard", 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 e2efdd25..c133748e 100644 --- a/src/main/generated/data/minecraft/item/armadillo_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/armadillo_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:armadillo" - }, + "entity": "minecraft:armadillo", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 11366765, - 8538184 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:armadillo_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/armor_stand.json b/src/main/generated/data/minecraft/item/armor_stand.json index 7e038ba7..a0851d91 100644 --- a/src/main/generated/data/minecraft/item/armor_stand.json +++ b/src/main/generated/data/minecraft/item/armor_stand.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:armor_stand" - } + "entity": "minecraft:armor_stand" }, "minecraft:stackable": 16 }, diff --git a/src/main/generated/data/minecraft/item/arrow.json b/src/main/generated/data/minecraft/item/arrow.json index 9438469f..e1fecfc7 100644 --- a/src/main/generated/data/minecraft/item/arrow.json +++ b/src/main/generated/data/minecraft/item/arrow.json @@ -4,9 +4,7 @@ "behavior": "minecraft:shoot_projectile" }, "minecraft:projectile": { - "entity": { - "type": "minecraft:arrow" - } + "entity": "minecraft:arrow" }, "minecraft:stackable": 64 }, diff --git a/src/main/generated/data/minecraft/item/axolotl_bucket.json b/src/main/generated/data/minecraft/item/axolotl_bucket.json index 510fc435..40b0d31a 100644 --- a/src/main/generated/data/minecraft/item/axolotl_bucket.json +++ b/src/main/generated/data/minecraft/item/axolotl_bucket.json @@ -3,9 +3,7 @@ "minecraft:bucket": { "emptying_sound_event": "minecraft:item.bucket.empty_axolotl", "entity": { - "entity": { - "type": "minecraft:axolotl" - }, + "entity": "minecraft:axolotl", "require_other_successful_placement": true }, "fluid": "minecraft:water", 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 be931eb8..a9fc07a2 100644 --- a/src/main/generated/data/minecraft/item/axolotl_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/axolotl_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:axolotl" - }, + "entity": "minecraft:axolotl", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 16499171, - 10890612 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:axolotl_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/azalea.json b/src/main/generated/data/minecraft/item/azalea.json index 7e9d2636..f7e9717e 100644 --- a/src/main/generated/data/minecraft/item/azalea.json +++ b/src/main/generated/data/minecraft/item/azalea.json @@ -24,7 +24,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_azalea_bush" } @@ -35,7 +35,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -56,23 +56,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/azure_bluet.json b/src/main/generated/data/minecraft/item/azure_bluet.json index 4915c4df..2f5add77 100644 --- a/src/main/generated/data/minecraft/item/azure_bluet.json +++ b/src/main/generated/data/minecraft/item/azure_bluet.json @@ -28,7 +28,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_azure_bluet" } @@ -39,7 +39,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -60,23 +60,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/bamboo.json b/src/main/generated/data/minecraft/item/bamboo.json index a4015ff6..2dba0594 100644 --- a/src/main/generated/data/minecraft/item/bamboo.json +++ b/src/main/generated/data/minecraft/item/bamboo.json @@ -21,7 +21,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_bamboo" } @@ -32,7 +32,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -53,23 +53,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/bamboo_chest_raft.json b/src/main/generated/data/minecraft/item/bamboo_chest_raft.json index 8e741c82..7c5d2a97 100644 --- a/src/main/generated/data/minecraft/item/bamboo_chest_raft.json +++ b/src/main/generated/data/minecraft/item/bamboo_chest_raft.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:bamboo_chest_raft" - } + "entity": "minecraft:bamboo_chest_raft" }, "minecraft:fuel": { "ticks": 1200 diff --git a/src/main/generated/data/minecraft/item/bamboo_raft.json b/src/main/generated/data/minecraft/item/bamboo_raft.json index 22d89309..33dac27f 100644 --- a/src/main/generated/data/minecraft/item/bamboo_raft.json +++ b/src/main/generated/data/minecraft/item/bamboo_raft.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:bamboo_raft" - } + "entity": "minecraft:bamboo_raft" }, "minecraft:fuel": { "ticks": 1200 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 cf96cb99..f6803b6d 100644 --- a/src/main/generated/data/minecraft/item/bat_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/bat_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:bat" - }, + "entity": "minecraft:bat", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 4996656, - 986895 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:bat_spawn_egg", 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 fb2fa81b..21323ab6 100644 --- a/src/main/generated/data/minecraft/item/bee_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/bee_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:bee" - }, + "entity": "minecraft:bee", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 15582019, - 4400155 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:bee_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/birch_boat.json b/src/main/generated/data/minecraft/item/birch_boat.json index d6269752..dc217484 100644 --- a/src/main/generated/data/minecraft/item/birch_boat.json +++ b/src/main/generated/data/minecraft/item/birch_boat.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:birch_boat" - } + "entity": "minecraft:birch_boat" }, "minecraft:fuel": { "ticks": 1200 diff --git a/src/main/generated/data/minecraft/item/birch_chest_boat.json b/src/main/generated/data/minecraft/item/birch_chest_boat.json index b48f2e56..7184c21d 100644 --- a/src/main/generated/data/minecraft/item/birch_chest_boat.json +++ b/src/main/generated/data/minecraft/item/birch_chest_boat.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:birch_chest_boat" - } + "entity": "minecraft:birch_chest_boat" }, "minecraft:fuel": { "ticks": 1200 diff --git a/src/main/generated/data/minecraft/item/birch_leaves.json b/src/main/generated/data/minecraft/item/birch_leaves.json index d44e99c8..c49cb237 100644 --- a/src/main/generated/data/minecraft/item/birch_leaves.json +++ b/src/main/generated/data/minecraft/item/birch_leaves.json @@ -6,13 +6,7 @@ "minecraft:compostable": { "level_increase_chance": 0.3 }, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:constant", - "color": -8345771 - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:birch_leaves", diff --git a/src/main/generated/data/minecraft/item/birch_sapling.json b/src/main/generated/data/minecraft/item/birch_sapling.json index 0e0fc06a..7d12aed6 100644 --- a/src/main/generated/data/minecraft/item/birch_sapling.json +++ b/src/main/generated/data/minecraft/item/birch_sapling.json @@ -24,7 +24,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_birch_sapling" } @@ -35,7 +35,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -56,23 +56,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/black_carpet.json b/src/main/generated/data/minecraft/item/black_carpet.json index 343f21e2..5edbfdf4 100644 --- a/src/main/generated/data/minecraft/item/black_carpet.json +++ b/src/main/generated/data/minecraft/item/black_carpet.json @@ -11,8 +11,8 @@ "minecraft:llama", "minecraft:trader_llama" ], + "asset_id": "minecraft:black_carpet", "equip_sound": "minecraft:entity.llama.swag", - "model": "minecraft:black_carpet", "slot": "body" }, "minecraft:fuel": { 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 6c1bfe2a..ffd3601f 100644 --- a/src/main/generated/data/minecraft/item/blaze_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/blaze_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:blaze" - }, + "entity": "minecraft:blaze", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 16167425, - 16775294 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:blaze_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/blue_carpet.json b/src/main/generated/data/minecraft/item/blue_carpet.json index 6033d83e..66cadc57 100644 --- a/src/main/generated/data/minecraft/item/blue_carpet.json +++ b/src/main/generated/data/minecraft/item/blue_carpet.json @@ -11,8 +11,8 @@ "minecraft:llama", "minecraft:trader_llama" ], + "asset_id": "minecraft:blue_carpet", "equip_sound": "minecraft:entity.llama.swag", - "model": "minecraft:blue_carpet", "slot": "body" }, "minecraft:fuel": { diff --git a/src/main/generated/data/minecraft/item/blue_egg.json b/src/main/generated/data/minecraft/item/blue_egg.json new file mode 100644 index 00000000..dc86954e --- /dev/null +++ b/src/main/generated/data/minecraft/item/blue_egg.json @@ -0,0 +1,22 @@ +{ + "behavior": { + "minecraft:dispensable": { + "behavior": "minecraft:shoot_projectile" + }, + "minecraft:projectile": { + "components": { + "minecraft:chicken/variant": "minecraft:cold" + }, + "entity": "minecraft:egg" + }, + "minecraft:stackable": 16, + "minecraft:throwable": { + "angle_offset": 0.0, + "speed": 1.5 + } + }, + "display": { + "model": "minecraft:blue_egg", + "translation_key": "item.minecraft.blue_egg" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/blue_orchid.json b/src/main/generated/data/minecraft/item/blue_orchid.json index 11639eff..41973e0d 100644 --- a/src/main/generated/data/minecraft/item/blue_orchid.json +++ b/src/main/generated/data/minecraft/item/blue_orchid.json @@ -29,7 +29,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_blue_orchid" } @@ -40,7 +40,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -61,23 +61,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } 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 580da0ee..614f30bd 100644 --- a/src/main/generated/data/minecraft/item/bogged_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/bogged_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:bogged" - }, + "entity": "minecraft:bogged", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 9084018, - 3231003 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:bogged_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/bolt_armor_trim_smithing_template.json b/src/main/generated/data/minecraft/item/bolt_armor_trim_smithing_template.json index 036b90e6..ba3878f0 100644 --- a/src/main/generated/data/minecraft/item/bolt_armor_trim_smithing_template.json +++ b/src/main/generated/data/minecraft/item/bolt_armor_trim_smithing_template.json @@ -1,13 +1,44 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:bolt_pattern" - }, + "minecraft:smithing_template_provider": "minecraft:trim_pattern", "minecraft:stackable": 64 }, "display": { "model": "minecraft:bolt_armor_trim_smithing_template", "rarity": "uncommon", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.bolt_armor_trim_smithing_template" } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/bone_meal.json b/src/main/generated/data/minecraft/item/bone_meal.json index 05bde70a..ba449e21 100644 --- a/src/main/generated/data/minecraft/item/bone_meal.json +++ b/src/main/generated/data/minecraft/item/bone_meal.json @@ -12,7 +12,30 @@ "events": { "minecraft:use_on_block": { "action": { - "type": "minecraft:fertilize" + "type": "minecraft:sequence", + "handler": "minecraft:passing", + "entries": [ + { + "action": { + "type": "minecraft:fertilize", + "position": "interacted" + } + }, + { + "action": { + "type": "minecraft:invoke_game_event", + "event": "minecraft:item_interact_finish", + "entity": "this", + "position": "origin" + } + }, + { + "action": { + "type": "minecraft:decrement_item", + "amount": 1 + } + } + ] } } } 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 2acbb8a6..259dc276 100644 --- a/src/main/generated/data/minecraft/item/breeze_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/breeze_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:breeze" - }, + "entity": "minecraft:breeze", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 11506911, - 9529055 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:breeze_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/brown_carpet.json b/src/main/generated/data/minecraft/item/brown_carpet.json index b902f4b8..aec18e24 100644 --- a/src/main/generated/data/minecraft/item/brown_carpet.json +++ b/src/main/generated/data/minecraft/item/brown_carpet.json @@ -11,8 +11,8 @@ "minecraft:llama", "minecraft:trader_llama" ], + "asset_id": "minecraft:brown_carpet", "equip_sound": "minecraft:entity.llama.swag", - "model": "minecraft:brown_carpet", "slot": "body" }, "minecraft:fuel": { diff --git a/src/main/generated/data/minecraft/item/brown_egg.json b/src/main/generated/data/minecraft/item/brown_egg.json new file mode 100644 index 00000000..863f38c5 --- /dev/null +++ b/src/main/generated/data/minecraft/item/brown_egg.json @@ -0,0 +1,22 @@ +{ + "behavior": { + "minecraft:dispensable": { + "behavior": "minecraft:shoot_projectile" + }, + "minecraft:projectile": { + "components": { + "minecraft:chicken/variant": "minecraft:warm" + }, + "entity": "minecraft:egg" + }, + "minecraft:stackable": 16, + "minecraft:throwable": { + "angle_offset": 0.0, + "speed": 1.5 + } + }, + "display": { + "model": "minecraft:brown_egg", + "translation_key": "item.minecraft.brown_egg" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/brown_mushroom.json b/src/main/generated/data/minecraft/item/brown_mushroom.json index 2dcbde9d..6349fe1a 100644 --- a/src/main/generated/data/minecraft/item/brown_mushroom.json +++ b/src/main/generated/data/minecraft/item/brown_mushroom.json @@ -21,7 +21,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_brown_mushroom" } @@ -32,7 +32,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -53,23 +53,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/bush.json b/src/main/generated/data/minecraft/item/bush.json new file mode 100644 index 00000000..59ab4764 --- /dev/null +++ b/src/main/generated/data/minecraft/item/bush.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:bush" + }, + "minecraft:compostable": { + "level_increase_chance": 0.3 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:bush", + "translation_key": "block.minecraft.bush" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/cactus.json b/src/main/generated/data/minecraft/item/cactus.json index 95cf07f8..0f7f5834 100644 --- a/src/main/generated/data/minecraft/item/cactus.json +++ b/src/main/generated/data/minecraft/item/cactus.json @@ -21,7 +21,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_cactus" } @@ -32,7 +32,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -53,23 +53,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/cactus_flower.json b/src/main/generated/data/minecraft/item/cactus_flower.json new file mode 100644 index 00000000..33e4afef --- /dev/null +++ b/src/main/generated/data/minecraft/item/cactus_flower.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:cactus_flower" + }, + "minecraft:compostable": { + "level_increase_chance": 0.3 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:cactus_flower", + "translation_key": "block.minecraft.cactus_flower" + } +} \ 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 60f9fb22..017af9b9 100644 --- a/src/main/generated/data/minecraft/item/camel_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/camel_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:camel" - }, + "entity": "minecraft:camel", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 16565097, - 13341495 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:camel_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/carrot_on_a_stick.json b/src/main/generated/data/minecraft/item/carrot_on_a_stick.json index 4fc8a41d..b87682f1 100644 --- a/src/main/generated/data/minecraft/item/carrot_on_a_stick.json +++ b/src/main/generated/data/minecraft/item/carrot_on_a_stick.json @@ -18,7 +18,10 @@ "action": { "type": "minecraft:exchange_item", "decrement_count": false, - "item": "minecraft:fishing_rod" + "item": { + "id": "minecraft:fishing_rod", + "count": 1 + } } } } 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 f01c2214..1160ed76 100644 --- a/src/main/generated/data/minecraft/item/cat_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/cat_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:cat" - }, + "entity": "minecraft:cat", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 15714446, - 9794134 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:cat_spawn_egg", 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 3bce91ba..ffcc3f9e 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 @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:cave_spider" - }, + "entity": "minecraft:cave_spider", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 803406, - 11013646 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:cave_spider_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/chainmail_boots.json b/src/main/generated/data/minecraft/item/chainmail_boots.json index 304bfe30..0d67b086 100644 --- a/src/main/generated/data/minecraft/item/chainmail_boots.json +++ b/src/main/generated/data/minecraft/item/chainmail_boots.json @@ -19,8 +19,8 @@ "enchantability": 12 }, "minecraft:equipment": { + "asset_id": "minecraft:chainmail", "equip_sound": "minecraft:item.armor.equip_chain", - "model": "minecraft:chainmail", "slot": "feet" }, "minecraft:repairable": { diff --git a/src/main/generated/data/minecraft/item/chainmail_chestplate.json b/src/main/generated/data/minecraft/item/chainmail_chestplate.json index 62526bab..4ba6dbc9 100644 --- a/src/main/generated/data/minecraft/item/chainmail_chestplate.json +++ b/src/main/generated/data/minecraft/item/chainmail_chestplate.json @@ -19,8 +19,8 @@ "enchantability": 12 }, "minecraft:equipment": { + "asset_id": "minecraft:chainmail", "equip_sound": "minecraft:item.armor.equip_chain", - "model": "minecraft:chainmail", "slot": "chest" }, "minecraft:repairable": { diff --git a/src/main/generated/data/minecraft/item/chainmail_helmet.json b/src/main/generated/data/minecraft/item/chainmail_helmet.json index 867bf7c0..2d13079f 100644 --- a/src/main/generated/data/minecraft/item/chainmail_helmet.json +++ b/src/main/generated/data/minecraft/item/chainmail_helmet.json @@ -19,8 +19,8 @@ "enchantability": 12 }, "minecraft:equipment": { + "asset_id": "minecraft:chainmail", "equip_sound": "minecraft:item.armor.equip_chain", - "model": "minecraft:chainmail", "slot": "head" }, "minecraft:repairable": { diff --git a/src/main/generated/data/minecraft/item/chainmail_leggings.json b/src/main/generated/data/minecraft/item/chainmail_leggings.json index ce812d11..5334d86b 100644 --- a/src/main/generated/data/minecraft/item/chainmail_leggings.json +++ b/src/main/generated/data/minecraft/item/chainmail_leggings.json @@ -19,8 +19,8 @@ "enchantability": 12 }, "minecraft:equipment": { + "asset_id": "minecraft:chainmail", "equip_sound": "minecraft:item.armor.equip_chain", - "model": "minecraft:chainmail", "slot": "legs" }, "minecraft:repairable": { diff --git a/src/main/generated/data/minecraft/item/cherry_boat.json b/src/main/generated/data/minecraft/item/cherry_boat.json index e1da5984..d64870ca 100644 --- a/src/main/generated/data/minecraft/item/cherry_boat.json +++ b/src/main/generated/data/minecraft/item/cherry_boat.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:cherry_boat" - } + "entity": "minecraft:cherry_boat" }, "minecraft:fuel": { "ticks": 1200 diff --git a/src/main/generated/data/minecraft/item/cherry_chest_boat.json b/src/main/generated/data/minecraft/item/cherry_chest_boat.json index 56a6b10c..b2a69c07 100644 --- a/src/main/generated/data/minecraft/item/cherry_chest_boat.json +++ b/src/main/generated/data/minecraft/item/cherry_chest_boat.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:cherry_chest_boat" - } + "entity": "minecraft:cherry_chest_boat" }, "minecraft:fuel": { "ticks": 1200 diff --git a/src/main/generated/data/minecraft/item/cherry_sapling.json b/src/main/generated/data/minecraft/item/cherry_sapling.json index 7e7c8c7d..2ee2e9df 100644 --- a/src/main/generated/data/minecraft/item/cherry_sapling.json +++ b/src/main/generated/data/minecraft/item/cherry_sapling.json @@ -24,7 +24,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_cherry_sapling" } @@ -35,7 +35,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -56,23 +56,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/chest_minecart.json b/src/main/generated/data/minecraft/item/chest_minecart.json index 5cb256e2..e134a48e 100644 --- a/src/main/generated/data/minecraft/item/chest_minecart.json +++ b/src/main/generated/data/minecraft/item/chest_minecart.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:chest_minecart" - } + "entity": "minecraft:chest_minecart" }, "minecraft:stackable": 1 }, diff --git a/src/main/generated/data/minecraft/item/chicken.json b/src/main/generated/data/minecraft/item/chicken.json index 7215e8b9..c0323526 100644 --- a/src/main/generated/data/minecraft/item/chicken.json +++ b/src/main/generated/data/minecraft/item/chicken.json @@ -32,14 +32,8 @@ "entity": "this" }, "requirements": { - "conditions": { - "chance": 0.3, - "condition": "minecraft:random_chance" - }, - "context": { - "entity": "this", - "position": "this" - } + "chance": 0.3, + "condition": "minecraft:random_chance" } } } 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 7d503187..1eb9b943 100644 --- a/src/main/generated/data/minecraft/item/chicken_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/chicken_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:chicken" - }, + "entity": "minecraft:chicken", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 10592673, - 16711680 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:chicken_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/chiseled_resin_bricks.json b/src/main/generated/data/minecraft/item/chiseled_resin_bricks.json new file mode 100644 index 00000000..1e73b491 --- /dev/null +++ b/src/main/generated/data/minecraft/item/chiseled_resin_bricks.json @@ -0,0 +1,12 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:chiseled_resin_bricks" + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:chiseled_resin_bricks", + "translation_key": "block.minecraft.chiseled_resin_bricks" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/closed_eyeblossom.json b/src/main/generated/data/minecraft/item/closed_eyeblossom.json new file mode 100644 index 00000000..ad86daa2 --- /dev/null +++ b/src/main/generated/data/minecraft/item/closed_eyeblossom.json @@ -0,0 +1,81 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:closed_eyeblossom" + }, + "minecraft:compostable": { + "level_increase_chance": 0.65 + }, + "minecraft:stackable": 64, + "minecraft:suspicious_effect_ingredient": { + "effects": [ + { + "id": "minecraft:nausea", + "duration": 140 + } + ] + } + }, + "display": { + "model": "minecraft:closed_eyeblossom", + "translation_key": "block.minecraft.closed_eyeblossom" + }, + "events": { + "minecraft:use_on_block": { + "action": { + "type": "minecraft:sequence", + "handler": "minecraft:passing", + "entries": [ + { + "action": { + "type": "minecraft:set_block_state", + "position": "interacted", + "state": { + "Name": "minecraft:potted_closed_eyeblossom" + } + } + }, + { + "action": { + "type": "minecraft:invoke_game_event", + "event": "minecraft:block_change", + "entity": "this", + "position": "interacted" + } + }, + { + "action": { + "type": "minecraft:increment_stat", + "entity": "this", + "stat": { + "type": "minecraft:custom", + "entry": "minecraft:pot_flower" + } + } + }, + { + "action": { + "type": "minecraft:decrement_item", + "amount": 1 + } + }, + { + "action": { + "type": "minecraft:swing_hand", + "entity": "this" + } + } + ] + }, + "requirements": { + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" + } + } + } + } + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/coast_armor_trim_smithing_template.json b/src/main/generated/data/minecraft/item/coast_armor_trim_smithing_template.json index dd1311a9..1b3ae632 100644 --- a/src/main/generated/data/minecraft/item/coast_armor_trim_smithing_template.json +++ b/src/main/generated/data/minecraft/item/coast_armor_trim_smithing_template.json @@ -1,13 +1,44 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:coast_pattern" - }, + "minecraft:smithing_template_provider": "minecraft:trim_pattern", "minecraft:stackable": 64 }, "display": { "model": "minecraft:coast_armor_trim_smithing_template", "rarity": "uncommon", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.coast_armor_trim_smithing_template" } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/cod_bucket.json b/src/main/generated/data/minecraft/item/cod_bucket.json index b91bc876..70aade48 100644 --- a/src/main/generated/data/minecraft/item/cod_bucket.json +++ b/src/main/generated/data/minecraft/item/cod_bucket.json @@ -3,9 +3,7 @@ "minecraft:bucket": { "emptying_sound_event": "minecraft:item.bucket.empty_fish", "entity": { - "entity": { - "type": "minecraft:cod" - }, + "entity": "minecraft:cod", "require_other_successful_placement": true }, "fluid": "minecraft:water", 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 b0f5980d..fb6ded02 100644 --- a/src/main/generated/data/minecraft/item/cod_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/cod_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:cod" - }, + "entity": "minecraft:cod", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 12691306, - 15058059 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:cod_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/command_block_minecart.json b/src/main/generated/data/minecraft/item/command_block_minecart.json index a607a03b..d20e83d0 100644 --- a/src/main/generated/data/minecraft/item/command_block_minecart.json +++ b/src/main/generated/data/minecraft/item/command_block_minecart.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:command_block_minecart" - } + "entity": "minecraft:command_block_minecart" }, "minecraft:stackable": 1 }, diff --git a/src/main/generated/data/minecraft/item/compass.json b/src/main/generated/data/minecraft/item/compass.json index 78adc357..8dd38ab3 100644 --- a/src/main/generated/data/minecraft/item/compass.json +++ b/src/main/generated/data/minecraft/item/compass.json @@ -1,9 +1,5 @@ { "behavior": { - "minecraft:pointable": { - "lodestone_translation_key": "item.minecraft.lodestone_compass", - "points_to": "minecraft:spawn_location" - }, "minecraft:stackable": 64 }, "display": { @@ -18,29 +14,60 @@ "entries": [ { "action": { - "type": "minecraft:set_item_pointer_location", - "position": "target" + "type": "minecraft:modify_item", + "item_modifier": { + "function": "minecraft:sequence", + "functions": [ + { + "count": 1.0, + "function": "minecraft:split" + }, + { + "function": "minecraft:set_item_pointer_location", + "position": "interacted" + }, + { + "function": "minecraft:set_name", + "name": { + "translate": "item.minecraft.lodestone_compass" + }, + "target": "item_name" + }, + { + "components": { + "minecraft:enchantment_glint_override": true + }, + "function": "minecraft:set_components" + } + ] + } } }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:play_sound", + "category": "player", + "pitch": 1.0, + "position": "interacted", + "sound": "minecraft:item.lodestone_compass.lock", + "volume": 1.0 + } + }, + { + "action": { + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:lodestone" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:lodestone" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/copper_ingot.json b/src/main/generated/data/minecraft/item/copper_ingot.json index 7ec814f8..a0bcf420 100644 --- a/src/main/generated/data/minecraft/item/copper_ingot.json +++ b/src/main/generated/data/minecraft/item/copper_ingot.json @@ -1,6 +1,7 @@ { "behavior": { - "minecraft:stackable": 64 + "minecraft:stackable": 64, + "minecraft:trim_material_provider": "minecraft:copper" }, "display": { "model": "minecraft:copper_ingot", diff --git a/src/main/generated/data/minecraft/item/cornflower.json b/src/main/generated/data/minecraft/item/cornflower.json index 6b08e63a..04815cf5 100644 --- a/src/main/generated/data/minecraft/item/cornflower.json +++ b/src/main/generated/data/minecraft/item/cornflower.json @@ -29,7 +29,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_cornflower" } @@ -40,7 +40,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -61,23 +61,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } 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 71057f8a..c371883c 100644 --- a/src/main/generated/data/minecraft/item/cow_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/cow_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:cow" - }, + "entity": "minecraft:cow", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 4470310, - 10592673 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:cow_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/creaking_heart.json b/src/main/generated/data/minecraft/item/creaking_heart.json new file mode 100644 index 00000000..50d87cfb --- /dev/null +++ b/src/main/generated/data/minecraft/item/creaking_heart.json @@ -0,0 +1,12 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:creaking_heart" + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:creaking_heart", + "translation_key": "block.minecraft.creaking_heart" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/creaking_spawn_egg.json b/src/main/generated/data/minecraft/item/creaking_spawn_egg.json new file mode 100644 index 00000000..e0c03126 --- /dev/null +++ b/src/main/generated/data/minecraft/item/creaking_spawn_egg.json @@ -0,0 +1,21 @@ +{ + "behavior": { + "minecraft:dispensable": { + "behavior": "minecraft:spawn_entity_from_item" + }, + "minecraft:entity": { + "allow_item_data": true, + "entity": "minecraft:creaking", + "passes": [ + "block", + "fluid" + ] + }, + "minecraft:spawn_egg": {}, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:creaking_spawn_egg", + "translation_key": "item.minecraft.creaking_spawn_egg" + } +} \ 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 8803e831..149eef85 100644 --- a/src/main/generated/data/minecraft/item/creeper_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/creeper_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:creeper" - }, + "entity": "minecraft:creeper", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 894731, - 0 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:creeper_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/crimson_fungus.json b/src/main/generated/data/minecraft/item/crimson_fungus.json index d1ff0a12..ce164348 100644 --- a/src/main/generated/data/minecraft/item/crimson_fungus.json +++ b/src/main/generated/data/minecraft/item/crimson_fungus.json @@ -21,7 +21,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_crimson_fungus" } @@ -32,7 +32,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -53,23 +53,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/crimson_roots.json b/src/main/generated/data/minecraft/item/crimson_roots.json index 51f5346a..25580449 100644 --- a/src/main/generated/data/minecraft/item/crimson_roots.json +++ b/src/main/generated/data/minecraft/item/crimson_roots.json @@ -21,7 +21,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_crimson_roots" } @@ -32,7 +32,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -53,23 +53,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/cyan_carpet.json b/src/main/generated/data/minecraft/item/cyan_carpet.json index cd7974d5..a4ce3cf3 100644 --- a/src/main/generated/data/minecraft/item/cyan_carpet.json +++ b/src/main/generated/data/minecraft/item/cyan_carpet.json @@ -11,8 +11,8 @@ "minecraft:llama", "minecraft:trader_llama" ], + "asset_id": "minecraft:cyan_carpet", "equip_sound": "minecraft:entity.llama.swag", - "model": "minecraft:cyan_carpet", "slot": "body" }, "minecraft:fuel": { diff --git a/src/main/generated/data/minecraft/item/dandelion.json b/src/main/generated/data/minecraft/item/dandelion.json index 57880c15..38aeafa5 100644 --- a/src/main/generated/data/minecraft/item/dandelion.json +++ b/src/main/generated/data/minecraft/item/dandelion.json @@ -29,7 +29,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_dandelion" } @@ -40,7 +40,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -61,23 +61,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/dark_oak_boat.json b/src/main/generated/data/minecraft/item/dark_oak_boat.json index 6b0c86c0..769a2aa8 100644 --- a/src/main/generated/data/minecraft/item/dark_oak_boat.json +++ b/src/main/generated/data/minecraft/item/dark_oak_boat.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:dark_oak_boat" - } + "entity": "minecraft:dark_oak_boat" }, "minecraft:fuel": { "ticks": 1200 diff --git a/src/main/generated/data/minecraft/item/dark_oak_chest_boat.json b/src/main/generated/data/minecraft/item/dark_oak_chest_boat.json index dda3d417..0b629cfc 100644 --- a/src/main/generated/data/minecraft/item/dark_oak_chest_boat.json +++ b/src/main/generated/data/minecraft/item/dark_oak_chest_boat.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:dark_oak_chest_boat" - } + "entity": "minecraft:dark_oak_chest_boat" }, "minecraft:fuel": { "ticks": 1200 diff --git a/src/main/generated/data/minecraft/item/dark_oak_leaves.json b/src/main/generated/data/minecraft/item/dark_oak_leaves.json index c05af1ef..80f1abff 100644 --- a/src/main/generated/data/minecraft/item/dark_oak_leaves.json +++ b/src/main/generated/data/minecraft/item/dark_oak_leaves.json @@ -6,13 +6,7 @@ "minecraft:compostable": { "level_increase_chance": 0.3 }, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:foliage", - "biome": "minecraft:plains" - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:dark_oak_leaves", diff --git a/src/main/generated/data/minecraft/item/dark_oak_sapling.json b/src/main/generated/data/minecraft/item/dark_oak_sapling.json index 5c923d87..18c52092 100644 --- a/src/main/generated/data/minecraft/item/dark_oak_sapling.json +++ b/src/main/generated/data/minecraft/item/dark_oak_sapling.json @@ -24,7 +24,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_dark_oak_sapling" } @@ -35,7 +35,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -56,23 +56,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/dead_bush.json b/src/main/generated/data/minecraft/item/dead_bush.json index a23629e5..e8995268 100644 --- a/src/main/generated/data/minecraft/item/dead_bush.json +++ b/src/main/generated/data/minecraft/item/dead_bush.json @@ -21,7 +21,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_dead_bush" } @@ -32,7 +32,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -53,23 +53,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/diamond.json b/src/main/generated/data/minecraft/item/diamond.json index aa2da596..91c005ee 100644 --- a/src/main/generated/data/minecraft/item/diamond.json +++ b/src/main/generated/data/minecraft/item/diamond.json @@ -1,6 +1,7 @@ { "behavior": { - "minecraft:stackable": 64 + "minecraft:stackable": 64, + "minecraft:trim_material_provider": "minecraft:diamond" }, "display": { "model": "minecraft:diamond", diff --git a/src/main/generated/data/minecraft/item/diamond_axe.json b/src/main/generated/data/minecraft/item/diamond_axe.json index c704e4ac..25002d63 100644 --- a/src/main/generated/data/minecraft/item/diamond_axe.json +++ b/src/main/generated/data/minecraft/item/diamond_axe.json @@ -29,7 +29,8 @@ "rules": [] }, "attack_speed": 0.25, - "damage_per_hit": 2 + "disable_blocking_for_seconds": 5.0, + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/diamond_boots.json b/src/main/generated/data/minecraft/item/diamond_boots.json index eb645b67..80727180 100644 --- a/src/main/generated/data/minecraft/item/diamond_boots.json +++ b/src/main/generated/data/minecraft/item/diamond_boots.json @@ -26,8 +26,8 @@ "enchantability": 10 }, "minecraft:equipment": { + "asset_id": "minecraft:diamond", "equip_sound": "minecraft:item.armor.equip_diamond", - "model": "minecraft:diamond", "slot": "feet" }, "minecraft:repairable": { diff --git a/src/main/generated/data/minecraft/item/diamond_chestplate.json b/src/main/generated/data/minecraft/item/diamond_chestplate.json index 8233a1b2..aa699720 100644 --- a/src/main/generated/data/minecraft/item/diamond_chestplate.json +++ b/src/main/generated/data/minecraft/item/diamond_chestplate.json @@ -26,8 +26,8 @@ "enchantability": 10 }, "minecraft:equipment": { + "asset_id": "minecraft:diamond", "equip_sound": "minecraft:item.armor.equip_diamond", - "model": "minecraft:diamond", "slot": "chest" }, "minecraft:repairable": { diff --git a/src/main/generated/data/minecraft/item/diamond_helmet.json b/src/main/generated/data/minecraft/item/diamond_helmet.json index 977a8731..86c60694 100644 --- a/src/main/generated/data/minecraft/item/diamond_helmet.json +++ b/src/main/generated/data/minecraft/item/diamond_helmet.json @@ -26,8 +26,8 @@ "enchantability": 10 }, "minecraft:equipment": { + "asset_id": "minecraft:diamond", "equip_sound": "minecraft:item.armor.equip_diamond", - "model": "minecraft:diamond", "slot": "head" }, "minecraft:repairable": { diff --git a/src/main/generated/data/minecraft/item/diamond_hoe.json b/src/main/generated/data/minecraft/item/diamond_hoe.json index 2d1cca75..5ae52a51 100644 --- a/src/main/generated/data/minecraft/item/diamond_hoe.json +++ b/src/main/generated/data/minecraft/item/diamond_hoe.json @@ -29,7 +29,7 @@ "rules": [] }, "attack_speed": 1.0, - "damage_per_hit": 2 + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/diamond_horse_armor.json b/src/main/generated/data/minecraft/item/diamond_horse_armor.json index 64983095..8f204e45 100644 --- a/src/main/generated/data/minecraft/item/diamond_horse_armor.json +++ b/src/main/generated/data/minecraft/item/diamond_horse_armor.json @@ -20,9 +20,10 @@ "behavior": "minecraft:equip_entity" }, "minecraft:equipment": { - "allowed_entities": "minecraft:horse", - "equip_sound": "minecraft:item.armor.equip_diamond", - "model": "minecraft:diamond", + "allowed_entities": "#minecraft:can_wear_horse_armor", + "asset_id": "minecraft:diamond", + "damage_on_hurt": false, + "equip_sound": "minecraft:entity.horse.armor", "slot": "body" }, "minecraft:stackable": 1 diff --git a/src/main/generated/data/minecraft/item/diamond_leggings.json b/src/main/generated/data/minecraft/item/diamond_leggings.json index 8f6e2ad4..a677692d 100644 --- a/src/main/generated/data/minecraft/item/diamond_leggings.json +++ b/src/main/generated/data/minecraft/item/diamond_leggings.json @@ -26,8 +26,8 @@ "enchantability": 10 }, "minecraft:equipment": { + "asset_id": "minecraft:diamond", "equip_sound": "minecraft:item.armor.equip_diamond", - "model": "minecraft:diamond", "slot": "legs" }, "minecraft:repairable": { diff --git a/src/main/generated/data/minecraft/item/diamond_pickaxe.json b/src/main/generated/data/minecraft/item/diamond_pickaxe.json index 0e2a1e0f..9ee48825 100644 --- a/src/main/generated/data/minecraft/item/diamond_pickaxe.json +++ b/src/main/generated/data/minecraft/item/diamond_pickaxe.json @@ -29,7 +29,7 @@ "rules": [] }, "attack_speed": 0.3, - "damage_per_hit": 2 + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/diamond_shovel.json b/src/main/generated/data/minecraft/item/diamond_shovel.json index 6878e057..8896cb70 100644 --- a/src/main/generated/data/minecraft/item/diamond_shovel.json +++ b/src/main/generated/data/minecraft/item/diamond_shovel.json @@ -29,7 +29,7 @@ "rules": [] }, "attack_speed": 0.25, - "damage_per_hit": 2 + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/diamond_sword.json b/src/main/generated/data/minecraft/item/diamond_sword.json index 97eaaf27..25c556fa 100644 --- a/src/main/generated/data/minecraft/item/diamond_sword.json +++ b/src/main/generated/data/minecraft/item/diamond_sword.json @@ -11,6 +11,7 @@ }, "minecraft:stackable": 1, "minecraft:tool": { + "can_destroy_blocks_in_creative": false, "damage_per_block": 2, "rules": [ { 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 a33aa5d1..2355a4f4 100644 --- a/src/main/generated/data/minecraft/item/dolphin_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/dolphin_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:dolphin" - }, + "entity": "minecraft:dolphin", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 2243405, - 16382457 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:dolphin_spawn_egg", 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 7752309c..b4b2e397 100644 --- a/src/main/generated/data/minecraft/item/donkey_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/donkey_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:donkey" - }, + "entity": "minecraft:donkey", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 5457209, - 8811878 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:donkey_spawn_egg", 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 58dbbd70..0093e4d0 100644 --- a/src/main/generated/data/minecraft/item/drowned_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/drowned_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:drowned" - }, + "entity": "minecraft:drowned", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 9433559, - 7969893 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:drowned_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/dune_armor_trim_smithing_template.json b/src/main/generated/data/minecraft/item/dune_armor_trim_smithing_template.json index 8ce6e7cf..c9ded6d1 100644 --- a/src/main/generated/data/minecraft/item/dune_armor_trim_smithing_template.json +++ b/src/main/generated/data/minecraft/item/dune_armor_trim_smithing_template.json @@ -1,13 +1,44 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:dune_pattern" - }, + "minecraft:smithing_template_provider": "minecraft:trim_pattern", "minecraft:stackable": 64 }, "display": { "model": "minecraft:dune_armor_trim_smithing_template", "rarity": "uncommon", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.dune_armor_trim_smithing_template" } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/egg.json b/src/main/generated/data/minecraft/item/egg.json index 97a1cac8..a8e8f62f 100644 --- a/src/main/generated/data/minecraft/item/egg.json +++ b/src/main/generated/data/minecraft/item/egg.json @@ -4,9 +4,10 @@ "behavior": "minecraft:shoot_projectile" }, "minecraft:projectile": { - "entity": { - "type": "minecraft:egg" - } + "components": { + "minecraft:chicken/variant": "minecraft:temperate" + }, + "entity": "minecraft:egg" }, "minecraft:stackable": 16, "minecraft:throwable": { 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 4f953f2a..f55e1c06 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 @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:elder_guardian" - }, + "entity": "minecraft:elder_guardian", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 13552826, - 7632531 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:elder_guardian_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/elytra.json b/src/main/generated/data/minecraft/item/elytra.json index d3c8d33d..29027229 100644 --- a/src/main/generated/data/minecraft/item/elytra.json +++ b/src/main/generated/data/minecraft/item/elytra.json @@ -8,8 +8,8 @@ "behavior": "minecraft:equip_entity" }, "minecraft:equipment": { + "asset_id": "minecraft:elytra", "equip_sound": "minecraft:item.armor.equip_elytra", - "model": "minecraft:elytra", "slot": "chest" }, "minecraft:glider": { diff --git a/src/main/generated/data/minecraft/item/emerald.json b/src/main/generated/data/minecraft/item/emerald.json index 608b1a43..b402638c 100644 --- a/src/main/generated/data/minecraft/item/emerald.json +++ b/src/main/generated/data/minecraft/item/emerald.json @@ -1,6 +1,7 @@ { "behavior": { - "minecraft:stackable": 64 + "minecraft:stackable": 64, + "minecraft:trim_material_provider": "minecraft:emerald" }, "display": { "model": "minecraft:emerald", diff --git a/src/main/generated/data/minecraft/item/end_crystal.json b/src/main/generated/data/minecraft/item/end_crystal.json index 4eac24ed..9c13312f 100644 --- a/src/main/generated/data/minecraft/item/end_crystal.json +++ b/src/main/generated/data/minecraft/item/end_crystal.json @@ -1,9 +1,7 @@ { "behavior": { "minecraft:entity": { - "entity": { - "type": "minecraft:end_crystal" - } + "entity": "minecraft:end_crystal" }, "minecraft:stackable": 64 }, 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 8303b729..0a5df00d 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 @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:ender_dragon" - }, + "entity": "minecraft:ender_dragon", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 1842204, - 14711290 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:ender_dragon_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/ender_eye.json b/src/main/generated/data/minecraft/item/ender_eye.json index 7788ec26..6612072f 100644 --- a/src/main/generated/data/minecraft/item/ender_eye.json +++ b/src/main/generated/data/minecraft/item/ender_eye.json @@ -4,9 +4,7 @@ "block": true }, "minecraft:projectile": { - "entity": { - "type": "minecraft:eye_of_ender" - } + "entity": "minecraft:eye_of_ender" }, "minecraft:stackable": 64, "minecraft:throwable": { @@ -27,7 +25,7 @@ "max": 0.5, "min": 0.33 }, - "position": "this", + "position": "origin", "sound": "minecraft:entity.ender_eye.launch", "volume": 1.0 } @@ -40,7 +38,7 @@ { "action": { "type": "minecraft:modify_block_state", - "position": "target", + "position": "interacted", "properties": { "eye": "true" }, @@ -55,7 +53,8 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } }, { @@ -63,7 +62,7 @@ "type": "minecraft:play_sound", "category": "block", "pitch": 1.0, - "position": "target", + "position": "interacted", "sound": "minecraft:block.end_portal_frame.fill", "volume": 1.0 } @@ -91,7 +90,7 @@ "particle": { "type": "minecraft:smoke" }, - "position": "target", + "position": "interacted", "speed": 0.0 } }, @@ -99,7 +98,7 @@ "entry": { "action": { "type": "minecraft:light_end_portal", - "position": "target" + "position": "interacted" } }, "optional": true @@ -107,20 +106,15 @@ ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:end_portal_frame", - "state": { - "eye": "false" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:end_portal_frame", + "state": { + "eye": "false" } } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/ender_pearl.json b/src/main/generated/data/minecraft/item/ender_pearl.json index 95d51e06..6b6a3a5d 100644 --- a/src/main/generated/data/minecraft/item/ender_pearl.json +++ b/src/main/generated/data/minecraft/item/ender_pearl.json @@ -4,9 +4,7 @@ "ticks": 20 }, "minecraft:projectile": { - "entity": { - "type": "minecraft:ender_pearl" - } + "entity": "minecraft:ender_pearl" }, "minecraft:stackable": 16, "minecraft:throwable": { 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 fdbe7fa9..03ef5768 100644 --- a/src/main/generated/data/minecraft/item/enderman_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/enderman_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:enderman" - }, + "entity": "minecraft:enderman", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 1447446, - 0 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:enderman_spawn_egg", 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 9736bbc3..3bc69afe 100644 --- a/src/main/generated/data/minecraft/item/endermite_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/endermite_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:endermite" - }, + "entity": "minecraft:endermite", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 1447446, - 7237230 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:endermite_spawn_egg", 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 88d03beb..216be775 100644 --- a/src/main/generated/data/minecraft/item/evoker_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/evoker_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:evoker" - }, + "entity": "minecraft:evoker", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 9804699, - 1973274 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:evoker_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/experience_bottle.json b/src/main/generated/data/minecraft/item/experience_bottle.json index f9c702bd..4f0b0af0 100644 --- a/src/main/generated/data/minecraft/item/experience_bottle.json +++ b/src/main/generated/data/minecraft/item/experience_bottle.json @@ -4,9 +4,7 @@ "behavior": "minecraft:shoot_bottle" }, "minecraft:projectile": { - "entity": { - "type": "minecraft:experience_bottle" - } + "entity": "minecraft:experience_bottle" }, "minecraft:stackable": 64, "minecraft:throwable": { diff --git a/src/main/generated/data/minecraft/item/eye_armor_trim_smithing_template.json b/src/main/generated/data/minecraft/item/eye_armor_trim_smithing_template.json index 900617ce..040d3476 100644 --- a/src/main/generated/data/minecraft/item/eye_armor_trim_smithing_template.json +++ b/src/main/generated/data/minecraft/item/eye_armor_trim_smithing_template.json @@ -1,13 +1,44 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:eye_pattern" - }, + "minecraft:smithing_template_provider": "minecraft:trim_pattern", "minecraft:stackable": 64 }, "display": { "model": "minecraft:eye_armor_trim_smithing_template", "rarity": "uncommon", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.eye_armor_trim_smithing_template" } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/fern.json b/src/main/generated/data/minecraft/item/fern.json index c81a06ca..aa0f37bf 100644 --- a/src/main/generated/data/minecraft/item/fern.json +++ b/src/main/generated/data/minecraft/item/fern.json @@ -6,13 +6,7 @@ "minecraft:compostable": { "level_increase_chance": 0.65 }, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:grass", - "biome": "minecraft:plains" - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:fern", @@ -27,7 +21,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_fern" } @@ -38,7 +32,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -59,23 +53,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/filled_map.json b/src/main/generated/data/minecraft/item/filled_map.json index b60073bc..5c76a8e5 100644 --- a/src/main/generated/data/minecraft/item/filled_map.json +++ b/src/main/generated/data/minecraft/item/filled_map.json @@ -1,12 +1,7 @@ { "behavior": { "minecraft:map_holder": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:map" - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:filled_map", @@ -21,12 +16,13 @@ { "action": { "type": "minecraft:mark_banner_on_item", - "position": "target" + "position": "interacted" } }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] diff --git a/src/main/generated/data/minecraft/item/fire_charge.json b/src/main/generated/data/minecraft/item/fire_charge.json index 5114e9fb..dc84b0d4 100644 --- a/src/main/generated/data/minecraft/item/fire_charge.json +++ b/src/main/generated/data/minecraft/item/fire_charge.json @@ -5,9 +5,7 @@ }, "minecraft:firework_shape_modifier": "large_ball", "minecraft:projectile": { - "entity": { - "type": "minecraft:small_fireball" - } + "entity": "minecraft:small_fireball" }, "minecraft:stackable": 64 }, @@ -36,7 +34,7 @@ "max": 1.2, "min": 0.8 }, - "position": "target", + "position": "interacted", "sound": "minecraft:item.firecharge.use", "volume": 1.0 } diff --git a/src/main/generated/data/minecraft/item/firefly_bush.json b/src/main/generated/data/minecraft/item/firefly_bush.json new file mode 100644 index 00000000..2884e575 --- /dev/null +++ b/src/main/generated/data/minecraft/item/firefly_bush.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:firefly_bush" + }, + "minecraft:compostable": { + "level_increase_chance": 0.3 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:firefly_bush", + "translation_key": "block.minecraft.firefly_bush" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/firework_rocket.json b/src/main/generated/data/minecraft/item/firework_rocket.json index d479e0f4..e7b9a230 100644 --- a/src/main/generated/data/minecraft/item/firework_rocket.json +++ b/src/main/generated/data/minecraft/item/firework_rocket.json @@ -5,9 +5,7 @@ }, "minecraft:firework": {}, "minecraft:projectile": { - "entity": { - "type": "minecraft:firework_rocket" - } + "entity": "minecraft:firework_rocket" }, "minecraft:stackable": 64 }, diff --git a/src/main/generated/data/minecraft/item/firework_star.json b/src/main/generated/data/minecraft/item/firework_star.json index c6e9cdec..db801c56 100644 --- a/src/main/generated/data/minecraft/item/firework_star.json +++ b/src/main/generated/data/minecraft/item/firework_star.json @@ -1,12 +1,7 @@ { "behavior": { "minecraft:firework_explosion_holder": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:firework" - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:firework_star", diff --git a/src/main/generated/data/minecraft/item/flint_and_steel.json b/src/main/generated/data/minecraft/item/flint_and_steel.json index 33f4aecf..90e4c9e4 100644 --- a/src/main/generated/data/minecraft/item/flint_and_steel.json +++ b/src/main/generated/data/minecraft/item/flint_and_steel.json @@ -33,7 +33,7 @@ "max": 1.2, "min": 0.8 }, - "position": "target", + "position": "interacted", "sound": "minecraft:item.flintandsteel.use", "volume": 1.0 } diff --git a/src/main/generated/data/minecraft/item/flow_armor_trim_smithing_template.json b/src/main/generated/data/minecraft/item/flow_armor_trim_smithing_template.json index 5cb452f1..c8a9c246 100644 --- a/src/main/generated/data/minecraft/item/flow_armor_trim_smithing_template.json +++ b/src/main/generated/data/minecraft/item/flow_armor_trim_smithing_template.json @@ -1,13 +1,44 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:flow_pattern" - }, + "minecraft:smithing_template_provider": "minecraft:trim_pattern", "minecraft:stackable": 64 }, "display": { "model": "minecraft:flow_armor_trim_smithing_template", "rarity": "uncommon", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.flow_armor_trim_smithing_template" } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/flowering_azalea.json b/src/main/generated/data/minecraft/item/flowering_azalea.json index b346358e..3c3b7aa0 100644 --- a/src/main/generated/data/minecraft/item/flowering_azalea.json +++ b/src/main/generated/data/minecraft/item/flowering_azalea.json @@ -24,7 +24,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_flowering_azalea_bush" } @@ -35,7 +35,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -56,23 +56,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } 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 c2f530d0..e5d7b66f 100644 --- a/src/main/generated/data/minecraft/item/fox_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/fox_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:fox" - }, + "entity": "minecraft:fox", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 14005919, - 13396256 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:fox_spawn_egg", 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 3a2a990e..09cbe47b 100644 --- a/src/main/generated/data/minecraft/item/frog_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/frog_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:frog" - }, + "entity": "minecraft:frog", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 13661252, - 16762748 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:frog_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/furnace_minecart.json b/src/main/generated/data/minecraft/item/furnace_minecart.json index 13e0ea41..dd53efa6 100644 --- a/src/main/generated/data/minecraft/item/furnace_minecart.json +++ b/src/main/generated/data/minecraft/item/furnace_minecart.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:furnace_minecart" - } + "entity": "minecraft:furnace_minecart" }, "minecraft:stackable": 1 }, 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 e1276691..edaa4243 100644 --- a/src/main/generated/data/minecraft/item/ghast_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/ghast_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:ghast" - }, + "entity": "minecraft:ghast", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 16382457, - 12369084 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:ghast_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/glass_bottle.json b/src/main/generated/data/minecraft/item/glass_bottle.json index 69ea7bb4..ecfb32ab 100644 --- a/src/main/generated/data/minecraft/item/glass_bottle.json +++ b/src/main/generated/data/minecraft/item/glass_bottle.json @@ -15,12 +15,15 @@ { "action": { "type": "minecraft:exchange_item", - "components": { - "minecraft:potion_contents": { - "potion": "minecraft:water" - } - }, - "item": "minecraft:potion" + "item": { + "id": "minecraft:potion", + "components": { + "minecraft:potion_contents": { + "potion": "minecraft:water" + } + }, + "count": 1 + } } }, { @@ -28,7 +31,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:fluid_pickup", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -36,29 +39,25 @@ "type": "minecraft:play_sound", "category": "neutral", "pitch": 1.0, - "position": "this", + "position": "origin", "sound": "minecraft:item.bottle.fill", "volume": 1.0 } }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ], "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "fluid": { - "fluids": "#minecraft:water" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "fluid": { + "fluids": "#minecraft:water" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/glow_ink_sac.json b/src/main/generated/data/minecraft/item/glow_ink_sac.json index 54041f55..fb532eec 100644 --- a/src/main/generated/data/minecraft/item/glow_ink_sac.json +++ b/src/main/generated/data/minecraft/item/glow_ink_sac.json @@ -16,7 +16,7 @@ "action": { "type": "minecraft:modify_sign", "glow": true, - "position": "target" + "position": "interacted" } }, { @@ -27,23 +27,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "#minecraft:signs" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "#minecraft:signs" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/glow_item_frame.json b/src/main/generated/data/minecraft/item/glow_item_frame.json index 9d6d0a88..bf0c4d65 100644 --- a/src/main/generated/data/minecraft/item/glow_item_frame.json +++ b/src/main/generated/data/minecraft/item/glow_item_frame.json @@ -1,9 +1,7 @@ { "behavior": { "minecraft:entity": { - "entity": { - "type": "minecraft:glow_item_frame" - } + "entity": "minecraft:glow_item_frame" }, "minecraft:stackable": 64 }, 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 a1011319..ab0bc765 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 @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:glow_squid" - }, + "entity": "minecraft:glow_squid", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 611926, - 8778172 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:glow_squid_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/goat_horn.json b/src/main/generated/data/minecraft/item/goat_horn.json index dfcf263f..40d4bf2a 100644 --- a/src/main/generated/data/minecraft/item/goat_horn.json +++ b/src/main/generated/data/minecraft/item/goat_horn.json @@ -1,7 +1,7 @@ { "behavior": { "minecraft:playable": { - "instruments": "minecraft:goat_horns" + "default_instrument": "minecraft:ponder_goat_horn" }, "minecraft:stackable": 1, "minecraft:useable": { 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 df34b566..7b2c951b 100644 --- a/src/main/generated/data/minecraft/item/goat_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/goat_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:goat" - }, + "entity": "minecraft:goat", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 10851452, - 5589310 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:goat_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/gold_ingot.json b/src/main/generated/data/minecraft/item/gold_ingot.json index c9ef1f53..e69ea2bd 100644 --- a/src/main/generated/data/minecraft/item/gold_ingot.json +++ b/src/main/generated/data/minecraft/item/gold_ingot.json @@ -1,6 +1,7 @@ { "behavior": { - "minecraft:stackable": 64 + "minecraft:stackable": 64, + "minecraft:trim_material_provider": "minecraft:gold" }, "display": { "model": "minecraft:gold_ingot", diff --git a/src/main/generated/data/minecraft/item/golden_axe.json b/src/main/generated/data/minecraft/item/golden_axe.json index e1feb855..38714af8 100644 --- a/src/main/generated/data/minecraft/item/golden_axe.json +++ b/src/main/generated/data/minecraft/item/golden_axe.json @@ -29,7 +29,8 @@ "rules": [] }, "attack_speed": 0.25, - "damage_per_hit": 2 + "disable_blocking_for_seconds": 5.0, + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/golden_boots.json b/src/main/generated/data/minecraft/item/golden_boots.json index 3449e23d..cfe3c12e 100644 --- a/src/main/generated/data/minecraft/item/golden_boots.json +++ b/src/main/generated/data/minecraft/item/golden_boots.json @@ -19,8 +19,8 @@ "enchantability": 25 }, "minecraft:equipment": { + "asset_id": "minecraft:gold", "equip_sound": "minecraft:item.armor.equip_gold", - "model": "minecraft:gold", "slot": "feet" }, "minecraft:repairable": { diff --git a/src/main/generated/data/minecraft/item/golden_chestplate.json b/src/main/generated/data/minecraft/item/golden_chestplate.json index 983d4257..0c35e21d 100644 --- a/src/main/generated/data/minecraft/item/golden_chestplate.json +++ b/src/main/generated/data/minecraft/item/golden_chestplate.json @@ -19,8 +19,8 @@ "enchantability": 25 }, "minecraft:equipment": { + "asset_id": "minecraft:gold", "equip_sound": "minecraft:item.armor.equip_gold", - "model": "minecraft:gold", "slot": "chest" }, "minecraft:repairable": { diff --git a/src/main/generated/data/minecraft/item/golden_helmet.json b/src/main/generated/data/minecraft/item/golden_helmet.json index 9643dcef..6568f129 100644 --- a/src/main/generated/data/minecraft/item/golden_helmet.json +++ b/src/main/generated/data/minecraft/item/golden_helmet.json @@ -19,8 +19,8 @@ "enchantability": 25 }, "minecraft:equipment": { + "asset_id": "minecraft:gold", "equip_sound": "minecraft:item.armor.equip_gold", - "model": "minecraft:gold", "slot": "head" }, "minecraft:repairable": { diff --git a/src/main/generated/data/minecraft/item/golden_hoe.json b/src/main/generated/data/minecraft/item/golden_hoe.json index 7b0a13ee..2ac767f0 100644 --- a/src/main/generated/data/minecraft/item/golden_hoe.json +++ b/src/main/generated/data/minecraft/item/golden_hoe.json @@ -29,7 +29,7 @@ "rules": [] }, "attack_speed": 0.25, - "damage_per_hit": 2 + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/golden_horse_armor.json b/src/main/generated/data/minecraft/item/golden_horse_armor.json index 086d9fd5..d5297ad8 100644 --- a/src/main/generated/data/minecraft/item/golden_horse_armor.json +++ b/src/main/generated/data/minecraft/item/golden_horse_armor.json @@ -13,9 +13,10 @@ "behavior": "minecraft:equip_entity" }, "minecraft:equipment": { - "allowed_entities": "minecraft:horse", - "equip_sound": "minecraft:item.armor.equip_gold", - "model": "minecraft:gold", + "allowed_entities": "#minecraft:can_wear_horse_armor", + "asset_id": "minecraft:gold", + "damage_on_hurt": false, + "equip_sound": "minecraft:entity.horse.armor", "slot": "body" }, "minecraft:stackable": 1 diff --git a/src/main/generated/data/minecraft/item/golden_leggings.json b/src/main/generated/data/minecraft/item/golden_leggings.json index 6509a707..e330bd71 100644 --- a/src/main/generated/data/minecraft/item/golden_leggings.json +++ b/src/main/generated/data/minecraft/item/golden_leggings.json @@ -19,8 +19,8 @@ "enchantability": 25 }, "minecraft:equipment": { + "asset_id": "minecraft:gold", "equip_sound": "minecraft:item.armor.equip_gold", - "model": "minecraft:gold", "slot": "legs" }, "minecraft:repairable": { diff --git a/src/main/generated/data/minecraft/item/golden_pickaxe.json b/src/main/generated/data/minecraft/item/golden_pickaxe.json index f9e06186..f3805ab3 100644 --- a/src/main/generated/data/minecraft/item/golden_pickaxe.json +++ b/src/main/generated/data/minecraft/item/golden_pickaxe.json @@ -29,7 +29,7 @@ "rules": [] }, "attack_speed": 0.3, - "damage_per_hit": 2 + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/golden_shovel.json b/src/main/generated/data/minecraft/item/golden_shovel.json index b496c65f..3ffcc5f2 100644 --- a/src/main/generated/data/minecraft/item/golden_shovel.json +++ b/src/main/generated/data/minecraft/item/golden_shovel.json @@ -29,7 +29,7 @@ "rules": [] }, "attack_speed": 0.25, - "damage_per_hit": 2 + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/golden_sword.json b/src/main/generated/data/minecraft/item/golden_sword.json index 5562ad6f..48c096cf 100644 --- a/src/main/generated/data/minecraft/item/golden_sword.json +++ b/src/main/generated/data/minecraft/item/golden_sword.json @@ -11,6 +11,7 @@ }, "minecraft:stackable": 1, "minecraft:tool": { + "can_destroy_blocks_in_creative": false, "damage_per_block": 2, "rules": [ { diff --git a/src/main/generated/data/minecraft/item/grass_block.json b/src/main/generated/data/minecraft/item/grass_block.json index 931e3e4b..89bc7bdf 100644 --- a/src/main/generated/data/minecraft/item/grass_block.json +++ b/src/main/generated/data/minecraft/item/grass_block.json @@ -3,13 +3,7 @@ "minecraft:block": { "block": "minecraft:grass_block" }, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:grass", - "biome": "minecraft:plains" - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:grass_block", diff --git a/src/main/generated/data/minecraft/item/gray_carpet.json b/src/main/generated/data/minecraft/item/gray_carpet.json index b84930b6..9aba5685 100644 --- a/src/main/generated/data/minecraft/item/gray_carpet.json +++ b/src/main/generated/data/minecraft/item/gray_carpet.json @@ -11,8 +11,8 @@ "minecraft:llama", "minecraft:trader_llama" ], + "asset_id": "minecraft:gray_carpet", "equip_sound": "minecraft:entity.llama.swag", - "model": "minecraft:gray_carpet", "slot": "body" }, "minecraft:fuel": { diff --git a/src/main/generated/data/minecraft/item/green_carpet.json b/src/main/generated/data/minecraft/item/green_carpet.json index 99222190..4549961e 100644 --- a/src/main/generated/data/minecraft/item/green_carpet.json +++ b/src/main/generated/data/minecraft/item/green_carpet.json @@ -11,8 +11,8 @@ "minecraft:llama", "minecraft:trader_llama" ], + "asset_id": "minecraft:green_carpet", "equip_sound": "minecraft:entity.llama.swag", - "model": "minecraft:green_carpet", "slot": "body" }, "minecraft:fuel": { 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 754a660e..d17f11b6 100644 --- a/src/main/generated/data/minecraft/item/guardian_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/guardian_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:guardian" - }, + "entity": "minecraft:guardian", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 5931634, - 15826224 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:guardian_spawn_egg", 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 ca3ab5bf..3902326a 100644 --- a/src/main/generated/data/minecraft/item/hoglin_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/hoglin_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:hoglin" - }, + "entity": "minecraft:hoglin", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 13004373, - 6251620 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:hoglin_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/honeycomb.json b/src/main/generated/data/minecraft/item/honeycomb.json index 2c71bb7c..a88e0f66 100644 --- a/src/main/generated/data/minecraft/item/honeycomb.json +++ b/src/main/generated/data/minecraft/item/honeycomb.json @@ -23,7 +23,7 @@ { "action": { "type": "minecraft:modify_sign", - "position": "target", + "position": "interacted", "wax": true } }, @@ -35,23 +35,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "#minecraft:signs" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "#minecraft:signs" } - }, - "context": { - "entity": "this", - "position": "target" } } }, @@ -63,7 +59,7 @@ { "action": { "type": "minecraft:wax_block", - "position": "target" + "position": "interacted" } }, { @@ -74,7 +70,8 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] diff --git a/src/main/generated/data/minecraft/item/hopper_minecart.json b/src/main/generated/data/minecraft/item/hopper_minecart.json index 60748175..b875e185 100644 --- a/src/main/generated/data/minecraft/item/hopper_minecart.json +++ b/src/main/generated/data/minecraft/item/hopper_minecart.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:hopper_minecart" - } + "entity": "minecraft:hopper_minecart" }, "minecraft:stackable": 1 }, 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 a14ce7a7..a7e4d5e0 100644 --- a/src/main/generated/data/minecraft/item/horse_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/horse_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:horse" - }, + "entity": "minecraft:horse", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 12623485, - 15656192 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:horse_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/host_armor_trim_smithing_template.json b/src/main/generated/data/minecraft/item/host_armor_trim_smithing_template.json index a73b60fa..0245f3b7 100644 --- a/src/main/generated/data/minecraft/item/host_armor_trim_smithing_template.json +++ b/src/main/generated/data/minecraft/item/host_armor_trim_smithing_template.json @@ -1,13 +1,44 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:host_pattern" - }, + "minecraft:smithing_template_provider": "minecraft:trim_pattern", "minecraft:stackable": 64 }, "display": { "model": "minecraft:host_armor_trim_smithing_template", "rarity": "uncommon", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.host_armor_trim_smithing_template" } } \ 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 e68d34b7..01ca6a3d 100644 --- a/src/main/generated/data/minecraft/item/husk_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/husk_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:husk" - }, + "entity": "minecraft:husk", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 7958625, - 15125652 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:husk_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/ink_sac.json b/src/main/generated/data/minecraft/item/ink_sac.json index 39590abf..73162b61 100644 --- a/src/main/generated/data/minecraft/item/ink_sac.json +++ b/src/main/generated/data/minecraft/item/ink_sac.json @@ -16,7 +16,7 @@ "action": { "type": "minecraft:modify_sign", "glow": false, - "position": "target" + "position": "interacted" } }, { @@ -27,23 +27,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "#minecraft:signs" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "#minecraft:signs" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/iron_axe.json b/src/main/generated/data/minecraft/item/iron_axe.json index 0b7da415..d522a059 100644 --- a/src/main/generated/data/minecraft/item/iron_axe.json +++ b/src/main/generated/data/minecraft/item/iron_axe.json @@ -29,7 +29,8 @@ "rules": [] }, "attack_speed": 0.225, - "damage_per_hit": 2 + "disable_blocking_for_seconds": 5.0, + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/iron_boots.json b/src/main/generated/data/minecraft/item/iron_boots.json index 997b916f..62d68120 100644 --- a/src/main/generated/data/minecraft/item/iron_boots.json +++ b/src/main/generated/data/minecraft/item/iron_boots.json @@ -19,8 +19,8 @@ "enchantability": 9 }, "minecraft:equipment": { + "asset_id": "minecraft:iron", "equip_sound": "minecraft:item.armor.equip_iron", - "model": "minecraft:iron", "slot": "feet" }, "minecraft:repairable": { diff --git a/src/main/generated/data/minecraft/item/iron_chestplate.json b/src/main/generated/data/minecraft/item/iron_chestplate.json index cc553ec6..840b9575 100644 --- a/src/main/generated/data/minecraft/item/iron_chestplate.json +++ b/src/main/generated/data/minecraft/item/iron_chestplate.json @@ -19,8 +19,8 @@ "enchantability": 9 }, "minecraft:equipment": { + "asset_id": "minecraft:iron", "equip_sound": "minecraft:item.armor.equip_iron", - "model": "minecraft:iron", "slot": "chest" }, "minecraft:repairable": { 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 5ade1c0f..f6cee180 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 @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:iron_golem" - }, + "entity": "minecraft:iron_golem", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 14405058, - 7643954 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:iron_golem_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/iron_helmet.json b/src/main/generated/data/minecraft/item/iron_helmet.json index a98e3926..b0626ba6 100644 --- a/src/main/generated/data/minecraft/item/iron_helmet.json +++ b/src/main/generated/data/minecraft/item/iron_helmet.json @@ -19,8 +19,8 @@ "enchantability": 9 }, "minecraft:equipment": { + "asset_id": "minecraft:iron", "equip_sound": "minecraft:item.armor.equip_iron", - "model": "minecraft:iron", "slot": "head" }, "minecraft:repairable": { diff --git a/src/main/generated/data/minecraft/item/iron_hoe.json b/src/main/generated/data/minecraft/item/iron_hoe.json index 45981982..b6eadcde 100644 --- a/src/main/generated/data/minecraft/item/iron_hoe.json +++ b/src/main/generated/data/minecraft/item/iron_hoe.json @@ -29,7 +29,7 @@ "rules": [] }, "attack_speed": 0.75, - "damage_per_hit": 2 + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/iron_horse_armor.json b/src/main/generated/data/minecraft/item/iron_horse_armor.json index b3b210b1..eea89d8a 100644 --- a/src/main/generated/data/minecraft/item/iron_horse_armor.json +++ b/src/main/generated/data/minecraft/item/iron_horse_armor.json @@ -13,9 +13,10 @@ "behavior": "minecraft:equip_entity" }, "minecraft:equipment": { - "allowed_entities": "minecraft:horse", - "equip_sound": "minecraft:item.armor.equip_iron", - "model": "minecraft:iron", + "allowed_entities": "#minecraft:can_wear_horse_armor", + "asset_id": "minecraft:iron", + "damage_on_hurt": false, + "equip_sound": "minecraft:entity.horse.armor", "slot": "body" }, "minecraft:stackable": 1 diff --git a/src/main/generated/data/minecraft/item/iron_ingot.json b/src/main/generated/data/minecraft/item/iron_ingot.json index 15767c6b..3ec26816 100644 --- a/src/main/generated/data/minecraft/item/iron_ingot.json +++ b/src/main/generated/data/minecraft/item/iron_ingot.json @@ -1,6 +1,7 @@ { "behavior": { - "minecraft:stackable": 64 + "minecraft:stackable": 64, + "minecraft:trim_material_provider": "minecraft:iron" }, "display": { "model": "minecraft:iron_ingot", diff --git a/src/main/generated/data/minecraft/item/iron_leggings.json b/src/main/generated/data/minecraft/item/iron_leggings.json index 7bb94ecb..e2cb3d3a 100644 --- a/src/main/generated/data/minecraft/item/iron_leggings.json +++ b/src/main/generated/data/minecraft/item/iron_leggings.json @@ -19,8 +19,8 @@ "enchantability": 9 }, "minecraft:equipment": { + "asset_id": "minecraft:iron", "equip_sound": "minecraft:item.armor.equip_iron", - "model": "minecraft:iron", "slot": "legs" }, "minecraft:repairable": { diff --git a/src/main/generated/data/minecraft/item/iron_pickaxe.json b/src/main/generated/data/minecraft/item/iron_pickaxe.json index 8e29e465..0b3058d1 100644 --- a/src/main/generated/data/minecraft/item/iron_pickaxe.json +++ b/src/main/generated/data/minecraft/item/iron_pickaxe.json @@ -29,7 +29,7 @@ "rules": [] }, "attack_speed": 0.3, - "damage_per_hit": 2 + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/iron_shovel.json b/src/main/generated/data/minecraft/item/iron_shovel.json index e8870512..b1f3dc6a 100644 --- a/src/main/generated/data/minecraft/item/iron_shovel.json +++ b/src/main/generated/data/minecraft/item/iron_shovel.json @@ -29,7 +29,7 @@ "rules": [] }, "attack_speed": 0.25, - "damage_per_hit": 2 + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/iron_sword.json b/src/main/generated/data/minecraft/item/iron_sword.json index 40c0d960..8b9a089c 100644 --- a/src/main/generated/data/minecraft/item/iron_sword.json +++ b/src/main/generated/data/minecraft/item/iron_sword.json @@ -11,6 +11,7 @@ }, "minecraft:stackable": 1, "minecraft:tool": { + "can_destroy_blocks_in_creative": false, "damage_per_block": 2, "rules": [ { diff --git a/src/main/generated/data/minecraft/item/item_frame.json b/src/main/generated/data/minecraft/item/item_frame.json index 37659350..8cf04201 100644 --- a/src/main/generated/data/minecraft/item/item_frame.json +++ b/src/main/generated/data/minecraft/item/item_frame.json @@ -1,9 +1,7 @@ { "behavior": { "minecraft:entity": { - "entity": { - "type": "minecraft:item_frame" - } + "entity": "minecraft:item_frame" }, "minecraft:stackable": 64 }, diff --git a/src/main/generated/data/minecraft/item/jungle_boat.json b/src/main/generated/data/minecraft/item/jungle_boat.json index 2da2e83b..8daebdb7 100644 --- a/src/main/generated/data/minecraft/item/jungle_boat.json +++ b/src/main/generated/data/minecraft/item/jungle_boat.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:jungle_boat" - } + "entity": "minecraft:jungle_boat" }, "minecraft:fuel": { "ticks": 1200 diff --git a/src/main/generated/data/minecraft/item/jungle_chest_boat.json b/src/main/generated/data/minecraft/item/jungle_chest_boat.json index 30731949..0f694caf 100644 --- a/src/main/generated/data/minecraft/item/jungle_chest_boat.json +++ b/src/main/generated/data/minecraft/item/jungle_chest_boat.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:jungle_chest_boat" - } + "entity": "minecraft:jungle_chest_boat" }, "minecraft:fuel": { "ticks": 1200 diff --git a/src/main/generated/data/minecraft/item/jungle_leaves.json b/src/main/generated/data/minecraft/item/jungle_leaves.json index be196c5e..fb91dedd 100644 --- a/src/main/generated/data/minecraft/item/jungle_leaves.json +++ b/src/main/generated/data/minecraft/item/jungle_leaves.json @@ -6,13 +6,7 @@ "minecraft:compostable": { "level_increase_chance": 0.3 }, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:foliage", - "biome": "minecraft:plains" - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:jungle_leaves", diff --git a/src/main/generated/data/minecraft/item/jungle_sapling.json b/src/main/generated/data/minecraft/item/jungle_sapling.json index a37246bd..c71a08ce 100644 --- a/src/main/generated/data/minecraft/item/jungle_sapling.json +++ b/src/main/generated/data/minecraft/item/jungle_sapling.json @@ -24,7 +24,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_jungle_sapling" } @@ -35,7 +35,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -56,23 +56,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/lapis_lazuli.json b/src/main/generated/data/minecraft/item/lapis_lazuli.json index 373d3737..690b0ad8 100644 --- a/src/main/generated/data/minecraft/item/lapis_lazuli.json +++ b/src/main/generated/data/minecraft/item/lapis_lazuli.json @@ -1,6 +1,7 @@ { "behavior": { - "minecraft:stackable": 64 + "minecraft:stackable": 64, + "minecraft:trim_material_provider": "minecraft:lapis" }, "display": { "model": "minecraft:lapis_lazuli", diff --git a/src/main/generated/data/minecraft/item/large_fern.json b/src/main/generated/data/minecraft/item/large_fern.json index f1429edb..2fb4b2e7 100644 --- a/src/main/generated/data/minecraft/item/large_fern.json +++ b/src/main/generated/data/minecraft/item/large_fern.json @@ -6,13 +6,7 @@ "minecraft:compostable": { "level_increase_chance": 0.65 }, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:grass", - "biome": "minecraft:plains" - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:large_fern", diff --git a/src/main/generated/data/minecraft/item/lead.json b/src/main/generated/data/minecraft/item/lead.json index 108115fb..81d65a01 100644 --- a/src/main/generated/data/minecraft/item/lead.json +++ b/src/main/generated/data/minecraft/item/lead.json @@ -14,12 +14,14 @@ "entries": [ { "action": { - "type": "minecraft:attach_leashed_entities_on_block" + "type": "minecraft:attach_leashed_entities_on_block", + "position": "interacted" } }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] diff --git a/src/main/generated/data/minecraft/item/leaf_litter.json b/src/main/generated/data/minecraft/item/leaf_litter.json new file mode 100644 index 00000000..b6b67c72 --- /dev/null +++ b/src/main/generated/data/minecraft/item/leaf_litter.json @@ -0,0 +1,18 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:leaf_litter" + }, + "minecraft:compostable": { + "level_increase_chance": 0.3 + }, + "minecraft:fuel": { + "ticks": 100 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:leaf_litter", + "translation_key": "block.minecraft.leaf_litter" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/leather_boots.json b/src/main/generated/data/minecraft/item/leather_boots.json index 161efc82..cbfce9cb 100644 --- a/src/main/generated/data/minecraft/item/leather_boots.json +++ b/src/main/generated/data/minecraft/item/leather_boots.json @@ -22,20 +22,14 @@ "enchantability": 15 }, "minecraft:equipment": { + "asset_id": "minecraft:leather", "equip_sound": "minecraft:item.armor.equip_leather", - "model": "minecraft:leather", "slot": "feet" }, "minecraft:repairable": { "items": "#minecraft:repairs_leather_armor" }, - "minecraft:stackable": 1, - "minecraft:tinted": { - "tint": { - "type": "minecraft:dyeable", - "index": 0 - } - } + "minecraft:stackable": 1 }, "display": { "model": "minecraft:leather_boots", diff --git a/src/main/generated/data/minecraft/item/leather_chestplate.json b/src/main/generated/data/minecraft/item/leather_chestplate.json index 6d7bbcfd..066444a8 100644 --- a/src/main/generated/data/minecraft/item/leather_chestplate.json +++ b/src/main/generated/data/minecraft/item/leather_chestplate.json @@ -22,20 +22,14 @@ "enchantability": 15 }, "minecraft:equipment": { + "asset_id": "minecraft:leather", "equip_sound": "minecraft:item.armor.equip_leather", - "model": "minecraft:leather", "slot": "chest" }, "minecraft:repairable": { "items": "#minecraft:repairs_leather_armor" }, - "minecraft:stackable": 1, - "minecraft:tinted": { - "tint": { - "type": "minecraft:dyeable", - "index": 0 - } - } + "minecraft:stackable": 1 }, "display": { "model": "minecraft:leather_chestplate", diff --git a/src/main/generated/data/minecraft/item/leather_helmet.json b/src/main/generated/data/minecraft/item/leather_helmet.json index 7d0daad1..2ace084b 100644 --- a/src/main/generated/data/minecraft/item/leather_helmet.json +++ b/src/main/generated/data/minecraft/item/leather_helmet.json @@ -22,20 +22,14 @@ "enchantability": 15 }, "minecraft:equipment": { + "asset_id": "minecraft:leather", "equip_sound": "minecraft:item.armor.equip_leather", - "model": "minecraft:leather", "slot": "head" }, "minecraft:repairable": { "items": "#minecraft:repairs_leather_armor" }, - "minecraft:stackable": 1, - "minecraft:tinted": { - "tint": { - "type": "minecraft:dyeable", - "index": 0 - } - } + "minecraft:stackable": 1 }, "display": { "model": "minecraft:leather_helmet", diff --git a/src/main/generated/data/minecraft/item/leather_horse_armor.json b/src/main/generated/data/minecraft/item/leather_horse_armor.json index e42cb4f0..84ee190a 100644 --- a/src/main/generated/data/minecraft/item/leather_horse_armor.json +++ b/src/main/generated/data/minecraft/item/leather_horse_armor.json @@ -16,18 +16,13 @@ "default_color": -6265536 }, "minecraft:equipment": { - "allowed_entities": "minecraft:horse", - "equip_sound": "minecraft:item.armor.equip_leather", - "model": "minecraft:leather", + "allowed_entities": "#minecraft:can_wear_horse_armor", + "asset_id": "minecraft:leather", + "damage_on_hurt": false, + "equip_sound": "minecraft:entity.horse.armor", "slot": "body" }, - "minecraft:stackable": 1, - "minecraft:tinted": { - "tint": { - "type": "minecraft:dyeable", - "index": 0 - } - } + "minecraft:stackable": 1 }, "display": { "model": "minecraft:leather_horse_armor", diff --git a/src/main/generated/data/minecraft/item/leather_leggings.json b/src/main/generated/data/minecraft/item/leather_leggings.json index 421b9944..3cc9a5bd 100644 --- a/src/main/generated/data/minecraft/item/leather_leggings.json +++ b/src/main/generated/data/minecraft/item/leather_leggings.json @@ -22,20 +22,14 @@ "enchantability": 15 }, "minecraft:equipment": { + "asset_id": "minecraft:leather", "equip_sound": "minecraft:item.armor.equip_leather", - "model": "minecraft:leather", "slot": "legs" }, "minecraft:repairable": { "items": "#minecraft:repairs_leather_armor" }, - "minecraft:stackable": 1, - "minecraft:tinted": { - "tint": { - "type": "minecraft:dyeable", - "index": 0 - } - } + "minecraft:stackable": 1 }, "display": { "model": "minecraft:leather_leggings", diff --git a/src/main/generated/data/minecraft/item/light_blue_carpet.json b/src/main/generated/data/minecraft/item/light_blue_carpet.json index de889154..38f5bcf5 100644 --- a/src/main/generated/data/minecraft/item/light_blue_carpet.json +++ b/src/main/generated/data/minecraft/item/light_blue_carpet.json @@ -11,8 +11,8 @@ "minecraft:llama", "minecraft:trader_llama" ], + "asset_id": "minecraft:light_blue_carpet", "equip_sound": "minecraft:entity.llama.swag", - "model": "minecraft:light_blue_carpet", "slot": "body" }, "minecraft:fuel": { diff --git a/src/main/generated/data/minecraft/item/light_gray_carpet.json b/src/main/generated/data/minecraft/item/light_gray_carpet.json index 07456b21..ca00694f 100644 --- a/src/main/generated/data/minecraft/item/light_gray_carpet.json +++ b/src/main/generated/data/minecraft/item/light_gray_carpet.json @@ -11,8 +11,8 @@ "minecraft:llama", "minecraft:trader_llama" ], + "asset_id": "minecraft:light_gray_carpet", "equip_sound": "minecraft:entity.llama.swag", - "model": "minecraft:light_gray_carpet", "slot": "body" }, "minecraft:fuel": { diff --git a/src/main/generated/data/minecraft/item/lily_of_the_valley.json b/src/main/generated/data/minecraft/item/lily_of_the_valley.json index 2dde18f1..e79a9627 100644 --- a/src/main/generated/data/minecraft/item/lily_of_the_valley.json +++ b/src/main/generated/data/minecraft/item/lily_of_the_valley.json @@ -29,7 +29,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_lily_of_the_valley" } @@ -40,7 +40,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -61,23 +61,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/lily_pad.json b/src/main/generated/data/minecraft/item/lily_pad.json index 06607b0f..b9adfcd8 100644 --- a/src/main/generated/data/minecraft/item/lily_pad.json +++ b/src/main/generated/data/minecraft/item/lily_pad.json @@ -9,13 +9,7 @@ "minecraft:compostable": { "level_increase_chance": 0.65 }, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:constant", - "color": -9321636 - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:lily_pad", diff --git a/src/main/generated/data/minecraft/item/lime_carpet.json b/src/main/generated/data/minecraft/item/lime_carpet.json index 4ddc9073..6b6ec9f7 100644 --- a/src/main/generated/data/minecraft/item/lime_carpet.json +++ b/src/main/generated/data/minecraft/item/lime_carpet.json @@ -11,8 +11,8 @@ "minecraft:llama", "minecraft:trader_llama" ], + "asset_id": "minecraft:lime_carpet", "equip_sound": "minecraft:entity.llama.swag", - "model": "minecraft:lime_carpet", "slot": "body" }, "minecraft:fuel": { diff --git a/src/main/generated/data/minecraft/item/lingering_potion.json b/src/main/generated/data/minecraft/item/lingering_potion.json index dce6fcc6..4cb97b82 100644 --- a/src/main/generated/data/minecraft/item/lingering_potion.json +++ b/src/main/generated/data/minecraft/item/lingering_potion.json @@ -7,19 +7,12 @@ "duration_multiplier": 0.25 }, "minecraft:projectile": { - "entity": { - "type": "minecraft:potion" - } + "entity": "minecraft:lingering_potion" }, "minecraft:stackable": 1, "minecraft:throwable": { "angle_offset": -20.0, "speed": 0.5 - }, - "minecraft:tinted": { - "tint": { - "type": "minecraft:potion" - } } }, "display": { 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 ffdd15f2..0757f86a 100644 --- a/src/main/generated/data/minecraft/item/llama_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/llama_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:llama" - }, + "entity": "minecraft:llama", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 12623485, - 10051392 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:llama_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/mace.json b/src/main/generated/data/minecraft/item/mace.json index 8997490a..549af49b 100644 --- a/src/main/generated/data/minecraft/item/mace.json +++ b/src/main/generated/data/minecraft/item/mace.json @@ -16,7 +16,7 @@ }, "minecraft:weapon": { "attack_damage": { - "default_damage": 6.0, + "default_damage": 5.0, "rules": [] }, "attack_speed": 0.15, diff --git a/src/main/generated/data/minecraft/item/magenta_carpet.json b/src/main/generated/data/minecraft/item/magenta_carpet.json index 255d65a3..3221d874 100644 --- a/src/main/generated/data/minecraft/item/magenta_carpet.json +++ b/src/main/generated/data/minecraft/item/magenta_carpet.json @@ -11,8 +11,8 @@ "minecraft:llama", "minecraft:trader_llama" ], + "asset_id": "minecraft:magenta_carpet", "equip_sound": "minecraft:entity.llama.swag", - "model": "minecraft:magenta_carpet", "slot": "body" }, "minecraft:fuel": { 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 2e0d16aa..a135c703 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 @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:magma_cube" - }, + "entity": "minecraft:magma_cube", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 3407872, - 16579584 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:magma_cube_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/mangrove_boat.json b/src/main/generated/data/minecraft/item/mangrove_boat.json index c2cd8bf0..7dc56058 100644 --- a/src/main/generated/data/minecraft/item/mangrove_boat.json +++ b/src/main/generated/data/minecraft/item/mangrove_boat.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:mangrove_boat" - } + "entity": "minecraft:mangrove_boat" }, "minecraft:fuel": { "ticks": 1200 diff --git a/src/main/generated/data/minecraft/item/mangrove_chest_boat.json b/src/main/generated/data/minecraft/item/mangrove_chest_boat.json index db56677b..7daba45f 100644 --- a/src/main/generated/data/minecraft/item/mangrove_chest_boat.json +++ b/src/main/generated/data/minecraft/item/mangrove_chest_boat.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:mangrove_chest_boat" - } + "entity": "minecraft:mangrove_chest_boat" }, "minecraft:fuel": { "ticks": 1200 diff --git a/src/main/generated/data/minecraft/item/mangrove_leaves.json b/src/main/generated/data/minecraft/item/mangrove_leaves.json index 34cfea16..9bdf7517 100644 --- a/src/main/generated/data/minecraft/item/mangrove_leaves.json +++ b/src/main/generated/data/minecraft/item/mangrove_leaves.json @@ -6,13 +6,7 @@ "minecraft:compostable": { "level_increase_chance": 0.3 }, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:constant", - "color": -7158200 - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:mangrove_leaves", diff --git a/src/main/generated/data/minecraft/item/mangrove_propagule.json b/src/main/generated/data/minecraft/item/mangrove_propagule.json index 9a00a710..90bcc6f1 100644 --- a/src/main/generated/data/minecraft/item/mangrove_propagule.json +++ b/src/main/generated/data/minecraft/item/mangrove_propagule.json @@ -24,7 +24,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_mangrove_propagule" } @@ -35,7 +35,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -56,23 +56,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/minecart.json b/src/main/generated/data/minecraft/item/minecart.json index 962a8cd1..4f81ff98 100644 --- a/src/main/generated/data/minecraft/item/minecart.json +++ b/src/main/generated/data/minecraft/item/minecart.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:minecart" - } + "entity": "minecraft:minecart" }, "minecraft:stackable": 1 }, 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 d240c0d1..a427aa60 100644 --- a/src/main/generated/data/minecraft/item/mooshroom_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/mooshroom_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:mooshroom" - }, + "entity": "minecraft:mooshroom", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 10489616, - 12040119 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:mooshroom_spawn_egg", 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 b2aad31f..2962b467 100644 --- a/src/main/generated/data/minecraft/item/mule_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/mule_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:mule" - }, + "entity": "minecraft:mule", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 1769984, - 5321501 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:mule_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/name_tag.json b/src/main/generated/data/minecraft/item/name_tag.json index 258e442b..ed8c64df 100644 --- a/src/main/generated/data/minecraft/item/name_tag.json +++ b/src/main/generated/data/minecraft/item/name_tag.json @@ -15,7 +15,7 @@ { "action": { "type": "minecraft:set_entity_name_from_item", - "entity": "target" + "entity": "target_entity" } }, { @@ -26,7 +26,8 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] diff --git a/src/main/generated/data/minecraft/item/netherite_axe.json b/src/main/generated/data/minecraft/item/netherite_axe.json index 61ac2508..27c1ef6a 100644 --- a/src/main/generated/data/minecraft/item/netherite_axe.json +++ b/src/main/generated/data/minecraft/item/netherite_axe.json @@ -32,7 +32,8 @@ "rules": [] }, "attack_speed": 0.25, - "damage_per_hit": 2 + "disable_blocking_for_seconds": 5.0, + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/netherite_boots.json b/src/main/generated/data/minecraft/item/netherite_boots.json index 63c68805..4434fd9c 100644 --- a/src/main/generated/data/minecraft/item/netherite_boots.json +++ b/src/main/generated/data/minecraft/item/netherite_boots.json @@ -33,8 +33,8 @@ "enchantability": 15 }, "minecraft:equipment": { + "asset_id": "minecraft:netherite", "equip_sound": "minecraft:item.armor.equip_netherite", - "model": "minecraft:netherite", "slot": "feet" }, "minecraft:immune_to_damage": { diff --git a/src/main/generated/data/minecraft/item/netherite_chestplate.json b/src/main/generated/data/minecraft/item/netherite_chestplate.json index 7dada8a5..77120fcc 100644 --- a/src/main/generated/data/minecraft/item/netherite_chestplate.json +++ b/src/main/generated/data/minecraft/item/netherite_chestplate.json @@ -33,8 +33,8 @@ "enchantability": 15 }, "minecraft:equipment": { + "asset_id": "minecraft:netherite", "equip_sound": "minecraft:item.armor.equip_netherite", - "model": "minecraft:netherite", "slot": "chest" }, "minecraft:immune_to_damage": { diff --git a/src/main/generated/data/minecraft/item/netherite_helmet.json b/src/main/generated/data/minecraft/item/netherite_helmet.json index 5aba2758..f1637ad8 100644 --- a/src/main/generated/data/minecraft/item/netherite_helmet.json +++ b/src/main/generated/data/minecraft/item/netherite_helmet.json @@ -33,8 +33,8 @@ "enchantability": 15 }, "minecraft:equipment": { + "asset_id": "minecraft:netherite", "equip_sound": "minecraft:item.armor.equip_netherite", - "model": "minecraft:netherite", "slot": "head" }, "minecraft:immune_to_damage": { diff --git a/src/main/generated/data/minecraft/item/netherite_hoe.json b/src/main/generated/data/minecraft/item/netherite_hoe.json index 3c53188a..5bcde35c 100644 --- a/src/main/generated/data/minecraft/item/netherite_hoe.json +++ b/src/main/generated/data/minecraft/item/netherite_hoe.json @@ -32,7 +32,7 @@ "rules": [] }, "attack_speed": 1.0, - "damage_per_hit": 2 + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/netherite_ingot.json b/src/main/generated/data/minecraft/item/netherite_ingot.json index 23cb38ff..585b261a 100644 --- a/src/main/generated/data/minecraft/item/netherite_ingot.json +++ b/src/main/generated/data/minecraft/item/netherite_ingot.json @@ -3,7 +3,8 @@ "minecraft:immune_to_damage": { "damage": "minecraft:is_fire" }, - "minecraft:stackable": 64 + "minecraft:stackable": 64, + "minecraft:trim_material_provider": "minecraft:netherite" }, "display": { "model": "minecraft:netherite_ingot", diff --git a/src/main/generated/data/minecraft/item/netherite_leggings.json b/src/main/generated/data/minecraft/item/netherite_leggings.json index 5589accc..002bdc6b 100644 --- a/src/main/generated/data/minecraft/item/netherite_leggings.json +++ b/src/main/generated/data/minecraft/item/netherite_leggings.json @@ -33,8 +33,8 @@ "enchantability": 15 }, "minecraft:equipment": { + "asset_id": "minecraft:netherite", "equip_sound": "minecraft:item.armor.equip_netherite", - "model": "minecraft:netherite", "slot": "legs" }, "minecraft:immune_to_damage": { diff --git a/src/main/generated/data/minecraft/item/netherite_pickaxe.json b/src/main/generated/data/minecraft/item/netherite_pickaxe.json index 648220e6..580d81a2 100644 --- a/src/main/generated/data/minecraft/item/netherite_pickaxe.json +++ b/src/main/generated/data/minecraft/item/netherite_pickaxe.json @@ -32,7 +32,7 @@ "rules": [] }, "attack_speed": 0.3, - "damage_per_hit": 2 + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/netherite_shovel.json b/src/main/generated/data/minecraft/item/netherite_shovel.json index bff386d9..00521bca 100644 --- a/src/main/generated/data/minecraft/item/netherite_shovel.json +++ b/src/main/generated/data/minecraft/item/netherite_shovel.json @@ -32,7 +32,7 @@ "rules": [] }, "attack_speed": 0.25, - "damage_per_hit": 2 + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/netherite_sword.json b/src/main/generated/data/minecraft/item/netherite_sword.json index 3f59ccda..fac68759 100644 --- a/src/main/generated/data/minecraft/item/netherite_sword.json +++ b/src/main/generated/data/minecraft/item/netherite_sword.json @@ -14,6 +14,7 @@ }, "minecraft:stackable": 1, "minecraft:tool": { + "can_destroy_blocks_in_creative": false, "damage_per_block": 2, "rules": [ { diff --git a/src/main/generated/data/minecraft/item/netherite_upgrade_smithing_template.json b/src/main/generated/data/minecraft/item/netherite_upgrade_smithing_template.json index ac2874c4..222e0324 100644 --- a/src/main/generated/data/minecraft/item/netherite_upgrade_smithing_template.json +++ b/src/main/generated/data/minecraft/item/netherite_upgrade_smithing_template.json @@ -1,13 +1,42 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:netherite_upgrade" - }, + "minecraft:smithing_template_provider": "minecraft:item_upgrade", "minecraft:stackable": 64 }, "display": { "model": "minecraft:netherite_upgrade_smithing_template", "rarity": "uncommon", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "translate": "smithing_template.minecraft.netherite_upgrade.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "translate": "smithing_template.minecraft.netherite_upgrade.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.netherite_upgrade_smithing_template" } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/oak_boat.json b/src/main/generated/data/minecraft/item/oak_boat.json index ba44271c..8bbd9f8c 100644 --- a/src/main/generated/data/minecraft/item/oak_boat.json +++ b/src/main/generated/data/minecraft/item/oak_boat.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:oak_boat" - } + "entity": "minecraft:oak_boat" }, "minecraft:fuel": { "ticks": 1200 diff --git a/src/main/generated/data/minecraft/item/oak_chest_boat.json b/src/main/generated/data/minecraft/item/oak_chest_boat.json index 4048f118..4f7f995d 100644 --- a/src/main/generated/data/minecraft/item/oak_chest_boat.json +++ b/src/main/generated/data/minecraft/item/oak_chest_boat.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:oak_chest_boat" - } + "entity": "minecraft:oak_chest_boat" }, "minecraft:fuel": { "ticks": 1200 diff --git a/src/main/generated/data/minecraft/item/oak_leaves.json b/src/main/generated/data/minecraft/item/oak_leaves.json index 82abb7de..9eb6718d 100644 --- a/src/main/generated/data/minecraft/item/oak_leaves.json +++ b/src/main/generated/data/minecraft/item/oak_leaves.json @@ -6,13 +6,7 @@ "minecraft:compostable": { "level_increase_chance": 0.3 }, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:foliage", - "biome": "minecraft:plains" - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:oak_leaves", diff --git a/src/main/generated/data/minecraft/item/oak_sapling.json b/src/main/generated/data/minecraft/item/oak_sapling.json index d08966fa..47cddd6a 100644 --- a/src/main/generated/data/minecraft/item/oak_sapling.json +++ b/src/main/generated/data/minecraft/item/oak_sapling.json @@ -24,7 +24,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_oak_sapling" } @@ -35,7 +35,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -56,23 +56,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } 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 b1557812..30c4bc56 100644 --- a/src/main/generated/data/minecraft/item/ocelot_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/ocelot_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:ocelot" - }, + "entity": "minecraft:ocelot", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 15720061, - 5653556 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:ocelot_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/ominous_bottle.json b/src/main/generated/data/minecraft/item/ominous_bottle.json index 461ddde7..6327ee2e 100644 --- a/src/main/generated/data/minecraft/item/ominous_bottle.json +++ b/src/main/generated/data/minecraft/item/ominous_bottle.json @@ -24,7 +24,7 @@ "action": { "type": "minecraft:play_sound", "pitch": 1.0, - "position": "this", + "position": "origin", "sound": "minecraft:item.ominous_bottle.dispose", "volume": 1.0 } diff --git a/src/main/generated/data/minecraft/item/open_eyeblossom.json b/src/main/generated/data/minecraft/item/open_eyeblossom.json new file mode 100644 index 00000000..693664c0 --- /dev/null +++ b/src/main/generated/data/minecraft/item/open_eyeblossom.json @@ -0,0 +1,81 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:open_eyeblossom" + }, + "minecraft:compostable": { + "level_increase_chance": 0.65 + }, + "minecraft:stackable": 64, + "minecraft:suspicious_effect_ingredient": { + "effects": [ + { + "id": "minecraft:blindness", + "duration": 140 + } + ] + } + }, + "display": { + "model": "minecraft:open_eyeblossom", + "translation_key": "block.minecraft.open_eyeblossom" + }, + "events": { + "minecraft:use_on_block": { + "action": { + "type": "minecraft:sequence", + "handler": "minecraft:passing", + "entries": [ + { + "action": { + "type": "minecraft:set_block_state", + "position": "interacted", + "state": { + "Name": "minecraft:potted_open_eyeblossom" + } + } + }, + { + "action": { + "type": "minecraft:invoke_game_event", + "event": "minecraft:block_change", + "entity": "this", + "position": "interacted" + } + }, + { + "action": { + "type": "minecraft:increment_stat", + "entity": "this", + "stat": { + "type": "minecraft:custom", + "entry": "minecraft:pot_flower" + } + } + }, + { + "action": { + "type": "minecraft:decrement_item", + "amount": 1 + } + }, + { + "action": { + "type": "minecraft:swing_hand", + "entity": "this" + } + } + ] + }, + "requirements": { + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" + } + } + } + } + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/orange_carpet.json b/src/main/generated/data/minecraft/item/orange_carpet.json index 8694f717..499b6036 100644 --- a/src/main/generated/data/minecraft/item/orange_carpet.json +++ b/src/main/generated/data/minecraft/item/orange_carpet.json @@ -11,8 +11,8 @@ "minecraft:llama", "minecraft:trader_llama" ], + "asset_id": "minecraft:orange_carpet", "equip_sound": "minecraft:entity.llama.swag", - "model": "minecraft:orange_carpet", "slot": "body" }, "minecraft:fuel": { diff --git a/src/main/generated/data/minecraft/item/orange_tulip.json b/src/main/generated/data/minecraft/item/orange_tulip.json index 318c2e88..2d10fa29 100644 --- a/src/main/generated/data/minecraft/item/orange_tulip.json +++ b/src/main/generated/data/minecraft/item/orange_tulip.json @@ -29,7 +29,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_orange_tulip" } @@ -40,7 +40,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -61,23 +61,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/oxeye_daisy.json b/src/main/generated/data/minecraft/item/oxeye_daisy.json index aeb46d94..0c44084e 100644 --- a/src/main/generated/data/minecraft/item/oxeye_daisy.json +++ b/src/main/generated/data/minecraft/item/oxeye_daisy.json @@ -28,7 +28,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_oxeye_daisy" } @@ -39,7 +39,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -60,23 +60,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/painting.json b/src/main/generated/data/minecraft/item/painting.json index 3ea3d81d..0b60842d 100644 --- a/src/main/generated/data/minecraft/item/painting.json +++ b/src/main/generated/data/minecraft/item/painting.json @@ -1,9 +1,7 @@ { "behavior": { "minecraft:entity": { - "entity": { - "type": "minecraft:painting" - } + "entity": "minecraft:painting" }, "minecraft:stackable": 64 }, diff --git a/src/main/generated/data/minecraft/item/pale_hanging_moss.json b/src/main/generated/data/minecraft/item/pale_hanging_moss.json new file mode 100644 index 00000000..c0681fba --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_hanging_moss.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:pale_hanging_moss" + }, + "minecraft:compostable": { + "level_increase_chance": 0.3 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:pale_hanging_moss", + "translation_key": "block.minecraft.pale_hanging_moss" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_moss_block.json b/src/main/generated/data/minecraft/item/pale_moss_block.json new file mode 100644 index 00000000..eaf798dd --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_moss_block.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:pale_moss_block" + }, + "minecraft:compostable": { + "level_increase_chance": 0.65 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:pale_moss_block", + "translation_key": "block.minecraft.pale_moss_block" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_moss_carpet.json b/src/main/generated/data/minecraft/item/pale_moss_carpet.json new file mode 100644 index 00000000..e70da3f5 --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_moss_carpet.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:pale_moss_carpet" + }, + "minecraft:compostable": { + "level_increase_chance": 0.3 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:pale_moss_carpet", + "translation_key": "block.minecraft.pale_moss_carpet" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_oak_boat.json b/src/main/generated/data/minecraft/item/pale_oak_boat.json new file mode 100644 index 00000000..60945613 --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_oak_boat.json @@ -0,0 +1,18 @@ +{ + "behavior": { + "minecraft:dispensable": { + "behavior": "minecraft:spawn_entity_from_item" + }, + "minecraft:entity": { + "entity": "minecraft:pale_oak_boat" + }, + "minecraft:fuel": { + "ticks": 1200 + }, + "minecraft:stackable": 1 + }, + "display": { + "model": "minecraft:pale_oak_boat", + "translation_key": "item.minecraft.pale_oak_boat" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_oak_button.json b/src/main/generated/data/minecraft/item/pale_oak_button.json new file mode 100644 index 00000000..15bf89af --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_oak_button.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:pale_oak_button" + }, + "minecraft:fuel": { + "ticks": 100 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:pale_oak_button", + "translation_key": "block.minecraft.pale_oak_button" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_oak_chest_boat.json b/src/main/generated/data/minecraft/item/pale_oak_chest_boat.json new file mode 100644 index 00000000..80851676 --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_oak_chest_boat.json @@ -0,0 +1,18 @@ +{ + "behavior": { + "minecraft:dispensable": { + "behavior": "minecraft:spawn_entity_from_item" + }, + "minecraft:entity": { + "entity": "minecraft:pale_oak_chest_boat" + }, + "minecraft:fuel": { + "ticks": 1200 + }, + "minecraft:stackable": 1 + }, + "display": { + "model": "minecraft:pale_oak_chest_boat", + "translation_key": "item.minecraft.pale_oak_chest_boat" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_oak_door.json b/src/main/generated/data/minecraft/item/pale_oak_door.json new file mode 100644 index 00000000..2f5459f0 --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_oak_door.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:pale_oak_door" + }, + "minecraft:fuel": { + "ticks": 200 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:pale_oak_door", + "translation_key": "block.minecraft.pale_oak_door" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_oak_fence.json b/src/main/generated/data/minecraft/item/pale_oak_fence.json new file mode 100644 index 00000000..e0caf193 --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_oak_fence.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:pale_oak_fence" + }, + "minecraft:fuel": { + "ticks": 300 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:pale_oak_fence", + "translation_key": "block.minecraft.pale_oak_fence" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_oak_fence_gate.json b/src/main/generated/data/minecraft/item/pale_oak_fence_gate.json new file mode 100644 index 00000000..706c8fc9 --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_oak_fence_gate.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:pale_oak_fence_gate" + }, + "minecraft:fuel": { + "ticks": 300 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:pale_oak_fence_gate", + "translation_key": "block.minecraft.pale_oak_fence_gate" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_oak_hanging_sign.json b/src/main/generated/data/minecraft/item/pale_oak_hanging_sign.json new file mode 100644 index 00000000..726e041a --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_oak_hanging_sign.json @@ -0,0 +1,20 @@ +{ + "behavior": { + "minecraft:block": { + "block": { + "type": "minecraft:attached_to_side", + "attached_block": "minecraft:pale_oak_hanging_sign", + "attached_side": "up", + "other_block": "minecraft:pale_oak_wall_hanging_sign" + } + }, + "minecraft:fuel": { + "ticks": 800 + }, + "minecraft:stackable": 16 + }, + "display": { + "model": "minecraft:pale_oak_hanging_sign", + "translation_key": "block.minecraft.pale_oak_hanging_sign" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_oak_leaves.json b/src/main/generated/data/minecraft/item/pale_oak_leaves.json new file mode 100644 index 00000000..2d77b2a6 --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_oak_leaves.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:pale_oak_leaves" + }, + "minecraft:compostable": { + "level_increase_chance": 0.3 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:pale_oak_leaves", + "translation_key": "block.minecraft.pale_oak_leaves" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_oak_log.json b/src/main/generated/data/minecraft/item/pale_oak_log.json new file mode 100644 index 00000000..ad4129f5 --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_oak_log.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:pale_oak_log" + }, + "minecraft:fuel": { + "ticks": 300 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:pale_oak_log", + "translation_key": "block.minecraft.pale_oak_log" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_oak_planks.json b/src/main/generated/data/minecraft/item/pale_oak_planks.json new file mode 100644 index 00000000..adf02055 --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_oak_planks.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:pale_oak_planks" + }, + "minecraft:fuel": { + "ticks": 300 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:pale_oak_planks", + "translation_key": "block.minecraft.pale_oak_planks" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_oak_pressure_plate.json b/src/main/generated/data/minecraft/item/pale_oak_pressure_plate.json new file mode 100644 index 00000000..d79b386a --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_oak_pressure_plate.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:pale_oak_pressure_plate" + }, + "minecraft:fuel": { + "ticks": 300 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:pale_oak_pressure_plate", + "translation_key": "block.minecraft.pale_oak_pressure_plate" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_oak_sapling.json b/src/main/generated/data/minecraft/item/pale_oak_sapling.json new file mode 100644 index 00000000..8e82aa7c --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_oak_sapling.json @@ -0,0 +1,76 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:pale_oak_sapling" + }, + "minecraft:compostable": { + "level_increase_chance": 0.3 + }, + "minecraft:fuel": { + "ticks": 100 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:pale_oak_sapling", + "translation_key": "block.minecraft.pale_oak_sapling" + }, + "events": { + "minecraft:use_on_block": { + "action": { + "type": "minecraft:sequence", + "handler": "minecraft:passing", + "entries": [ + { + "action": { + "type": "minecraft:set_block_state", + "position": "interacted", + "state": { + "Name": "minecraft:potted_pale_oak_sapling" + } + } + }, + { + "action": { + "type": "minecraft:invoke_game_event", + "event": "minecraft:block_change", + "entity": "this", + "position": "interacted" + } + }, + { + "action": { + "type": "minecraft:increment_stat", + "entity": "this", + "stat": { + "type": "minecraft:custom", + "entry": "minecraft:pot_flower" + } + } + }, + { + "action": { + "type": "minecraft:decrement_item", + "amount": 1 + } + }, + { + "action": { + "type": "minecraft:swing_hand", + "entity": "this" + } + } + ] + }, + "requirements": { + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" + } + } + } + } + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_oak_sign.json b/src/main/generated/data/minecraft/item/pale_oak_sign.json new file mode 100644 index 00000000..3f431db7 --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_oak_sign.json @@ -0,0 +1,20 @@ +{ + "behavior": { + "minecraft:block": { + "block": { + "type": "minecraft:attached_to_side", + "attached_block": "minecraft:pale_oak_sign", + "attached_side": "down", + "other_block": "minecraft:pale_oak_wall_sign" + } + }, + "minecraft:fuel": { + "ticks": 200 + }, + "minecraft:stackable": 16 + }, + "display": { + "model": "minecraft:pale_oak_sign", + "translation_key": "block.minecraft.pale_oak_sign" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_oak_slab.json b/src/main/generated/data/minecraft/item/pale_oak_slab.json new file mode 100644 index 00000000..3bba06a4 --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_oak_slab.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:pale_oak_slab" + }, + "minecraft:fuel": { + "ticks": 150 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:pale_oak_slab", + "translation_key": "block.minecraft.pale_oak_slab" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_oak_stairs.json b/src/main/generated/data/minecraft/item/pale_oak_stairs.json new file mode 100644 index 00000000..e0bf2271 --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_oak_stairs.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:pale_oak_stairs" + }, + "minecraft:fuel": { + "ticks": 300 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:pale_oak_stairs", + "translation_key": "block.minecraft.pale_oak_stairs" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_oak_trapdoor.json b/src/main/generated/data/minecraft/item/pale_oak_trapdoor.json new file mode 100644 index 00000000..0753b06b --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_oak_trapdoor.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:pale_oak_trapdoor" + }, + "minecraft:fuel": { + "ticks": 300 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:pale_oak_trapdoor", + "translation_key": "block.minecraft.pale_oak_trapdoor" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pale_oak_wood.json b/src/main/generated/data/minecraft/item/pale_oak_wood.json new file mode 100644 index 00000000..5c7a012c --- /dev/null +++ b/src/main/generated/data/minecraft/item/pale_oak_wood.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:pale_oak_wood" + }, + "minecraft:fuel": { + "ticks": 300 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:pale_oak_wood", + "translation_key": "block.minecraft.pale_oak_wood" + } +} \ 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 a8eb5b00..6f36016f 100644 --- a/src/main/generated/data/minecraft/item/panda_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/panda_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:panda" - }, + "entity": "minecraft:panda", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 15198183, - 1776418 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:panda_spawn_egg", 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 4dd1e7b5..07fa36e5 100644 --- a/src/main/generated/data/minecraft/item/parrot_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/parrot_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:parrot" - }, + "entity": "minecraft:parrot", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 894731, - 16711680 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:parrot_spawn_egg", 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 0374d441..03c873c7 100644 --- a/src/main/generated/data/minecraft/item/phantom_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/phantom_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:phantom" - }, + "entity": "minecraft:phantom", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 4411786, - 8978176 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:phantom_spawn_egg", 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 29f68905..ef83ae4f 100644 --- a/src/main/generated/data/minecraft/item/pig_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/pig_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:pig" - }, + "entity": "minecraft:pig", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 15771042, - 14377823 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:pig_spawn_egg", 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 2464c674..19b7757d 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 @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:piglin_brute" - }, + "entity": "minecraft:piglin_brute", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 5843472, - 16380836 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:piglin_brute_spawn_egg", 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 6bff66ea..5cb04138 100644 --- a/src/main/generated/data/minecraft/item/piglin_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/piglin_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:piglin" - }, + "entity": "minecraft:piglin", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 10051392, - 16380836 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:piglin_spawn_egg", 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 1a2fa339..c33dd4aa 100644 --- a/src/main/generated/data/minecraft/item/pillager_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/pillager_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:pillager" - }, + "entity": "minecraft:pillager", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 5451574, - 9804699 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:pillager_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/pink_carpet.json b/src/main/generated/data/minecraft/item/pink_carpet.json index a97536e7..783c7546 100644 --- a/src/main/generated/data/minecraft/item/pink_carpet.json +++ b/src/main/generated/data/minecraft/item/pink_carpet.json @@ -11,8 +11,8 @@ "minecraft:llama", "minecraft:trader_llama" ], + "asset_id": "minecraft:pink_carpet", "equip_sound": "minecraft:entity.llama.swag", - "model": "minecraft:pink_carpet", "slot": "body" }, "minecraft:fuel": { diff --git a/src/main/generated/data/minecraft/item/pink_tulip.json b/src/main/generated/data/minecraft/item/pink_tulip.json index 0371ecc7..4651e803 100644 --- a/src/main/generated/data/minecraft/item/pink_tulip.json +++ b/src/main/generated/data/minecraft/item/pink_tulip.json @@ -29,7 +29,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_pink_tulip" } @@ -40,7 +40,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -61,23 +61,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/poisonous_potato.json b/src/main/generated/data/minecraft/item/poisonous_potato.json index 556effc6..2fe32d5c 100644 --- a/src/main/generated/data/minecraft/item/poisonous_potato.json +++ b/src/main/generated/data/minecraft/item/poisonous_potato.json @@ -32,14 +32,8 @@ "entity": "this" }, "requirements": { - "conditions": { - "chance": 0.6, - "condition": "minecraft:random_chance" - }, - "context": { - "entity": "this", - "position": "this" - } + "chance": 0.6, + "condition": "minecraft:random_chance" } } } 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 75a2b370..9fb4c6ee 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 @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:polar_bear" - }, + "entity": "minecraft:polar_bear", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 15658718, - 14014157 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:polar_bear_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/poppy.json b/src/main/generated/data/minecraft/item/poppy.json index 38d98e0b..ddd5ded0 100644 --- a/src/main/generated/data/minecraft/item/poppy.json +++ b/src/main/generated/data/minecraft/item/poppy.json @@ -29,7 +29,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_poppy" } @@ -40,7 +40,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -61,23 +61,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/potion.json b/src/main/generated/data/minecraft/item/potion.json index 135fdea3..9bae58e2 100644 --- a/src/main/generated/data/minecraft/item/potion.json +++ b/src/main/generated/data/minecraft/item/potion.json @@ -7,16 +7,10 @@ "minecraft:dispensable": { "behavior": "minecraft:use_item_on_block_or_dispense_item" }, - "minecraft:potion": {}, "minecraft:potion_holder": { "duration_multiplier": 1.0 }, "minecraft:stackable": 1, - "minecraft:tinted": { - "tint": { - "type": "minecraft:potion" - } - }, "minecraft:useable": { "animation": "drink", "remainder": { @@ -41,7 +35,7 @@ "type": "minecraft:play_sound", "category": "block", "pitch": 1.0, - "position": "target", + "position": "interacted", "sound": "minecraft:entity.generic.splash", "volume": 1.0 } @@ -49,7 +43,10 @@ { "action": { "type": "minecraft:exchange_item", - "item": "minecraft:glass_bottle" + "item": { + "id": "minecraft:glass_bottle", + "count": 1 + } } }, { @@ -75,7 +72,7 @@ "particle": { "type": "minecraft:splash" }, - "position": "target", + "position": "interacted", "speed": 1.0 } }, @@ -84,7 +81,7 @@ "type": "minecraft:play_sound", "category": "block", "pitch": 1.0, - "position": "target", + "position": "interacted", "sound": "minecraft:item.bottle.empty", "volume": 1.0 } @@ -92,7 +89,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:mud" } @@ -100,45 +97,41 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ], "requirements": { - "conditions": { - "condition": "minecraft:all_of", - "terms": [ - { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:side_check", - "sides": [ - "down" - ] - } - }, - { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "#minecraft:convertable_to_mud" - } + "condition": "minecraft:all_of", + "terms": [ + { + "condition": "minecraft:inverted", + "term": { + "condition": "minecraft:side_check", + "sides": [ + "down" + ] + } + }, + { + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "#minecraft:convertable_to_mud" } - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:potion_contents": "minecraft:water" - } + } + }, + { + "condition": "minecraft:match_tool", + "predicate": { + "predicates": { + "minecraft:potion_contents": "minecraft:water" } } - ] - }, - "context": { - "entity": "this", - "position": "target" - } + } + ] } } } diff --git a/src/main/generated/data/minecraft/item/pufferfish_bucket.json b/src/main/generated/data/minecraft/item/pufferfish_bucket.json index 900a80d5..cf9a8e55 100644 --- a/src/main/generated/data/minecraft/item/pufferfish_bucket.json +++ b/src/main/generated/data/minecraft/item/pufferfish_bucket.json @@ -3,9 +3,7 @@ "minecraft:bucket": { "emptying_sound_event": "minecraft:item.bucket.empty_fish", "entity": { - "entity": { - "type": "minecraft:pufferfish" - }, + "entity": "minecraft:pufferfish", "require_other_successful_placement": true }, "fluid": "minecraft:water", 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 ec406b78..ac696e1e 100644 --- a/src/main/generated/data/minecraft/item/pufferfish_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/pufferfish_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:pufferfish" - }, + "entity": "minecraft:pufferfish", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 16167425, - 3654642 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:pufferfish_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/purple_carpet.json b/src/main/generated/data/minecraft/item/purple_carpet.json index 07bc071d..2581274a 100644 --- a/src/main/generated/data/minecraft/item/purple_carpet.json +++ b/src/main/generated/data/minecraft/item/purple_carpet.json @@ -11,8 +11,8 @@ "minecraft:llama", "minecraft:trader_llama" ], + "asset_id": "minecraft:purple_carpet", "equip_sound": "minecraft:entity.llama.swag", - "model": "minecraft:purple_carpet", "slot": "body" }, "minecraft:fuel": { diff --git a/src/main/generated/data/minecraft/item/quartz.json b/src/main/generated/data/minecraft/item/quartz.json index 5b2dccf6..098371db 100644 --- a/src/main/generated/data/minecraft/item/quartz.json +++ b/src/main/generated/data/minecraft/item/quartz.json @@ -1,6 +1,7 @@ { "behavior": { - "minecraft:stackable": 64 + "minecraft:stackable": 64, + "minecraft:trim_material_provider": "minecraft:quartz" }, "display": { "model": "minecraft:quartz", 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 2efb9add..72db87c6 100644 --- a/src/main/generated/data/minecraft/item/rabbit_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/rabbit_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:rabbit" - }, + "entity": "minecraft:rabbit", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 10051392, - 7555121 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:rabbit_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/raiser_armor_trim_smithing_template.json b/src/main/generated/data/minecraft/item/raiser_armor_trim_smithing_template.json index 28303a03..73c4c4cf 100644 --- a/src/main/generated/data/minecraft/item/raiser_armor_trim_smithing_template.json +++ b/src/main/generated/data/minecraft/item/raiser_armor_trim_smithing_template.json @@ -1,13 +1,44 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:raiser_pattern" - }, + "minecraft:smithing_template_provider": "minecraft:trim_pattern", "minecraft:stackable": 64 }, "display": { "model": "minecraft:raiser_armor_trim_smithing_template", "rarity": "uncommon", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.raiser_armor_trim_smithing_template" } } \ No newline at end of file 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 1133b816..8bbb9ac3 100644 --- a/src/main/generated/data/minecraft/item/ravager_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/ravager_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:ravager" - }, + "entity": "minecraft:ravager", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 7697520, - 5984329 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:ravager_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/recovery_compass.json b/src/main/generated/data/minecraft/item/recovery_compass.json index 4981ef3e..474fc670 100644 --- a/src/main/generated/data/minecraft/item/recovery_compass.json +++ b/src/main/generated/data/minecraft/item/recovery_compass.json @@ -1,8 +1,5 @@ { "behavior": { - "minecraft:pointable": { - "points_to": "minecraft:last_death" - }, "minecraft:stackable": 64 }, "display": { diff --git a/src/main/generated/data/minecraft/item/red_carpet.json b/src/main/generated/data/minecraft/item/red_carpet.json index 66251998..e3a32171 100644 --- a/src/main/generated/data/minecraft/item/red_carpet.json +++ b/src/main/generated/data/minecraft/item/red_carpet.json @@ -11,8 +11,8 @@ "minecraft:llama", "minecraft:trader_llama" ], + "asset_id": "minecraft:red_carpet", "equip_sound": "minecraft:entity.llama.swag", - "model": "minecraft:red_carpet", "slot": "body" }, "minecraft:fuel": { diff --git a/src/main/generated/data/minecraft/item/red_mushroom.json b/src/main/generated/data/minecraft/item/red_mushroom.json index 933703c9..50119ace 100644 --- a/src/main/generated/data/minecraft/item/red_mushroom.json +++ b/src/main/generated/data/minecraft/item/red_mushroom.json @@ -21,7 +21,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_red_mushroom" } @@ -32,7 +32,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -53,23 +53,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/red_tulip.json b/src/main/generated/data/minecraft/item/red_tulip.json index 11190e0b..50f21e7e 100644 --- a/src/main/generated/data/minecraft/item/red_tulip.json +++ b/src/main/generated/data/minecraft/item/red_tulip.json @@ -29,7 +29,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_red_tulip" } @@ -40,7 +40,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -61,23 +61,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/redstone.json b/src/main/generated/data/minecraft/item/redstone.json index ae531cec..5adbc879 100644 --- a/src/main/generated/data/minecraft/item/redstone.json +++ b/src/main/generated/data/minecraft/item/redstone.json @@ -3,7 +3,8 @@ "minecraft:block": { "block": "minecraft:redstone_wire" }, - "minecraft:stackable": 64 + "minecraft:stackable": 64, + "minecraft:trim_material_provider": "minecraft:redstone" }, "display": { "model": "minecraft:redstone", diff --git a/src/main/generated/data/minecraft/item/resin_block.json b/src/main/generated/data/minecraft/item/resin_block.json new file mode 100644 index 00000000..9258e423 --- /dev/null +++ b/src/main/generated/data/minecraft/item/resin_block.json @@ -0,0 +1,12 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:resin_block" + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:resin_block", + "translation_key": "block.minecraft.resin_block" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/resin_brick.json b/src/main/generated/data/minecraft/item/resin_brick.json new file mode 100644 index 00000000..7d3c88e9 --- /dev/null +++ b/src/main/generated/data/minecraft/item/resin_brick.json @@ -0,0 +1,10 @@ +{ + "behavior": { + "minecraft:stackable": 64, + "minecraft:trim_material_provider": "minecraft:resin" + }, + "display": { + "model": "minecraft:resin_brick", + "translation_key": "item.minecraft.resin_brick" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/resin_brick_slab.json b/src/main/generated/data/minecraft/item/resin_brick_slab.json new file mode 100644 index 00000000..901ae430 --- /dev/null +++ b/src/main/generated/data/minecraft/item/resin_brick_slab.json @@ -0,0 +1,12 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:resin_brick_slab" + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:resin_brick_slab", + "translation_key": "block.minecraft.resin_brick_slab" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/resin_brick_stairs.json b/src/main/generated/data/minecraft/item/resin_brick_stairs.json new file mode 100644 index 00000000..05c183d1 --- /dev/null +++ b/src/main/generated/data/minecraft/item/resin_brick_stairs.json @@ -0,0 +1,12 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:resin_brick_stairs" + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:resin_brick_stairs", + "translation_key": "block.minecraft.resin_brick_stairs" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/resin_brick_wall.json b/src/main/generated/data/minecraft/item/resin_brick_wall.json new file mode 100644 index 00000000..40e45809 --- /dev/null +++ b/src/main/generated/data/minecraft/item/resin_brick_wall.json @@ -0,0 +1,12 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:resin_brick_wall" + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:resin_brick_wall", + "translation_key": "block.minecraft.resin_brick_wall" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/resin_bricks.json b/src/main/generated/data/minecraft/item/resin_bricks.json new file mode 100644 index 00000000..c71a241f --- /dev/null +++ b/src/main/generated/data/minecraft/item/resin_bricks.json @@ -0,0 +1,12 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:resin_bricks" + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:resin_bricks", + "translation_key": "block.minecraft.resin_bricks" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/resin_clump.json b/src/main/generated/data/minecraft/item/resin_clump.json new file mode 100644 index 00000000..eb20f4af --- /dev/null +++ b/src/main/generated/data/minecraft/item/resin_clump.json @@ -0,0 +1,12 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:resin_clump" + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:resin_clump", + "translation_key": "item.minecraft.resin_clump" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/rib_armor_trim_smithing_template.json b/src/main/generated/data/minecraft/item/rib_armor_trim_smithing_template.json index 53a66840..94ea495d 100644 --- a/src/main/generated/data/minecraft/item/rib_armor_trim_smithing_template.json +++ b/src/main/generated/data/minecraft/item/rib_armor_trim_smithing_template.json @@ -1,13 +1,44 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:rib_pattern" - }, + "minecraft:smithing_template_provider": "minecraft:trim_pattern", "minecraft:stackable": 64 }, "display": { "model": "minecraft:rib_armor_trim_smithing_template", "rarity": "uncommon", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.rib_armor_trim_smithing_template" } } \ 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 94dd1361..7fbb48ea 100644 --- a/src/main/generated/data/minecraft/item/rotten_flesh.json +++ b/src/main/generated/data/minecraft/item/rotten_flesh.json @@ -32,14 +32,8 @@ "entity": "this" }, "requirements": { - "conditions": { - "chance": 0.8, - "condition": "minecraft:random_chance" - }, - "context": { - "entity": "this", - "position": "this" - } + "chance": 0.8, + "condition": "minecraft:random_chance" } } } diff --git a/src/main/generated/data/minecraft/item/saddle.json b/src/main/generated/data/minecraft/item/saddle.json index 4fb39cdc..81944b62 100644 --- a/src/main/generated/data/minecraft/item/saddle.json +++ b/src/main/generated/data/minecraft/item/saddle.json @@ -1,9 +1,15 @@ { "behavior": { "minecraft:dispensable": { - "behavior": "minecraft:saddle" + "behavior": "minecraft:equip_entity" + }, + "minecraft:equipment": { + "allowed_entities": "#minecraft:can_equip_saddle", + "asset_id": "minecraft:saddle", + "equip_on_interact": true, + "equip_sound": "minecraft:entity.horse.saddle", + "slot": "saddle" }, - "minecraft:saddle": {}, "minecraft:stackable": 1 }, "display": { diff --git a/src/main/generated/data/minecraft/item/salmon_bucket.json b/src/main/generated/data/minecraft/item/salmon_bucket.json index f7423305..c3721d34 100644 --- a/src/main/generated/data/minecraft/item/salmon_bucket.json +++ b/src/main/generated/data/minecraft/item/salmon_bucket.json @@ -3,9 +3,7 @@ "minecraft:bucket": { "emptying_sound_event": "minecraft:item.bucket.empty_fish", "entity": { - "entity": { - "type": "minecraft:salmon" - }, + "entity": "minecraft:salmon", "require_other_successful_placement": true }, "fluid": "minecraft:water", 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 8b1cb9b1..3c971dee 100644 --- a/src/main/generated/data/minecraft/item/salmon_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/salmon_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:salmon" - }, + "entity": "minecraft:salmon", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 10489616, - 951412 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:salmon_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/sentry_armor_trim_smithing_template.json b/src/main/generated/data/minecraft/item/sentry_armor_trim_smithing_template.json index ec8605aa..98d28da8 100644 --- a/src/main/generated/data/minecraft/item/sentry_armor_trim_smithing_template.json +++ b/src/main/generated/data/minecraft/item/sentry_armor_trim_smithing_template.json @@ -1,13 +1,44 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:sentry_pattern" - }, + "minecraft:smithing_template_provider": "minecraft:trim_pattern", "minecraft:stackable": 64 }, "display": { "model": "minecraft:sentry_armor_trim_smithing_template", "rarity": "uncommon", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.sentry_armor_trim_smithing_template" } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/shaper_armor_trim_smithing_template.json b/src/main/generated/data/minecraft/item/shaper_armor_trim_smithing_template.json index 79f22f63..79ea43bd 100644 --- a/src/main/generated/data/minecraft/item/shaper_armor_trim_smithing_template.json +++ b/src/main/generated/data/minecraft/item/shaper_armor_trim_smithing_template.json @@ -1,13 +1,44 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:shaper_pattern" - }, + "minecraft:smithing_template_provider": "minecraft:trim_pattern", "minecraft:stackable": 64 }, "display": { "model": "minecraft:shaper_armor_trim_smithing_template", "rarity": "uncommon", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.shaper_armor_trim_smithing_template" } } \ 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 9deadb42..cb8955a2 100644 --- a/src/main/generated/data/minecraft/item/sheep_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/sheep_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:sheep" - }, + "entity": "minecraft:sheep", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 15198183, - 16758197 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:sheep_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/shield.json b/src/main/generated/data/minecraft/item/shield.json index 7ead730e..89358302 100644 --- a/src/main/generated/data/minecraft/item/shield.json +++ b/src/main/generated/data/minecraft/item/shield.json @@ -1,5 +1,16 @@ { "behavior": { + "minecraft:attack_blocking": { + "block_delay_seconds": 0.25, + "block_sound": "minecraft:item.shield.block", + "bypassed_by": "#minecraft:bypasses_shield", + "disabled_sound": "minecraft:item.shield.break", + "item_damage": { + "base": 1.0, + "factor": 1.0, + "threshold": 3.0 + } + }, "minecraft:banner_pattern_holder": {}, "minecraft:damageable": { "durability": 336 diff --git a/src/main/generated/data/minecraft/item/short_dry_grass.json b/src/main/generated/data/minecraft/item/short_dry_grass.json new file mode 100644 index 00000000..079bf781 --- /dev/null +++ b/src/main/generated/data/minecraft/item/short_dry_grass.json @@ -0,0 +1,18 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:short_dry_grass" + }, + "minecraft:compostable": { + "level_increase_chance": 0.3 + }, + "minecraft:fuel": { + "ticks": 100 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:short_dry_grass", + "translation_key": "block.minecraft.short_dry_grass" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/short_grass.json b/src/main/generated/data/minecraft/item/short_grass.json index bd25c24d..3e151e8b 100644 --- a/src/main/generated/data/minecraft/item/short_grass.json +++ b/src/main/generated/data/minecraft/item/short_grass.json @@ -6,13 +6,7 @@ "minecraft:compostable": { "level_increase_chance": 0.3 }, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:grass", - "biome": "minecraft:plains" - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:short_grass", 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 69f7012e..abdb770e 100644 --- a/src/main/generated/data/minecraft/item/shulker_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/shulker_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:shulker" - }, + "entity": "minecraft:shulker", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 9725844, - 5060690 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:shulker_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/silence_armor_trim_smithing_template.json b/src/main/generated/data/minecraft/item/silence_armor_trim_smithing_template.json index 2bcc7b87..9eabffeb 100644 --- a/src/main/generated/data/minecraft/item/silence_armor_trim_smithing_template.json +++ b/src/main/generated/data/minecraft/item/silence_armor_trim_smithing_template.json @@ -1,13 +1,44 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:silence_pattern" - }, + "minecraft:smithing_template_provider": "minecraft:trim_pattern", "minecraft:stackable": 64 }, "display": { "model": "minecraft:silence_armor_trim_smithing_template", "rarity": "epic", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.silence_armor_trim_smithing_template" } } \ 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 039334fc..1e938503 100644 --- a/src/main/generated/data/minecraft/item/silverfish_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/silverfish_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:silverfish" - }, + "entity": "minecraft:silverfish", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 7237230, - 3158064 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:silverfish_spawn_egg", 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 a29285d6..9204261c 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 @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:skeleton_horse" - }, + "entity": "minecraft:skeleton_horse", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 6842447, - 15066584 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:skeleton_horse_spawn_egg", 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 5abafb26..e3b8cadd 100644 --- a/src/main/generated/data/minecraft/item/skeleton_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/skeleton_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:skeleton" - }, + "entity": "minecraft:skeleton", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 12698049, - 4802889 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:skeleton_spawn_egg", 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 c371fef8..96546919 100644 --- a/src/main/generated/data/minecraft/item/slime_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/slime_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:slime" - }, + "entity": "minecraft:slime", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 5349438, - 8306542 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:slime_spawn_egg", 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 4568ef20..fe03b074 100644 --- a/src/main/generated/data/minecraft/item/sniffer_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/sniffer_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:sniffer" - }, + "entity": "minecraft:sniffer", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 8855049, - 2468720 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:sniffer_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/snout_armor_trim_smithing_template.json b/src/main/generated/data/minecraft/item/snout_armor_trim_smithing_template.json index 798daa88..7782c944 100644 --- a/src/main/generated/data/minecraft/item/snout_armor_trim_smithing_template.json +++ b/src/main/generated/data/minecraft/item/snout_armor_trim_smithing_template.json @@ -1,13 +1,44 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:snout_pattern" - }, + "minecraft:smithing_template_provider": "minecraft:trim_pattern", "minecraft:stackable": 64 }, "display": { "model": "minecraft:snout_armor_trim_smithing_template", "rarity": "uncommon", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.snout_armor_trim_smithing_template" } } \ 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 bf77d06e..41e32067 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 @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:snow_golem" - }, + "entity": "minecraft:snow_golem", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 14283506, - 8496292 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:snow_golem_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/snowball.json b/src/main/generated/data/minecraft/item/snowball.json index 967d98e6..29bbf121 100644 --- a/src/main/generated/data/minecraft/item/snowball.json +++ b/src/main/generated/data/minecraft/item/snowball.json @@ -4,9 +4,7 @@ "behavior": "minecraft:shoot_projectile" }, "minecraft:projectile": { - "entity": { - "type": "minecraft:snowball" - } + "entity": "minecraft:snowball" }, "minecraft:stackable": 16, "minecraft:throwable": { diff --git a/src/main/generated/data/minecraft/item/spectral_arrow.json b/src/main/generated/data/minecraft/item/spectral_arrow.json index fcfc8f8e..2eb62863 100644 --- a/src/main/generated/data/minecraft/item/spectral_arrow.json +++ b/src/main/generated/data/minecraft/item/spectral_arrow.json @@ -4,9 +4,7 @@ "behavior": "minecraft:shoot_projectile" }, "minecraft:projectile": { - "entity": { - "type": "minecraft:spectral_arrow" - } + "entity": "minecraft:spectral_arrow" }, "minecraft:stackable": 64 }, 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 79d888b9..abd7c626 100644 --- a/src/main/generated/data/minecraft/item/spider_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/spider_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:spider" - }, + "entity": "minecraft:spider", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 3419431, - 11013646 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:spider_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/spire_armor_trim_smithing_template.json b/src/main/generated/data/minecraft/item/spire_armor_trim_smithing_template.json index ca61d85e..6a1610f5 100644 --- a/src/main/generated/data/minecraft/item/spire_armor_trim_smithing_template.json +++ b/src/main/generated/data/minecraft/item/spire_armor_trim_smithing_template.json @@ -1,13 +1,44 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:spire_pattern" - }, + "minecraft:smithing_template_provider": "minecraft:trim_pattern", "minecraft:stackable": 64 }, "display": { "model": "minecraft:spire_armor_trim_smithing_template", "rarity": "uncommon", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.spire_armor_trim_smithing_template" } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/splash_potion.json b/src/main/generated/data/minecraft/item/splash_potion.json index aa7071bb..77b15f63 100644 --- a/src/main/generated/data/minecraft/item/splash_potion.json +++ b/src/main/generated/data/minecraft/item/splash_potion.json @@ -7,19 +7,12 @@ "duration_multiplier": 1.0 }, "minecraft:projectile": { - "entity": { - "type": "minecraft:potion" - } + "entity": "minecraft:splash_potion" }, "minecraft:stackable": 1, "minecraft:throwable": { "angle_offset": -20.0, "speed": 0.5 - }, - "minecraft:tinted": { - "tint": { - "type": "minecraft:potion" - } } }, "display": { diff --git a/src/main/generated/data/minecraft/item/spruce_boat.json b/src/main/generated/data/minecraft/item/spruce_boat.json index f2af68b5..44b05567 100644 --- a/src/main/generated/data/minecraft/item/spruce_boat.json +++ b/src/main/generated/data/minecraft/item/spruce_boat.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:spruce_boat" - } + "entity": "minecraft:spruce_boat" }, "minecraft:fuel": { "ticks": 1200 diff --git a/src/main/generated/data/minecraft/item/spruce_chest_boat.json b/src/main/generated/data/minecraft/item/spruce_chest_boat.json index 5bb94d76..956e2e3d 100644 --- a/src/main/generated/data/minecraft/item/spruce_chest_boat.json +++ b/src/main/generated/data/minecraft/item/spruce_chest_boat.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:spruce_chest_boat" - } + "entity": "minecraft:spruce_chest_boat" }, "minecraft:fuel": { "ticks": 1200 diff --git a/src/main/generated/data/minecraft/item/spruce_leaves.json b/src/main/generated/data/minecraft/item/spruce_leaves.json index 9735b621..a1ffc6a9 100644 --- a/src/main/generated/data/minecraft/item/spruce_leaves.json +++ b/src/main/generated/data/minecraft/item/spruce_leaves.json @@ -6,13 +6,7 @@ "minecraft:compostable": { "level_increase_chance": 0.3 }, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:constant", - "color": -10380959 - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:spruce_leaves", diff --git a/src/main/generated/data/minecraft/item/spruce_sapling.json b/src/main/generated/data/minecraft/item/spruce_sapling.json index 6281e809..b1eca607 100644 --- a/src/main/generated/data/minecraft/item/spruce_sapling.json +++ b/src/main/generated/data/minecraft/item/spruce_sapling.json @@ -24,7 +24,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_spruce_sapling" } @@ -35,7 +35,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -56,23 +56,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } 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 4a593b06..a12db2c2 100644 --- a/src/main/generated/data/minecraft/item/squid_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/squid_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:squid" - }, + "entity": "minecraft:squid", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 2243405, - 7375001 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:squid_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/stone_axe.json b/src/main/generated/data/minecraft/item/stone_axe.json index 9c0ca595..0c13e0a2 100644 --- a/src/main/generated/data/minecraft/item/stone_axe.json +++ b/src/main/generated/data/minecraft/item/stone_axe.json @@ -29,7 +29,8 @@ "rules": [] }, "attack_speed": 0.2, - "damage_per_hit": 2 + "disable_blocking_for_seconds": 5.0, + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/stone_hoe.json b/src/main/generated/data/minecraft/item/stone_hoe.json index 6a3916bc..d29e71ea 100644 --- a/src/main/generated/data/minecraft/item/stone_hoe.json +++ b/src/main/generated/data/minecraft/item/stone_hoe.json @@ -29,7 +29,7 @@ "rules": [] }, "attack_speed": 0.5, - "damage_per_hit": 2 + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/stone_pickaxe.json b/src/main/generated/data/minecraft/item/stone_pickaxe.json index 1387786d..6d2db1b3 100644 --- a/src/main/generated/data/minecraft/item/stone_pickaxe.json +++ b/src/main/generated/data/minecraft/item/stone_pickaxe.json @@ -29,7 +29,7 @@ "rules": [] }, "attack_speed": 0.3, - "damage_per_hit": 2 + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/stone_shovel.json b/src/main/generated/data/minecraft/item/stone_shovel.json index 2120a114..35e9f06c 100644 --- a/src/main/generated/data/minecraft/item/stone_shovel.json +++ b/src/main/generated/data/minecraft/item/stone_shovel.json @@ -29,7 +29,7 @@ "rules": [] }, "attack_speed": 0.25, - "damage_per_hit": 2 + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/stone_sword.json b/src/main/generated/data/minecraft/item/stone_sword.json index 250f6465..51e67bc9 100644 --- a/src/main/generated/data/minecraft/item/stone_sword.json +++ b/src/main/generated/data/minecraft/item/stone_sword.json @@ -11,6 +11,7 @@ }, "minecraft:stackable": 1, "minecraft:tool": { + "can_destroy_blocks_in_creative": false, "damage_per_block": 2, "rules": [ { 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 f2c798de..e101440f 100644 --- a/src/main/generated/data/minecraft/item/stray_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/stray_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:stray" - }, + "entity": "minecraft:stray", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 6387319, - 14543594 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:stray_spawn_egg", 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 55098658..d9fd05ec 100644 --- a/src/main/generated/data/minecraft/item/strider_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/strider_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:strider" - }, + "entity": "minecraft:strider", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 10236982, - 5065037 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:strider_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/stripped_pale_oak_log.json b/src/main/generated/data/minecraft/item/stripped_pale_oak_log.json new file mode 100644 index 00000000..df895fe3 --- /dev/null +++ b/src/main/generated/data/minecraft/item/stripped_pale_oak_log.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:stripped_pale_oak_log" + }, + "minecraft:fuel": { + "ticks": 300 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:stripped_pale_oak_log", + "translation_key": "block.minecraft.stripped_pale_oak_log" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/stripped_pale_oak_wood.json b/src/main/generated/data/minecraft/item/stripped_pale_oak_wood.json new file mode 100644 index 00000000..b75e95d5 --- /dev/null +++ b/src/main/generated/data/minecraft/item/stripped_pale_oak_wood.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:stripped_pale_oak_wood" + }, + "minecraft:fuel": { + "ticks": 300 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:stripped_pale_oak_wood", + "translation_key": "block.minecraft.stripped_pale_oak_wood" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/tadpole_bucket.json b/src/main/generated/data/minecraft/item/tadpole_bucket.json index fa2a1066..120344c6 100644 --- a/src/main/generated/data/minecraft/item/tadpole_bucket.json +++ b/src/main/generated/data/minecraft/item/tadpole_bucket.json @@ -3,9 +3,7 @@ "minecraft:bucket": { "emptying_sound_event": "minecraft:item.bucket.empty_tadpole", "entity": { - "entity": { - "type": "minecraft:tadpole" - }, + "entity": "minecraft:tadpole", "require_other_successful_placement": true }, "fluid": "minecraft:water", 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 1bbdf196..242a1f87 100644 --- a/src/main/generated/data/minecraft/item/tadpole_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/tadpole_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:tadpole" - }, + "entity": "minecraft:tadpole", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 7164733, - 1444352 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:tadpole_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/tall_dry_grass.json b/src/main/generated/data/minecraft/item/tall_dry_grass.json new file mode 100644 index 00000000..c500de0c --- /dev/null +++ b/src/main/generated/data/minecraft/item/tall_dry_grass.json @@ -0,0 +1,18 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:tall_dry_grass" + }, + "minecraft:compostable": { + "level_increase_chance": 0.3 + }, + "minecraft:fuel": { + "ticks": 100 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:tall_dry_grass", + "translation_key": "block.minecraft.tall_dry_grass" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/tall_grass.json b/src/main/generated/data/minecraft/item/tall_grass.json index 0c67ebe3..ef96e131 100644 --- a/src/main/generated/data/minecraft/item/tall_grass.json +++ b/src/main/generated/data/minecraft/item/tall_grass.json @@ -6,13 +6,7 @@ "minecraft:compostable": { "level_increase_chance": 0.5 }, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:grass", - "biome": "minecraft:plains" - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:tall_grass", diff --git a/src/main/generated/data/minecraft/item/tide_armor_trim_smithing_template.json b/src/main/generated/data/minecraft/item/tide_armor_trim_smithing_template.json index 27eb4824..481da6be 100644 --- a/src/main/generated/data/minecraft/item/tide_armor_trim_smithing_template.json +++ b/src/main/generated/data/minecraft/item/tide_armor_trim_smithing_template.json @@ -1,13 +1,44 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:tide_pattern" - }, + "minecraft:smithing_template_provider": "minecraft:trim_pattern", "minecraft:stackable": 64 }, "display": { "model": "minecraft:tide_armor_trim_smithing_template", "rarity": "uncommon", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.tide_armor_trim_smithing_template" } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/tipped_arrow.json b/src/main/generated/data/minecraft/item/tipped_arrow.json index 6324b12e..b012afdb 100644 --- a/src/main/generated/data/minecraft/item/tipped_arrow.json +++ b/src/main/generated/data/minecraft/item/tipped_arrow.json @@ -7,16 +7,9 @@ "duration_multiplier": 0.125 }, "minecraft:projectile": { - "entity": { - "type": "minecraft:arrow" - } + "entity": "minecraft:arrow" }, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:potion" - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:tipped_arrow", diff --git a/src/main/generated/data/minecraft/item/tnt_minecart.json b/src/main/generated/data/minecraft/item/tnt_minecart.json index f5e20edb..bfeb9f6a 100644 --- a/src/main/generated/data/minecraft/item/tnt_minecart.json +++ b/src/main/generated/data/minecraft/item/tnt_minecart.json @@ -4,9 +4,7 @@ "behavior": "minecraft:spawn_entity_from_item" }, "minecraft:entity": { - "entity": { - "type": "minecraft:tnt_minecart" - } + "entity": "minecraft:tnt_minecart" }, "minecraft:stackable": 1 }, diff --git a/src/main/generated/data/minecraft/item/torchflower.json b/src/main/generated/data/minecraft/item/torchflower.json index 1f55212f..ab59e463 100644 --- a/src/main/generated/data/minecraft/item/torchflower.json +++ b/src/main/generated/data/minecraft/item/torchflower.json @@ -29,7 +29,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_torchflower" } @@ -40,7 +40,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -61,23 +61,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } 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 526d539a..115027c0 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 @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:trader_llama" - }, + "entity": "minecraft:trader_llama", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 15377456, - 4547222 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:trader_llama_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/trident.json b/src/main/generated/data/minecraft/item/trident.json index 8e1e7731..8a84fd7f 100644 --- a/src/main/generated/data/minecraft/item/trident.json +++ b/src/main/generated/data/minecraft/item/trident.json @@ -8,9 +8,7 @@ "enchantability": 1 }, "minecraft:projectile": { - "entity": { - "type": "minecraft:trident" - } + "entity": "minecraft:trident" }, "minecraft:stackable": 1, "minecraft:throwable": { @@ -21,6 +19,7 @@ "speed": 2.5 }, "minecraft:tool": { + "can_destroy_blocks_in_creative": false, "damage_per_block": 2, "rules": [] }, @@ -32,7 +31,7 @@ }, "minecraft:weapon": { "attack_damage": { - "default_damage": 9.0, + "default_damage": 8.0, "rules": [] }, "attack_speed": 0.275 @@ -63,37 +62,31 @@ ] }, "requirements": { - "conditions": { - "condition": "minecraft:all_of", - "terms": [ - { - "condition": "minecraft:entity_properties", - "entity": "this", - "predicate": { - "in_water_or_rain": true, - "used_item_ticks": { - "min": 10 - } + "condition": "minecraft:all_of", + "terms": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "in_water_or_rain": true, + "used_item_ticks": { + "min": 10 } - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:riptide" - } - ] - } + } + }, + { + "condition": "minecraft:match_tool", + "predicate": { + "predicates": { + "minecraft:enchantments": [ + { + "enchantments": "minecraft:riptide" + } + ] } } - ] - }, - "context": { - "entity": "this", - "position": "this" - } + } + ] } } } diff --git a/src/main/generated/data/minecraft/item/tropical_fish_bucket.json b/src/main/generated/data/minecraft/item/tropical_fish_bucket.json index 8891bdf3..d2774573 100644 --- a/src/main/generated/data/minecraft/item/tropical_fish_bucket.json +++ b/src/main/generated/data/minecraft/item/tropical_fish_bucket.json @@ -3,9 +3,7 @@ "minecraft:bucket": { "emptying_sound_event": "minecraft:item.bucket.empty_fish", "entity": { - "entity": { - "type": "minecraft:tropical_fish" - }, + "entity": "minecraft:tropical_fish", "require_other_successful_placement": true }, "fluid": "minecraft:water", 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 fb701222..b401f668 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 @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:tropical_fish" - }, + "entity": "minecraft:tropical_fish", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 15690005, - 16775663 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:tropical_fish_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/turtle_helmet.json b/src/main/generated/data/minecraft/item/turtle_helmet.json index 6a514f1f..03c6a89d 100644 --- a/src/main/generated/data/minecraft/item/turtle_helmet.json +++ b/src/main/generated/data/minecraft/item/turtle_helmet.json @@ -19,8 +19,8 @@ "enchantability": 9 }, "minecraft:equipment": { + "asset_id": "minecraft:turtle_scute", "equip_sound": "minecraft:item.armor.equip_turtle", - "model": "minecraft:turtle_scute", "slot": "head" }, "minecraft:repairable": { 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 e89d77b5..04e633ad 100644 --- a/src/main/generated/data/minecraft/item/turtle_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/turtle_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:turtle" - }, + "entity": "minecraft:turtle", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 15198183, - 44975 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:turtle_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/vex_armor_trim_smithing_template.json b/src/main/generated/data/minecraft/item/vex_armor_trim_smithing_template.json index 81937df6..0c9d7fcc 100644 --- a/src/main/generated/data/minecraft/item/vex_armor_trim_smithing_template.json +++ b/src/main/generated/data/minecraft/item/vex_armor_trim_smithing_template.json @@ -1,13 +1,44 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:vex_pattern" - }, + "minecraft:smithing_template_provider": "minecraft:trim_pattern", "minecraft:stackable": 64 }, "display": { "model": "minecraft:vex_armor_trim_smithing_template", "rarity": "uncommon", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.vex_armor_trim_smithing_template" } } \ 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 2fbf6bf1..d2a41843 100644 --- a/src/main/generated/data/minecraft/item/vex_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/vex_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:vex" - }, + "entity": "minecraft:vex", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 8032420, - 15265265 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:vex_spawn_egg", 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 6bac3f0c..6cb12b8c 100644 --- a/src/main/generated/data/minecraft/item/villager_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/villager_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:villager" - }, + "entity": "minecraft:villager", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 5651507, - 12422002 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:villager_spawn_egg", 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 be56aa85..ec4e8b0d 100644 --- a/src/main/generated/data/minecraft/item/vindicator_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/vindicator_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:vindicator" - }, + "entity": "minecraft:vindicator", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 9804699, - 2580065 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:vindicator_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/vine.json b/src/main/generated/data/minecraft/item/vine.json index bd435483..43cf42ed 100644 --- a/src/main/generated/data/minecraft/item/vine.json +++ b/src/main/generated/data/minecraft/item/vine.json @@ -6,13 +6,7 @@ "minecraft:compostable": { "level_increase_chance": 0.5 }, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:foliage", - "biome": "minecraft:plains" - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:vine", 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 6cee902e..9cb664ac 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 @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:wandering_trader" - }, + "entity": "minecraft:wandering_trader", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 4547222, - 15377456 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:wandering_trader_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/ward_armor_trim_smithing_template.json b/src/main/generated/data/minecraft/item/ward_armor_trim_smithing_template.json index 6f1473f2..cac3eeab 100644 --- a/src/main/generated/data/minecraft/item/ward_armor_trim_smithing_template.json +++ b/src/main/generated/data/minecraft/item/ward_armor_trim_smithing_template.json @@ -1,13 +1,44 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:ward_pattern" - }, + "minecraft:smithing_template_provider": "minecraft:trim_pattern", "minecraft:stackable": 64 }, "display": { "model": "minecraft:ward_armor_trim_smithing_template", "rarity": "uncommon", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.ward_armor_trim_smithing_template" } } \ 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 00053d20..64402c8c 100644 --- a/src/main/generated/data/minecraft/item/warden_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/warden_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:warden" - }, + "entity": "minecraft:warden", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 1001033, - 3790560 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:warden_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/warped_fungus.json b/src/main/generated/data/minecraft/item/warped_fungus.json index 940c7fdc..a47ec7a8 100644 --- a/src/main/generated/data/minecraft/item/warped_fungus.json +++ b/src/main/generated/data/minecraft/item/warped_fungus.json @@ -21,7 +21,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_warped_fungus" } @@ -32,7 +32,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -53,23 +53,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/warped_fungus_on_a_stick.json b/src/main/generated/data/minecraft/item/warped_fungus_on_a_stick.json index cf67ded5..305f7ccb 100644 --- a/src/main/generated/data/minecraft/item/warped_fungus_on_a_stick.json +++ b/src/main/generated/data/minecraft/item/warped_fungus_on_a_stick.json @@ -17,7 +17,10 @@ "action": { "type": "minecraft:exchange_item", "decrement_count": false, - "item": "minecraft:fishing_rod" + "item": { + "id": "minecraft:fishing_rod", + "count": 1 + } } } } diff --git a/src/main/generated/data/minecraft/item/warped_roots.json b/src/main/generated/data/minecraft/item/warped_roots.json index 54b8a9bc..4c9f3767 100644 --- a/src/main/generated/data/minecraft/item/warped_roots.json +++ b/src/main/generated/data/minecraft/item/warped_roots.json @@ -21,7 +21,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_warped_roots" } @@ -32,7 +32,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -53,23 +53,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/wayfinder_armor_trim_smithing_template.json b/src/main/generated/data/minecraft/item/wayfinder_armor_trim_smithing_template.json index 93eb3e84..46959ca0 100644 --- a/src/main/generated/data/minecraft/item/wayfinder_armor_trim_smithing_template.json +++ b/src/main/generated/data/minecraft/item/wayfinder_armor_trim_smithing_template.json @@ -1,13 +1,44 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:wayfinder_pattern" - }, + "minecraft:smithing_template_provider": "minecraft:trim_pattern", "minecraft:stackable": 64 }, "display": { "model": "minecraft:wayfinder_armor_trim_smithing_template", "rarity": "uncommon", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.wayfinder_armor_trim_smithing_template" } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/white_carpet.json b/src/main/generated/data/minecraft/item/white_carpet.json index 77d0e754..0a9f0daf 100644 --- a/src/main/generated/data/minecraft/item/white_carpet.json +++ b/src/main/generated/data/minecraft/item/white_carpet.json @@ -11,8 +11,8 @@ "minecraft:llama", "minecraft:trader_llama" ], + "asset_id": "minecraft:white_carpet", "equip_sound": "minecraft:entity.llama.swag", - "model": "minecraft:white_carpet", "slot": "body" }, "minecraft:fuel": { diff --git a/src/main/generated/data/minecraft/item/white_tulip.json b/src/main/generated/data/minecraft/item/white_tulip.json index 88b0de85..a7c6a4e7 100644 --- a/src/main/generated/data/minecraft/item/white_tulip.json +++ b/src/main/generated/data/minecraft/item/white_tulip.json @@ -29,7 +29,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_white_tulip" } @@ -40,7 +40,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -61,23 +61,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } diff --git a/src/main/generated/data/minecraft/item/wild_armor_trim_smithing_template.json b/src/main/generated/data/minecraft/item/wild_armor_trim_smithing_template.json index bb1d6dff..49e1c496 100644 --- a/src/main/generated/data/minecraft/item/wild_armor_trim_smithing_template.json +++ b/src/main/generated/data/minecraft/item/wild_armor_trim_smithing_template.json @@ -1,13 +1,44 @@ { "behavior": { - "minecraft:smithing_template": { - "template": "minecraft:wild_pattern" - }, + "minecraft:smithing_template_provider": "minecraft:trim_pattern", "minecraft:stackable": 64 }, "display": { "model": "minecraft:wild_armor_trim_smithing_template", "rarity": "uncommon", + "tooltip": [ + { + "color": "gray", + "translate": "item.minecraft.smithing_template" + }, + "", + { + "color": "gray", + "translate": "item.minecraft.smithing_template.applies_to" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.applies_to" + } + ], + "text": " " + }, + { + "color": "gray", + "translate": "item.minecraft.smithing_template.ingredients" + }, + { + "extra": [ + { + "color": "blue", + "translate": "item.minecraft.smithing_template.armor_trim.ingredients" + } + ], + "text": " " + } + ], "translation_key": "item.minecraft.wild_armor_trim_smithing_template" } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/wildflowers.json b/src/main/generated/data/minecraft/item/wildflowers.json new file mode 100644 index 00000000..643698d2 --- /dev/null +++ b/src/main/generated/data/minecraft/item/wildflowers.json @@ -0,0 +1,15 @@ +{ + "behavior": { + "minecraft:block": { + "block": "minecraft:wildflowers" + }, + "minecraft:compostable": { + "level_increase_chance": 0.3 + }, + "minecraft:stackable": 64 + }, + "display": { + "model": "minecraft:wildflowers", + "translation_key": "block.minecraft.wildflowers" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/wind_charge.json b/src/main/generated/data/minecraft/item/wind_charge.json index 2dd9a61d..933f5278 100644 --- a/src/main/generated/data/minecraft/item/wind_charge.json +++ b/src/main/generated/data/minecraft/item/wind_charge.json @@ -7,9 +7,7 @@ "behavior": "minecraft:shoot_projectile" }, "minecraft:projectile": { - "entity": { - "type": "minecraft:wind_charge" - } + "entity": "minecraft:wind_charge" }, "minecraft:stackable": 64, "minecraft:throwable": { 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 e1fa3caa..058b4a27 100644 --- a/src/main/generated/data/minecraft/item/witch_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/witch_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:witch" - }, + "entity": "minecraft:witch", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 3407872, - 5349438 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:witch_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/wither_rose.json b/src/main/generated/data/minecraft/item/wither_rose.json index aa003cee..8a5cdfab 100644 --- a/src/main/generated/data/minecraft/item/wither_rose.json +++ b/src/main/generated/data/minecraft/item/wither_rose.json @@ -28,7 +28,7 @@ { "action": { "type": "minecraft:set_block_state", - "position": "target", + "position": "interacted", "state": { "Name": "minecraft:potted_wither_rose" } @@ -39,7 +39,7 @@ "type": "minecraft:invoke_game_event", "event": "minecraft:block_change", "entity": "this", - "position": "target" + "position": "interacted" } }, { @@ -60,23 +60,19 @@ }, { "action": { - "type": "minecraft:swing_hand" + "type": "minecraft:swing_hand", + "entity": "this" } } ] }, "requirements": { - "conditions": { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": "minecraft:flower_pot" - } + "condition": "minecraft:location_check", + "position": "interacted", + "predicate": { + "block": { + "blocks": "minecraft:flower_pot" } - }, - "context": { - "entity": "this", - "position": "target" } } } 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 0bd76025..1b8a85e2 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 @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:wither_skeleton" - }, + "entity": "minecraft:wither_skeleton", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 1315860, - 4672845 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:wither_skeleton_spawn_egg", 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 b36608bf..c79c4a76 100644 --- a/src/main/generated/data/minecraft/item/wither_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/wither_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:wither" - }, + "entity": "minecraft:wither", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 1315860, - 5075616 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:wither_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/wolf_armor.json b/src/main/generated/data/minecraft/item/wolf_armor.json index 8dcfdf53..7896dadc 100644 --- a/src/main/generated/data/minecraft/item/wolf_armor.json +++ b/src/main/generated/data/minecraft/item/wolf_armor.json @@ -18,17 +18,14 @@ }, "minecraft:equipment": { "allowed_entities": "minecraft:wolf", + "asset_id": "minecraft:armadillo_scute", "equip_sound": "minecraft:item.armor.equip_wolf", - "model": "minecraft:armadillo_scute", "slot": "body" }, - "minecraft:stackable": 1, - "minecraft:tinted": { - "tint": { - "type": "minecraft:dyeable", - "index": 1 - } - } + "minecraft:repairable": { + "items": "#minecraft:repairs_wolf_armor" + }, + "minecraft:stackable": 1 }, "display": { "model": "minecraft:wolf_armor", 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 1e9c05a1..26eb835a 100644 --- a/src/main/generated/data/minecraft/item/wolf_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/wolf_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:wolf" - }, + "entity": "minecraft:wolf", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 14144467, - 13545366 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:wolf_spawn_egg", diff --git a/src/main/generated/data/minecraft/item/wooden_axe.json b/src/main/generated/data/minecraft/item/wooden_axe.json index 68077771..00367c30 100644 --- a/src/main/generated/data/minecraft/item/wooden_axe.json +++ b/src/main/generated/data/minecraft/item/wooden_axe.json @@ -32,7 +32,8 @@ "rules": [] }, "attack_speed": 0.2, - "damage_per_hit": 2 + "disable_blocking_for_seconds": 5.0, + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/wooden_hoe.json b/src/main/generated/data/minecraft/item/wooden_hoe.json index d8d36a08..0ae7ebd5 100644 --- a/src/main/generated/data/minecraft/item/wooden_hoe.json +++ b/src/main/generated/data/minecraft/item/wooden_hoe.json @@ -32,7 +32,7 @@ "rules": [] }, "attack_speed": 0.25, - "damage_per_hit": 2 + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/wooden_pickaxe.json b/src/main/generated/data/minecraft/item/wooden_pickaxe.json index 011de7bf..2341574b 100644 --- a/src/main/generated/data/minecraft/item/wooden_pickaxe.json +++ b/src/main/generated/data/minecraft/item/wooden_pickaxe.json @@ -32,7 +32,7 @@ "rules": [] }, "attack_speed": 0.3, - "damage_per_hit": 2 + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/wooden_shovel.json b/src/main/generated/data/minecraft/item/wooden_shovel.json index 8f11fc3a..8e6720b4 100644 --- a/src/main/generated/data/minecraft/item/wooden_shovel.json +++ b/src/main/generated/data/minecraft/item/wooden_shovel.json @@ -32,7 +32,7 @@ "rules": [] }, "attack_speed": 0.25, - "damage_per_hit": 2 + "item_damage_per_attack": 2 } }, "display": { diff --git a/src/main/generated/data/minecraft/item/wooden_sword.json b/src/main/generated/data/minecraft/item/wooden_sword.json index fc9be2e1..0db64b5e 100644 --- a/src/main/generated/data/minecraft/item/wooden_sword.json +++ b/src/main/generated/data/minecraft/item/wooden_sword.json @@ -14,6 +14,7 @@ }, "minecraft:stackable": 1, "minecraft:tool": { + "can_destroy_blocks_in_creative": false, "damage_per_block": 2, "rules": [ { diff --git a/src/main/generated/data/minecraft/item/written_book.json b/src/main/generated/data/minecraft/item/written_book.json index c5c6c87d..5cd3f0dd 100644 --- a/src/main/generated/data/minecraft/item/written_book.json +++ b/src/main/generated/data/minecraft/item/written_book.json @@ -7,12 +7,5 @@ "glint": true, "model": "minecraft:written_book", "translation_key": "item.minecraft.written_book" - }, - "events": { - "minecraft:use": { - "action": { - "type": "minecraft:open_book_from_item" - } - } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/yellow_carpet.json b/src/main/generated/data/minecraft/item/yellow_carpet.json index e25fbc25..15904095 100644 --- a/src/main/generated/data/minecraft/item/yellow_carpet.json +++ b/src/main/generated/data/minecraft/item/yellow_carpet.json @@ -11,8 +11,8 @@ "minecraft:llama", "minecraft:trader_llama" ], + "asset_id": "minecraft:yellow_carpet", "equip_sound": "minecraft:entity.llama.swag", - "model": "minecraft:yellow_carpet", "slot": "body" }, "minecraft:fuel": { 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 03f2dc84..917f0875 100644 --- a/src/main/generated/data/minecraft/item/zoglin_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/zoglin_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:zoglin" - }, + "entity": "minecraft:zoglin", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 13004373, - 15132390 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:zoglin_spawn_egg", 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 e8a4f3b7..b430ae3e 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 @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:zombie_horse" - }, + "entity": "minecraft:zombie_horse", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 3232308, - 9945732 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:zombie_horse_spawn_egg", 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 622b3866..afde7c41 100644 --- a/src/main/generated/data/minecraft/item/zombie_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/zombie_spawn_egg.json @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:zombie" - }, + "entity": "minecraft:zombie", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 44975, - 7969893 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:zombie_spawn_egg", 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 1b058ea2..86116712 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 @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:zombie_villager" - }, + "entity": "minecraft:zombie_villager", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 5651507, - 7969893 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:zombie_villager_spawn_egg", 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 a9748821..9905992c 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 @@ -5,25 +5,14 @@ }, "minecraft:entity": { "allow_item_data": true, - "entity": { - "type": "minecraft:zombified_piglin" - }, + "entity": "minecraft:zombified_piglin", "passes": [ "block", "fluid" ] }, "minecraft:spawn_egg": {}, - "minecraft:stackable": 64, - "minecraft:tinted": { - "tint": { - "type": "minecraft:index", - "indices": [ - 15373203, - 5009705 - ] - } - } + "minecraft:stackable": 64 }, "display": { "model": "minecraft:zombified_piglin_spawn_egg", diff --git a/src/main/generated/data/minecraft/item_group_entry_provider/combat.json b/src/main/generated/data/minecraft/item_group_entry_provider/combat.json index a9aaf1be..b336efa0 100644 --- a/src/main/generated/data/minecraft/item_group_entry_provider/combat.json +++ b/src/main/generated/data/minecraft/item_group_entry_provider/combat.json @@ -24,7 +24,10 @@ "minecraft:tnt", "minecraft:end_crystal", "minecraft:snowball", - "minecraft:egg", + { + "type": "tag", + "tag": "minecraft:item_group/eggs" + }, "minecraft:wind_charge", "minecraft:bow", "minecraft:crossbow", diff --git a/src/main/generated/data/minecraft/item_group_entry_provider/functional_blocks.json b/src/main/generated/data/minecraft/item_group_entry_provider/functional_blocks.json index 140e3e88..297661bd 100644 --- a/src/main/generated/data/minecraft/item_group_entry_provider/functional_blocks.json +++ b/src/main/generated/data/minecraft/item_group_entry_provider/functional_blocks.json @@ -125,9 +125,15 @@ "pattern": "minecraft:border" } ], - "minecraft:hide_additional_tooltip": {}, - "minecraft:item_name": "{\"translate\":\"block.minecraft.ominous_banner\"}", - "minecraft:rarity": "uncommon" + "minecraft:item_name": { + "translate": "block.minecraft.ominous_banner" + }, + "minecraft:rarity": "uncommon", + "minecraft:tooltip_display": { + "hidden_components": [ + "minecraft:banner_patterns" + ] + } }, "item": "minecraft:white_banner" }, diff --git a/src/main/generated/data/minecraft/item_group_entry_provider/ingredients.json b/src/main/generated/data/minecraft/item_group_entry_provider/ingredients.json index cc202611..980f60e1 100644 --- a/src/main/generated/data/minecraft/item_group_entry_provider/ingredients.json +++ b/src/main/generated/data/minecraft/item_group_entry_provider/ingredients.json @@ -11,6 +11,7 @@ "minecraft:ancient_debris", "minecraft:quartz", "minecraft:amethyst_shard", + "minecraft:resin_clump", "minecraft:iron_nugget", "minecraft:gold_nugget", "minecraft:iron_ingot", @@ -26,7 +27,10 @@ "minecraft:string", "minecraft:feather", "minecraft:snowball", - "minecraft:egg", + { + "type": "tag", + "tag": "minecraft:item_group/eggs" + }, "minecraft:leather", "minecraft:rabbit_hide", "minecraft:honeycomb", @@ -58,6 +62,7 @@ "minecraft:bowl", "minecraft:brick", "minecraft:nether_brick", + "minecraft:resin_brick", "minecraft:paper", "minecraft:book", "minecraft:firework_star", diff --git a/src/main/generated/data/minecraft/item_group_entry_provider/natural_blocks.json b/src/main/generated/data/minecraft/item_group_entry_provider/natural_blocks.json index 35203cbb..dc9161be 100644 --- a/src/main/generated/data/minecraft/item_group_entry_provider/natural_blocks.json +++ b/src/main/generated/data/minecraft/item_group_entry_provider/natural_blocks.json @@ -87,6 +87,7 @@ "minecraft:honeycomb_block", "minecraft:slime_block", "minecraft:honey_block", + "minecraft:resin_block", { "type": "tag", "tag": "minecraft:item_group/froglights" diff --git a/src/main/generated/data/minecraft/item_group_entry_provider/op_blocks.json b/src/main/generated/data/minecraft/item_group_entry_provider/op_blocks.json index bcc91f4e..854dc9ee 100644 --- a/src/main/generated/data/minecraft/item_group_entry_provider/op_blocks.json +++ b/src/main/generated/data/minecraft/item_group_entry_provider/op_blocks.json @@ -47,6 +47,11 @@ }, { "type": "stack", + "components": { + "minecraft:block_state": { + "level": "15" + } + }, "item": "minecraft:light", "requires_permissions": true }, diff --git a/src/main/generated/data/minecraft/item_group_entry_provider/spawn_eggs.json b/src/main/generated/data/minecraft/item_group_entry_provider/spawn_eggs.json index cefe9d7d..41184b14 100644 --- a/src/main/generated/data/minecraft/item_group_entry_provider/spawn_eggs.json +++ b/src/main/generated/data/minecraft/item_group_entry_provider/spawn_eggs.json @@ -4,6 +4,7 @@ "type": "tag", "tag": "minecraft:item_group/spawners" }, + "minecraft:creaking_heart", "minecraft:allay_spawn_egg", "minecraft:armadillo_spawn_egg", "minecraft:axolotl_spawn_egg", @@ -18,6 +19,7 @@ "minecraft:chicken_spawn_egg", "minecraft:cod_spawn_egg", "minecraft:cow_spawn_egg", + "minecraft:creaking_spawn_egg", "minecraft:creeper_spawn_egg", "minecraft:dolphin_spawn_egg", "minecraft:donkey_spawn_egg", diff --git a/src/main/generated/data/minecraft/smithing_template/bolt_pattern.json b/src/main/generated/data/minecraft/smithing_template/bolt_pattern.json deleted file mode 100644 index c84566c5..00000000 --- a/src/main/generated/data/minecraft/smithing_template/bolt_pattern.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:trim_pattern", - "trim_pattern": "minecraft:bolt" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/smithing_template/coast_pattern.json b/src/main/generated/data/minecraft/smithing_template/coast_pattern.json deleted file mode 100644 index c49267d3..00000000 --- a/src/main/generated/data/minecraft/smithing_template/coast_pattern.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:trim_pattern", - "trim_pattern": "minecraft:coast" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/smithing_template/dune_pattern.json b/src/main/generated/data/minecraft/smithing_template/dune_pattern.json deleted file mode 100644 index 7287317f..00000000 --- a/src/main/generated/data/minecraft/smithing_template/dune_pattern.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:trim_pattern", - "trim_pattern": "minecraft:dune" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/smithing_template/eye_pattern.json b/src/main/generated/data/minecraft/smithing_template/eye_pattern.json deleted file mode 100644 index 5a22b7d2..00000000 --- a/src/main/generated/data/minecraft/smithing_template/eye_pattern.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:trim_pattern", - "trim_pattern": "minecraft:eye" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/smithing_template/flow_pattern.json b/src/main/generated/data/minecraft/smithing_template/flow_pattern.json deleted file mode 100644 index 295c5fd8..00000000 --- a/src/main/generated/data/minecraft/smithing_template/flow_pattern.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:trim_pattern", - "trim_pattern": "minecraft:flow" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/smithing_template/host_pattern.json b/src/main/generated/data/minecraft/smithing_template/host_pattern.json deleted file mode 100644 index ca389985..00000000 --- a/src/main/generated/data/minecraft/smithing_template/host_pattern.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:trim_pattern", - "trim_pattern": "minecraft:host" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/smithing_template/netherite_upgrade.json b/src/main/generated/data/minecraft/smithing_template/netherite_upgrade.json deleted file mode 100644 index 8db7808d..00000000 --- a/src/main/generated/data/minecraft/smithing_template/netherite_upgrade.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "type": "minecraft:item_upgrade", - "item": "minecraft:netherite_ingot", - "translation_key_id": "minecraft:netherite_upgrade" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/smithing_template/raiser_pattern.json b/src/main/generated/data/minecraft/smithing_template/raiser_pattern.json deleted file mode 100644 index 98b84c5c..00000000 --- a/src/main/generated/data/minecraft/smithing_template/raiser_pattern.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:trim_pattern", - "trim_pattern": "minecraft:raiser" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/smithing_template/rib_pattern.json b/src/main/generated/data/minecraft/smithing_template/rib_pattern.json deleted file mode 100644 index de1c54f3..00000000 --- a/src/main/generated/data/minecraft/smithing_template/rib_pattern.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:trim_pattern", - "trim_pattern": "minecraft:rib" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/smithing_template/sentry_pattern.json b/src/main/generated/data/minecraft/smithing_template/sentry_pattern.json deleted file mode 100644 index 46a3af1d..00000000 --- a/src/main/generated/data/minecraft/smithing_template/sentry_pattern.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:trim_pattern", - "trim_pattern": "minecraft:sentry" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/smithing_template/shaper_pattern.json b/src/main/generated/data/minecraft/smithing_template/shaper_pattern.json deleted file mode 100644 index 22ae1f5f..00000000 --- a/src/main/generated/data/minecraft/smithing_template/shaper_pattern.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:trim_pattern", - "trim_pattern": "minecraft:shaper" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/smithing_template/silence_pattern.json b/src/main/generated/data/minecraft/smithing_template/silence_pattern.json deleted file mode 100644 index 982699dc..00000000 --- a/src/main/generated/data/minecraft/smithing_template/silence_pattern.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:trim_pattern", - "trim_pattern": "minecraft:silence" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/smithing_template/snout_pattern.json b/src/main/generated/data/minecraft/smithing_template/snout_pattern.json deleted file mode 100644 index 96e2b521..00000000 --- a/src/main/generated/data/minecraft/smithing_template/snout_pattern.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:trim_pattern", - "trim_pattern": "minecraft:snout" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/smithing_template/spire_pattern.json b/src/main/generated/data/minecraft/smithing_template/spire_pattern.json deleted file mode 100644 index 9f2dea98..00000000 --- a/src/main/generated/data/minecraft/smithing_template/spire_pattern.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:trim_pattern", - "trim_pattern": "minecraft:spire" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/smithing_template/tide_pattern.json b/src/main/generated/data/minecraft/smithing_template/tide_pattern.json deleted file mode 100644 index a1c8ca2f..00000000 --- a/src/main/generated/data/minecraft/smithing_template/tide_pattern.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:trim_pattern", - "trim_pattern": "minecraft:tide" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/smithing_template/vex_pattern.json b/src/main/generated/data/minecraft/smithing_template/vex_pattern.json deleted file mode 100644 index 3003d1f4..00000000 --- a/src/main/generated/data/minecraft/smithing_template/vex_pattern.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:trim_pattern", - "trim_pattern": "minecraft:vex" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/smithing_template/ward_pattern.json b/src/main/generated/data/minecraft/smithing_template/ward_pattern.json deleted file mode 100644 index be3b8cef..00000000 --- a/src/main/generated/data/minecraft/smithing_template/ward_pattern.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:trim_pattern", - "trim_pattern": "minecraft:ward" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/smithing_template/wayfinder_pattern.json b/src/main/generated/data/minecraft/smithing_template/wayfinder_pattern.json deleted file mode 100644 index a72c487c..00000000 --- a/src/main/generated/data/minecraft/smithing_template/wayfinder_pattern.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:trim_pattern", - "trim_pattern": "minecraft:wayfinder" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/smithing_template/wild_pattern.json b/src/main/generated/data/minecraft/smithing_template/wild_pattern.json deleted file mode 100644 index 8c7659bc..00000000 --- a/src/main/generated/data/minecraft/smithing_template/wild_pattern.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:trim_pattern", - "trim_pattern": "minecraft:wild" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/tags/item/item_group/boats.json b/src/main/generated/data/minecraft/tags/item/item_group/boats.json index 8b29f323..3f5c4d0f 100644 --- a/src/main/generated/data/minecraft/tags/item/item_group/boats.json +++ b/src/main/generated/data/minecraft/tags/item/item_group/boats.json @@ -16,6 +16,8 @@ "minecraft:mangrove_chest_boat", "minecraft:cherry_boat", "minecraft:cherry_chest_boat", + "minecraft:pale_oak_boat", + "minecraft:pale_oak_chest_boat", "minecraft:bamboo_raft", "minecraft:bamboo_chest_raft" ] diff --git a/src/main/generated/data/minecraft/tags/item/item_group/eggs.json b/src/main/generated/data/minecraft/tags/item/item_group/eggs.json new file mode 100644 index 00000000..b78a29d7 --- /dev/null +++ b/src/main/generated/data/minecraft/tags/item/item_group/eggs.json @@ -0,0 +1,7 @@ +{ + "values": [ + "minecraft:egg", + "minecraft:brown_egg", + "minecraft:blue_egg" + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/tags/item/item_group/leaves.json b/src/main/generated/data/minecraft/tags/item/item_group/leaves.json index 0d25ffee..09541eeb 100644 --- a/src/main/generated/data/minecraft/tags/item/item_group/leaves.json +++ b/src/main/generated/data/minecraft/tags/item/item_group/leaves.json @@ -8,6 +8,7 @@ "minecraft:dark_oak_leaves", "minecraft:mangrove_leaves", "minecraft:cherry_leaves", + "minecraft:pale_oak_leaves", "minecraft:azalea_leaves", "minecraft:flowering_azalea_leaves" ] diff --git a/src/main/generated/data/minecraft/tags/item/item_group/log_like_blocks.json b/src/main/generated/data/minecraft/tags/item/item_group/log_like_blocks.json index b1bd9551..b476d45c 100644 --- a/src/main/generated/data/minecraft/tags/item/item_group/log_like_blocks.json +++ b/src/main/generated/data/minecraft/tags/item/item_group/log_like_blocks.json @@ -10,6 +10,7 @@ "minecraft:mangrove_roots", "minecraft:muddy_mangrove_roots", "minecraft:cherry_log", + "minecraft:pale_oak_log", "minecraft:mushroom_stem", "minecraft:crimson_stem", "minecraft:warped_stem" diff --git a/src/main/generated/data/minecraft/tags/item/item_group/moss_blocks.json b/src/main/generated/data/minecraft/tags/item/item_group/moss_blocks.json index bde29f40..6d2a6c8c 100644 --- a/src/main/generated/data/minecraft/tags/item/item_group/moss_blocks.json +++ b/src/main/generated/data/minecraft/tags/item/item_group/moss_blocks.json @@ -1,6 +1,9 @@ { "values": [ "minecraft:moss_block", - "minecraft:moss_carpet" + "minecraft:moss_carpet", + "minecraft:pale_moss_block", + "minecraft:pale_moss_carpet", + "minecraft:pale_hanging_moss" ] } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/tags/item/item_group/pale_oak_building_blocks.json b/src/main/generated/data/minecraft/tags/item/item_group/pale_oak_building_blocks.json new file mode 100644 index 00000000..da40e463 --- /dev/null +++ b/src/main/generated/data/minecraft/tags/item/item_group/pale_oak_building_blocks.json @@ -0,0 +1,17 @@ +{ + "values": [ + "minecraft:pale_oak_log", + "minecraft:pale_oak_wood", + "minecraft:stripped_pale_oak_log", + "minecraft:stripped_pale_oak_wood", + "minecraft:pale_oak_planks", + "minecraft:pale_oak_stairs", + "minecraft:pale_oak_slab", + "minecraft:pale_oak_fence", + "minecraft:pale_oak_fence_gate", + "minecraft:pale_oak_door", + "minecraft:pale_oak_trapdoor", + "minecraft:pale_oak_pressure_plate", + "minecraft:pale_oak_button" + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/tags/item/item_group/plants.json b/src/main/generated/data/minecraft/tags/item/item_group/plants.json index 999832f1..7a805ea8 100644 --- a/src/main/generated/data/minecraft/tags/item/item_group/plants.json +++ b/src/main/generated/data/minecraft/tags/item/item_group/plants.json @@ -8,6 +8,8 @@ "minecraft:warped_fungus", "minecraft:short_grass", "minecraft:fern", + "minecraft:short_dry_grass", + "minecraft:bush", "minecraft:dead_bush", "minecraft:dandelion", "minecraft:poppy", @@ -22,9 +24,15 @@ "minecraft:cornflower", "minecraft:lily_of_the_valley", "minecraft:torchflower", + "minecraft:cactus_flower", + "minecraft:closed_eyeblossom", + "minecraft:open_eyeblossom", "minecraft:wither_rose", "minecraft:pink_petals", + "minecraft:wildflowers", + "minecraft:leaf_litter", "minecraft:spore_blossom", + "minecraft:firefly_bush", "minecraft:bamboo", "minecraft:sugar_cane", "minecraft:cactus", @@ -36,6 +44,7 @@ "minecraft:vine", "minecraft:tall_grass", "minecraft:large_fern", + "minecraft:tall_dry_grass", "minecraft:sunflower", "minecraft:lilac", "minecraft:rose_bush", diff --git a/src/main/generated/data/minecraft/tags/item/item_group/resin_brick_building_blocks.json b/src/main/generated/data/minecraft/tags/item/item_group/resin_brick_building_blocks.json new file mode 100644 index 00000000..cb02bf90 --- /dev/null +++ b/src/main/generated/data/minecraft/tags/item/item_group/resin_brick_building_blocks.json @@ -0,0 +1,9 @@ +{ + "values": [ + "minecraft:resin_bricks", + "minecraft:resin_brick_stairs", + "minecraft:resin_brick_slab", + "minecraft:resin_brick_wall", + "minecraft:chiseled_resin_bricks" + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/tags/item/item_group/saplings.json b/src/main/generated/data/minecraft/tags/item/item_group/saplings.json index 34411116..6989a6d6 100644 --- a/src/main/generated/data/minecraft/tags/item/item_group/saplings.json +++ b/src/main/generated/data/minecraft/tags/item/item_group/saplings.json @@ -7,6 +7,7 @@ "minecraft:acacia_sapling", "minecraft:dark_oak_sapling", "minecraft:mangrove_propagule", - "minecraft:cherry_sapling" + "minecraft:cherry_sapling", + "minecraft:pale_oak_sapling" ] } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/tags/item/item_group/signs.json b/src/main/generated/data/minecraft/tags/item/item_group/signs.json index 07e691f1..299fd3e4 100644 --- a/src/main/generated/data/minecraft/tags/item/item_group/signs.json +++ b/src/main/generated/data/minecraft/tags/item/item_group/signs.json @@ -16,6 +16,8 @@ "minecraft:mangrove_hanging_sign", "minecraft:cherry_sign", "minecraft:cherry_hanging_sign", + "minecraft:pale_oak_sign", + "minecraft:pale_oak_hanging_sign", "minecraft:bamboo_sign", "minecraft:bamboo_hanging_sign", "minecraft:crimson_sign", diff --git a/src/main/generated/data/minecraft/tags/item/item_group/stone_like_building_blocks.json b/src/main/generated/data/minecraft/tags/item/item_group/stone_like_building_blocks.json index c880d171..9acf3a17 100644 --- a/src/main/generated/data/minecraft/tags/item/item_group/stone_like_building_blocks.json +++ b/src/main/generated/data/minecraft/tags/item/item_group/stone_like_building_blocks.json @@ -23,6 +23,7 @@ "#minecraft:item_group/brick_building_blocks", "minecraft:packed_mud", "#minecraft:item_group/mud_brick_building_blocks", + "#minecraft:item_group/resin_brick_building_blocks", "#minecraft:item_group/sandstone_building_blocks", "#minecraft:item_group/smooth_sandstone_building_blocks", "#minecraft:item_group/cut_sandstone_building_blocks", diff --git a/src/main/generated/data/minecraft/tags/item/item_group/wooden_building_blocks.json b/src/main/generated/data/minecraft/tags/item/item_group/wooden_building_blocks.json index 9921a281..4e57d082 100644 --- a/src/main/generated/data/minecraft/tags/item/item_group/wooden_building_blocks.json +++ b/src/main/generated/data/minecraft/tags/item/item_group/wooden_building_blocks.json @@ -8,6 +8,7 @@ "#minecraft:item_group/dark_oak_building_blocks", "#minecraft:item_group/mangrove_building_blocks", "#minecraft:item_group/cherry_building_blocks", + "#minecraft:item_group/pale_oak_building_blocks", "#minecraft:item_group/bamboo_building_blocks", "#minecraft:item_group/crimson_building_blocks", "#minecraft:item_group/warped_building_blocks" diff --git a/src/main/generated/data/minecraft/tags/item/prevents_mining_in_creative.json b/src/main/generated/data/minecraft/tags/item/prevents_mining_in_creative.json deleted file mode 100644 index 95a6daa0..00000000 --- a/src/main/generated/data/minecraft/tags/item/prevents_mining_in_creative.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "values": [ - "#minecraft:swords", - "minecraft:trident" - ] -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/tags/trade/cartographer_apprentice.json b/src/main/generated/data/minecraft/tags/trade/cartographer_apprentice.json index 881e7cfc..ea494db0 100644 --- a/src/main/generated/data/minecraft/tags/trade/cartographer_apprentice.json +++ b/src/main/generated/data/minecraft/tags/trade/cartographer_apprentice.json @@ -1,6 +1,12 @@ { "values": [ "minecraft:buy_glass_pane", - "minecraft:sell_monument_map" + "minecraft:sell_taiga_village_map", + "minecraft:sell_swamp_hut_map", + "minecraft:sell_snowy_village_map", + "minecraft:sell_savanna_village_map", + "minecraft:sell_plains_village_map", + "minecraft:sell_jungle_temple_map", + "minecraft:sell_desert_village_map" ] } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/tags/trade/cartographer_expert.json b/src/main/generated/data/minecraft/tags/trade/cartographer_expert.json index 234b93cf..b7d9c6d9 100644 --- a/src/main/generated/data/minecraft/tags/trade/cartographer_expert.json +++ b/src/main/generated/data/minecraft/tags/trade/cartographer_expert.json @@ -1,21 +1,20 @@ { "values": [ "minecraft:sell_item_frame", - "minecraft:sell_white_banner", - "minecraft:sell_blue_banner", - "minecraft:sell_light_blue_banner", - "minecraft:sell_red_banner", - "minecraft:sell_pink_banner", - "minecraft:sell_green_banner", - "minecraft:sell_lime_banner", - "minecraft:sell_gray_banner", - "minecraft:sell_black_banner", - "minecraft:sell_purple_banner", - "minecraft:sell_magenta_banner", - "minecraft:sell_cyan_banner", - "minecraft:sell_brown_banner", - "minecraft:sell_yellow_banner", - "minecraft:sell_orange_banner", - "minecraft:sell_light_gray_banner" + "minecraft:sell_blue_banner_cartographer", + "minecraft:sell_white_banner_cartographer", + "minecraft:sell_red_banner_cartographer", + "minecraft:sell_green_banner_cartographer", + "minecraft:sell_lime_banner_cartographer", + "minecraft:sell_purple_banner_cartographer", + "minecraft:sell_cyan_banner_cartographer", + "minecraft:sell_yellow_banner_cartographer", + "minecraft:sell_orange_banner_cartographer", + "minecraft:sell_brown_banner_cartographer", + "minecraft:sell_magenta_banner_cartographer", + "minecraft:sell_light_blue_banner_cartographer", + "minecraft:sell_pink_banner_cartographer", + "minecraft:sell_gray_banner_cartographer", + "minecraft:sell_black_banner_cartographer" ] } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/tags/trade/cartographer_journeyman.json b/src/main/generated/data/minecraft/tags/trade/cartographer_journeyman.json index 85a0bba7..6d60ce1b 100644 --- a/src/main/generated/data/minecraft/tags/trade/cartographer_journeyman.json +++ b/src/main/generated/data/minecraft/tags/trade/cartographer_journeyman.json @@ -1,6 +1,7 @@ { "values": [ "minecraft:buy_compass", - "minecraft:sell_mansion_map" + "minecraft:sell_monument_map", + "minecraft:sell_trial_chamber_map" ] } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/tags/trade/cartographer_master.json b/src/main/generated/data/minecraft/tags/trade/cartographer_master.json index 9ee1bf94..adc15db0 100644 --- a/src/main/generated/data/minecraft/tags/trade/cartographer_master.json +++ b/src/main/generated/data/minecraft/tags/trade/cartographer_master.json @@ -1,5 +1,6 @@ { "values": [ - "minecraft:sell_globe_banner_pattern" + "minecraft:sell_globe_banner_pattern", + "minecraft:sell_mansion_map" ] } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/tags/trade/cartographer_novice.json b/src/main/generated/data/minecraft/tags/trade/cartographer_novice.json index 76f94d49..26da7e36 100644 --- a/src/main/generated/data/minecraft/tags/trade/cartographer_novice.json +++ b/src/main/generated/data/minecraft/tags/trade/cartographer_novice.json @@ -1,6 +1,6 @@ { "values": [ - "minecraft:buy_paper", + "minecraft:buy_paper_cartographer", "minecraft:sell_map" ] } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/tags/trade/librarian_novice.json b/src/main/generated/data/minecraft/tags/trade/librarian_novice.json index a8f47236..8bb10593 100644 --- a/src/main/generated/data/minecraft/tags/trade/librarian_novice.json +++ b/src/main/generated/data/minecraft/tags/trade/librarian_novice.json @@ -1,6 +1,6 @@ { "values": [ - "minecraft:buy_paper", + "minecraft:buy_paper_librarian", "minecraft:sell_enchanted_book_novice", "minecraft:sell_bookshelf" ] diff --git a/src/main/generated/data/minecraft/tags/trade/shepherd_apprentice.json b/src/main/generated/data/minecraft/tags/trade/shepherd_apprentice.json index 4f9f5932..3c54b69b 100644 --- a/src/main/generated/data/minecraft/tags/trade/shepherd_apprentice.json +++ b/src/main/generated/data/minecraft/tags/trade/shepherd_apprentice.json @@ -5,22 +5,22 @@ "minecraft:buy_black_dye", "minecraft:buy_light_blue_dye", "minecraft:buy_lime_dye", - "minecraft:sell_white_wool", - "minecraft:sell_orange_wool", - "minecraft:sell_magenta_wool", - "minecraft:sell_light_blue_wool", - "minecraft:sell_yellow_wool", - "minecraft:sell_lime_wool", - "minecraft:sell_pink_wool", - "minecraft:sell_gray_wool", - "minecraft:sell_light_gray_wool", - "minecraft:sell_cyan_wool", - "minecraft:sell_purple_wool", - "minecraft:sell_blue_wool", - "minecraft:sell_brown_wool", - "minecraft:sell_green_wool", - "minecraft:sell_red_wool", - "minecraft:sell_black_wool", + "minecraft:sell_white_wool_shepherd", + "minecraft:sell_orange_wool_shepherd", + "minecraft:sell_magenta_wool_shepherd", + "minecraft:sell_light_blue_wool_shepherd", + "minecraft:sell_yellow_wool_shepherd", + "minecraft:sell_lime_wool_shepherd", + "minecraft:sell_pink_wool_shepherd", + "minecraft:sell_gray_wool_shepherd", + "minecraft:sell_light_gray_wool_shepherd", + "minecraft:sell_cyan_wool_shepherd", + "minecraft:sell_purple_wool_shepherd", + "minecraft:sell_blue_wool_shepherd", + "minecraft:sell_brown_wool_shepherd", + "minecraft:sell_green_wool_shepherd", + "minecraft:sell_red_wool_shepherd", + "minecraft:sell_black_wool_shepherd", "minecraft:sell_white_carpet", "minecraft:sell_orange_carpet", "minecraft:sell_magenta_carpet", diff --git a/src/main/generated/data/minecraft/tags/trade/wandering_trader_buying.json b/src/main/generated/data/minecraft/tags/trade/wandering_trader_buying.json new file mode 100644 index 00000000..8d653f9e --- /dev/null +++ b/src/main/generated/data/minecraft/tags/trade/wandering_trader_buying.json @@ -0,0 +1,10 @@ +{ + "values": [ + "minecraft:buy_water_bottle", + "minecraft:buy_water_bucket", + "minecraft:buy_milk_bucket", + "minecraft:buy_fermented_spider_eye", + "minecraft:buy_baked_potato", + "minecraft:buy_hay_block" + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/tags/trade/wandering_trader_regular.json b/src/main/generated/data/minecraft/tags/trade/wandering_trader_regular.json index 88c3269a..cf07e7cb 100644 --- a/src/main/generated/data/minecraft/tags/trade/wandering_trader_regular.json +++ b/src/main/generated/data/minecraft/tags/trade/wandering_trader_regular.json @@ -1,5 +1,7 @@ { "values": [ + "minecraft:sell_tropical_fish_bucket", + "minecraft:sell_pufferfish_bucket", "minecraft:sell_sea_pickle", "minecraft:sell_slime_ball", "minecraft:sell_glowstone_wandering_trader", @@ -21,6 +23,7 @@ "minecraft:sell_oxeye_daisy", "minecraft:sell_cornflower", "minecraft:sell_lily_of_the_valley", + "minecraft:sell_open_eyeblossom", "minecraft:sell_wheat_seeds", "minecraft:sell_beetroot_seeds", "minecraft:sell_pumpkin_seeds", @@ -32,6 +35,7 @@ "minecraft:sell_oak_sapling", "minecraft:sell_spruce_sapling", "minecraft:sell_cherry_sapling", + "minecraft:sell_pale_oak_sapling", "minecraft:sell_mangrove_propagule", "minecraft:sell_red_dye", "minecraft:sell_white_dye", @@ -55,6 +59,7 @@ "minecraft:sell_horn_coral_block", "minecraft:sell_tube_coral_block", "minecraft:sell_vine", + "minecraft:sell_pale_hanging_moss", "minecraft:sell_brown_mushroom", "minecraft:sell_red_mushroom", "minecraft:sell_lily_pad", @@ -63,6 +68,10 @@ "minecraft:sell_red_sand", "minecraft:sell_pointed_dripstone", "minecraft:sell_rooted_dirt", - "minecraft:sell_moss_block" + "minecraft:sell_moss_block", + "minecraft:sell_pale_moss_block", + "minecraft:sell_wildflowers", + "minecraft:sell_tall_dry_grass", + "minecraft:sell_firefly_bush" ] } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/tags/trade/wandering_trader_special.json b/src/main/generated/data/minecraft/tags/trade/wandering_trader_special.json index 88d01e51..dc712d47 100644 --- a/src/main/generated/data/minecraft/tags/trade/wandering_trader_special.json +++ b/src/main/generated/data/minecraft/tags/trade/wandering_trader_special.json @@ -1,10 +1,19 @@ { "values": [ - "minecraft:sell_tropical_fish_bucket", - "minecraft:sell_pufferfish_bucket", "minecraft:sell_packed_ice", "minecraft:sell_blue_ice", "minecraft:sell_gunpowder", - "minecraft:sell_podzol" + "minecraft:sell_podzol", + "minecraft:sell_acacia_log", + "minecraft:sell_birch_log", + "minecraft:sell_dark_oak_log", + "minecraft:sell_jungle_log", + "minecraft:sell_oak_log", + "minecraft:sell_spruce_log", + "minecraft:sell_cherry_log", + "minecraft:sell_mangrove_log", + "minecraft:sell_pale_oak_log", + "minecraft:sell_enchanted_iron_pickaxe_wandering_trader", + "minecraft:sell_long_invisibility_potion" ] } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/buy_baked_potato.json b/src/main/generated/data/minecraft/trade/buy_baked_potato.json new file mode 100644 index 00000000..4b55f3fa --- /dev/null +++ b/src/main/generated/data/minecraft/trade/buy_baked_potato.json @@ -0,0 +1,13 @@ +{ + "gives": { + "item": "minecraft:emerald" + }, + "max_uses": 2, + "price_multiplier": 0.05, + "wants": [ + { + "count": 4, + "item": "minecraft:baked_potato" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/buy_fermented_spider_eye.json b/src/main/generated/data/minecraft/trade/buy_fermented_spider_eye.json new file mode 100644 index 00000000..f44fd873 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/buy_fermented_spider_eye.json @@ -0,0 +1,13 @@ +{ + "gives": { + "count": 3, + "item": "minecraft:emerald" + }, + "max_uses": 2, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:fermented_spider_eye" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/buy_hay_block.json b/src/main/generated/data/minecraft/trade/buy_hay_block.json new file mode 100644 index 00000000..7fe903e9 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/buy_hay_block.json @@ -0,0 +1,12 @@ +{ + "gives": { + "item": "minecraft:emerald" + }, + "max_uses": 2, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:hay_block" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/buy_milk_bucket.json b/src/main/generated/data/minecraft/trade/buy_milk_bucket.json new file mode 100644 index 00000000..4286b833 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/buy_milk_bucket.json @@ -0,0 +1,13 @@ +{ + "gives": { + "count": 2, + "item": "minecraft:emerald" + }, + "max_uses": 2, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:milk_bucket" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/buy_paper_cartographer.json b/src/main/generated/data/minecraft/trade/buy_paper_cartographer.json new file mode 100644 index 00000000..e4f8366b --- /dev/null +++ b/src/main/generated/data/minecraft/trade/buy_paper_cartographer.json @@ -0,0 +1,14 @@ +{ + "gives": { + "item": "minecraft:emerald" + }, + "max_uses": 12, + "price_multiplier": 0.05, + "trade_experience": 2, + "wants": [ + { + "count": 24, + "item": "minecraft:paper" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/buy_paper.json b/src/main/generated/data/minecraft/trade/buy_paper_librarian.json similarity index 100% rename from src/main/generated/data/minecraft/trade/buy_paper.json rename to src/main/generated/data/minecraft/trade/buy_paper_librarian.json diff --git a/src/main/generated/data/minecraft/trade/buy_water_bottle.json b/src/main/generated/data/minecraft/trade/buy_water_bottle.json new file mode 100644 index 00000000..e6ffa50f --- /dev/null +++ b/src/main/generated/data/minecraft/trade/buy_water_bottle.json @@ -0,0 +1,16 @@ +{ + "gives": { + "item": "minecraft:emerald" + }, + "max_uses": 2, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:potion", + "item_modifier": { + "id": "minecraft:water", + "function": "minecraft:set_potion" + } + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/buy_water_bucket.json b/src/main/generated/data/minecraft/trade/buy_water_bucket.json new file mode 100644 index 00000000..ddc32491 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/buy_water_bucket.json @@ -0,0 +1,13 @@ +{ + "gives": { + "count": 2, + "item": "minecraft:emerald" + }, + "max_uses": 2, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:water_bucket" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_acacia_log.json b/src/main/generated/data/minecraft/trade/sell_acacia_log.json new file mode 100644 index 00000000..89b2f8e3 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_acacia_log.json @@ -0,0 +1,13 @@ +{ + "gives": { + "count": 8, + "item": "minecraft:acacia_log" + }, + "max_uses": 4, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_birch_log.json b/src/main/generated/data/minecraft/trade/sell_birch_log.json new file mode 100644 index 00000000..649694c7 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_birch_log.json @@ -0,0 +1,13 @@ +{ + "gives": { + "count": 8, + "item": "minecraft:birch_log" + }, + "max_uses": 4, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_black_banner_cartographer.json b/src/main/generated/data/minecraft/trade/sell_black_banner_cartographer.json new file mode 100644 index 00000000..eb23e6e4 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_black_banner_cartographer.json @@ -0,0 +1,24 @@ +{ + "gives": { + "item": "minecraft:black_banner" + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": "minecraft:swamp" + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 15, + "wants": [ + { + "count": 2, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_black_wool.json b/src/main/generated/data/minecraft/trade/sell_black_wool_shepherd.json similarity index 100% rename from src/main/generated/data/minecraft/trade/sell_black_wool.json rename to src/main/generated/data/minecraft/trade/sell_black_wool_shepherd.json diff --git a/src/main/generated/data/minecraft/trade/sell_blue_banner_cartographer.json b/src/main/generated/data/minecraft/trade/sell_blue_banner_cartographer.json new file mode 100644 index 00000000..931c51c3 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_blue_banner_cartographer.json @@ -0,0 +1,27 @@ +{ + "gives": { + "item": "minecraft:blue_banner" + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:snow", + "minecraft:taiga" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 15, + "wants": [ + { + "count": 2, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_blue_wool.json b/src/main/generated/data/minecraft/trade/sell_blue_wool_shepherd.json similarity index 100% rename from src/main/generated/data/minecraft/trade/sell_blue_wool.json rename to src/main/generated/data/minecraft/trade/sell_blue_wool_shepherd.json diff --git a/src/main/generated/data/minecraft/trade/sell_brown_banner_cartographer.json b/src/main/generated/data/minecraft/trade/sell_brown_banner_cartographer.json new file mode 100644 index 00000000..4b048d67 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_brown_banner_cartographer.json @@ -0,0 +1,27 @@ +{ + "gives": { + "item": "minecraft:brown_banner" + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:plains", + "minecraft:jungle" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 15, + "wants": [ + { + "count": 2, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_brown_wool.json b/src/main/generated/data/minecraft/trade/sell_brown_wool_shepherd.json similarity index 100% rename from src/main/generated/data/minecraft/trade/sell_brown_wool.json rename to src/main/generated/data/minecraft/trade/sell_brown_wool_shepherd.json diff --git a/src/main/generated/data/minecraft/trade/sell_cherry_log.json b/src/main/generated/data/minecraft/trade/sell_cherry_log.json new file mode 100644 index 00000000..83b42ed7 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_cherry_log.json @@ -0,0 +1,13 @@ +{ + "gives": { + "count": 8, + "item": "minecraft:cherry_log" + }, + "max_uses": 4, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_cyan_banner_cartographer.json b/src/main/generated/data/minecraft/trade/sell_cyan_banner_cartographer.json new file mode 100644 index 00000000..da2d5204 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_cyan_banner_cartographer.json @@ -0,0 +1,27 @@ +{ + "gives": { + "item": "minecraft:cyan_banner" + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:desert", + "minecraft:snow" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 15, + "wants": [ + { + "count": 2, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_cyan_wool.json b/src/main/generated/data/minecraft/trade/sell_cyan_wool_shepherd.json similarity index 100% rename from src/main/generated/data/minecraft/trade/sell_cyan_wool.json rename to src/main/generated/data/minecraft/trade/sell_cyan_wool_shepherd.json diff --git a/src/main/generated/data/minecraft/trade/sell_dark_oak_log.json b/src/main/generated/data/minecraft/trade/sell_dark_oak_log.json new file mode 100644 index 00000000..7b74c0d7 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_dark_oak_log.json @@ -0,0 +1,13 @@ +{ + "gives": { + "count": 8, + "item": "minecraft:dark_oak_log" + }, + "max_uses": 4, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_desert_village_map.json b/src/main/generated/data/minecraft/trade/sell_desert_village_map.json new file mode 100644 index 00000000..28403692 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_desert_village_map.json @@ -0,0 +1,45 @@ +{ + "gives": { + "item": "minecraft:map", + "item_modifier": { + "function": "minecraft:sequence", + "functions": [ + { + "decoration": "minecraft:village_desert", + "destination": "minecraft:on_desert_village_maps", + "function": "minecraft:exploration_map", + "search_radius": 100 + }, + { + "function": "minecraft:set_name", + "name": { + "translate": "filled_map.village_desert" + }, + "target": "item_name" + } + ] + } + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:savanna", + "minecraft:jungle" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 5, + "wants": [ + { + "count": 8, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_enchanted_iron_pickaxe_wandering_trader.json b/src/main/generated/data/minecraft/trade/sell_enchanted_iron_pickaxe_wandering_trader.json new file mode 100644 index 00000000..723c5f3f --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_enchanted_iron_pickaxe_wandering_trader.json @@ -0,0 +1,21 @@ +{ + "gives": { + "item": "minecraft:iron_pickaxe" + }, + "max_uses": 1, + "price_multiplier": 0.2, + "trade_modifier": { + "type": "minecraft:enchant_with_levels", + "index": 0, + "level": { + "max": 19, + "min": 5 + } + }, + "wants": [ + { + "count": 3, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_firefly_bush.json b/src/main/generated/data/minecraft/trade/sell_firefly_bush.json new file mode 100644 index 00000000..e628045b --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_firefly_bush.json @@ -0,0 +1,12 @@ +{ + "gives": { + "item": "minecraft:firefly_bush" + }, + "max_uses": 5, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_gray_banner_cartographer.json b/src/main/generated/data/minecraft/trade/sell_gray_banner_cartographer.json new file mode 100644 index 00000000..3ec71cb7 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_gray_banner_cartographer.json @@ -0,0 +1,24 @@ +{ + "gives": { + "item": "minecraft:gray_banner" + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": "minecraft:desert" + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 15, + "wants": [ + { + "count": 2, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_gray_wool.json b/src/main/generated/data/minecraft/trade/sell_gray_wool_shepherd.json similarity index 100% rename from src/main/generated/data/minecraft/trade/sell_gray_wool.json rename to src/main/generated/data/minecraft/trade/sell_gray_wool_shepherd.json diff --git a/src/main/generated/data/minecraft/trade/sell_green_banner_cartographer.json b/src/main/generated/data/minecraft/trade/sell_green_banner_cartographer.json new file mode 100644 index 00000000..0e9bad2d --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_green_banner_cartographer.json @@ -0,0 +1,28 @@ +{ + "gives": { + "item": "minecraft:green_banner" + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:desert", + "minecraft:savanna", + "minecraft:jungle" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 15, + "wants": [ + { + "count": 2, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_green_wool.json b/src/main/generated/data/minecraft/trade/sell_green_wool_shepherd.json similarity index 100% rename from src/main/generated/data/minecraft/trade/sell_green_wool.json rename to src/main/generated/data/minecraft/trade/sell_green_wool_shepherd.json diff --git a/src/main/generated/data/minecraft/trade/sell_jungle_log.json b/src/main/generated/data/minecraft/trade/sell_jungle_log.json new file mode 100644 index 00000000..352fbc2b --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_jungle_log.json @@ -0,0 +1,13 @@ +{ + "gives": { + "count": 8, + "item": "minecraft:jungle_log" + }, + "max_uses": 4, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_jungle_temple_map.json b/src/main/generated/data/minecraft/trade/sell_jungle_temple_map.json new file mode 100644 index 00000000..3dd29f65 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_jungle_temple_map.json @@ -0,0 +1,46 @@ +{ + "gives": { + "item": "minecraft:map", + "item_modifier": { + "function": "minecraft:sequence", + "functions": [ + { + "decoration": "minecraft:jungle_temple", + "destination": "minecraft:on_jungle_explorer_maps", + "function": "minecraft:exploration_map", + "search_radius": 100 + }, + { + "function": "minecraft:set_name", + "name": { + "translate": "filled_map.explorer_jungle" + }, + "target": "item_name" + } + ] + } + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:swamp", + "minecraft:savanna", + "minecraft:desert" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 5, + "wants": [ + { + "count": 8, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_light_blue_banner_cartographer.json b/src/main/generated/data/minecraft/trade/sell_light_blue_banner_cartographer.json new file mode 100644 index 00000000..6c243a06 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_light_blue_banner_cartographer.json @@ -0,0 +1,27 @@ +{ + "gives": { + "item": "minecraft:light_blue_banner" + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:snow", + "minecraft:swamp" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 15, + "wants": [ + { + "count": 2, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_light_blue_wool.json b/src/main/generated/data/minecraft/trade/sell_light_blue_wool_shepherd.json similarity index 100% rename from src/main/generated/data/minecraft/trade/sell_light_blue_wool.json rename to src/main/generated/data/minecraft/trade/sell_light_blue_wool_shepherd.json diff --git a/src/main/generated/data/minecraft/trade/sell_light_gray_wool.json b/src/main/generated/data/minecraft/trade/sell_light_gray_wool_shepherd.json similarity index 100% rename from src/main/generated/data/minecraft/trade/sell_light_gray_wool.json rename to src/main/generated/data/minecraft/trade/sell_light_gray_wool_shepherd.json diff --git a/src/main/generated/data/minecraft/trade/sell_lime_banner_cartographer.json b/src/main/generated/data/minecraft/trade/sell_lime_banner_cartographer.json new file mode 100644 index 00000000..a11dd2ae --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_lime_banner_cartographer.json @@ -0,0 +1,27 @@ +{ + "gives": { + "item": "minecraft:lime_banner" + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:desert", + "minecraft:taiga" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 15, + "wants": [ + { + "count": 2, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_lime_wool.json b/src/main/generated/data/minecraft/trade/sell_lime_wool_shepherd.json similarity index 100% rename from src/main/generated/data/minecraft/trade/sell_lime_wool.json rename to src/main/generated/data/minecraft/trade/sell_lime_wool_shepherd.json diff --git a/src/main/generated/data/minecraft/trade/sell_long_invisibility_potion.json b/src/main/generated/data/minecraft/trade/sell_long_invisibility_potion.json new file mode 100644 index 00000000..072ec270 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_long_invisibility_potion.json @@ -0,0 +1,17 @@ +{ + "gives": { + "item": "minecraft:potion", + "item_modifier": { + "id": "minecraft:long_invisibility", + "function": "minecraft:set_potion" + } + }, + "max_uses": 1, + "price_multiplier": 0.05, + "wants": [ + { + "count": 5, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_magenta_banner_cartographer.json b/src/main/generated/data/minecraft/trade/sell_magenta_banner_cartographer.json new file mode 100644 index 00000000..b9f74d83 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_magenta_banner_cartographer.json @@ -0,0 +1,24 @@ +{ + "gives": { + "item": "minecraft:magenta_banner" + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": "minecraft:savanna" + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 15, + "wants": [ + { + "count": 2, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_magenta_wool.json b/src/main/generated/data/minecraft/trade/sell_magenta_wool_shepherd.json similarity index 100% rename from src/main/generated/data/minecraft/trade/sell_magenta_wool.json rename to src/main/generated/data/minecraft/trade/sell_magenta_wool_shepherd.json diff --git a/src/main/generated/data/minecraft/trade/sell_mangrove_log.json b/src/main/generated/data/minecraft/trade/sell_mangrove_log.json new file mode 100644 index 00000000..10547e66 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_mangrove_log.json @@ -0,0 +1,13 @@ +{ + "gives": { + "count": 8, + "item": "minecraft:mangrove_log" + }, + "max_uses": 4, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_monument_map.json b/src/main/generated/data/minecraft/trade/sell_monument_map.json index 38dd2069..6697dd2a 100644 --- a/src/main/generated/data/minecraft/trade/sell_monument_map.json +++ b/src/main/generated/data/minecraft/trade/sell_monument_map.json @@ -22,7 +22,7 @@ }, "max_uses": 12, "price_multiplier": 0.05, - "trade_experience": 5, + "trade_experience": 10, "wants": [ { "count": 13, diff --git a/src/main/generated/data/minecraft/trade/sell_oak_log.json b/src/main/generated/data/minecraft/trade/sell_oak_log.json new file mode 100644 index 00000000..ea470ea1 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_oak_log.json @@ -0,0 +1,13 @@ +{ + "gives": { + "count": 8, + "item": "minecraft:oak_log" + }, + "max_uses": 4, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_open_eyeblossom.json b/src/main/generated/data/minecraft/trade/sell_open_eyeblossom.json new file mode 100644 index 00000000..da468b81 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_open_eyeblossom.json @@ -0,0 +1,12 @@ +{ + "gives": { + "item": "minecraft:open_eyeblossom" + }, + "max_uses": 7, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_orange_banner_cartographer.json b/src/main/generated/data/minecraft/trade/sell_orange_banner_cartographer.json new file mode 100644 index 00000000..e5a8534b --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_orange_banner_cartographer.json @@ -0,0 +1,27 @@ +{ + "gives": { + "item": "minecraft:orange_banner" + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:savanna", + "minecraft:desert" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 15, + "wants": [ + { + "count": 2, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_orange_wool.json b/src/main/generated/data/minecraft/trade/sell_orange_wool_shepherd.json similarity index 100% rename from src/main/generated/data/minecraft/trade/sell_orange_wool.json rename to src/main/generated/data/minecraft/trade/sell_orange_wool_shepherd.json diff --git a/src/main/generated/data/minecraft/trade/sell_pale_hanging_moss.json b/src/main/generated/data/minecraft/trade/sell_pale_hanging_moss.json new file mode 100644 index 00000000..8f1f6e90 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_pale_hanging_moss.json @@ -0,0 +1,12 @@ +{ + "gives": { + "item": "minecraft:pale_hanging_moss" + }, + "max_uses": 12, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_pale_moss_block.json b/src/main/generated/data/minecraft/trade/sell_pale_moss_block.json new file mode 100644 index 00000000..5af3bd91 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_pale_moss_block.json @@ -0,0 +1,13 @@ +{ + "gives": { + "count": 2, + "item": "minecraft:pale_moss_block" + }, + "max_uses": 5, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_pale_oak_log.json b/src/main/generated/data/minecraft/trade/sell_pale_oak_log.json new file mode 100644 index 00000000..a1b802b6 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_pale_oak_log.json @@ -0,0 +1,13 @@ +{ + "gives": { + "count": 8, + "item": "minecraft:pale_oak_log" + }, + "max_uses": 4, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_pale_oak_sapling.json b/src/main/generated/data/minecraft/trade/sell_pale_oak_sapling.json new file mode 100644 index 00000000..46abbd4b --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_pale_oak_sapling.json @@ -0,0 +1,13 @@ +{ + "gives": { + "item": "minecraft:pale_oak_sapling" + }, + "max_uses": 8, + "price_multiplier": 0.05, + "wants": [ + { + "count": 5, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_pink_banner_cartographer.json b/src/main/generated/data/minecraft/trade/sell_pink_banner_cartographer.json new file mode 100644 index 00000000..b1628865 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_pink_banner_cartographer.json @@ -0,0 +1,27 @@ +{ + "gives": { + "item": "minecraft:pink_banner" + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:taiga", + "minecraft:plains" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 15, + "wants": [ + { + "count": 2, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_pink_wool.json b/src/main/generated/data/minecraft/trade/sell_pink_wool_shepherd.json similarity index 100% rename from src/main/generated/data/minecraft/trade/sell_pink_wool.json rename to src/main/generated/data/minecraft/trade/sell_pink_wool_shepherd.json diff --git a/src/main/generated/data/minecraft/trade/sell_plains_village_map.json b/src/main/generated/data/minecraft/trade/sell_plains_village_map.json new file mode 100644 index 00000000..5e5511d9 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_plains_village_map.json @@ -0,0 +1,47 @@ +{ + "gives": { + "item": "minecraft:map", + "item_modifier": { + "function": "minecraft:sequence", + "functions": [ + { + "decoration": "minecraft:village_plains", + "destination": "minecraft:on_plains_village_maps", + "function": "minecraft:exploration_map", + "search_radius": 100 + }, + { + "function": "minecraft:set_name", + "name": { + "translate": "filled_map.village_plains" + }, + "target": "item_name" + } + ] + } + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:taiga", + "minecraft:snow", + "minecraft:savanna", + "minecraft:desert" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 5, + "wants": [ + { + "count": 8, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_purple_banner_cartographer.json b/src/main/generated/data/minecraft/trade/sell_purple_banner_cartographer.json new file mode 100644 index 00000000..ac2c02ea --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_purple_banner_cartographer.json @@ -0,0 +1,27 @@ +{ + "gives": { + "item": "minecraft:purple_banner" + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:taiga", + "minecraft:swamp" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 15, + "wants": [ + { + "count": 2, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_purple_wool.json b/src/main/generated/data/minecraft/trade/sell_purple_wool_shepherd.json similarity index 100% rename from src/main/generated/data/minecraft/trade/sell_purple_wool.json rename to src/main/generated/data/minecraft/trade/sell_purple_wool_shepherd.json diff --git a/src/main/generated/data/minecraft/trade/sell_red_banner_cartographer.json b/src/main/generated/data/minecraft/trade/sell_red_banner_cartographer.json new file mode 100644 index 00000000..528f9234 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_red_banner_cartographer.json @@ -0,0 +1,27 @@ +{ + "gives": { + "item": "minecraft:red_banner" + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:snow", + "minecraft:savanna" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 15, + "wants": [ + { + "count": 2, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_red_wool.json b/src/main/generated/data/minecraft/trade/sell_red_wool_shepherd.json similarity index 100% rename from src/main/generated/data/minecraft/trade/sell_red_wool.json rename to src/main/generated/data/minecraft/trade/sell_red_wool_shepherd.json diff --git a/src/main/generated/data/minecraft/trade/sell_savanna_village_map.json b/src/main/generated/data/minecraft/trade/sell_savanna_village_map.json new file mode 100644 index 00000000..fce8d08a --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_savanna_village_map.json @@ -0,0 +1,46 @@ +{ + "gives": { + "item": "minecraft:map", + "item_modifier": { + "function": "minecraft:sequence", + "functions": [ + { + "decoration": "minecraft:village_savanna", + "destination": "minecraft:on_savanna_village_maps", + "function": "minecraft:exploration_map", + "search_radius": 100 + }, + { + "function": "minecraft:set_name", + "name": { + "translate": "filled_map.village_savanna" + }, + "target": "item_name" + } + ] + } + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:plains", + "minecraft:jungle", + "minecraft:desert" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 5, + "wants": [ + { + "count": 8, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_snowy_village_map.json b/src/main/generated/data/minecraft/trade/sell_snowy_village_map.json new file mode 100644 index 00000000..25a872e4 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_snowy_village_map.json @@ -0,0 +1,45 @@ +{ + "gives": { + "item": "minecraft:map", + "item_modifier": { + "function": "minecraft:sequence", + "functions": [ + { + "decoration": "minecraft:village_snowy", + "destination": "minecraft:on_snowy_village_maps", + "function": "minecraft:exploration_map", + "search_radius": 100 + }, + { + "function": "minecraft:set_name", + "name": { + "translate": "filled_map.village_snowy" + }, + "target": "item_name" + } + ] + } + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:taiga", + "minecraft:swamp" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 5, + "wants": [ + { + "count": 8, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_spruce_log.json b/src/main/generated/data/minecraft/trade/sell_spruce_log.json new file mode 100644 index 00000000..2ad47602 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_spruce_log.json @@ -0,0 +1,13 @@ +{ + "gives": { + "count": 8, + "item": "minecraft:spruce_log" + }, + "max_uses": 4, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_swamp_hut_map.json b/src/main/generated/data/minecraft/trade/sell_swamp_hut_map.json new file mode 100644 index 00000000..7fbce3ab --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_swamp_hut_map.json @@ -0,0 +1,46 @@ +{ + "gives": { + "item": "minecraft:map", + "item_modifier": { + "function": "minecraft:sequence", + "functions": [ + { + "decoration": "minecraft:swamp_hut", + "destination": "minecraft:on_swamp_explorer_maps", + "function": "minecraft:exploration_map", + "search_radius": 100 + }, + { + "function": "minecraft:set_name", + "name": { + "translate": "filled_map.explorer_swamp" + }, + "target": "item_name" + } + ] + } + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:taiga", + "minecraft:snow", + "minecraft:jungle" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 5, + "wants": [ + { + "count": 8, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_taiga_village_map.json b/src/main/generated/data/minecraft/trade/sell_taiga_village_map.json new file mode 100644 index 00000000..4d0739d7 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_taiga_village_map.json @@ -0,0 +1,46 @@ +{ + "gives": { + "item": "minecraft:map", + "item_modifier": { + "function": "minecraft:sequence", + "functions": [ + { + "decoration": "minecraft:village_taiga", + "destination": "minecraft:on_taiga_village_maps", + "function": "minecraft:exploration_map", + "search_radius": 100 + }, + { + "function": "minecraft:set_name", + "name": { + "translate": "filled_map.village_taiga" + }, + "target": "item_name" + } + ] + } + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:swamp", + "minecraft:snow", + "minecraft:plains" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 5, + "wants": [ + { + "count": 8, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_tall_dry_grass.json b/src/main/generated/data/minecraft/trade/sell_tall_dry_grass.json new file mode 100644 index 00000000..ec2a86cb --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_tall_dry_grass.json @@ -0,0 +1,12 @@ +{ + "gives": { + "item": "minecraft:tall_dry_grass" + }, + "max_uses": 5, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_trial_chamber_map.json b/src/main/generated/data/minecraft/trade/sell_trial_chamber_map.json new file mode 100644 index 00000000..8aaf8029 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_trial_chamber_map.json @@ -0,0 +1,32 @@ +{ + "gives": { + "item": "minecraft:map", + "item_modifier": { + "function": "minecraft:sequence", + "functions": [ + { + "decoration": "minecraft:trial_chambers", + "destination": "minecraft:on_trial_chambers_maps", + "function": "minecraft:exploration_map", + "search_radius": 100 + }, + { + "function": "minecraft:set_name", + "name": { + "translate": "filled_map.trial_chambers" + }, + "target": "item_name" + } + ] + } + }, + "max_uses": 12, + "price_multiplier": 0.05, + "trade_experience": 10, + "wants": [ + { + "count": 12, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_white_banner_cartographer.json b/src/main/generated/data/minecraft/trade/sell_white_banner_cartographer.json new file mode 100644 index 00000000..1d0614c6 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_white_banner_cartographer.json @@ -0,0 +1,27 @@ +{ + "gives": { + "item": "minecraft:white_banner" + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:snow", + "minecraft:plains" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 15, + "wants": [ + { + "count": 2, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_white_wool.json b/src/main/generated/data/minecraft/trade/sell_white_wool_shepherd.json similarity index 100% rename from src/main/generated/data/minecraft/trade/sell_white_wool.json rename to src/main/generated/data/minecraft/trade/sell_white_wool_shepherd.json diff --git a/src/main/generated/data/minecraft/trade/sell_wildflowers.json b/src/main/generated/data/minecraft/trade/sell_wildflowers.json new file mode 100644 index 00000000..2bdb1bea --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_wildflowers.json @@ -0,0 +1,12 @@ +{ + "gives": { + "item": "minecraft:wildflowers" + }, + "max_uses": 5, + "price_multiplier": 0.05, + "wants": [ + { + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_yellow_banner_cartographer.json b/src/main/generated/data/minecraft/trade/sell_yellow_banner_cartographer.json new file mode 100644 index 00000000..09a50a96 --- /dev/null +++ b/src/main/generated/data/minecraft/trade/sell_yellow_banner_cartographer.json @@ -0,0 +1,27 @@ +{ + "gives": { + "item": "minecraft:yellow_banner" + }, + "max_uses": 12, + "merchant_predicate": { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "minecraft:villager", + "variant": [ + "minecraft:plains", + "minecraft:jungle" + ] + } + } + }, + "price_multiplier": 0.05, + "trade_experience": 15, + "wants": [ + { + "count": 2, + "item": "minecraft:emerald" + } + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/trade/sell_yellow_wool.json b/src/main/generated/data/minecraft/trade/sell_yellow_wool_shepherd.json similarity index 100% rename from src/main/generated/data/minecraft/trade/sell_yellow_wool.json rename to src/main/generated/data/minecraft/trade/sell_yellow_wool_shepherd.json diff --git a/src/main/java/net/errorcraft/itematic/Itematic.java b/src/main/java/net/errorcraft/itematic/Itematic.java index d6df0efe..52a2e04a 100644 --- a/src/main/java/net/errorcraft/itematic/Itematic.java +++ b/src/main/java/net/errorcraft/itematic/Itematic.java @@ -1,18 +1,16 @@ package net.errorcraft.itematic; import net.errorcraft.itematic.component.ItematicDataComponentTypes; -import net.errorcraft.itematic.item.color.ItemColorTypes; import net.errorcraft.itematic.item.component.ItemComponentTypes; import net.errorcraft.itematic.item.event.ItemEvents; import net.errorcraft.itematic.item.holder.rule.ItemHolderRuleTypes; -import net.errorcraft.itematic.item.model.override.ModelOverrides; import net.errorcraft.itematic.item.placement.block.picker.BlockPickerTypes; -import net.errorcraft.itematic.item.pointer.Pointers; import net.errorcraft.itematic.item.shooter.method.ShooterMethodTypes; -import net.errorcraft.itematic.item.smithing.template.SmithingTemplateTypes; +import net.errorcraft.itematic.item.smithing.template.SmithingTemplates; import net.errorcraft.itematic.item.use.provider.IntegerProviderTypes; import net.errorcraft.itematic.loot.function.ItematicItemModifierTypes; import net.errorcraft.itematic.loot.predicate.ItematicPredicateTypes; +import net.errorcraft.itematic.predicate.entity.ItematicEntitySubPredicateTypes; import net.errorcraft.itematic.recipe.ItematicRecipeSerializers; import net.errorcraft.itematic.recipe.ItematicRecipeTypes; import net.errorcraft.itematic.recipe.book.ItematicRecipeBookCategories; @@ -29,16 +27,13 @@ public class Itematic implements ModInitializer { @Override public void onInitialize() { ItemComponentTypes.init(); - ItemColorTypes.init(); ItemEvents.init(); ActionTypes.init(); ItematicContextTypes.init(); - ModelOverrides.init(); - Pointers.init(); SequenceHandlerTypes.init(); ItematicPredicateTypes.init(); ItematicContextParameters.init(); - SmithingTemplateTypes.init(); + SmithingTemplates.init(); BlockPickerTypes.init(); ItematicItemModifierTypes.init(); TradeModifierTypes.init(); @@ -51,5 +46,6 @@ public void onInitialize() { ItematicRecipeBookCategories.init(); ItematicRecipeDisplaySerializers.init(); ItematicSlotDisplaySerializers.init(); + ItematicEntitySubPredicateTypes.init(); } } diff --git a/src/main/java/net/errorcraft/itematic/access/block/BlockAccess.java b/src/main/java/net/errorcraft/itematic/access/block/AbstractBlockAccess.java similarity index 93% rename from src/main/java/net/errorcraft/itematic/access/block/BlockAccess.java rename to src/main/java/net/errorcraft/itematic/access/block/AbstractBlockAccess.java index 50176138..d2cf17ef 100644 --- a/src/main/java/net/errorcraft/itematic/access/block/BlockAccess.java +++ b/src/main/java/net/errorcraft/itematic/access/block/AbstractBlockAccess.java @@ -5,7 +5,7 @@ import net.minecraft.item.ItemPlacementContext; import net.minecraft.registry.RegistryKey; -public interface BlockAccess { +public interface AbstractBlockAccess { default RegistryKey itematic$asItemKey() { return null; } diff --git a/src/main/java/net/errorcraft/itematic/access/block/entity/SherdsAccess.java b/src/main/java/net/errorcraft/itematic/access/block/entity/SherdsAccess.java index ab31ab0f..bf9e86eb 100644 --- a/src/main/java/net/errorcraft/itematic/access/block/entity/SherdsAccess.java +++ b/src/main/java/net/errorcraft/itematic/access/block/entity/SherdsAccess.java @@ -1,7 +1,6 @@ package net.errorcraft.itematic.access.block.entity; import net.minecraft.item.Item; -import net.minecraft.nbt.NbtCompound; import net.minecraft.registry.RegistryWrapper; import net.minecraft.registry.entry.RegistryEntry; @@ -9,16 +8,10 @@ import java.util.Optional; public interface SherdsAccess { - default NbtCompound itematic$toNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup lookup) { - return null; - } default List>> itematic$optionalEntries() { return null; } default List> itematic$entries(RegistryWrapper.WrapperLookup lookup) { return null; } - default List> itematic$entriesForwards(RegistryWrapper.WrapperLookup lookup) { - return null; - } } diff --git a/src/main/java/net/errorcraft/itematic/access/entity/EntityTypeAccess.java b/src/main/java/net/errorcraft/itematic/access/entity/EntityTypeAccess.java index b1761213..c2c35843 100644 --- a/src/main/java/net/errorcraft/itematic/access/entity/EntityTypeAccess.java +++ b/src/main/java/net/errorcraft/itematic/access/entity/EntityTypeAccess.java @@ -1,13 +1,16 @@ package net.errorcraft.itematic.access.entity; -import com.mojang.serialization.MapCodec; +import net.errorcraft.itematic.entity.EntitySpawnCallback; import net.errorcraft.itematic.entity.initializer.EntityInitializer; import net.errorcraft.itematic.world.action.context.ActionContext; +import net.minecraft.entity.Entity; +import net.minecraft.entity.SpawnReason; +import net.minecraft.util.math.BlockPos; +import org.jetbrains.annotations.Nullable; -public interface EntityTypeAccess { - default MapCodec> itematic$initializerCodec() { +public interface EntityTypeAccess { + default void itematic$setInitializer(EntityInitializer initializer) {} + default T itematic$create(ActionContext context, SpawnReason reason, BlockPos pos, @Nullable EntitySpawnCallback callback, boolean allowItemData, boolean invertY) { return null; } - default void itematic$setInitializerCodec(MapCodec> initializerCodec) {} - default void itematic$setInitializer(EntityInitializer initializer, ActionContext actionContext) {} } diff --git a/src/main/java/net/errorcraft/itematic/access/entity/EntityTypeBuilderAccess.java b/src/main/java/net/errorcraft/itematic/access/entity/EntityTypeBuilderAccess.java index c9b7d061..2639115a 100644 --- a/src/main/java/net/errorcraft/itematic/access/entity/EntityTypeBuilderAccess.java +++ b/src/main/java/net/errorcraft/itematic/access/entity/EntityTypeBuilderAccess.java @@ -1,11 +1,10 @@ package net.errorcraft.itematic.access.entity; -import com.mojang.serialization.MapCodec; import net.errorcraft.itematic.entity.initializer.EntityInitializer; -import net.errorcraft.itematic.entity.initializer.EntityInitializerCodecCreator; +import net.errorcraft.itematic.entity.initializer.EntityInitializerSupplier; import net.minecraft.entity.Entity; public interface EntityTypeBuilderAccess { - default void itematic$initializerCodec(MapCodec> codec) {} - default void itematic$initializerCodec(EntityInitializerCodecCreator creator) {} + default void itematic$initializer(EntityInitializer initializer) {} + default void itematic$initializer(EntityInitializerSupplier initializer) {} } 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 caab6e61..44f6a83d 100644 --- a/src/main/java/net/errorcraft/itematic/access/entity/LivingEntityAccess.java +++ b/src/main/java/net/errorcraft/itematic/access/entity/LivingEntityAccess.java @@ -6,6 +6,9 @@ import net.minecraft.util.Hand; public interface LivingEntityAccess { + default boolean itematic$hasStackInInventory(ItemStack stack) { + return false; + } default boolean itematic$isHolding(RegistryKey key) { return false; } diff --git a/src/main/java/net/errorcraft/itematic/access/item/AnimalArmorItemTypeAccess.java b/src/main/java/net/errorcraft/itematic/access/item/AnimalArmorItemTypeAccess.java deleted file mode 100644 index 2bd8853e..00000000 --- a/src/main/java/net/errorcraft/itematic/access/item/AnimalArmorItemTypeAccess.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.errorcraft.itematic.access.item; - -import net.minecraft.entity.EntityType; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.registry.entry.RegistryEntryList; -import net.minecraft.sound.SoundEvent; - -public interface AnimalArmorItemTypeAccess { - default RegistryEntry itematic$breakSound() { - return null; - } - default RegistryEntryList> itematic$allowedEntities() { - return null; - } -} 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 5d8511f2..3c6d953c 100644 --- a/src/main/java/net/errorcraft/itematic/access/item/ItemAccess.java +++ b/src/main/java/net/errorcraft/itematic/access/item/ItemAccess.java @@ -9,11 +9,15 @@ import net.errorcraft.itematic.world.action.context.ActionContext; import net.minecraft.component.type.AttributeModifiersComponent; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.item.tooltip.TooltipType; +import net.minecraft.text.Text; import net.minecraft.util.Hand; import net.minecraft.world.World; import java.util.Optional; +import java.util.function.Consumer; public interface ItemAccess { default ItemDisplay itematic$display() { @@ -44,6 +48,7 @@ public interface ItemAccess { default boolean itematic$hasEventListener(ItemEvent event) { return false; } + default void itematic$addTooltip(ItemStack stack, Item.TooltipContext context, Consumer tooltip, TooltipType type) {} 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 acf767be..8208ca29 100644 --- a/src/main/java/net/errorcraft/itematic/access/item/ItemStackAccess.java +++ b/src/main/java/net/errorcraft/itematic/access/item/ItemStackAccess.java @@ -4,16 +4,16 @@ import net.errorcraft.itematic.item.component.ItemComponentType; import net.errorcraft.itematic.item.event.ItemEvent; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.minecraft.block.BlockState; import net.minecraft.component.MergedComponentMap; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.util.Hand; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; import java.util.Optional; @@ -26,6 +26,9 @@ public interface ItemStackAccess { default int itematic$tryDecrement(int amount) { return 0; } + default ItemStack itematic$copyOrSplit(@Nullable LivingEntity holder, int amount) { + return ItemStack.EMPTY; + } default ItemStack itematic$copyWithItem(RegistryEntry item) { return ItemStack.EMPTY; } @@ -51,9 +54,6 @@ public interface ItemStackAccess { default boolean itematic$hasEventListener(ItemEvent event) { return false; } - default boolean itematic$canMine(BlockState state, World world, BlockPos pos, PlayerEntity miner) { - return false; - } default boolean itematic$mayStartUsing(World world, PlayerEntity user, Hand hand, ItemStack stack) { return false; } diff --git a/src/main/java/net/errorcraft/itematic/access/item/ItemUsageContextAccess.java b/src/main/java/net/errorcraft/itematic/access/item/ItemUsageContextAccess.java new file mode 100644 index 00000000..ad198738 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/access/item/ItemUsageContextAccess.java @@ -0,0 +1,9 @@ +package net.errorcraft.itematic.access.item; + +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; + +public interface ItemUsageContextAccess { + default ItemStackExchanger itematic$stackExchanger() { + return null; + } +} diff --git a/src/main/java/net/errorcraft/itematic/access/loot/condition/LocationCheckLootConditionAccess.java b/src/main/java/net/errorcraft/itematic/access/loot/condition/LocationCheckLootConditionAccess.java new file mode 100644 index 00000000..0978dcfd --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/access/loot/condition/LocationCheckLootConditionAccess.java @@ -0,0 +1,10 @@ +package net.errorcraft.itematic.access.loot.condition; + +import net.errorcraft.itematic.loot.condition.LocationCheckLootConditionExtraFields; + +public interface LocationCheckLootConditionAccess { + default void itematic$setExtraFields(LocationCheckLootConditionExtraFields extraFields) {} + default LocationCheckLootConditionExtraFields itematic$extraFields() { + return null; + } +} diff --git a/src/main/java/net/errorcraft/itematic/access/util/context/ContextParameterMapBuilderAccess.java b/src/main/java/net/errorcraft/itematic/access/util/context/ContextParameterMapBuilderAccess.java new file mode 100644 index 00000000..5ec95588 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/access/util/context/ContextParameterMapBuilderAccess.java @@ -0,0 +1,10 @@ +package net.errorcraft.itematic.access.util.context; + +import net.minecraft.util.context.ContextParameterMap; + +public interface ContextParameterMapBuilderAccess { + default void itematic$copy(ContextParameterMap other) {} + default ContextParameterMap itematic$build() { + return null; + } +} diff --git a/src/main/java/net/errorcraft/itematic/access/village/VillagerProfessionAccess.java b/src/main/java/net/errorcraft/itematic/access/village/VillagerProfessionAccess.java index efe4b93d..5bcca79d 100644 --- a/src/main/java/net/errorcraft/itematic/access/village/VillagerProfessionAccess.java +++ b/src/main/java/net/errorcraft/itematic/access/village/VillagerProfessionAccess.java @@ -6,7 +6,8 @@ public interface VillagerProfessionAccess { @Nullable - default TagKey itematic$gatherableItemsTag() { + default TagKey itematic$gatherableItems() { return null; } + default void itematic$setGatherableItems(TagKey gatherableItems) {} } diff --git a/src/main/java/net/errorcraft/itematic/access/world/WorldAccess.java b/src/main/java/net/errorcraft/itematic/access/world/WorldAccess.java index aef72918..e5f5d5e5 100644 --- a/src/main/java/net/errorcraft/itematic/access/world/WorldAccess.java +++ b/src/main/java/net/errorcraft/itematic/access/world/WorldAccess.java @@ -7,5 +7,5 @@ import org.jetbrains.annotations.Nullable; public interface WorldAccess { - default void itematic$playSound(@Nullable PlayerEntity except, Vec3d pos, SoundEvent sound, SoundCategory category, float volume, float pitch) {} + default void itematic$playSound(@Nullable PlayerEntity source, Vec3d pos, SoundEvent sound, SoundCategory category, float volume, float pitch) {} } diff --git a/src/main/java/net/errorcraft/itematic/block/BlockKeys.java b/src/main/java/net/errorcraft/itematic/block/BlockKeys.java index 7223e034..11038326 100644 --- a/src/main/java/net/errorcraft/itematic/block/BlockKeys.java +++ b/src/main/java/net/errorcraft/itematic/block/BlockKeys.java @@ -6,6 +6,7 @@ import net.minecraft.util.Identifier; public class BlockKeys { + public static final RegistryKey AIR = of("air"); public static final RegistryKey STONE = of("stone"); public static final RegistryKey GRANITE = of("granite"); public static final RegistryKey POLISHED_GRANITE = of("polished_granite"); @@ -25,6 +26,8 @@ public class BlockKeys { public static final RegistryKey ACACIA_PLANKS = of("acacia_planks"); public static final RegistryKey CHERRY_PLANKS = of("cherry_planks"); public static final RegistryKey DARK_OAK_PLANKS = of("dark_oak_planks"); + public static final RegistryKey PALE_OAK_WOOD = of("pale_oak_wood"); + public static final RegistryKey PALE_OAK_PLANKS = of("pale_oak_planks"); public static final RegistryKey MANGROVE_PLANKS = of("mangrove_planks"); public static final RegistryKey BAMBOO_PLANKS = of("bamboo_planks"); public static final RegistryKey BAMBOO_MOSAIC = of("bamboo_mosaic"); @@ -35,6 +38,7 @@ public class BlockKeys { public static final RegistryKey ACACIA_SAPLING = of("acacia_sapling"); public static final RegistryKey CHERRY_SAPLING = of("cherry_sapling"); public static final RegistryKey DARK_OAK_SAPLING = of("dark_oak_sapling"); + public static final RegistryKey PALE_OAK_SAPLING = of("pale_oak_sapling"); public static final RegistryKey MANGROVE_PROPAGULE = of("mangrove_propagule"); public static final RegistryKey BEDROCK = of("bedrock"); public static final RegistryKey WATER = of("water"); @@ -58,6 +62,7 @@ public class BlockKeys { public static final RegistryKey ACACIA_LOG = of("acacia_log"); public static final RegistryKey CHERRY_LOG = of("cherry_log"); public static final RegistryKey DARK_OAK_LOG = of("dark_oak_log"); + public static final RegistryKey PALE_OAK_LOG = of("pale_oak_log"); public static final RegistryKey MANGROVE_LOG = of("mangrove_log"); public static final RegistryKey MANGROVE_ROOTS = of("mangrove_roots"); public static final RegistryKey MUDDY_MANGROVE_ROOTS = of("muddy_mangrove_roots"); @@ -68,6 +73,7 @@ public class BlockKeys { public static final RegistryKey STRIPPED_ACACIA_LOG = of("stripped_acacia_log"); public static final RegistryKey STRIPPED_CHERRY_LOG = of("stripped_cherry_log"); public static final RegistryKey STRIPPED_DARK_OAK_LOG = of("stripped_dark_oak_log"); + public static final RegistryKey STRIPPED_PALE_OAK_LOG = of("stripped_pale_oak_log"); public static final RegistryKey STRIPPED_OAK_LOG = of("stripped_oak_log"); public static final RegistryKey STRIPPED_MANGROVE_LOG = of("stripped_mangrove_log"); public static final RegistryKey STRIPPED_BAMBOO_BLOCK = of("stripped_bamboo_block"); @@ -86,6 +92,7 @@ public class BlockKeys { public static final RegistryKey STRIPPED_ACACIA_WOOD = of("stripped_acacia_wood"); public static final RegistryKey STRIPPED_CHERRY_WOOD = of("stripped_cherry_wood"); public static final RegistryKey STRIPPED_DARK_OAK_WOOD = of("stripped_dark_oak_wood"); + public static final RegistryKey STRIPPED_PALE_OAK_WOOD = of("stripped_pale_oak_wood"); public static final RegistryKey STRIPPED_MANGROVE_WOOD = of("stripped_mangrove_wood"); public static final RegistryKey OAK_LEAVES = of("oak_leaves"); public static final RegistryKey SPRUCE_LEAVES = of("spruce_leaves"); @@ -94,6 +101,7 @@ public class BlockKeys { public static final RegistryKey ACACIA_LEAVES = of("acacia_leaves"); public static final RegistryKey CHERRY_LEAVES = of("cherry_leaves"); public static final RegistryKey DARK_OAK_LEAVES = of("dark_oak_leaves"); + public static final RegistryKey PALE_OAK_LEAVES = of("pale_oak_leaves"); public static final RegistryKey MANGROVE_LEAVES = of("mangrove_leaves"); public static final RegistryKey AZALEA_LEAVES = of("azalea_leaves"); public static final RegistryKey FLOWERING_AZALEA_LEAVES = of("flowering_azalea_leaves"); @@ -131,6 +139,9 @@ public class BlockKeys { public static final RegistryKey SHORT_GRASS = of("short_grass"); public static final RegistryKey FERN = of("fern"); public static final RegistryKey DEAD_BUSH = of("dead_bush"); + public static final RegistryKey BUSH = of("bush"); + public static final RegistryKey SHORT_DRY_GRASS = of("short_dry_grass"); + public static final RegistryKey TALL_DRY_GRASS = of("tall_dry_grass"); public static final RegistryKey SEAGRASS = of("seagrass"); public static final RegistryKey PISTON = of("piston"); public static final RegistryKey WHITE_WOOL = of("white_wool"); @@ -177,6 +188,7 @@ public class BlockKeys { public static final RegistryKey WALL_TORCH = of("wall_torch"); public static final RegistryKey FIRE = of("fire"); public static final RegistryKey SPAWNER = of("spawner"); + public static final RegistryKey CREAKING_HEART = of("creaking_heart"); public static final RegistryKey OAK_STAIRS = of("oak_stairs"); public static final RegistryKey CHEST = of("chest"); public static final RegistryKey REDSTONE_WIRE = of("redstone_wire"); @@ -194,6 +206,7 @@ public class BlockKeys { public static final RegistryKey CHERRY_SIGN = of("cherry_sign"); public static final RegistryKey JUNGLE_SIGN = of("jungle_sign"); public static final RegistryKey DARK_OAK_SIGN = of("dark_oak_sign"); + public static final RegistryKey PALE_OAK_SIGN = of("pale_oak_sign"); public static final RegistryKey MANGROVE_SIGN = of("mangrove_sign"); public static final RegistryKey BAMBOO_SIGN = of("bamboo_sign"); public static final RegistryKey OAK_DOOR = of("oak_door"); @@ -207,6 +220,7 @@ public class BlockKeys { public static final RegistryKey CHERRY_WALL_SIGN = of("cherry_wall_sign"); public static final RegistryKey JUNGLE_WALL_SIGN = of("jungle_wall_sign"); public static final RegistryKey DARK_OAK_WALL_SIGN = of("dark_oak_wall_sign"); + public static final RegistryKey PALE_OAK_WALL_SIGN = of("pale_oak_wall_sign"); public static final RegistryKey MANGROVE_WALL_SIGN = of("mangrove_wall_sign"); public static final RegistryKey BAMBOO_WALL_SIGN = of("bamboo_wall_sign"); public static final RegistryKey OAK_HANGING_SIGN = of("oak_hanging_sign"); @@ -216,6 +230,7 @@ public class BlockKeys { public static final RegistryKey CHERRY_HANGING_SIGN = of("cherry_hanging_sign"); public static final RegistryKey JUNGLE_HANGING_SIGN = of("jungle_hanging_sign"); public static final RegistryKey DARK_OAK_HANGING_SIGN = of("dark_oak_hanging_sign"); + public static final RegistryKey PALE_OAK_HANGING_SIGN = of("pale_oak_hanging_sign"); public static final RegistryKey CRIMSON_HANGING_SIGN = of("crimson_hanging_sign"); public static final RegistryKey WARPED_HANGING_SIGN = of("warped_hanging_sign"); public static final RegistryKey MANGROVE_HANGING_SIGN = of("mangrove_hanging_sign"); @@ -227,6 +242,7 @@ public class BlockKeys { public static final RegistryKey CHERRY_WALL_HANGING_SIGN = of("cherry_wall_hanging_sign"); public static final RegistryKey JUNGLE_WALL_HANGING_SIGN = of("jungle_wall_hanging_sign"); public static final RegistryKey DARK_OAK_WALL_HANGING_SIGN = of("dark_oak_wall_hanging_sign"); + public static final RegistryKey PALE_OAK_WALL_HANGING_SIGN = of("pale_oak_wall_hanging_sign"); public static final RegistryKey MANGROVE_WALL_HANGING_SIGN = of("mangrove_wall_hanging_sign"); public static final RegistryKey CRIMSON_WALL_HANGING_SIGN = of("crimson_wall_hanging_sign"); public static final RegistryKey WARPED_WALL_HANGING_SIGN = of("warped_wall_hanging_sign"); @@ -241,6 +257,7 @@ public class BlockKeys { public static final RegistryKey ACACIA_PRESSURE_PLATE = of("acacia_pressure_plate"); public static final RegistryKey CHERRY_PRESSURE_PLATE = of("cherry_pressure_plate"); public static final RegistryKey DARK_OAK_PRESSURE_PLATE = of("dark_oak_pressure_plate"); + public static final RegistryKey PALE_OAK_PRESSURE_PLATE = of("pale_oak_pressure_plate"); public static final RegistryKey MANGROVE_PRESSURE_PLATE = of("mangrove_pressure_plate"); public static final RegistryKey BAMBOO_PRESSURE_PLATE = of("bamboo_pressure_plate"); public static final RegistryKey REDSTONE_ORE = of("redstone_ore"); @@ -252,6 +269,7 @@ public class BlockKeys { public static final RegistryKey ICE = of("ice"); public static final RegistryKey SNOW_BLOCK = of("snow_block"); public static final RegistryKey CACTUS = of("cactus"); + public static final RegistryKey CACTUS_FLOWER = of("cactus_flower"); public static final RegistryKey CLAY = of("clay"); public static final RegistryKey SUGAR_CANE = of("sugar_cane"); public static final RegistryKey JUKEBOX = of("jukebox"); @@ -291,6 +309,7 @@ public class BlockKeys { public static final RegistryKey ACACIA_TRAPDOOR = of("acacia_trapdoor"); public static final RegistryKey CHERRY_TRAPDOOR = of("cherry_trapdoor"); public static final RegistryKey DARK_OAK_TRAPDOOR = of("dark_oak_trapdoor"); + public static final RegistryKey PALE_OAK_TRAPDOOR = of("pale_oak_trapdoor"); public static final RegistryKey MANGROVE_TRAPDOOR = of("mangrove_trapdoor"); public static final RegistryKey BAMBOO_TRAPDOOR = of("bamboo_trapdoor"); public static final RegistryKey STONE_BRICKS = of("stone_bricks"); @@ -317,12 +336,19 @@ public class BlockKeys { public static final RegistryKey MELON_STEM = of("melon_stem"); public static final RegistryKey VINE = of("vine"); public static final RegistryKey GLOW_LICHEN = of("glow_lichen"); + public static final RegistryKey RESIN_CLUMP = of("resin_clump"); public static final RegistryKey OAK_FENCE_GATE = of("oak_fence_gate"); public static final RegistryKey BRICK_STAIRS = of("brick_stairs"); public static final RegistryKey STONE_BRICK_STAIRS = of("stone_brick_stairs"); public static final RegistryKey MUD_BRICK_STAIRS = of("mud_brick_stairs"); public static final RegistryKey MYCELIUM = of("mycelium"); public static final RegistryKey LILY_PAD = of("lily_pad"); + public static final RegistryKey RESIN_BLOCK = of("resin_block"); + public static final RegistryKey RESIN_BRICKS = of("resin_bricks"); + public static final RegistryKey RESIN_BRICK_STAIRS = of("resin_brick_stairs"); + public static final RegistryKey RESIN_BRICK_SLAB = of("resin_brick_slab"); + public static final RegistryKey RESIN_BRICK_WALL = of("resin_brick_wall"); + public static final RegistryKey CHISELED_RESIN_BRICKS = of("chiseled_resin_bricks"); public static final RegistryKey NETHER_BRICKS = of("nether_bricks"); public static final RegistryKey NETHER_BRICK_FENCE = of("nether_brick_fence"); public static final RegistryKey NETHER_BRICK_STAIRS = of("nether_brick_stairs"); @@ -358,6 +384,7 @@ public class BlockKeys { public static final RegistryKey POTTED_ACACIA_SAPLING = of("potted_acacia_sapling"); public static final RegistryKey POTTED_CHERRY_SAPLING = of("potted_cherry_sapling"); public static final RegistryKey POTTED_DARK_OAK_SAPLING = of("potted_dark_oak_sapling"); + public static final RegistryKey POTTED_PALE_OAK_SAPLING = of("potted_pale_oak_sapling"); public static final RegistryKey POTTED_MANGROVE_PROPAGULE = of("potted_mangrove_propagule"); public static final RegistryKey POTTED_FERN = of("potted_fern"); public static final RegistryKey POTTED_DANDELION = of("potted_dandelion"); @@ -386,6 +413,7 @@ public class BlockKeys { public static final RegistryKey ACACIA_BUTTON = of("acacia_button"); public static final RegistryKey CHERRY_BUTTON = of("cherry_button"); public static final RegistryKey DARK_OAK_BUTTON = of("dark_oak_button"); + public static final RegistryKey PALE_OAK_BUTTON = of("pale_oak_button"); public static final RegistryKey MANGROVE_BUTTON = of("mangrove_button"); public static final RegistryKey BAMBOO_BUTTON = of("bamboo_button"); public static final RegistryKey SKELETON_SKULL = of("skeleton_skull"); @@ -454,6 +482,7 @@ public class BlockKeys { public static final RegistryKey ACACIA_STAIRS = of("acacia_stairs"); public static final RegistryKey CHERRY_STAIRS = of("cherry_stairs"); public static final RegistryKey DARK_OAK_STAIRS = of("dark_oak_stairs"); + public static final RegistryKey PALE_OAK_STAIRS = of("pale_oak_stairs"); public static final RegistryKey MANGROVE_STAIRS = of("mangrove_stairs"); public static final RegistryKey BAMBOO_STAIRS = of("bamboo_stairs"); public static final RegistryKey BAMBOO_MOSAIC_STAIRS = of("bamboo_mosaic_stairs"); @@ -540,6 +569,7 @@ public class BlockKeys { public static final RegistryKey ACACIA_SLAB = of("acacia_slab"); public static final RegistryKey CHERRY_SLAB = of("cherry_slab"); public static final RegistryKey DARK_OAK_SLAB = of("dark_oak_slab"); + public static final RegistryKey PALE_OAK_SLAB = of("pale_oak_slab"); public static final RegistryKey MANGROVE_SLAB = of("mangrove_slab"); public static final RegistryKey BAMBOO_SLAB = of("bamboo_slab"); public static final RegistryKey BAMBOO_MOSAIC_SLAB = of("bamboo_mosaic_slab"); @@ -567,6 +597,7 @@ public class BlockKeys { public static final RegistryKey ACACIA_FENCE_GATE = of("acacia_fence_gate"); public static final RegistryKey CHERRY_FENCE_GATE = of("cherry_fence_gate"); public static final RegistryKey DARK_OAK_FENCE_GATE = of("dark_oak_fence_gate"); + public static final RegistryKey PALE_OAK_FENCE_GATE = of("pale_oak_fence_gate"); public static final RegistryKey MANGROVE_FENCE_GATE = of("mangrove_fence_gate"); public static final RegistryKey BAMBOO_FENCE_GATE = of("bamboo_fence_gate"); public static final RegistryKey SPRUCE_FENCE = of("spruce_fence"); @@ -575,6 +606,7 @@ public class BlockKeys { public static final RegistryKey ACACIA_FENCE = of("acacia_fence"); public static final RegistryKey CHERRY_FENCE = of("cherry_fence"); public static final RegistryKey DARK_OAK_FENCE = of("dark_oak_fence"); + public static final RegistryKey PALE_OAK_FENCE = of("pale_oak_fence"); public static final RegistryKey MANGROVE_FENCE = of("mangrove_fence"); public static final RegistryKey BAMBOO_FENCE = of("bamboo_fence"); public static final RegistryKey SPRUCE_DOOR = of("spruce_door"); @@ -583,6 +615,7 @@ public class BlockKeys { public static final RegistryKey ACACIA_DOOR = of("acacia_door"); public static final RegistryKey CHERRY_DOOR = of("cherry_door"); public static final RegistryKey DARK_OAK_DOOR = of("dark_oak_door"); + public static final RegistryKey PALE_OAK_DOOR = of("pale_oak_door"); public static final RegistryKey MANGROVE_DOOR = of("mangrove_door"); public static final RegistryKey BAMBOO_DOOR = of("bamboo_door"); public static final RegistryKey END_ROD = of("end_rod"); @@ -983,6 +1016,8 @@ public class BlockKeys { public static final RegistryKey FLOWERING_AZALEA = of("flowering_azalea"); public static final RegistryKey MOSS_CARPET = of("moss_carpet"); public static final RegistryKey PINK_PETALS = of("pink_petals"); + public static final RegistryKey WILDFLOWERS = of("wildflowers"); + public static final RegistryKey LEAF_LITTER = of("leaf_litter"); public static final RegistryKey MOSS_BLOCK = of("moss_block"); public static final RegistryKey BIG_DRIPLEAF = of("big_dripleaf"); public static final RegistryKey SMALL_DRIPLEAF = of("small_dripleaf"); @@ -1026,6 +1061,14 @@ public class BlockKeys { public static final RegistryKey TRIAL_SPAWNER = of("trial_spawner"); public static final RegistryKey VAULT = of("vault"); public static final RegistryKey HEAVY_CORE = of("heavy_core"); + public static final RegistryKey PALE_MOSS_BLOCK = of("pale_moss_block"); + public static final RegistryKey PALE_MOSS_CARPET = of("pale_moss_carpet"); + public static final RegistryKey PALE_HANGING_MOSS = of("pale_hanging_moss"); + public static final RegistryKey OPEN_EYEBLOSSOM = of("open_eyeblossom"); + public static final RegistryKey CLOSED_EYEBLOSSOM = of("closed_eyeblossom"); + public static final RegistryKey POTTED_OPEN_EYEBLOSSOM = of("potted_open_eyeblossom"); + public static final RegistryKey POTTED_CLOSED_EYEBLOSSOM = of("potted_closed_eyeblossom"); + public static final RegistryKey FIREFLY_BUSH = of("firefly_bush"); private BlockKeys() {} diff --git a/src/main/java/net/errorcraft/itematic/block/BlockStateUtil.java b/src/main/java/net/errorcraft/itematic/block/BlockStateUtil.java deleted file mode 100644 index 06a7ae56..00000000 --- a/src/main/java/net/errorcraft/itematic/block/BlockStateUtil.java +++ /dev/null @@ -1,14 +0,0 @@ -package net.errorcraft.itematic.block; - -import net.minecraft.block.BlockState; -import net.minecraft.state.property.Property; - -public class BlockStateUtil { - private BlockStateUtil() {} - - public static > BlockState with(BlockState state, Property property, String name) { - return property.parse(name) - .map((value) -> state.with(property, value)) - .orElse(state); - } -} diff --git a/src/main/java/net/errorcraft/itematic/block/ComposterBlockUtil.java b/src/main/java/net/errorcraft/itematic/block/ComposterBlockUtil.java deleted file mode 100644 index 0af5252d..00000000 --- a/src/main/java/net/errorcraft/itematic/block/ComposterBlockUtil.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.errorcraft.itematic.block; - -public class ComposterBlockUtil { - public static final float SMALL_CHANCE_TO_COMPOST = 0.3f; - public static final float HALF_CHANCE_TO_COMPOST = 0.5f; - public static final float BIG_CHANCE_TO_COMPOST = 0.65f; - public static final float ALMOST_GUARANTEED_TO_COMPOST = 0.85f; - public static final float GUARANTEED_TO_COMPOST = 1.0f; - - private ComposterBlockUtil() {} -} diff --git a/src/main/java/net/errorcraft/itematic/block/entity/FurnaceBlockEntityUtil.java b/src/main/java/net/errorcraft/itematic/block/entity/FurnaceBlockEntityUtil.java deleted file mode 100644 index 6658fb1b..00000000 --- a/src/main/java/net/errorcraft/itematic/block/entity/FurnaceBlockEntityUtil.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.errorcraft.itematic.block.entity; - -public class FurnaceBlockEntityUtil { - public static final int LAVA_FUEL_TIME = 20000; - public static final int COAL_BLOCK_FUEL_TIME = 16000; - public static final int DRIED_KELP_BLOCK_FUEL_TIME = 4001; - public static final int BLAZE_ROD_FUEL_TIME = 2400; - public static final int COAL_FUEL_TIME = 1600; - - public static final int BOAT_FUEL_TIME = 1200; - public static final int HANGING_SIGN_FUEL_TIME = 800; - public static final int SIGN_FUEL_TIME = 200; - public static final int WOOD_FUEL_TIME = 300; - public static final int DOOR_FUEL_TIME = 200; - public static final int SLAB_FUEL_TIME = 150; - public static final int PLANT_FUEL_TIME = 100; - public static final int BUTTON_FUEL_TIME = 100; - public static final int SMALL_WOODEN_ITEM_FUEL_TIME = 100; - public static final int BAMBOO_FUEL_TIME = 50; - public static final int SCAFFOLDING_FUEL_TIME = 50; - - public static final int TOOL_FUEL_TIME = 200; - - public static final int WOOL_FUEL_TIME = 100; - public static final int WOOL_CARPET_FUEL_TIME = 67; -} diff --git a/src/main/java/net/errorcraft/itematic/block/entity/SherdsUtil.java b/src/main/java/net/errorcraft/itematic/block/entity/SherdsUtil.java index 91e500aa..64e5e856 100644 --- a/src/main/java/net/errorcraft/itematic/block/entity/SherdsUtil.java +++ b/src/main/java/net/errorcraft/itematic/block/entity/SherdsUtil.java @@ -2,6 +2,8 @@ import net.minecraft.block.entity.DecoratedPotBlockEntity; import net.minecraft.block.entity.Sherds; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtOps; import net.minecraft.registry.RegistryWrapper; @@ -9,6 +11,11 @@ public class SherdsUtil { private SherdsUtil() {} + public static ItemStack addSherdsToStack(ItemStack stack, Sherds sherds) { + stack.set(DataComponentTypes.POT_DECORATIONS, sherds); + return stack; + } + public static Sherds fromNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup lookup) { if (nbt == null || !nbt.contains(DecoratedPotBlockEntity.SHERDS_NBT_KEY)) { return Sherds.DEFAULT; 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 ed806c91..e9a77713 100644 --- a/src/main/java/net/errorcraft/itematic/component/type/WeaponAttackDamageDataComponent.java +++ b/src/main/java/net/errorcraft/itematic/component/type/WeaponAttackDamageDataComponent.java @@ -60,7 +60,7 @@ public record Rule(Optional>> entities, Optional PacketCodecs.registryEntryList(RegistryKeys.ENTITY_TYPE).collect(PacketCodecs::optional), Rule::entities, ItemPredicateUtil.PACKET_CODEC.collect(PacketCodecs::optional), Rule::item, PacketCodecs.DOUBLE.collect(PacketCodecs::optional), Rule::damage, - PacketCodecs.BOOL.collect(PacketCodecs::optional), Rule::addBase, + PacketCodecs.BOOLEAN.collect(PacketCodecs::optional), Rule::addBase, Rule::new ); diff --git a/src/main/java/net/errorcraft/itematic/entity/EntitySpawnCallback.java b/src/main/java/net/errorcraft/itematic/entity/EntitySpawnCallback.java new file mode 100644 index 00000000..a7830832 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/entity/EntitySpawnCallback.java @@ -0,0 +1,9 @@ +package net.errorcraft.itematic.entity; + +import net.minecraft.entity.Entity; +import net.minecraft.item.ItemStack; + +@FunctionalInterface +public interface EntitySpawnCallback { + void accept(T entity, ItemStack stack); +} diff --git a/src/main/java/net/errorcraft/itematic/entity/EntitySpawner.java b/src/main/java/net/errorcraft/itematic/entity/EntitySpawner.java new file mode 100644 index 00000000..69879d64 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/entity/EntitySpawner.java @@ -0,0 +1,48 @@ +package net.errorcraft.itematic.entity; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.errorcraft.itematic.mixin.entity.EntityAccessor; +import net.errorcraft.itematic.world.action.context.ActionContext; +import net.minecraft.component.ComponentChanges; +import net.minecraft.component.ComponentMap; +import net.minecraft.component.MergedComponentMap; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.SpawnReason; +import net.minecraft.item.ItemStack; +import net.minecraft.registry.Registries; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.util.math.BlockPos; + +public record EntitySpawner(RegistryEntry> entity, ComponentChanges components) { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + Registries.ENTITY_TYPE.getEntryCodec().fieldOf("entity").forGetter(EntitySpawner::entity), + ComponentChanges.CODEC.optionalFieldOf("components", ComponentChanges.EMPTY).forGetter(EntitySpawner::components) + ).apply(instance, EntitySpawner::new)); + + public static EntitySpawner of(RegistryEntry> entity) { + return new EntitySpawner(entity, ComponentChanges.EMPTY); + } + + public static EntitySpawner of(RegistryEntry> entity, ComponentChanges components) { + return new EntitySpawner(entity, components); + } + + public Entity create(ActionContext context, BlockPos pos, SpawnReason reason) { + return this.entity.value().itematic$create( + context, + reason, + pos, + this::applyComponents, + false, + false + ); + } + + private void applyComponents(Entity entity, ItemStack stack) { + ((EntityAccessor) entity).itematic$copyComponentsFrom( + MergedComponentMap.create(ComponentMap.EMPTY, this.components) + ); + } +} diff --git a/src/main/java/net/errorcraft/itematic/entity/EntityTypeKeys.java b/src/main/java/net/errorcraft/itematic/entity/EntityTypeKeys.java index 4629a69b..c38c7f4b 100644 --- a/src/main/java/net/errorcraft/itematic/entity/EntityTypeKeys.java +++ b/src/main/java/net/errorcraft/itematic/entity/EntityTypeKeys.java @@ -6,22 +6,36 @@ import net.minecraft.util.Identifier; public class EntityTypeKeys { + public static final RegistryKey> ACACIA_BOAT = of("acacia_boat"); + public static final RegistryKey> ACACIA_CHEST_BOAT = of("acacia_chest_boat"); public static final RegistryKey> ALLAY = of("allay"); public static final RegistryKey> ARMADILLO = of("armadillo"); + public static final RegistryKey> ARMOR_STAND = of("armor_stand"); public static final RegistryKey> ARROW = of("arrow"); public static final RegistryKey> AXOLOTL = of("axolotl"); + public static final RegistryKey> BAMBOO_CHEST_RAFT = of("bamboo_chest_raft"); + public static final RegistryKey> BAMBOO_RAFT = of("bamboo_raft"); public static final RegistryKey> BAT = of("bat"); public static final RegistryKey> BEE = of("bee"); + public static final RegistryKey> BIRCH_BOAT = of("birch_boat"); + public static final RegistryKey> BIRCH_CHEST_BOAT = of("birch_chest_boat"); public static final RegistryKey> BLAZE = of("blaze"); public static final RegistryKey> BOGGED = of("bogged"); public static final RegistryKey> BREEZE = of("breeze"); public static final RegistryKey> CAMEL = of("camel"); public static final RegistryKey> CAT = of("cat"); public static final RegistryKey> CAVE_SPIDER = of("cave_spider"); + public static final RegistryKey> CHERRY_BOAT = of("cherry_boat"); + public static final RegistryKey> CHERRY_CHEST_BOAT = of("cherry_chest_boat"); + public static final RegistryKey> CHEST_MINECART = of("chest_minecart"); public static final RegistryKey> CHICKEN = of("chicken"); public static final RegistryKey> COD = of("cod"); + public static final RegistryKey> COMMAND_BLOCK_MINECART = of("command_block_minecart"); public static final RegistryKey> COW = of("cow"); + public static final RegistryKey> CREAKING = of("creaking"); public static final RegistryKey> CREEPER = of("creeper"); + public static final RegistryKey> DARK_OAK_BOAT = of("dark_oak_boat"); + public static final RegistryKey> DARK_OAK_CHEST_BOAT = of("dark_oak_chest_boat"); public static final RegistryKey> DOLPHIN = of("dolphin"); public static final RegistryKey> DONKEY = of("donkey"); public static final RegistryKey> DROWNED = of("drowned"); @@ -31,24 +45,41 @@ public class EntityTypeKeys { public static final RegistryKey> ENDERMITE = of("endermite"); public static final RegistryKey> ENDER_DRAGON = of("ender_dragon"); public static final RegistryKey> ENDER_PEARL = of("ender_pearl"); + public static final RegistryKey> END_CRYSTAL = of("end_crystal"); public static final RegistryKey> EVOKER = of("evoker"); public static final RegistryKey> EXPERIENCE_BOTTLE = of("experience_bottle"); + public static final RegistryKey> EYE_OF_ENDER = of("eye_of_ender"); + public static final RegistryKey> FIREWORK_ROCKET = of("firework_rocket"); public static final RegistryKey> FOX = of("fox"); public static final RegistryKey> FROG = of("frog"); + public static final RegistryKey> FURNACE_MINECART = of("furnace_minecart"); public static final RegistryKey> GHAST = of("ghast"); + public static final RegistryKey> GLOW_ITEM_FRAME = of("glow_item_frame"); public static final RegistryKey> GLOW_SQUID = of("glow_squid"); public static final RegistryKey> GOAT = of("goat"); public static final RegistryKey> GUARDIAN = of("guardian"); public static final RegistryKey> HOGLIN = of("hoglin"); + public static final RegistryKey> HOPPER_MINECART = of("hopper_minecart"); public static final RegistryKey> HORSE = of("horse"); public static final RegistryKey> HUSK = of("husk"); public static final RegistryKey> IRON_GOLEM = of("iron_golem"); + public static final RegistryKey> ITEM_FRAME = of("item_frame"); + public static final RegistryKey> JUNGLE_BOAT = of("jungle_boat"); + public static final RegistryKey> JUNGLE_CHEST_BOAT = of("jungle_chest_boat"); + public static final RegistryKey> LINGERING_POTION = of("lingering_potion"); public static final RegistryKey> LLAMA = of("llama"); public static final RegistryKey> MAGMA_CUBE = of("magma_cube"); + public static final RegistryKey> MANGROVE_BOAT = of("mangrove_boat"); + public static final RegistryKey> MANGROVE_CHEST_BOAT = of("mangrove_chest_boat"); + public static final RegistryKey> MINECART = of("minecart"); public static final RegistryKey> MOOSHROOM = of("mooshroom"); public static final RegistryKey> MULE = of("mule"); + public static final RegistryKey> OAK_BOAT = of("oak_boat"); + public static final RegistryKey> OAK_CHEST_BOAT = of("oak_chest_boat"); public static final RegistryKey> OCELOT = of("ocelot"); public static final RegistryKey> PAINTING = of("painting"); + public static final RegistryKey> PALE_OAK_BOAT = of("pale_oak_boat"); + public static final RegistryKey> PALE_OAK_CHEST_BOAT = of("pale_oak_chest_boat"); public static final RegistryKey> PANDA = of("panda"); public static final RegistryKey> PARROT = of("parrot"); public static final RegistryKey> PHANTOM = of("phantom"); @@ -57,7 +88,6 @@ public class EntityTypeKeys { public static final RegistryKey> PIGLIN_BRUTE = of("piglin_brute"); public static final RegistryKey> PILLAGER = of("pillager"); public static final RegistryKey> POLAR_BEAR = of("polar_bear"); - public static final RegistryKey> POTION = of("potion"); public static final RegistryKey> PUFFERFISH = of("pufferfish"); public static final RegistryKey> RABBIT = of("rabbit"); public static final RegistryKey> RAVAGER = of("ravager"); @@ -72,12 +102,19 @@ public class EntityTypeKeys { public static final RegistryKey> SNIFFER = of("sniffer"); public static final RegistryKey> SNOWBALL = of("snowball"); public static final RegistryKey> SNOW_GOLEM = of("snow_golem"); + public static final RegistryKey> SPECTRAL_ARROW = of("spectral_arrow"); public static final RegistryKey> SPIDER = of("spider"); + public static final RegistryKey> SPLASH_POTION = of("splash_potion"); + public static final RegistryKey> SPRUCE_BOAT = of("spruce_boat"); + public static final RegistryKey> SPRUCE_CHEST_BOAT = of("spruce_chest_boat"); public static final RegistryKey> SQUID = of("squid"); public static final RegistryKey> STRAY = of("stray"); public static final RegistryKey> STRIDER = of("strider"); public static final RegistryKey> TADPOLE = of("tadpole"); + public static final RegistryKey> TNT = of("tnt"); + public static final RegistryKey> TNT_MINECART = of("tnt_minecart"); public static final RegistryKey> TRADER_LLAMA = of("trader_llama"); + public static final RegistryKey> TRIDENT = of("trident"); public static final RegistryKey> TROPICAL_FISH = of("tropical_fish"); public static final RegistryKey> TURTLE = of("turtle"); public static final RegistryKey> VEX = of("vex"); diff --git a/src/main/java/net/errorcraft/itematic/entity/initializer/EntityInitializer.java b/src/main/java/net/errorcraft/itematic/entity/initializer/EntityInitializer.java index a0f2a824..2774e405 100644 --- a/src/main/java/net/errorcraft/itematic/entity/initializer/EntityInitializer.java +++ b/src/main/java/net/errorcraft/itematic/entity/initializer/EntityInitializer.java @@ -1,14 +1,9 @@ package net.errorcraft.itematic.entity.initializer; -import com.mojang.serialization.Codec; import net.errorcraft.itematic.world.action.context.ActionContext; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityType; import net.minecraft.entity.SpawnReason; -import net.minecraft.registry.Registries; public interface EntityInitializer { - Codec> CODEC = Registries.ENTITY_TYPE.getCodec().dispatch(EntityInitializer::type, EntityType::itematic$initializerCodec); - EntityType type(); T create(ActionContext context, SpawnReason reason); } diff --git a/src/main/java/net/errorcraft/itematic/entity/initializer/EntityInitializerCodecCreator.java b/src/main/java/net/errorcraft/itematic/entity/initializer/EntityInitializerCodecCreator.java deleted file mode 100644 index 71c43732..00000000 --- a/src/main/java/net/errorcraft/itematic/entity/initializer/EntityInitializerCodecCreator.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.errorcraft.itematic.entity.initializer; - -import com.mojang.serialization.MapCodec; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityType; - -@FunctionalInterface -public interface EntityInitializerCodecCreator { - MapCodec> create(EntityType type); -} diff --git a/src/main/java/net/errorcraft/itematic/entity/initializer/EntityInitializerSupplier.java b/src/main/java/net/errorcraft/itematic/entity/initializer/EntityInitializerSupplier.java new file mode 100644 index 00000000..9cb6beeb --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/entity/initializer/EntityInitializerSupplier.java @@ -0,0 +1,9 @@ +package net.errorcraft.itematic.entity.initializer; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; + +@FunctionalInterface +public interface EntityInitializerSupplier { + EntityInitializer create(EntityType type); +} diff --git a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/ArmorStandEntityInitializer.java b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/ArmorStandEntityInitializer.java index 30270ca8..a9f4ba22 100644 --- a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/ArmorStandEntityInitializer.java +++ b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/ArmorStandEntityInitializer.java @@ -1,13 +1,13 @@ package net.errorcraft.itematic.entity.initializer.initializers; -import com.mojang.serialization.MapCodec; import net.errorcraft.itematic.entity.initializer.EntityInitializer; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.SpawnReason; import net.minecraft.entity.decoration.ArmorStandEntity; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.server.world.ServerWorld; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvents; @@ -16,46 +16,47 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; -import java.util.Optional; - -public record ArmorStandEntityInitializer() implements EntityInitializer { +public class ArmorStandEntityInitializer implements EntityInitializer { public static final ArmorStandEntityInitializer INSTANCE = new ArmorStandEntityInitializer(); - public static final MapCodec CODEC = MapCodec.unit(INSTANCE); - @Override - public EntityType type() { - return EntityType.ARMOR_STAND; - } + private ArmorStandEntityInitializer() {} @Override public ArmorStandEntity create(ActionContext context, SpawnReason reason) { - if (!mayCreate(context)) { + Vec3d position = context.get(ItematicContextParameters.INTERACTED_POSITION); + if (position == null) { return null; } - Vec3d position = context.position(ActionContextParameter.TARGET); + + if (!mayCreate(context, position)) { + return null; + } + ServerWorld world = context.world(); ArmorStandEntity entity = new ArmorStandEntity(world, position.getX(), position.getY(), position.getZ()); - float angle = getRoundedAngle(context.entity(ActionContextParameter.THIS).map(Entity::getYaw).orElse(0.0f)); + float angle = getRoundedAngle(context); entity.refreshPositionAndAngles(entity.getX(), entity.getY(), entity.getZ(), angle, 0.0f); world.playSound(null, entity.getX(), entity.getY(), entity.getZ(), SoundEvents.ENTITY_ARMOR_STAND_PLACE, SoundCategory.BLOCKS, 0.75f, 0.8f); return entity; } - private static boolean mayCreate(ActionContext context) { - Optional entity = context.entity(ActionContextParameter.THIS); - if (entity.isEmpty()) { + private static boolean mayCreate(ActionContext context, Vec3d position) { + if (!context.has(LootContextParameters.THIS_ENTITY)) { return true; } + ServerWorld world = context.world(); - if (context.side() == Direction.DOWN) { + if (context.get(ItematicContextParameters.SIDE) == Direction.DOWN) { return false; } - Vec3d position = context.position(ActionContextParameter.TARGET); + Box box = EntityType.ARMOR_STAND.getDimensions().getBoxAt(position.getX(), position.getY(), position.getZ()); return world.isSpaceEmpty(null, box) && world.getOtherEntities(null, box).isEmpty(); } - private static float getRoundedAngle(float angle) { + private static float getRoundedAngle(ActionContext context) { + Entity entity = context.get(LootContextParameters.THIS_ENTITY); + float angle = entity != null ? entity.getYaw() : 0.0f; return MathHelper.floor((MathHelper.wrapDegrees(angle - 180.0f) + 22.5f) / 45.0f) * 45.0f; } } diff --git a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/DecorationEntityInitializer.java b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/DecorationEntityInitializer.java index e2baccac..23ee260d 100644 --- a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/DecorationEntityInitializer.java +++ b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/DecorationEntityInitializer.java @@ -1,8 +1,8 @@ package net.errorcraft.itematic.entity.initializer.initializers; import net.errorcraft.itematic.entity.initializer.EntityInitializer; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.NbtComponent; import net.minecraft.entity.EntityType; @@ -12,47 +12,69 @@ import net.minecraft.entity.decoration.painting.PaintingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; -public record DecorationEntityInitializer(EntityType type, Creator creator, PlacementChecker checker) implements EntityInitializer { +public record DecorationEntityInitializer(Creator creator, PlacementChecker checker) implements EntityInitializer { + public static EntityInitializer ofPainting() { + return new DecorationEntityInitializer<>( + (world, pos, facing) -> PaintingEntity.placePainting(world, pos, facing).orElse(null), + DecorationEntityInitializer::mayPlacePainting + ); + } + + public static EntityInitializer ofItemFrame(Creator creator) { + return new DecorationEntityInitializer<>( + creator, + DecorationEntityInitializer::mayPlaceItemFrame + ); + } + @Override public T create(ActionContext context, SpawnReason reason) { - Direction side = context.side(); - return this.create(context.world(), context.player(ActionContextParameter.THIS).orElse(null), context.blockPos(ActionContextParameter.TARGET), side, context.stack()); + BlockPos pos = context.getBlockPos(ItematicContextParameters.INTERACTED_POSITION); + if (pos == null) { + return null; + } + + Direction side = context.getOrDefault(ItematicContextParameters.SIDE, Direction.UP); + return this.create( + context.world(), + context.get(LootContextParameters.THIS_ENTITY, PlayerEntity.class), + pos, + side, + context.getOrDefault(LootContextParameters.TOOL, ItemStack.EMPTY) + ); } private T create(ServerWorld world, PlayerEntity player, BlockPos pos, Direction facing, ItemStack stack) { if (player == null || !this.checker.mayPlace(player, pos, facing, stack)) { return null; } + T entity = this.creator.create(world, pos, facing); if (entity == null) { return null; } - EntityType.loadFromEntityNbt(world, player, entity, stack.getOrDefault(DataComponentTypes.ENTITY_DATA, NbtComponent.DEFAULT)); + + EntityType.loadFromEntityNbt( + world, + player, + entity, + stack.getOrDefault(DataComponentTypes.ENTITY_DATA, NbtComponent.DEFAULT) + ); if (!entity.canStayAttached()) { return null; } + entity.onPlace(); return entity; } - public static EntityInitializer createPainting(EntityType type) { - return create(type, ((world, pos, facing) -> PaintingEntity.placePainting(world, pos, facing).orElse(null)), DecorationEntityInitializer::mayPlacePainting); - } - - public static EntityInitializer createItemFrame(EntityType type, Creator creator) { - return create(type, creator, DecorationEntityInitializer::mayPlaceItemFrame); - } - - private static EntityInitializer create(EntityType type, Creator creator, PlacementChecker checker) { - return new DecorationEntityInitializer<>(type, creator, checker); - } - private static boolean mayPlacePainting(PlayerEntity player, BlockPos pos, Direction facing, ItemStack stack) { return !facing.getAxis().isVertical() && player.canPlaceOn(pos, facing, stack); } diff --git a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/EndCrystalEntityInitializer.java b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/EndCrystalEntityInitializer.java index 9bab7bc7..cab7f7de 100644 --- a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/EndCrystalEntityInitializer.java +++ b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/EndCrystalEntityInitializer.java @@ -1,12 +1,10 @@ package net.errorcraft.itematic.entity.initializer.initializers; -import com.mojang.serialization.MapCodec; import net.errorcraft.itematic.block.ItematicBlockTags; import net.errorcraft.itematic.entity.initializer.EntityInitializer; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityType; import net.minecraft.entity.SpawnReason; import net.minecraft.entity.boss.dragon.EnderDragonFight; import net.minecraft.entity.decoration.EndCrystalEntity; @@ -16,24 +14,25 @@ import java.util.List; -public record EndCrystalEntityInitializer() implements EntityInitializer { +public class EndCrystalEntityInitializer implements EntityInitializer { public static final EndCrystalEntityInitializer INSTANCE = new EndCrystalEntityInitializer(); - public static final MapCodec CODEC = MapCodec.unit(INSTANCE); private static final double HORIZONTAL_SEARCH_DISTANCE = 1.0d; private static final double VERTICAL_SEARCH_DISTANCE = 2.0d; - @Override - public EntityType type() { - return EntityType.END_CRYSTAL; - } + private EndCrystalEntityInitializer() {} @Override public EndCrystalEntity create(ActionContext context, SpawnReason reason) { ServerWorld world = context.world(); - BlockPos pos = context.blockPos(ActionContextParameter.TARGET); + BlockPos pos = context.getBlockPos(ItematicContextParameters.INTERACTED_POSITION); + if (pos == null) { + return null; + } + if (!world.getBlockState(pos.down()).isIn(ItematicBlockTags.END_CRYSTAL_SPAWNABLE_ON)) { return null; } + return this.trySpawn(world, pos); } @@ -41,19 +40,22 @@ private EndCrystalEntity trySpawn(ServerWorld world, BlockPos pos) { if (!world.isAir(pos)) { return null; } + double x = pos.getX(); double y = pos.getY(); double z = pos.getZ(); - List v = world.getOtherEntities(null, new Box(x, y, z, x + HORIZONTAL_SEARCH_DISTANCE, y + VERTICAL_SEARCH_DISTANCE, z + HORIZONTAL_SEARCH_DISTANCE)); - if (!v.isEmpty()) { + List entities = world.getOtherEntities(null, new Box(x, y, z, x + HORIZONTAL_SEARCH_DISTANCE, y + VERTICAL_SEARCH_DISTANCE, z + HORIZONTAL_SEARCH_DISTANCE)); + if (!entities.isEmpty()) { return null; } + EndCrystalEntity endCrystalEntity = new EndCrystalEntity(world, x + 0.5d, y, z + 0.5d); endCrystalEntity.setShowBottom(false); EnderDragonFight enderDragonFight = world.getEnderDragonFight(); if (enderDragonFight != null) { enderDragonFight.respawnDragon(); } + return endCrystalEntity; } } diff --git a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/EyeOfEnderEntityInitializer.java b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/EyeOfEnderEntityInitializer.java index 213177b4..343ede22 100644 --- a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/EyeOfEnderEntityInitializer.java +++ b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/EyeOfEnderEntityInitializer.java @@ -1,15 +1,14 @@ package net.errorcraft.itematic.entity.initializer.initializers; -import com.mojang.serialization.MapCodec; import net.errorcraft.itematic.entity.initializer.EntityInitializer; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; import net.minecraft.advancement.criterion.Criteria; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityType; import net.minecraft.entity.EyeOfEnderEntity; import net.minecraft.entity.SpawnReason; import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.registry.tag.StructureTags; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; @@ -17,27 +16,32 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.event.GameEvent; -public record EyeOfEnderEntityInitializer() implements EntityInitializer { +public class EyeOfEnderEntityInitializer implements EntityInitializer { public static final EyeOfEnderEntityInitializer INSTANCE = new EyeOfEnderEntityInitializer(); - public static final MapCodec CODEC = MapCodec.unit(INSTANCE); - @Override - public EntityType type() { - return EntityType.EYE_OF_ENDER; - } + private EyeOfEnderEntityInitializer() {} @Override public EyeOfEnderEntity create(ActionContext context, SpawnReason reason) { ServerWorld world = context.world(); BlockPos blockPos = this.getBlockPos(context); - BlockPos strongholdPos = world.locateStructure(StructureTags.EYE_OF_ENDER_LOCATED, blockPos, 100, false); + if (blockPos == null) { + return null; + } + + BlockPos strongholdPos = world.locateStructure( + StructureTags.EYE_OF_ENDER_LOCATED, + blockPos, + 100, + false + ); if (strongholdPos == null) { return null; } Vec3d pos = this.getPosition(context); - EyeOfEnderEntity entity = this.createEntity(world, pos, context.stack(), strongholdPos); - Entity user = context.entity(ActionContextParameter.THIS).orElse(null); + EyeOfEnderEntity entity = this.createEntity(world, pos, context.get(LootContextParameters.TOOL), strongholdPos); + Entity user = context.get(LootContextParameters.THIS_ENTITY); world.emitGameEvent(GameEvent.PROJECTILE_SHOOT, pos, GameEvent.Emitter.of(user)); if (user instanceof ServerPlayerEntity serverPlayer) { Criteria.USED_ENDER_EYE.trigger(serverPlayer, strongholdPos); @@ -47,20 +51,29 @@ public EyeOfEnderEntity create(ActionContext context, SpawnReason reason) { } private Vec3d getPosition(ActionContext context) { - return context.entity(ActionContextParameter.THIS) - .map(target -> new Vec3d(target.getX(), target.getBodyY(0.5d), target.getZ())) - .orElseGet(() -> context.position(ActionContextParameter.TARGET)); + Entity entity = context.get(LootContextParameters.THIS_ENTITY); + if (entity != null) { + return new Vec3d(entity.getX(), entity.getBodyY(0.5d), entity.getZ()); + } + + return context.get(ItematicContextParameters.INTERACTED_POSITION); } private BlockPos getBlockPos(ActionContext context) { - return context.entity(ActionContextParameter.THIS) - .map(Entity::getBlockPos) - .orElseGet(() -> context.blockPos(ActionContextParameter.TARGET)); + Entity entity = context.get(LootContextParameters.THIS_ENTITY); + if (entity != null) { + return entity.getBlockPos(); + } + + return context.getBlockPos(ItematicContextParameters.INTERACTED_POSITION); } private EyeOfEnderEntity createEntity(ServerWorld world, Vec3d pos, ItemStack stack, BlockPos strongholdPos) { EyeOfEnderEntity entity = new EyeOfEnderEntity(world, pos.getX(), pos.getY(), pos.getZ()); - entity.setItem(stack); + if (stack != null) { + entity.setItem(stack); + } + entity.initTargetPos(strongholdPos); return entity; } diff --git a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/FireworkRocketEntityInitializer.java b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/FireworkRocketEntityInitializer.java index c661838c..a0e389ae 100644 --- a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/FireworkRocketEntityInitializer.java +++ b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/FireworkRocketEntityInitializer.java @@ -1,26 +1,32 @@ package net.errorcraft.itematic.entity.initializer.initializers; -import com.mojang.serialization.MapCodec; import net.errorcraft.itematic.entity.initializer.EntityInitializer; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; -import net.minecraft.entity.EntityType; import net.minecraft.entity.SpawnReason; import net.minecraft.entity.projectile.FireworkRocketEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.util.math.Vec3d; -public record FireworkRocketEntityInitializer() implements EntityInitializer { +public class FireworkRocketEntityInitializer implements EntityInitializer { public static final FireworkRocketEntityInitializer INSTANCE = new FireworkRocketEntityInitializer(); - public static final MapCodec CODEC = MapCodec.unit(INSTANCE); - @Override - public EntityType type() { - return EntityType.FIREWORK_ROCKET; - } + private FireworkRocketEntityInitializer() {} @Override public FireworkRocketEntity create(ActionContext context, SpawnReason reason) { - Vec3d pos = context.position(ActionContextParameter.TARGET); - return new FireworkRocketEntity(context.world(), pos.getX(), pos.getY(), pos.getZ(), context.stack().copyWithCount(1)); + Vec3d pos = context.get(ItematicContextParameters.INTERACTED_POSITION); + if (pos == null) { + return null; + } + + return new FireworkRocketEntity( + context.world(), + pos.getX(), + pos.getY(), + pos.getZ(), + context.getOrDefault(LootContextParameters.TOOL, ItemStack.EMPTY).copyWithCount(1) + ); } } diff --git a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/MinecartEntityInitializer.java b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/MinecartEntityInitializer.java index 4252d5f1..9560dc79 100644 --- a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/MinecartEntityInitializer.java +++ b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/MinecartEntityInitializer.java @@ -1,8 +1,8 @@ package net.errorcraft.itematic.entity.initializer.initializers; import net.errorcraft.itematic.entity.initializer.EntityInitializer; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; import net.minecraft.block.AbstractRailBlock; import net.minecraft.block.BlockState; import net.minecraft.block.enums.RailShape; @@ -10,8 +10,10 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.SpawnReason; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.vehicle.AbstractMinecartEntity; import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.registry.tag.BlockTags; import net.minecraft.server.world.ServerWorld; import net.minecraft.text.Text; @@ -21,7 +23,11 @@ public record MinecartEntityInitializer(Entity @Override public T create(ActionContext context, SpawnReason reason) { ServerWorld world = context.world(); - BlockPos pos = context.blockPos(ActionContextParameter.TARGET); + BlockPos pos = context.getBlockPos(ItematicContextParameters.INTERACTED_POSITION); + if (pos == null) { + return null; + } + BlockState blockState = world.getBlockState(pos); if (!blockState.isIn(BlockTags.RAILS)) { return null; @@ -29,7 +35,7 @@ public T create(ActionContext context, SpawnReason reason) { RailShape railShape = blockState.getBlock() instanceof AbstractRailBlock railBlock ? blockState.get(railBlock.getShapeProperty()) : RailShape.NORTH_SOUTH; double verticalOffset = railShape.isAscending() ? 0.5d : 0.0d; - ItemStack stack = context.stack(); + ItemStack stack = context.getOrDefault(LootContextParameters.TOOL, ItemStack.EMPTY); T entity = AbstractMinecartEntity.create( world, pos.getX() + 0.5d, @@ -38,7 +44,7 @@ public T create(ActionContext context, SpawnReason reason) { this.type, SpawnReason.SPAWN_ITEM_USE, stack, - context.player(ActionContextParameter.THIS).orElse(null) + context.get(LootContextParameters.THIS_ENTITY, PlayerEntity.class) ); if (entity == null) { return null; diff --git a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/PersistentProjectileEntityInitializer.java b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/PersistentProjectileEntityInitializer.java index 57d450da..1b09bba9 100644 --- a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/PersistentProjectileEntityInitializer.java +++ b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/PersistentProjectileEntityInitializer.java @@ -1,22 +1,25 @@ package net.errorcraft.itematic.entity.initializer.initializers; -import com.mojang.serialization.MapCodec; import net.errorcraft.itematic.entity.initializer.EntityInitializer; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; -import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.SpawnReason; import net.minecraft.entity.projectile.PersistentProjectileEntity; import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; -public record PersistentProjectileEntityInitializer(EntityType type, OwnerCreator ownerCreator, SimpleCreator simpleCreator) implements EntityInitializer { +public record PersistentProjectileEntityInitializer(OwnerCreator ownerCreator, SimpleCreator simpleCreator) implements EntityInitializer { + public static EntityInitializer of(OwnerCreator ownerCreator, SimpleCreator simpleCreator) { + return new PersistentProjectileEntityInitializer<>(ownerCreator, simpleCreator); + } + @Override public T create(ActionContext context, SpawnReason reason) { - if (context.entity(ActionContextParameter.THIS).orElse(null) instanceof LivingEntity entity) { + if (context.get(LootContextParameters.THIS_ENTITY) instanceof LivingEntity entity) { ItemStack shooter = entity.getActiveItem(); if (shooter.isEmpty()) { shooter = null; @@ -25,28 +28,28 @@ public T create(ActionContext context, SpawnReason reason) { return this.ownerCreator.create( context.world(), entity, - context.stack().copyWithCount(1), + context.getOrDefault(LootContextParameters.TOOL, ItemStack.EMPTY).copyWithCount(1), shooter ); } - Vec3d pos = context.position(ActionContextParameter.TARGET); + Vec3d pos = context.get(ItematicContextParameters.INTERACTED_POSITION); + if (pos == null) { + return null; + } + T entity = this.simpleCreator.create( context.world(), pos.getX(), pos.getY(), pos.getZ(), - context.stack().copyWithCount(1), + context.getOrDefault(LootContextParameters.TOOL, ItemStack.EMPTY).copyWithCount(1), null ); entity.pickupType = PersistentProjectileEntity.PickupPermission.ALLOWED; return entity; } - public static MapCodec> createCodec(EntityType type, OwnerCreator ownerCreator, SimpleCreator simpleCreator) { - return MapCodec.unit(new PersistentProjectileEntityInitializer<>(type, ownerCreator, simpleCreator)); - } - @FunctionalInterface public interface OwnerCreator { T create(World world, LivingEntity owner, ItemStack ammunition, @Nullable ItemStack weapon); diff --git a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/SimpleEntityInitializer.java b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/SimpleEntityInitializer.java index 41410680..8be59634 100644 --- a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/SimpleEntityInitializer.java +++ b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/SimpleEntityInitializer.java @@ -1,6 +1,5 @@ package net.errorcraft.itematic.entity.initializer.initializers; -import com.mojang.serialization.MapCodec; import net.errorcraft.itematic.entity.initializer.EntityInitializer; import net.errorcraft.itematic.world.action.context.ActionContext; import net.minecraft.entity.Entity; @@ -8,16 +7,8 @@ import net.minecraft.entity.SpawnReason; public record SimpleEntityInitializer(EntityType type) implements EntityInitializer { - public static SimpleEntityInitializer of(EntityType type) { - return new SimpleEntityInitializer<>(type); - } - @Override public T create(ActionContext context, SpawnReason reason) { return this.type.create(context.world(), reason); } - - public static MapCodec> createCodec(EntityType type) { - return MapCodec.unit(of(type)); - } } diff --git a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/SmallFireballEntityInitializer.java b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/SmallFireballEntityInitializer.java index 369cf38e..3c52d3a7 100644 --- a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/SmallFireballEntityInitializer.java +++ b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/SmallFireballEntityInitializer.java @@ -1,41 +1,40 @@ package net.errorcraft.itematic.entity.initializer.initializers; -import com.mojang.serialization.MapCodec; import net.errorcraft.itematic.entity.initializer.EntityInitializer; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; -import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.SpawnReason; import net.minecraft.entity.projectile.SmallFireballEntity; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.random.Random; -public record SmallFireballEntityInitializer() implements EntityInitializer { +public class SmallFireballEntityInitializer implements EntityInitializer { public static final SmallFireballEntityInitializer INSTANCE = new SmallFireballEntityInitializer(); - public static final MapCodec CODEC = MapCodec.unit(INSTANCE); private static final double VELOCITY_DEVIATION = 0.11485d; - @Override - public EntityType type() { - return EntityType.SMALL_FIREBALL; - } + private SmallFireballEntityInitializer() {} @Override public SmallFireballEntity create(ActionContext context, SpawnReason reason) { ServerWorld world = context.world(); Random random = world.getRandom(); - Direction direction = context.side(); + Direction direction = context.getOrDefault(ItematicContextParameters.SIDE, Direction.UP); double velocityX = random.nextTriangular(direction.getOffsetX(), VELOCITY_DEVIATION); double velocityY = random.nextTriangular(direction.getOffsetY(), VELOCITY_DEVIATION); double velocityZ = random.nextTriangular(direction.getOffsetZ(), VELOCITY_DEVIATION); - if (context.entity(ActionContextParameter.THIS).orElse(null) instanceof LivingEntity owner) { + if (context.get(LootContextParameters.THIS_ENTITY) instanceof LivingEntity owner) { return new SmallFireballEntity(world, owner, new Vec3d(velocityX, velocityY, velocityZ)); } - Vec3d pos = context.position(ActionContextParameter.TARGET); + Vec3d pos = context.get(ItematicContextParameters.INTERACTED_POSITION); + if (pos == null) { + return null; + } + return new SmallFireballEntity(world, pos.getX(), pos.getY(), pos.getZ(), new Vec3d(velocityX, velocityY, velocityZ)); } } diff --git a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/TridentEntityInitializer.java b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/TridentEntityInitializer.java index 020722fa..6f4c7675 100644 --- a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/TridentEntityInitializer.java +++ b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/TridentEntityInitializer.java @@ -1,30 +1,25 @@ package net.errorcraft.itematic.entity.initializer.initializers; -import com.mojang.serialization.MapCodec; import net.errorcraft.itematic.entity.initializer.EntityInitializer; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.SpawnReason; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.PersistentProjectileEntity; import net.minecraft.entity.projectile.TridentEntity; import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; +import net.minecraft.server.world.ServerWorld; public class TridentEntityInitializer implements EntityInitializer { public static final TridentEntityInitializer INSTANCE = new TridentEntityInitializer(); - public static final MapCodec CODEC = MapCodec.unit(INSTANCE); - - @Override - public EntityType type() { - return EntityType.TRIDENT; - } @Override public TridentEntity create(ActionContext context, SpawnReason reason) { - ItemStack stack = context.stack(); - LivingEntity user = context.livingEntity(ActionContextParameter.THIS).orElse(null); + ItemStack stack = context.getOrDefault(LootContextParameters.TOOL, ItemStack.EMPTY); + LivingEntity user = context.get(LootContextParameters.THIS_ENTITY, LivingEntity.class); float spinAttackStrength = user != null ? EnchantmentHelper.getTridentSpinAttackStrength(stack, user) : 0.0f; @@ -33,19 +28,17 @@ public TridentEntity create(ActionContext context, SpawnReason reason) { } stack.itematic$damage(1, context); - TridentEntity entity = this.create(context, stack); - stack.decrementUnlessCreative(1, context.player(ActionContextParameter.THIS).orElse(null)); + TridentEntity entity = this.create(context.world(), user, stack); + stack.decrementUnlessCreative(1, context.get(LootContextParameters.THIS_ENTITY, PlayerEntity.class)); entity.pickupType = PersistentProjectileEntity.PickupPermission.ALLOWED; return entity; } - private TridentEntity create(ActionContext context, ItemStack stack) { - return context.livingEntity(ActionContextParameter.THIS) - .map(user -> new TridentEntity(context.world(), user, stack)) - .orElseGet(() -> { - TridentEntity entity = new TridentEntity(EntityType.TRIDENT, context.world()); - entity.setPosition(context.position(ActionContextParameter.TARGET)); - return entity; - }); + private TridentEntity create(ServerWorld world, LivingEntity possibleUser, ItemStack stack) { + if (possibleUser != null) { + return new TridentEntity(world, possibleUser, stack); + } + + return new TridentEntity(EntityType.TRIDENT, world); } } diff --git a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/WindChargeEntityInitializer.java b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/WindChargeEntityInitializer.java index 82b605ad..87da153e 100644 --- a/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/WindChargeEntityInitializer.java +++ b/src/main/java/net/errorcraft/itematic/entity/initializer/initializers/WindChargeEntityInitializer.java @@ -1,13 +1,12 @@ package net.errorcraft.itematic.entity.initializer.initializers; -import com.mojang.serialization.MapCodec; import net.errorcraft.itematic.entity.initializer.EntityInitializer; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; -import net.minecraft.entity.EntityType; import net.minecraft.entity.SpawnReason; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.WindChargeEntity; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; @@ -16,27 +15,22 @@ public class WindChargeEntityInitializer implements EntityInitializer { public static final WindChargeEntityInitializer INSTANCE = new WindChargeEntityInitializer(); - public static final MapCodec CODEC = MapCodec.unit(INSTANCE); private static final double VELOCITY_DEVIATION = 0.11485d; private WindChargeEntityInitializer() {} - @Override - public EntityType type() { - return EntityType.WIND_CHARGE; - } - @Override public WindChargeEntity create(ActionContext context, SpawnReason reason) { ServerWorld world = context.world(); - PlayerEntity user = context.player(ActionContextParameter.THIS).orElse(null); + PlayerEntity user = context.get(LootContextParameters.THIS_ENTITY, PlayerEntity.class); if (user != null) { return spawnFromUser(world, user); } - Direction side = context.side(); - if (side != null) { - return spawnFromSide(world, side, context.position(ActionContextParameter.TARGET)); + Direction side = context.get(ItematicContextParameters.SIDE); + Vec3d position = context.get(ItematicContextParameters.INTERACTED_POSITION); + if (side != null && position != null) { + return spawnFromSide(world, side, position); } return null; diff --git a/src/main/java/net/errorcraft/itematic/inventory/SimpleStackReference.java b/src/main/java/net/errorcraft/itematic/inventory/SimpleStackReference.java new file mode 100644 index 00000000..837f8845 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/inventory/SimpleStackReference.java @@ -0,0 +1,35 @@ +package net.errorcraft.itematic.inventory; + +import net.minecraft.inventory.StackReference; +import net.minecraft.item.ItemStack; + +public class SimpleStackReference implements StackReference { + private ItemStack stack; + + private SimpleStackReference(ItemStack stack) { + this.stack = stack; + } + + public static SimpleStackReference of(ItemStack stack) { + return new SimpleStackReference(stack); + } + + @Override + public ItemStack get() { + return this.stack; + } + + @Override + public boolean set(ItemStack stack) { + if (stack == null) { + return false; + } + + if (this.stack == stack) { + return false; + } + + this.stack = stack; + return true; + } +} diff --git a/src/main/java/net/errorcraft/itematic/inventory/StackReferenceUtil.java b/src/main/java/net/errorcraft/itematic/inventory/StackReferenceUtil.java deleted file mode 100644 index afd3b83f..00000000 --- a/src/main/java/net/errorcraft/itematic/inventory/StackReferenceUtil.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.errorcraft.itematic.inventory; - -import net.minecraft.inventory.StackReference; -import net.minecraft.item.ItemStack; - -public class StackReferenceUtil { - private StackReferenceUtil() {} - - public static StackReference of(ItemStack stack) { - return new Simple(stack); - } - - private static class Simple implements StackReference { - private ItemStack stack; - - private Simple(ItemStack stack) { - this.stack = stack; - } - - @Override - public ItemStack get() { - return this.stack; - } - - @Override - public boolean set(ItemStack stack) { - if (stack == null) { - return false; - } - if (this.stack == stack) { - return false; - } - this.stack = stack; - return true; - } - } -} diff --git a/src/main/java/net/errorcraft/itematic/component/AttributeModifiersComponentUtil.java b/src/main/java/net/errorcraft/itematic/item/AttributeModifiers.java similarity index 81% rename from src/main/java/net/errorcraft/itematic/component/AttributeModifiersComponentUtil.java rename to src/main/java/net/errorcraft/itematic/item/AttributeModifiers.java index f7d41952..f91d9504 100644 --- a/src/main/java/net/errorcraft/itematic/component/AttributeModifiersComponentUtil.java +++ b/src/main/java/net/errorcraft/itematic/item/AttributeModifiers.java @@ -1,6 +1,5 @@ -package net.errorcraft.itematic.component; +package net.errorcraft.itematic.item; -import com.mojang.serialization.Codec; import net.minecraft.component.type.AttributeModifierSlot; import net.minecraft.component.type.AttributeModifiersComponent; import net.minecraft.entity.attribute.EntityAttributeModifier; @@ -9,13 +8,8 @@ import net.minecraft.item.equipment.EquipmentType; import net.minecraft.util.Identifier; -public class AttributeModifiersComponentUtil { - public static final Codec LIST_CODEC = AttributeModifiersComponent.Entry.CODEC.listOf().xmap( - entries -> new AttributeModifiersComponent(entries, true), - AttributeModifiersComponent::modifiers - ); - - private AttributeModifiersComponentUtil() {} +public class AttributeModifiers { + private AttributeModifiers() {} public static AttributeModifiersComponent armor(ArmorMaterial material, EquipmentType type) { Identifier attributeId = Identifier.ofVanilla("armor." + type.getName()); diff --git a/src/main/java/net/errorcraft/itematic/item/ItemDisplay.java b/src/main/java/net/errorcraft/itematic/item/ItemDisplay.java index 33fd27af..1b59b1c9 100644 --- a/src/main/java/net/errorcraft/itematic/item/ItemDisplay.java +++ b/src/main/java/net/errorcraft/itematic/item/ItemDisplay.java @@ -4,7 +4,6 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.component.ItematicDataComponentTypes; import net.errorcraft.itematic.mixin.item.ItemAccessor; -import net.errorcraft.itematic.util.IdentifierUtil; import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; import net.minecraft.item.Item; @@ -12,7 +11,6 @@ import net.minecraft.registry.RegistryKeyedValue; import net.minecraft.text.Text; import net.minecraft.text.TextCodecs; -import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; import net.minecraft.util.Rarity; @@ -81,14 +79,11 @@ public Builder rarity(Rarity rarity) { return this; } - public Builder tooltip(RegistryKey name) { - return this.tooltip(Text.translatable(IdentifierUtil.createTranslationKey(name, "item", "desc")).formatted(Formatting.GRAY)); - } - public Builder tooltip(Text... lines) { if (this.tooltip == null) { this.tooltip = new ArrayList<>(); } + this.tooltip.addAll(List.of(lines)); return this; } diff --git a/src/main/java/net/errorcraft/itematic/item/ItemKeys.java b/src/main/java/net/errorcraft/itematic/item/ItemKeys.java index c7c05997..aac3921c 100644 --- a/src/main/java/net/errorcraft/itematic/item/ItemKeys.java +++ b/src/main/java/net/errorcraft/itematic/item/ItemKeys.java @@ -49,6 +49,7 @@ public class ItemKeys { public static final RegistryKey ACACIA_PLANKS = register("acacia_planks"); public static final RegistryKey CHERRY_PLANKS = register("cherry_planks"); public static final RegistryKey DARK_OAK_PLANKS = register("dark_oak_planks"); + public static final RegistryKey PALE_OAK_PLANKS = register("pale_oak_planks"); public static final RegistryKey MANGROVE_PLANKS = register("mangrove_planks"); public static final RegistryKey BAMBOO_PLANKS = register("bamboo_planks"); public static final RegistryKey CRIMSON_PLANKS = register("crimson_planks"); @@ -61,6 +62,7 @@ public class ItemKeys { public static final RegistryKey ACACIA_SAPLING = register("acacia_sapling"); public static final RegistryKey CHERRY_SAPLING = register("cherry_sapling"); public static final RegistryKey DARK_OAK_SAPLING = register("dark_oak_sapling"); + public static final RegistryKey PALE_OAK_SAPLING = register("pale_oak_sapling"); public static final RegistryKey MANGROVE_PROPAGULE = register("mangrove_propagule"); public static final RegistryKey BEDROCK = register("bedrock"); public static final RegistryKey SAND = register("sand"); @@ -144,6 +146,7 @@ public class ItemKeys { public static final RegistryKey JUNGLE_LOG = register("jungle_log"); public static final RegistryKey ACACIA_LOG = register("acacia_log"); public static final RegistryKey CHERRY_LOG = register("cherry_log"); + public static final RegistryKey PALE_OAK_LOG = register("pale_oak_log"); public static final RegistryKey DARK_OAK_LOG = register("dark_oak_log"); public static final RegistryKey MANGROVE_LOG = register("mangrove_log"); public static final RegistryKey MANGROVE_ROOTS = register("mangrove_roots"); @@ -158,6 +161,7 @@ public class ItemKeys { public static final RegistryKey STRIPPED_ACACIA_LOG = register("stripped_acacia_log"); public static final RegistryKey STRIPPED_CHERRY_LOG = register("stripped_cherry_log"); public static final RegistryKey STRIPPED_DARK_OAK_LOG = register("stripped_dark_oak_log"); + public static final RegistryKey STRIPPED_PALE_OAK_LOG = register("stripped_pale_oak_log"); public static final RegistryKey STRIPPED_MANGROVE_LOG = register("stripped_mangrove_log"); public static final RegistryKey STRIPPED_CRIMSON_STEM = register("stripped_crimson_stem"); public static final RegistryKey STRIPPED_WARPED_STEM = register("stripped_warped_stem"); @@ -168,6 +172,7 @@ public class ItemKeys { public static final RegistryKey STRIPPED_ACACIA_WOOD = register("stripped_acacia_wood"); public static final RegistryKey STRIPPED_CHERRY_WOOD = register("stripped_cherry_wood"); public static final RegistryKey STRIPPED_DARK_OAK_WOOD = register("stripped_dark_oak_wood"); + public static final RegistryKey STRIPPED_PALE_OAK_WOOD = register("stripped_pale_oak_wood"); public static final RegistryKey STRIPPED_MANGROVE_WOOD = register("stripped_mangrove_wood"); public static final RegistryKey STRIPPED_CRIMSON_HYPHAE = register("stripped_crimson_hyphae"); public static final RegistryKey STRIPPED_WARPED_HYPHAE = register("stripped_warped_hyphae"); @@ -179,6 +184,7 @@ public class ItemKeys { public static final RegistryKey ACACIA_WOOD = register("acacia_wood"); public static final RegistryKey CHERRY_WOOD = register("cherry_wood"); public static final RegistryKey DARK_OAK_WOOD = register("dark_oak_wood"); + public static final RegistryKey PALE_OAK_WOOD = register("pale_oak_wood"); public static final RegistryKey MANGROVE_WOOD = register("mangrove_wood"); public static final RegistryKey CRIMSON_HYPHAE = register("crimson_hyphae"); public static final RegistryKey WARPED_HYPHAE = register("warped_hyphae"); @@ -189,6 +195,7 @@ public class ItemKeys { public static final RegistryKey ACACIA_LEAVES = register("acacia_leaves"); public static final RegistryKey CHERRY_LEAVES = register("cherry_leaves"); public static final RegistryKey DARK_OAK_LEAVES = register("dark_oak_leaves"); + public static final RegistryKey PALE_OAK_LEAVES = register("pale_oak_leaves"); public static final RegistryKey MANGROVE_LEAVES = register("mangrove_leaves"); public static final RegistryKey AZALEA_LEAVES = register("azalea_leaves"); public static final RegistryKey FLOWERING_AZALEA_LEAVES = register("flowering_azalea_leaves"); @@ -203,9 +210,13 @@ public class ItemKeys { public static final RegistryKey COBWEB = register("cobweb"); public static final RegistryKey SHORT_GRASS = register("short_grass"); public static final RegistryKey FERN = register("fern"); + public static final RegistryKey BUSH = register("bush"); public static final RegistryKey AZALEA = register("azalea"); public static final RegistryKey FLOWERING_AZALEA = register("flowering_azalea"); public static final RegistryKey DEAD_BUSH = register("dead_bush"); + public static final RegistryKey FIREFLY_BUSH = register("firefly_bush"); + public static final RegistryKey SHORT_DRY_GRASS = register("short_dry_grass"); + public static final RegistryKey TALL_DRY_GRASS = register("tall_dry_grass"); public static final RegistryKey SEAGRASS = register("seagrass"); public static final RegistryKey SEA_PICKLE = register("sea_pickle"); public static final RegistryKey WHITE_WOOL = register("white_wool"); @@ -225,6 +236,8 @@ public class ItemKeys { public static final RegistryKey RED_WOOL = register("red_wool"); public static final RegistryKey BLACK_WOOL = register("black_wool"); public static final RegistryKey DANDELION = register("dandelion"); + public static final RegistryKey OPEN_EYEBLOSSOM = register("open_eyeblossom"); + public static final RegistryKey CLOSED_EYEBLOSSOM = register("closed_eyeblossom"); public static final RegistryKey POPPY = register("poppy"); public static final RegistryKey BLUE_ORCHID = register("blue_orchid"); public static final RegistryKey ALLIUM = register("allium"); @@ -251,9 +264,14 @@ public class ItemKeys { public static final RegistryKey TWISTING_VINES = register("twisting_vines"); public static final RegistryKey SUGAR_CANE = register("sugar_cane"); public static final RegistryKey KELP = register("kelp"); - public static final RegistryKey MOSS_CARPET = register("moss_carpet"); public static final RegistryKey PINK_PETALS = register("pink_petals"); + public static final RegistryKey WILDFLOWERS = register("wildflowers"); + public static final RegistryKey LEAF_LITTER = register("leaf_litter"); + public static final RegistryKey MOSS_CARPET = register("moss_carpet"); public static final RegistryKey MOSS_BLOCK = register("moss_block"); + public static final RegistryKey PALE_MOSS_CARPET = register("pale_moss_carpet"); + public static final RegistryKey PALE_HANGING_MOSS = register("pale_hanging_moss"); + public static final RegistryKey PALE_MOSS_BLOCK = register("pale_moss_block"); public static final RegistryKey HANGING_ROOTS = register("hanging_roots"); public static final RegistryKey BIG_DRIPLEAF = register("big_dripleaf"); public static final RegistryKey SMALL_DRIPLEAF = register("small_dripleaf"); @@ -265,6 +283,7 @@ public class ItemKeys { public static final RegistryKey ACACIA_SLAB = register("acacia_slab"); public static final RegistryKey CHERRY_SLAB = register("cherry_slab"); public static final RegistryKey DARK_OAK_SLAB = register("dark_oak_slab"); + public static final RegistryKey PALE_OAK_SLAB = register("pale_oak_slab"); public static final RegistryKey MANGROVE_SLAB = register("mangrove_slab"); public static final RegistryKey BAMBOO_SLAB = register("bamboo_slab"); public static final RegistryKey BAMBOO_MOSAIC_SLAB = register("bamboo_mosaic_slab"); @@ -305,6 +324,7 @@ public class ItemKeys { public static final RegistryKey PURPUR_PILLAR = register("purpur_pillar"); public static final RegistryKey PURPUR_STAIRS = register("purpur_stairs"); public static final RegistryKey SPAWNER = register("spawner"); + public static final RegistryKey CREAKING_HEART = register("creaking_heart"); public static final RegistryKey CHEST = register("chest"); public static final RegistryKey CRAFTING_TABLE = register("crafting_table"); public static final RegistryKey FARMLAND = register("farmland"); @@ -315,6 +335,7 @@ public class ItemKeys { public static final RegistryKey ICE = register("ice"); public static final RegistryKey SNOW_BLOCK = register("snow_block"); public static final RegistryKey CACTUS = register("cactus"); + public static final RegistryKey CACTUS_FLOWER = register("cactus_flower"); public static final RegistryKey CLAY = register("clay"); public static final RegistryKey JUKEBOX = register("jukebox"); public static final RegistryKey OAK_FENCE = register("oak_fence"); @@ -324,6 +345,7 @@ public class ItemKeys { public static final RegistryKey ACACIA_FENCE = register("acacia_fence"); public static final RegistryKey CHERRY_FENCE = register("cherry_fence"); public static final RegistryKey DARK_OAK_FENCE = register("dark_oak_fence"); + public static final RegistryKey PALE_OAK_FENCE = register("pale_oak_fence"); public static final RegistryKey MANGROVE_FENCE = register("mangrove_fence"); public static final RegistryKey BAMBOO_FENCE = register("bamboo_fence"); public static final RegistryKey CRIMSON_FENCE = register("crimson_fence"); @@ -367,6 +389,13 @@ public class ItemKeys { public static final RegistryKey MELON = register("melon"); public static final RegistryKey VINE = register("vine"); public static final RegistryKey GLOW_LICHEN = register("glow_lichen"); + public static final RegistryKey RESIN_CLUMP = register("resin_clump"); + public static final RegistryKey RESIN_BLOCK = register("resin_block"); + public static final RegistryKey RESIN_BRICKS = register("resin_bricks"); + public static final RegistryKey RESIN_BRICK_STAIRS = register("resin_brick_stairs"); + public static final RegistryKey RESIN_BRICK_SLAB = register("resin_brick_slab"); + public static final RegistryKey RESIN_BRICK_WALL = register("resin_brick_wall"); + public static final RegistryKey CHISELED_RESIN_BRICKS = register("chiseled_resin_bricks"); public static final RegistryKey BRICK_STAIRS = register("brick_stairs"); public static final RegistryKey STONE_BRICK_STAIRS = register("stone_brick_stairs"); public static final RegistryKey MUD_BRICK_STAIRS = register("mud_brick_stairs"); @@ -396,6 +425,7 @@ public class ItemKeys { public static final RegistryKey ACACIA_STAIRS = register("acacia_stairs"); public static final RegistryKey CHERRY_STAIRS = register("cherry_stairs"); public static final RegistryKey DARK_OAK_STAIRS = register("dark_oak_stairs"); + public static final RegistryKey PALE_OAK_STAIRS = register("pale_oak_stairs"); public static final RegistryKey MANGROVE_STAIRS = register("mangrove_stairs"); public static final RegistryKey BAMBOO_STAIRS = register("bamboo_stairs"); public static final RegistryKey BAMBOO_MOSAIC_STAIRS = register("bamboo_mosaic_stairs"); @@ -697,6 +727,7 @@ public class ItemKeys { public static final RegistryKey ACACIA_BUTTON = register("acacia_button"); public static final RegistryKey CHERRY_BUTTON = register("cherry_button"); public static final RegistryKey DARK_OAK_BUTTON = register("dark_oak_button"); + public static final RegistryKey PALE_OAK_BUTTON = register("pale_oak_button"); public static final RegistryKey MANGROVE_BUTTON = register("mangrove_button"); public static final RegistryKey BAMBOO_BUTTON = register("bamboo_button"); public static final RegistryKey CRIMSON_BUTTON = register("crimson_button"); @@ -712,6 +743,7 @@ public class ItemKeys { public static final RegistryKey ACACIA_PRESSURE_PLATE = register("acacia_pressure_plate"); public static final RegistryKey CHERRY_PRESSURE_PLATE = register("cherry_pressure_plate"); public static final RegistryKey DARK_OAK_PRESSURE_PLATE = register("dark_oak_pressure_plate"); + public static final RegistryKey PALE_OAK_PRESSURE_PLATE = register("pale_oak_pressure_plate"); public static final RegistryKey MANGROVE_PRESSURE_PLATE = register("mangrove_pressure_plate"); public static final RegistryKey BAMBOO_PRESSURE_PLATE = register("bamboo_pressure_plate"); public static final RegistryKey CRIMSON_PRESSURE_PLATE = register("crimson_pressure_plate"); @@ -724,6 +756,7 @@ public class ItemKeys { public static final RegistryKey ACACIA_DOOR = register("acacia_door"); public static final RegistryKey CHERRY_DOOR = register("cherry_door"); public static final RegistryKey DARK_OAK_DOOR = register("dark_oak_door"); + public static final RegistryKey PALE_OAK_DOOR = register("pale_oak_door"); public static final RegistryKey MANGROVE_DOOR = register("mangrove_door"); public static final RegistryKey BAMBOO_DOOR = register("bamboo_door"); public static final RegistryKey CRIMSON_DOOR = register("crimson_door"); @@ -744,6 +777,7 @@ public class ItemKeys { public static final RegistryKey ACACIA_TRAPDOOR = register("acacia_trapdoor"); public static final RegistryKey CHERRY_TRAPDOOR = register("cherry_trapdoor"); public static final RegistryKey DARK_OAK_TRAPDOOR = register("dark_oak_trapdoor"); + public static final RegistryKey PALE_OAK_TRAPDOOR = register("pale_oak_trapdoor"); public static final RegistryKey MANGROVE_TRAPDOOR = register("mangrove_trapdoor"); public static final RegistryKey BAMBOO_TRAPDOOR = register("bamboo_trapdoor"); public static final RegistryKey CRIMSON_TRAPDOOR = register("crimson_trapdoor"); @@ -763,6 +797,7 @@ public class ItemKeys { public static final RegistryKey ACACIA_FENCE_GATE = register("acacia_fence_gate"); public static final RegistryKey CHERRY_FENCE_GATE = register("cherry_fence_gate"); public static final RegistryKey DARK_OAK_FENCE_GATE = register("dark_oak_fence_gate"); + public static final RegistryKey PALE_OAK_FENCE_GATE = register("pale_oak_fence_gate"); public static final RegistryKey MANGROVE_FENCE_GATE = register("mangrove_fence_gate"); public static final RegistryKey BAMBOO_FENCE_GATE = register("bamboo_fence_gate"); public static final RegistryKey CRIMSON_FENCE_GATE = register("crimson_fence_gate"); @@ -779,6 +814,7 @@ public class ItemKeys { public static final RegistryKey HOPPER_MINECART = register("hopper_minecart"); public static final RegistryKey CARROT_ON_A_STICK = register("carrot_on_a_stick"); public static final RegistryKey WARPED_FUNGUS_ON_A_STICK = register("warped_fungus_on_a_stick"); + public static final RegistryKey PHANTOM_MEMBRANE = register("phantom_membrane"); public static final RegistryKey ELYTRA = register("elytra"); public static final RegistryKey OAK_BOAT = register("oak_boat"); public static final RegistryKey OAK_CHEST_BOAT = register("oak_chest_boat"); @@ -794,6 +830,8 @@ public class ItemKeys { public static final RegistryKey CHERRY_CHEST_BOAT = register("cherry_chest_boat"); public static final RegistryKey DARK_OAK_BOAT = register("dark_oak_boat"); public static final RegistryKey DARK_OAK_CHEST_BOAT = register("dark_oak_chest_boat"); + public static final RegistryKey PALE_OAK_BOAT = register("pale_oak_boat"); + public static final RegistryKey PALE_OAK_CHEST_BOAT = register("pale_oak_chest_boat"); public static final RegistryKey MANGROVE_BOAT = register("mangrove_boat"); public static final RegistryKey MANGROVE_CHEST_BOAT = register("mangrove_chest_boat"); public static final RegistryKey BAMBOO_RAFT = register("bamboo_raft"); @@ -805,6 +843,7 @@ public class ItemKeys { public static final RegistryKey ARMADILLO_SCUTE = register("armadillo_scute"); public static final RegistryKey WOLF_ARMOR = register("wolf_armor"); public static final RegistryKey FLINT_AND_STEEL = register("flint_and_steel"); + public static final RegistryKey BOWL = register("bowl"); public static final RegistryKey APPLE = register("apple"); public static final RegistryKey BOW = register("bow"); public static final RegistryKey ARROW = register("arrow"); @@ -854,7 +893,6 @@ public class ItemKeys { public static final RegistryKey NETHERITE_AXE = register("netherite_axe"); public static final RegistryKey NETHERITE_HOE = register("netherite_hoe"); public static final RegistryKey STICK = register("stick"); - public static final RegistryKey BOWL = register("bowl"); public static final RegistryKey MUSHROOM_STEW = register("mushroom_stew"); public static final RegistryKey STRING = register("string"); public static final RegistryKey FEATHER = register("feather"); @@ -899,6 +937,7 @@ public class ItemKeys { public static final RegistryKey ACACIA_SIGN = register("acacia_sign"); public static final RegistryKey CHERRY_SIGN = register("cherry_sign"); public static final RegistryKey DARK_OAK_SIGN = register("dark_oak_sign"); + public static final RegistryKey PALE_OAK_SIGN = register("pale_oak_sign"); public static final RegistryKey MANGROVE_SIGN = register("mangrove_sign"); public static final RegistryKey BAMBOO_SIGN = register("bamboo_sign"); public static final RegistryKey CRIMSON_SIGN = register("crimson_sign"); @@ -910,6 +949,7 @@ public class ItemKeys { public static final RegistryKey ACACIA_HANGING_SIGN = register("acacia_hanging_sign"); public static final RegistryKey CHERRY_HANGING_SIGN = register("cherry_hanging_sign"); public static final RegistryKey DARK_OAK_HANGING_SIGN = register("dark_oak_hanging_sign"); + public static final RegistryKey PALE_OAK_HANGING_SIGN = register("pale_oak_hanging_sign"); public static final RegistryKey MANGROVE_HANGING_SIGN = register("mangrove_hanging_sign"); public static final RegistryKey BAMBOO_HANGING_SIGN = register("bamboo_hanging_sign"); public static final RegistryKey CRIMSON_HANGING_SIGN = register("crimson_hanging_sign"); @@ -934,6 +974,8 @@ public class ItemKeys { public static final RegistryKey BOOK = register("book"); public static final RegistryKey SLIME_BALL = register("slime_ball"); public static final RegistryKey EGG = register("egg"); + public static final RegistryKey BLUE_EGG = register("blue_egg"); + public static final RegistryKey BROWN_EGG = register("brown_egg"); public static final RegistryKey COMPASS = register("compass"); public static final RegistryKey RECOVERY_COMPASS = register("recovery_compass"); public static final RegistryKey BUNDLE = register("bundle"); @@ -1020,8 +1062,8 @@ public class ItemKeys { public static final RegistryKey GHAST_TEAR = register("ghast_tear"); public static final RegistryKey GOLD_NUGGET = register("gold_nugget"); public static final RegistryKey NETHER_WART = register("nether_wart"); - public static final RegistryKey POTION = register("potion"); public static final RegistryKey GLASS_BOTTLE = register("glass_bottle"); + public static final RegistryKey POTION = register("potion"); public static final RegistryKey SPIDER_EYE = register("spider_eye"); public static final RegistryKey FERMENTED_SPIDER_EYE = register("fermented_spider_eye"); public static final RegistryKey BLAZE_POWDER = register("blaze_powder"); @@ -1044,6 +1086,7 @@ public class ItemKeys { public static final RegistryKey CHICKEN_SPAWN_EGG = register("chicken_spawn_egg"); public static final RegistryKey COD_SPAWN_EGG = register("cod_spawn_egg"); public static final RegistryKey COW_SPAWN_EGG = register("cow_spawn_egg"); + public static final RegistryKey CREAKING_SPAWN_EGG = register("creaking_spawn_egg"); public static final RegistryKey CREEPER_SPAWN_EGG = register("creeper_spawn_egg"); public static final RegistryKey DOLPHIN_SPAWN_EGG = register("dolphin_spawn_egg"); public static final RegistryKey DONKEY_SPAWN_EGG = register("donkey_spawn_egg"); @@ -1115,6 +1158,7 @@ public class ItemKeys { public static final RegistryKey WIND_CHARGE = register("wind_charge"); public static final RegistryKey WRITABLE_BOOK = register("writable_book"); public static final RegistryKey WRITTEN_BOOK = register("written_book"); + public static final RegistryKey BREEZE_ROD = register("breeze_rod"); public static final RegistryKey MACE = register("mace"); public static final RegistryKey ITEM_FRAME = register("item_frame"); public static final RegistryKey GLOW_ITEM_FRAME = register("glow_item_frame"); @@ -1138,6 +1182,7 @@ public class ItemKeys { public static final RegistryKey FIREWORK_STAR = register("firework_star"); public static final RegistryKey ENCHANTED_BOOK = register("enchanted_book"); public static final RegistryKey NETHER_BRICK = register("nether_brick"); + public static final RegistryKey RESIN_BRICK = register("resin_brick"); public static final RegistryKey PRISMARINE_SHARD = register("prismarine_shard"); public static final RegistryKey PRISMARINE_CRYSTALS = register("prismarine_crystals"); public static final RegistryKey RABBIT = register("rabbit"); @@ -1211,7 +1256,6 @@ public class ItemKeys { public static final RegistryKey MUSIC_DISC_PRECIPICE = register("music_disc_precipice"); public static final RegistryKey DISC_FRAGMENT_5 = register("disc_fragment_5"); public static final RegistryKey TRIDENT = register("trident"); - public static final RegistryKey PHANTOM_MEMBRANE = register("phantom_membrane"); public static final RegistryKey NAUTILUS_SHELL = register("nautilus_shell"); public static final RegistryKey HEART_OF_THE_SEA = register("heart_of_the_sea"); public static final RegistryKey CROSSBOW = register("crossbow"); @@ -1356,8 +1400,8 @@ public class ItemKeys { public static final RegistryKey OMINOUS_TRIAL_KEY = register("ominous_trial_key"); public static final RegistryKey VAULT = register("vault"); public static final RegistryKey OMINOUS_BOTTLE = register("ominous_bottle"); - public static final RegistryKey BREEZE_ROD = register("breeze_rod"); + private ItemKeys() {} private static RegistryKey register(String name) { return RegistryKey.of(RegistryKeys.ITEM, Identifier.ofVanilla(name)); diff --git a/src/main/java/net/errorcraft/itematic/item/ItemStackConsumer.java b/src/main/java/net/errorcraft/itematic/item/ItemStackConsumer.java deleted file mode 100644 index 81655075..00000000 --- a/src/main/java/net/errorcraft/itematic/item/ItemStackConsumer.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.errorcraft.itematic.item; - -import net.minecraft.item.ItemStack; - -@FunctionalInterface -public interface ItemStackConsumer { - ItemStackConsumer EMPTY = stack -> {}; - - void set(ItemStack stack); -} diff --git a/src/main/java/net/errorcraft/itematic/item/ItemStackUtil.java b/src/main/java/net/errorcraft/itematic/item/ItemStackUtil.java new file mode 100644 index 00000000..7c65f24b --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/item/ItemStackUtil.java @@ -0,0 +1,11 @@ +package net.errorcraft.itematic.item; + +import net.minecraft.item.ItemStack; + +public class ItemStackUtil { + private ItemStackUtil() {} + + public static boolean isNullOrEmpty(ItemStack stack) { + return stack == null || stack.isEmpty(); + } +} diff --git a/src/main/java/net/errorcraft/itematic/item/ItemUsageUtil.java b/src/main/java/net/errorcraft/itematic/item/ItemUsageUtil.java deleted file mode 100644 index c5950f9d..00000000 --- a/src/main/java/net/errorcraft/itematic/item/ItemUsageUtil.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.errorcraft.itematic.item; - -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemUsage; - -public class ItemUsageUtil { - private static boolean decrementCount = true; - - private ItemUsageUtil() {} - - public static boolean decrementCount() { - return ItemUsageUtil.decrementCount; - } - - public static ItemStack exchangeStack(ItemStack inputStack, PlayerEntity player, ItemStack outputStack, boolean creativeOverride, boolean decrementCount) { - ItemUsageUtil.decrementCount = decrementCount; - ItemStack resultStack = ItemUsage.exchangeStack(inputStack, player, outputStack, creativeOverride); - ItemUsageUtil.decrementCount = true; - return resultStack; - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/ItemUtil.java b/src/main/java/net/errorcraft/itematic/item/ItemUtil.java index 9619e7e3..3ca5c5d1 100644 --- a/src/main/java/net/errorcraft/itematic/item/ItemUtil.java +++ b/src/main/java/net/errorcraft/itematic/item/ItemUtil.java @@ -3,27 +3,24 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; 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.effect.StatusEffectKeys; -import net.errorcraft.itematic.entity.initializer.initializers.*; import net.errorcraft.itematic.fluid.FluidKeys; -import net.errorcraft.itematic.item.color.colors.*; import net.errorcraft.itematic.item.component.ItemComponentSet; import net.errorcraft.itematic.item.component.components.*; +import net.errorcraft.itematic.item.composting.CompostChances; import net.errorcraft.itematic.item.dispense.behavior.DispenseBehavior; import net.errorcraft.itematic.item.dispense.behavior.DispenseBehaviors; import net.errorcraft.itematic.item.event.ItemEventMap; import net.errorcraft.itematic.item.event.ItemEvents; -import net.errorcraft.itematic.item.pointer.Pointer; -import net.errorcraft.itematic.item.pointer.PointerKeys; +import net.errorcraft.itematic.item.fuel.FuelTimes; import net.errorcraft.itematic.item.shooter.method.methods.ChargeableShooterMethod; 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.loot.condition.LocationCheckLootConditionUtil; +import net.errorcraft.itematic.loot.function.SetItemPointerLocationItemModifier; +import net.errorcraft.itematic.loot.function.SplitItemModifier; import net.errorcraft.itematic.loot.predicate.SideCheckPredicate; import net.errorcraft.itematic.mixin.item.BrushItemAccessor; import net.errorcraft.itematic.mixin.item.CrossbowItemAccessor; @@ -32,11 +29,11 @@ import net.errorcraft.itematic.sound.SoundEventKeys; import net.errorcraft.itematic.util.Vec3dProvider; import net.errorcraft.itematic.world.action.ActionEntry; -import net.errorcraft.itematic.world.action.ActionRequirements; import net.errorcraft.itematic.world.action.Actions; import net.errorcraft.itematic.world.action.actions.*; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameters; +import net.errorcraft.itematic.world.action.context.ItemStackTarget; +import net.errorcraft.itematic.world.action.context.ItematicEntityTargets; +import net.errorcraft.itematic.world.action.context.PositionTarget; import net.errorcraft.itematic.world.action.sequence.handler.handlers.FirstToPassRequirementsSequenceHandler; import net.errorcraft.itematic.world.action.sequence.handler.handlers.PassingSequenceHandler; import net.errorcraft.itematic.world.action.sequence.handler.handlers.UncheckedSequenceHandler; @@ -52,52 +49,57 @@ import net.minecraft.enchantment.Enchantments; import net.minecraft.entity.EntityType; import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.decoration.GlowItemFrameEntity; -import net.minecraft.entity.decoration.ItemFrameEntity; import net.minecraft.entity.effect.StatusEffect; import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.entity.projectile.ArrowEntity; -import net.minecraft.entity.projectile.SpectralArrowEntity; +import net.minecraft.entity.passive.ChickenVariant; +import net.minecraft.entity.passive.ChickenVariants; import net.minecraft.fluid.Fluid; import net.minecraft.item.*; import net.minecraft.item.consume.UseAction; import net.minecraft.item.equipment.ArmorMaterials; -import net.minecraft.item.equipment.EquipmentModels; +import net.minecraft.item.equipment.EquipmentAssetKeys; import net.minecraft.item.equipment.EquipmentType; +import net.minecraft.item.equipment.trim.ArmorTrimMaterial; +import net.minecraft.item.equipment.trim.ArmorTrimMaterials; import net.minecraft.loot.condition.*; import net.minecraft.loot.context.LootContext; +import net.minecraft.loot.function.SetComponentsLootFunction; +import net.minecraft.loot.function.SetNameLootFunction; import net.minecraft.particle.ParticleTypes; import net.minecraft.potion.Potion; import net.minecraft.predicate.BlockPredicate; import net.minecraft.predicate.FluidPredicate; import net.minecraft.predicate.NumberRange; import net.minecraft.predicate.StatePredicate; +import net.minecraft.predicate.component.ComponentPredicateTypes; +import net.minecraft.predicate.component.ComponentsPredicate; import net.minecraft.predicate.entity.EntityPredicate; import net.minecraft.predicate.entity.LocationPredicate; import net.minecraft.predicate.item.*; import net.minecraft.registry.*; +import net.minecraft.registry.entry.LazyRegistryEntryReference; import net.minecraft.registry.entry.RegistryEntryList; import net.minecraft.registry.tag.*; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvent; +import net.minecraft.sound.SoundEvents; import net.minecraft.state.property.Properties; +import net.minecraft.text.Text; import net.minecraft.util.DyeColor; import net.minecraft.util.Identifier; import net.minecraft.util.Rarity; import net.minecraft.util.Util; import net.minecraft.util.math.Direction; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.biome.BiomeKeys; -import net.minecraft.world.biome.FoliageColors; import net.minecraft.world.event.GameEvent; import java.util.List; +import java.util.Optional; public class ItemUtil { public static final int UNSTACKABLE_MAX_STACK_SIZE = 1; public static final Codec CODEC = RecordCodecBuilder.create((instance) -> instance.group( ItemDisplay.CODEC.fieldOf("display").forGetter(Item::itematic$display), - AttributeModifiersComponentUtil.LIST_CODEC.optionalFieldOf("attribute_modifiers", AttributeModifiersComponent.DEFAULT).forGetter(Item::itematic$attributeModifiers), + AttributeModifiersComponent.CODEC.optionalFieldOf("attribute_modifiers", AttributeModifiersComponent.DEFAULT).forGetter(Item::itematic$attributeModifiers), ItemComponentSet.CODEC.optionalFieldOf("behavior", ItemComponentSet.EMPTY).forGetter(Item::itematic$behavior), ItemEventMap.CODEC.optionalFieldOf("events", ItemEventMap.EMPTY).forGetter(Item::itematic$events) ).apply(instance, ItemUtil::create)); @@ -140,37 +142,37 @@ private static class Bootstrapper { private final Registerable registerable; private final RegistryEntryLookup items; private final RegistryEntryLookup> entityTypes; - private final RegistryEntryLookup biomes; private final RegistryEntryLookup blocks; private final RegistryEntryLookup dispenseBehaviors; private final RegistryEntryLookup soundEvents; private final RegistryEntryLookup fluids; - private final RegistryEntryLookup pointers; private final RegistryEntryLookup actions; - private final RegistryEntryLookup smithingTemplates; private final RegistryEntryLookup decoratedPotPatterns; private final RegistryEntryLookup statusEffects; private final RegistryEntryLookup potions; private final RegistryEntryLookup enchantments; private final RegistryEntryLookup jukeboxSongs; + private final RegistryEntryLookup instruments; + private final RegistryEntryLookup trimMaterials; + private final RegistryEntryLookup chickenVariants; private Bootstrapper(Registerable registerable) { this.registerable = registerable; this.items = registerable.getRegistryLookup(RegistryKeys.ITEM); this.entityTypes = registerable.getRegistryLookup(RegistryKeys.ENTITY_TYPE); - this.biomes = registerable.getRegistryLookup(RegistryKeys.BIOME); this.blocks = registerable.getRegistryLookup(RegistryKeys.BLOCK); this.dispenseBehaviors = registerable.getRegistryLookup(ItematicRegistryKeys.DISPENSE_BEHAVIOR); this.soundEvents = registerable.getRegistryLookup(RegistryKeys.SOUND_EVENT); this.fluids = registerable.getRegistryLookup(RegistryKeys.FLUID); - this.pointers = registerable.getRegistryLookup(ItematicRegistryKeys.POINTER); this.actions = registerable.getRegistryLookup(ItematicRegistryKeys.ACTION); - this.smithingTemplates = registerable.getRegistryLookup(ItematicRegistryKeys.SMITHING_TEMPLATE); this.decoratedPotPatterns = registerable.getRegistryLookup(RegistryKeys.DECORATED_POT_PATTERN); this.statusEffects = registerable.getRegistryLookup(RegistryKeys.STATUS_EFFECT); this.potions = registerable.getRegistryLookup(RegistryKeys.POTION); this.enchantments = registerable.getRegistryLookup(RegistryKeys.ENCHANTMENT); this.jukeboxSongs = registerable.getRegistryLookup(RegistryKeys.JUKEBOX_SONG); + this.instruments = registerable.getRegistryLookup(RegistryKeys.INSTRUMENT); + this.trimMaterials = registerable.getRegistryLookup(RegistryKeys.TRIM_MATERIAL); + this.chickenVariants = registerable.getRegistryLookup(RegistryKeys.CHICKEN_VARIANT); } private void bootstrap() { @@ -189,6 +191,7 @@ private void bootstrap() { this.bootstrapBanners(); this.bootstrapDecoratedPotPatterns(); this.bootstrapImmuneToDamage(); + this.bootstrapTrimMaterialProviders(); this.bootstrapMiscellaneous(); } @@ -203,7 +206,7 @@ private void bootstrapConsumables() { .build()) .build(), ItemEventMap.builder() - .add(ItemEvents.CONSUME_ITEM, ActionEntry.of(ClearStatusEffectsAction.of(ActionContextParameter.THIS))) + .add(ItemEvents.CONSUME_ITEM, ActionEntry.of(ClearStatusEffectsAction.of(LootContext.EntityTarget.THIS))) .build() )); this.registerable.register(ItemKeys.POTION, create( @@ -213,36 +216,36 @@ private void bootstrapConsumables() { .with(ConsumableItemComponent.builder(ConsumableComponents.DRINK) .remainder(this.items.getOrThrow(ItemKeys.GLASS_BOTTLE)) .build()) - .with(PotionItemComponent.INSTANCE) .with(PotionHolderItemComponent.of(1.0f)) - .with(TintedItemComponent.of(PotionItemColor.INSTANCE)) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.USE_ITEM_ON_BLOCK_OR_DISPENSE_ITEM))) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, ActionEntry.of( - ActionRequirements.of( - ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.TARGET), - AllOfLootCondition.builder( - InvertedLootCondition.builder( - SideCheckPredicate.builder(Direction.DOWN) - ), - LocationCheckLootCondition.builder( - LocationPredicate.Builder.create() - .block(BlockPredicate.Builder.create() - .tag(this.blocks, BlockTags.CONVERTABLE_TO_MUD)) - ), - MatchToolLootCondition.builder( - ItemPredicate.Builder.create() - .subPredicate(ItemSubPredicateTypes.POTION_CONTENTS, new PotionContentsPredicate(RegistryEntryList.of( + AllOfLootCondition.builder( + InvertedLootCondition.builder( + SideCheckPredicate.builder(Direction.DOWN) + ), + LocationCheckLootConditionUtil.builder( + PositionTarget.INTERACTED_POSITION, + LocationPredicate.Builder.create() + .block(BlockPredicate.Builder.create() + .tag(this.blocks, BlockTags.CONVERTABLE_TO_MUD)) + ), + MatchToolLootCondition.builder(ItemPredicate.Builder.create() + .components(ComponentsPredicate.Builder.create() + .partial( + ComponentPredicateTypes.POTION_CONTENTS, + new PotionContentsPredicate(RegistryEntryList.of( this.potions.getOrThrow(PotionKeys.WATER) - ))) + )) + ).build() ) - ).build() + ) ), UncheckedSequenceHandler.builder() - .add(PlaySoundAction.of(ActionContextParameter.TARGET, this.soundEvents.getOrThrow(SoundEventKeys.GENERIC_SPLASH), SoundCategory.BLOCKS)) + .add(PlaySoundAction.of(PositionTarget.INTERACTED_POSITION, this.soundEvents.getOrThrow(SoundEventKeys.GENERIC_SPLASH), SoundCategory.BLOCKS)) .add(ExchangeItemAction.of(this.items.getOrThrow(ItemKeys.GLASS_BOTTLE))) - .add(DisplayParticleAction.builder(ActionContextParameter.TARGET, ParticleTypes.SPLASH) + .add(DisplayParticleAction.builder(PositionTarget.INTERACTED_POSITION, ParticleTypes.SPLASH) .count(5) .offset(Vec3dProvider.of( -0.5d, 0.5d, @@ -251,9 +254,9 @@ private void bootstrapConsumables() { )) .speed(1.0d) .build()) - .add(PlaySoundAction.of(ActionContextParameter.TARGET, this.soundEvents.getOrThrow(SoundEventKeys.BOTTLE_EMPTY), SoundCategory.BLOCKS)) - .add(SetBlockStateAction.of(ActionContextParameter.TARGET, this.blocks.getOrThrow(BlockKeys.MUD))) - .add(SwingHandAction.INSTANCE) + .add(PlaySoundAction.of(PositionTarget.INTERACTED_POSITION, this.soundEvents.getOrThrow(SoundEventKeys.BOTTLE_EMPTY), SoundCategory.BLOCKS)) + .add(SetBlockStateAction.of(PositionTarget.INTERACTED_POSITION, this.blocks.getOrThrow(BlockKeys.MUD))) + .add(SwingHandAction.of(LootContext.EntityTarget.THIS)) )) .build() )); @@ -267,7 +270,7 @@ private void bootstrapConsumables() { .with(OminousEffectProviderItemComponent.INSTANCE) .build(), ItemEventMap.builder() - .add(ItemEvents.CONSUME_ITEM, ActionEntry.of(PlaySoundAction.of(ActionContextParameter.THIS, this.soundEvents.getOrThrow(SoundEventKeys.OMINOUS_BOTTLE_DISPOSE)))) + .add(ItemEvents.CONSUME_ITEM, ActionEntry.of(PlaySoundAction.of(PositionTarget.ORIGIN, this.soundEvents.getOrThrow(SoundEventKeys.OMINOUS_BOTTLE_DISPOSE)))) .build() )); } @@ -280,7 +283,7 @@ private void bootstrapFood() { .with(ConsumableItemComponent.builder(ConsumableComponents.FOOD) .food(FoodComponents.APPLE) .build()) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.MELON_SLICE, create( @@ -290,7 +293,7 @@ private void bootstrapFood() { .with(ConsumableItemComponent.builder(ConsumableComponents.FOOD) .food(FoodComponents.MELON_SLICE) .build()) - .with(CompostableItemComponent.of(ComposterBlockUtil.HALF_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.FIFTY_FIFTY)) .build() )); this.registerable.register(ItemKeys.DRIED_KELP, create( @@ -300,7 +303,7 @@ private void bootstrapFood() { .with(ConsumableItemComponent.builder(ConsumableComponents.DRIED_KELP) .food(FoodComponents.DRIED_KELP) .build()) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.CARROT, create( @@ -311,7 +314,7 @@ private void bootstrapFood() { .food(FoodComponents.CARROT) .build()) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CARROTS))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.POTATO, create( @@ -322,7 +325,7 @@ private void bootstrapFood() { .food(FoodComponents.POTATO) .build()) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.POTATOES))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.BAKED_POTATO, create( @@ -332,7 +335,7 @@ private void bootstrapFood() { .with(ConsumableItemComponent.builder(ConsumableComponents.FOOD) .food(FoodComponents.BAKED_POTATO) .build()) - .with(CompostableItemComponent.of(ComposterBlockUtil.ALMOST_GUARANTEED_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.ALMOST_GUARANTEED)) .build() )); this.registerable.register(ItemKeys.CHORUS_FRUIT, create( @@ -344,7 +347,7 @@ private void bootstrapFood() { .build()) .build(), ItemEventMap.builder() - .add(ItemEvents.CONSUME_ITEM, ActionEntry.of(TeleportAction.of(16, ActionContextParameter.THIS))) + .add(ItemEvents.CONSUME_ITEM, ActionEntry.of(TeleportAction.of(16, LootContext.EntityTarget.THIS))) .build() )); this.registerable.register(ItemKeys.BEETROOT, create( @@ -354,7 +357,7 @@ private void bootstrapFood() { .with(ConsumableItemComponent.builder(ConsumableComponents.FOOD) .food(FoodComponents.BEETROOT) .build()) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.SWEET_BERRIES, create( @@ -365,7 +368,7 @@ private void bootstrapFood() { .food(FoodComponents.SWEET_BERRIES) .build()) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SWEET_BERRY_BUSH))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.GLOW_BERRIES, create( @@ -376,7 +379,7 @@ private void bootstrapFood() { .food(FoodComponents.GLOW_BERRIES) .build()) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CAVE_VINES))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.BREAD, create( @@ -386,7 +389,7 @@ private void bootstrapFood() { .with(ConsumableItemComponent.builder(ConsumableComponents.FOOD) .food(FoodComponents.BREAD) .build()) - .with(CompostableItemComponent.of(ComposterBlockUtil.ALMOST_GUARANTEED_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.ALMOST_GUARANTEED)) .build() )); this.registerable.register(ItemKeys.COOKIE, create( @@ -396,7 +399,7 @@ private void bootstrapFood() { .with(ConsumableItemComponent.builder(ConsumableComponents.FOOD) .food(FoodComponents.COOKIE) .build()) - .with(CompostableItemComponent.of(ComposterBlockUtil.ALMOST_GUARANTEED_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.ALMOST_GUARANTEED)) .build() )); this.registerable.register(ItemKeys.PORKCHOP, create( @@ -445,10 +448,7 @@ private void bootstrapFood() { .build(), ItemEventMap.builder() .add(ItemEvents.CONSUME_ITEM, ActionEntry.of( - ActionRequirements.of( - ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.THIS), - RandomChanceLootCondition.builder(0.3f).build() - ), + RandomChanceLootCondition.builder(0.3f), AddStatusEffectsAction.of( new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.POISON), 600) ) @@ -603,7 +603,7 @@ private void bootstrapFood() { .build()) .build(), ItemEventMap.builder() - .add(ItemEvents.CONSUME_ITEM, ActionEntry.of(ApplySuspiciousStewEffectsFromItemAction.of(ActionContextParameter.THIS))) + .add(ItemEvents.CONSUME_ITEM, ActionEntry.of(ApplySuspiciousStewEffectsFromItemAction.of(LootContext.EntityTarget.THIS))) .build() )); this.registerable.register(ItemKeys.ROTTEN_FLESH, create( @@ -616,10 +616,7 @@ private void bootstrapFood() { .build(), ItemEventMap.builder() .add(ItemEvents.CONSUME_ITEM, ActionEntry.of( - ActionRequirements.of( - ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.THIS), - RandomChanceLootCondition.builder(0.8f).build() - ), + RandomChanceLootCondition.builder(0.8f), AddStatusEffectsAction.of( new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.HUNGER), 600) ) @@ -652,10 +649,7 @@ private void bootstrapFood() { .build(), ItemEventMap.builder() .add(ItemEvents.CONSUME_ITEM, ActionEntry.of( - ActionRequirements.of( - ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.THIS), - RandomChanceLootCondition.builder(0.6f).build() - ), + RandomChanceLootCondition.builder(0.6f), AddStatusEffectsAction.of( new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.POISON), 100) ) @@ -717,7 +711,7 @@ private void bootstrapFood() { .with(ConsumableItemComponent.builder(ConsumableComponents.FOOD) .food(FoodComponents.PUMPKIN_PIE) .build()) - .with(CompostableItemComponent.of(ComposterBlockUtil.GUARANTEED_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.GUARANTEED)) .build() )); this.registerable.register(ItemKeys.HONEY_BOTTLE, create( @@ -735,7 +729,7 @@ private void bootstrapFood() { ItemEventMap.builder() .add(ItemEvents.CONSUME_ITEM, ActionEntry.of( RemoveStatusEffectsAction.of( - ActionContextParameter.THIS, + LootContext.EntityTarget.THIS, this.statusEffects.getOrThrow(StatusEffectKeys.POISON) ) )) @@ -935,7 +929,6 @@ private void bootstrapBlocks() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.GRASS_BLOCK))) - .with(TintedItemComponent.of(GrassItemColor.of(this.biomes.getOrThrow(BiomeKeys.PLAINS)))) .build() )); this.registerable.register(ItemKeys.DIRT, create( @@ -1885,6 +1878,13 @@ private void bootstrapBlocks() { .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SPAWNER))) .build() )); + this.registerable.register(ItemKeys.CREAKING_HEART, create( + ItemDisplay.Builder.forBlock(ItemKeys.CREAKING_HEART).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CREAKING_HEART))) + .build() + )); this.registerable.register(ItemKeys.FARMLAND, create( ItemDisplay.Builder.forBlock(ItemKeys.FARMLAND).build(), ItemComponentSet.builder() @@ -3917,6 +3917,48 @@ private void bootstrapBlocks() { .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CRAFTER))) .build() )); + this.registerable.register(ItemKeys.RESIN_BLOCK, create( + ItemDisplay.Builder.forBlock(ItemKeys.RESIN_BLOCK).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.RESIN_BLOCK))) + .build() + )); + this.registerable.register(ItemKeys.RESIN_BRICKS, create( + ItemDisplay.Builder.forBlock(ItemKeys.RESIN_BRICKS).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.RESIN_BRICKS))) + .build() + )); + this.registerable.register(ItemKeys.RESIN_BRICK_STAIRS, create( + ItemDisplay.Builder.forBlock(ItemKeys.RESIN_BRICK_STAIRS).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.RESIN_BRICK_STAIRS))) + .build() + )); + this.registerable.register(ItemKeys.RESIN_BRICK_SLAB, create( + ItemDisplay.Builder.forBlock(ItemKeys.RESIN_BRICK_SLAB).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.RESIN_BRICK_SLAB))) + .build() + )); + this.registerable.register(ItemKeys.RESIN_BRICK_WALL, create( + ItemDisplay.Builder.forBlock(ItemKeys.RESIN_BRICK_WALL).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.RESIN_BRICK_WALL))) + .build() + )); + this.registerable.register(ItemKeys.CHISELED_RESIN_BRICKS, create( + ItemDisplay.Builder.forBlock(ItemKeys.CHISELED_RESIN_BRICKS).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CHISELED_RESIN_BRICKS))) + .build() + )); } private void bootstrapAttachedToSideBlocks() { @@ -5081,18 +5123,18 @@ private void bootstrapShulkerBoxes() { } private void bootstrapItemNameBlocks() { - this.registerable.register(ItemKeys.REDSTONE, create( - ItemDisplay.Builder.forItem(ItemKeys.REDSTONE).build(), + this.registerable.register(ItemKeys.STRING, create( + ItemDisplay.Builder.forItem(ItemKeys.STRING).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.REDSTONE_WIRE))) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.TRIPWIRE))) .build() )); - this.registerable.register(ItemKeys.STRING, create( - ItemDisplay.Builder.forItem(ItemKeys.STRING).build(), + this.registerable.register(ItemKeys.RESIN_CLUMP, create( + ItemDisplay.Builder.forItem(ItemKeys.RESIN_CLUMP).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.TRIPWIRE))) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.RESIN_CLUMP))) .build() )); } @@ -5150,14 +5192,14 @@ private void bootstrapToolsAndWeapons() { ItemDisplay.Builder.forItem(ItemKeys.WOODEN_SWORD).build(), ItemComponentSet.builder() .with(DamageableItemComponent.sword(this.blocks, ToolMaterial.WOOD, this.items.getOrThrow(ItemTags.WOODEN_TOOL_MATERIALS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.TOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.TOOL)) .build() )); this.registerable.register(ItemKeys.WOODEN_SHOVEL, create( ItemDisplay.Builder.forItem(ItemKeys.WOODEN_SHOVEL).build(), ItemComponentSet.builder() .with(DamageableItemComponent.shovel(this.blocks, ToolMaterial.WOOD, this.items.getOrThrow(ItemTags.WOODEN_TOOL_MATERIALS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.TOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.TOOL)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, this.actions.getOrThrow(Actions.USE_SHOVEL_ON_BLOCK)) @@ -5167,21 +5209,21 @@ private void bootstrapToolsAndWeapons() { ItemDisplay.Builder.forItem(ItemKeys.WOODEN_PICKAXE).build(), ItemComponentSet.builder() .with(DamageableItemComponent.pickaxe(this.blocks, ToolMaterial.WOOD, this.items.getOrThrow(ItemTags.WOODEN_TOOL_MATERIALS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.TOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.TOOL)) .build() )); this.registerable.register(ItemKeys.WOODEN_AXE, create( ItemDisplay.Builder.forItem(ItemKeys.WOODEN_AXE).build(), ItemComponentSet.builder() .with(DamageableItemComponent.axe(this.blocks, ToolMaterial.WOOD, 7.0d, 0.2d, this.items.getOrThrow(ItemTags.WOODEN_TOOL_MATERIALS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.TOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.TOOL)) .build() )); this.registerable.register(ItemKeys.WOODEN_HOE, create( ItemDisplay.Builder.forItem(ItemKeys.WOODEN_HOE).build(), ItemComponentSet.builder() .with(DamageableItemComponent.hoe(this.blocks, ToolMaterial.WOOD, 1.0d, 0.25d, this.items.getOrThrow(ItemTags.WOODEN_TOOL_MATERIALS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.TOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.TOOL)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, this.actions.getOrThrow(Actions.USE_HOE_ON_BLOCK)) @@ -5377,7 +5419,7 @@ private void bootstrapToolsAndWeapons() { ItemComponentSet.builder() .with(StackableItemComponent.of(1)) .with(CastableItemComponent.INSTANCE) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.SHEARS, create( @@ -5407,7 +5449,7 @@ private void bootstrapToolsAndWeapons() { DirectShooterMethod.of() )) .with(EnchantableItemComponent.of(1)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.CROSSBOW, create( @@ -5433,7 +5475,7 @@ private void bootstrapToolsAndWeapons() { ) )) .with(EnchantableItemComponent.of(1)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.TRIDENT, create( @@ -5444,29 +5486,32 @@ private void bootstrapToolsAndWeapons() { .with(StackableItemComponent.of(1)) .with(DamageableItemComponent.ofPreserved(250)) .with(ToolItemComponent.builder(2) + .preventCreativeDestruction() .build()) - .with(WeaponItemComponent.of(1, TridentItem.ATTACK_DAMAGE + 1, 0.275d)) + .with(WeaponItemComponent.of(1, 0.0f, TridentItem.ATTACK_DAMAGE, 0.275d)) .with(ThrowableItemComponent.trident(TridentItem.THROW_SPEED, 0.0f, TridentItem.MIN_DRAW_DURATION)) - .with(ProjectileItemComponent.of(TridentEntityInitializer.INSTANCE)) + .with(ProjectileItemComponent.of(this.entityTypes.getOrThrow(EntityTypeKeys.TRIDENT))) .with(EnchantableItemComponent.of(1)) .build(), ItemEventMap.builder() .add(ItemEvents.STOPPED_USING, ActionEntry.of( - ActionRequirements.of( - ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.THIS), - AllOfLootCondition.builder( - EntityPropertiesLootCondition.builder( - LootContext.EntityTarget.THIS, - EntityPredicate.Builder.create() - .itematic$usedItemAtLeast(TridentItem.MIN_DRAW_DURATION) - .itematic$inWaterOrRain(true) - ), - MatchToolLootCondition.builder( - ItemPredicate.Builder.create() - .subPredicate(ItemSubPredicateTypes.ENCHANTMENTS, EnchantmentsPredicate.enchantments(List.of( + AllOfLootCondition.builder( + EntityPropertiesLootCondition.builder( + LootContext.EntityTarget.THIS, + EntityPredicate.Builder.create() + .itematic$usedItemAtLeast(TridentItem.MIN_DRAW_DURATION) + .itematic$inWaterOrRain(true) + ), + MatchToolLootCondition.builder(ItemPredicate.Builder.create() + .components(ComponentsPredicate.Builder.create() + .partial( + ComponentPredicateTypes.ENCHANTMENTS, + EnchantmentsPredicate.enchantments(List.of( new EnchantmentPredicate(this.enchantments.getOrThrow(Enchantments.RIPTIDE), NumberRange.IntRange.ANY) - )))) - ).build() + )) + ).build() + ) + ) ), PassingSequenceHandler.builder() .add(TwirlPlayerAction.INSTANCE) @@ -5508,7 +5553,7 @@ private void bootstrapToolsAndWeapons() { PassingSequenceHandler.builder() .add(this.actions.getOrThrow(Actions.LIGHT_BLOCK)) .add(DamageItemAction.of(1)) - .add(PlaySoundAction.builder(ActionContextParameter.TARGET, this.soundEvents.getOrThrow(SoundEventKeys.FLINT_AND_STEEL_USE), SoundCategory.BLOCKS) + .add(PlaySoundAction.builder(PositionTarget.INTERACTED_POSITION, this.soundEvents.getOrThrow(SoundEventKeys.FLINT_AND_STEEL_USE), SoundCategory.BLOCKS) .pitch(0.8f, 1.2f) .build()) )) @@ -5531,7 +5576,7 @@ private void bootstrapToolsAndWeapons() { .with(StackableItemComponent.of(1)) .with(DamageableItemComponent.of(500)) .with(ToolItemComponent.builder(2).build()) - .with(WeaponItemComponent.ofSmashing(1, 6.0d, 0.15d)) + .with(WeaponItemComponent.ofSmashing(1, 5.0d, 0.15d)) .with(EnchantableItemComponent.of(15)) .with(RepairableItemComponent.of(RegistryEntryList.of( this.items.getOrThrow(ItemKeys.BREEZE_ROD) @@ -5546,35 +5591,35 @@ private void bootstrapEntities() { ItemDisplay.Builder.forItem(ItemKeys.MINECART).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(new MinecartEntityInitializer<>(EntityType.MINECART), this.dispenseBehaviors)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.MINECART), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.CHEST_MINECART, create( ItemDisplay.Builder.forItem(ItemKeys.CHEST_MINECART).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(new MinecartEntityInitializer<>(EntityType.CHEST_MINECART), this.dispenseBehaviors)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.CHEST_MINECART), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.FURNACE_MINECART, create( ItemDisplay.Builder.forItem(ItemKeys.FURNACE_MINECART).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(new MinecartEntityInitializer<>(EntityType.FURNACE_MINECART), this.dispenseBehaviors)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.FURNACE_MINECART), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.TNT_MINECART, create( ItemDisplay.Builder.forItem(ItemKeys.TNT_MINECART).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(new MinecartEntityInitializer<>(EntityType.TNT_MINECART), this.dispenseBehaviors)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.TNT_MINECART), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.HOPPER_MINECART, create( ItemDisplay.Builder.forItem(ItemKeys.HOPPER_MINECART).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(new MinecartEntityInitializer<>(EntityType.HOPPER_MINECART), this.dispenseBehaviors)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.HOPPER_MINECART), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.COMMAND_BLOCK_MINECART, create( @@ -5583,179 +5628,195 @@ private void bootstrapEntities() { .build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(new MinecartEntityInitializer<>(EntityType.COMMAND_BLOCK_MINECART), this.dispenseBehaviors)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.COMMAND_BLOCK_MINECART), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.OAK_BOAT, create( ItemDisplay.Builder.forItem(ItemKeys.OAK_BOAT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(SimpleEntityInitializer.of(EntityType.OAK_BOAT), this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BOAT_FUEL_TIME)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.OAK_BOAT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) .build() )); this.registerable.register(ItemKeys.OAK_CHEST_BOAT, create( ItemDisplay.Builder.forItem(ItemKeys.OAK_CHEST_BOAT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(SimpleEntityInitializer.of(EntityType.OAK_CHEST_BOAT), this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BOAT_FUEL_TIME)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.OAK_CHEST_BOAT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) .build() )); this.registerable.register(ItemKeys.SPRUCE_BOAT, create( ItemDisplay.Builder.forItem(ItemKeys.SPRUCE_BOAT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(SimpleEntityInitializer.of(EntityType.SPRUCE_BOAT), this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BOAT_FUEL_TIME)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SPRUCE_BOAT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) .build() )); this.registerable.register(ItemKeys.SPRUCE_CHEST_BOAT, create( ItemDisplay.Builder.forItem(ItemKeys.SPRUCE_CHEST_BOAT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(SimpleEntityInitializer.of(EntityType.SPRUCE_CHEST_BOAT), this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BOAT_FUEL_TIME)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SPRUCE_CHEST_BOAT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) .build() )); this.registerable.register(ItemKeys.BIRCH_BOAT, create( ItemDisplay.Builder.forItem(ItemKeys.BIRCH_BOAT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(SimpleEntityInitializer.of(EntityType.BIRCH_BOAT), this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BOAT_FUEL_TIME)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.BIRCH_BOAT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) .build() )); this.registerable.register(ItemKeys.BIRCH_CHEST_BOAT, create( ItemDisplay.Builder.forItem(ItemKeys.BIRCH_CHEST_BOAT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(SimpleEntityInitializer.of(EntityType.BIRCH_CHEST_BOAT), this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BOAT_FUEL_TIME)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.BIRCH_CHEST_BOAT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) .build() )); this.registerable.register(ItemKeys.JUNGLE_BOAT, create( ItemDisplay.Builder.forItem(ItemKeys.JUNGLE_BOAT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(SimpleEntityInitializer.of(EntityType.JUNGLE_BOAT), this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BOAT_FUEL_TIME)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.JUNGLE_BOAT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) .build() )); this.registerable.register(ItemKeys.JUNGLE_CHEST_BOAT, create( ItemDisplay.Builder.forItem(ItemKeys.JUNGLE_CHEST_BOAT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(SimpleEntityInitializer.of(EntityType.JUNGLE_CHEST_BOAT), this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BOAT_FUEL_TIME)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.JUNGLE_CHEST_BOAT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) .build() )); this.registerable.register(ItemKeys.ACACIA_BOAT, create( ItemDisplay.Builder.forItem(ItemKeys.ACACIA_BOAT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(SimpleEntityInitializer.of(EntityType.ACACIA_BOAT), this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BOAT_FUEL_TIME)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ACACIA_BOAT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) .build() )); this.registerable.register(ItemKeys.ACACIA_CHEST_BOAT, create( ItemDisplay.Builder.forItem(ItemKeys.ACACIA_CHEST_BOAT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(SimpleEntityInitializer.of(EntityType.ACACIA_CHEST_BOAT), this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BOAT_FUEL_TIME)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ACACIA_CHEST_BOAT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) .build() )); this.registerable.register(ItemKeys.CHERRY_BOAT, create( ItemDisplay.Builder.forItem(ItemKeys.CHERRY_BOAT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(SimpleEntityInitializer.of(EntityType.CHERRY_BOAT), this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BOAT_FUEL_TIME)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.CHERRY_BOAT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) .build() )); this.registerable.register(ItemKeys.CHERRY_CHEST_BOAT, create( ItemDisplay.Builder.forItem(ItemKeys.CHERRY_CHEST_BOAT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(SimpleEntityInitializer.of(EntityType.CHERRY_CHEST_BOAT), this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BOAT_FUEL_TIME)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.CHERRY_CHEST_BOAT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) .build() )); this.registerable.register(ItemKeys.DARK_OAK_BOAT, create( ItemDisplay.Builder.forItem(ItemKeys.DARK_OAK_BOAT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(SimpleEntityInitializer.of(EntityType.DARK_OAK_BOAT), this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BOAT_FUEL_TIME)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.DARK_OAK_BOAT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) .build() )); this.registerable.register(ItemKeys.DARK_OAK_CHEST_BOAT, create( ItemDisplay.Builder.forItem(ItemKeys.DARK_OAK_CHEST_BOAT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(SimpleEntityInitializer.of(EntityType.DARK_OAK_CHEST_BOAT), this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BOAT_FUEL_TIME)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.DARK_OAK_CHEST_BOAT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) + .build() + )); + this.registerable.register(ItemKeys.PALE_OAK_BOAT, create( + ItemDisplay.Builder.forItem(ItemKeys.PALE_OAK_BOAT).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(1)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.PALE_OAK_BOAT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) + .build() + )); + this.registerable.register(ItemKeys.PALE_OAK_CHEST_BOAT, create( + ItemDisplay.Builder.forItem(ItemKeys.PALE_OAK_CHEST_BOAT).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(1)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.PALE_OAK_CHEST_BOAT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) .build() )); this.registerable.register(ItemKeys.MANGROVE_BOAT, create( ItemDisplay.Builder.forItem(ItemKeys.MANGROVE_BOAT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(SimpleEntityInitializer.of(EntityType.MANGROVE_BOAT), this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BOAT_FUEL_TIME)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.MANGROVE_BOAT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) .build() )); this.registerable.register(ItemKeys.MANGROVE_CHEST_BOAT, create( ItemDisplay.Builder.forItem(ItemKeys.MANGROVE_CHEST_BOAT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(SimpleEntityInitializer.of(EntityType.MANGROVE_CHEST_BOAT), this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BOAT_FUEL_TIME)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.MANGROVE_CHEST_BOAT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) .build() )); this.registerable.register(ItemKeys.BAMBOO_RAFT, create( ItemDisplay.Builder.forItem(ItemKeys.BAMBOO_RAFT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(SimpleEntityInitializer.of(EntityType.BAMBOO_RAFT), this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BOAT_FUEL_TIME)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.BAMBOO_RAFT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) .build() )); this.registerable.register(ItemKeys.BAMBOO_CHEST_RAFT, create( ItemDisplay.Builder.forItem(ItemKeys.BAMBOO_CHEST_RAFT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(EntityItemComponent.from(SimpleEntityInitializer.of(EntityType.BAMBOO_CHEST_RAFT), this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BOAT_FUEL_TIME)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.BAMBOO_CHEST_RAFT), this.dispenseBehaviors)) + .with(FuelItemComponent.of(FuelTimes.BOAT)) .build() )); this.registerable.register(ItemKeys.PAINTING, create( ItemDisplay.Builder.forItem(ItemKeys.PAINTING).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(EntityItemComponent.of(DecorationEntityInitializer.createPainting(EntityType.PAINTING))) + .with(EntityItemComponent.of(this.entityTypes.getOrThrow(EntityTypeKeys.PAINTING))) .build() )); this.registerable.register(ItemKeys.ITEM_FRAME, create( ItemDisplay.Builder.forItem(ItemKeys.ITEM_FRAME).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(EntityItemComponent.of(DecorationEntityInitializer.createItemFrame(EntityType.ITEM_FRAME, ItemFrameEntity::new))) + .with(EntityItemComponent.of(this.entityTypes.getOrThrow(EntityTypeKeys.ITEM_FRAME))) .build() )); this.registerable.register(ItemKeys.GLOW_ITEM_FRAME, create( ItemDisplay.Builder.forItem(ItemKeys.GLOW_ITEM_FRAME).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(EntityItemComponent.of(DecorationEntityInitializer.createItemFrame(EntityType.GLOW_ITEM_FRAME, GlowItemFrameEntity::new))) + .with(EntityItemComponent.of(this.entityTypes.getOrThrow(EntityTypeKeys.GLOW_ITEM_FRAME))) .build() )); this.registerable.register(ItemKeys.ARMOR_STAND, create( ItemDisplay.Builder.forItem(ItemKeys.ARMOR_STAND).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(16)) - .with(EntityItemComponent.from(new ArmorStandEntityInitializer(), this.dispenseBehaviors)) + .with(EntityItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ARMOR_STAND), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.END_CRYSTAL, create( @@ -5764,7 +5825,7 @@ private void bootstrapEntities() { .build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(EntityItemComponent.of(EndCrystalEntityInitializer.INSTANCE)) + .with(EntityItemComponent.of(this.entityTypes.getOrThrow(EntityTypeKeys.END_CRYSTAL))) .build() )); } @@ -5774,560 +5835,567 @@ private void bootstrapSpawnEggs() { ItemDisplay.Builder.forItem(ItemKeys.ARMADILLO_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ARMADILLO), 0xad716d, 0x824848, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ARMADILLO), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.ALLAY_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.ALLAY_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ALLAY), 0x00daff, 0x00adff, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ALLAY), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.AXOLOTL_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.AXOLOTL_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.AXOLOTL), 0xfbc1e3, 0xa62d74, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.AXOLOTL), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.BAT_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.BAT_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.BAT), 0x4c3e30, 0x0f0f0f, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.BAT), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.BEE_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.BEE_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.BEE), 0xedc343, 0x43241b, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.BEE), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.BLAZE_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.BLAZE_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.BLAZE), 0xf6b201, 0xfff87e, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.BLAZE), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.BOGGED_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.BOGGED_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.BOGGED), 0x8a9c72, 0x314d1b, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.BOGGED), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.BREEZE_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.BREEZE_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.BREEZE), 0xaf94df, 0x9166df, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.BREEZE), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.CAT_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.CAT_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.CAT), 0xefc88e, 0x957256, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.CAT), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.CAMEL_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.CAMEL_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.CAMEL), 0xfcc369, 0xcb9337, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.CAMEL), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.CAVE_SPIDER_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.CAVE_SPIDER_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.CAVE_SPIDER), 0x0c424e, 0xa80e0e, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.CAVE_SPIDER), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.CHICKEN_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.CHICKEN_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.CHICKEN), 0xa1a1a1, 0xff0000, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.CHICKEN), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.COD_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.COD_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.COD), 0xc1a76a, 0xe5c48b, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.COD), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.COW_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.COW_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.COW), 0x443626, 0xa1a1a1, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.COW), this.dispenseBehaviors)) + .build() + )); + this.registerable.register(ItemKeys.CREAKING_SPAWN_EGG, create( + ItemDisplay.Builder.forItem(ItemKeys.CREAKING_SPAWN_EGG).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.CREAKING), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.CREEPER_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.CREEPER_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.CREEPER), 0x0da70b, 0x000000, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.CREEPER), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.DOLPHIN_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.DOLPHIN_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.DOLPHIN), 0x223b4d, 0xf9f9f9, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.DOLPHIN), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.DONKEY_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.DONKEY_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.DONKEY), 0x534539, 0x867566, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.DONKEY), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.DROWNED_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.DROWNED_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.DROWNED), 0x8ff1d7, 0x799c65, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.DROWNED), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.ELDER_GUARDIAN_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.ELDER_GUARDIAN_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ELDER_GUARDIAN), 0xceccba, 0x747693, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ELDER_GUARDIAN), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.ENDER_DRAGON_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.ENDER_DRAGON_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ENDER_DRAGON), 0x1c1c1c, 0xe079fa, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ENDER_DRAGON), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.ENDERMAN_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.ENDERMAN_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ENDERMAN), 0x161616, 0x000000, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ENDERMAN), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.ENDERMITE_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.ENDERMITE_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ENDERMITE), 0x161616, 0x6e6e6e, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ENDERMITE), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.EVOKER_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.EVOKER_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.EVOKER), 0x959b9b, 0x1e1c1a, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.EVOKER), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.FOX_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.FOX_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.FOX), 0xd5b69f, 0xcc6920, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.FOX), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.FROG_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.FROG_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.FROG), 0xd07444, 0xffc77c, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.FROG), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.GHAST_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.GHAST_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.GHAST), 0xf9f9f9, 0xbcbcbc, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.GHAST), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.GLOW_SQUID_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.GLOW_SQUID_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.GLOW_SQUID), 0x095656, 0x85f1bc, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.GLOW_SQUID), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.GOAT_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.GOAT_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.GOAT), 0xa5947c, 0x55493e, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.GOAT), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.GUARDIAN_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.GUARDIAN_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.GUARDIAN), 0x5a8272, 0xf17d30, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.GUARDIAN), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.HOGLIN_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.HOGLIN_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.HOGLIN), 0xc66e55, 0x5f6464, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.HOGLIN), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.HORSE_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.HORSE_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.HORSE), 0xc09e7d, 0xeee500, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.HORSE), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.HUSK_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.HUSK_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.HUSK), 0x797061, 0xe6cc94, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.HUSK), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.IRON_GOLEM_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.IRON_GOLEM_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.IRON_GOLEM), 0xdbcdc2, 0x74a332, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.IRON_GOLEM), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.LLAMA_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.LLAMA_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.LLAMA), 0xc09e7d, 0x995f40, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.LLAMA), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.MAGMA_CUBE_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.MAGMA_CUBE_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.MAGMA_CUBE), 0x340000, 0xfcfc00, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.MAGMA_CUBE), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.MOOSHROOM_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.MOOSHROOM_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.MOOSHROOM), 0xa00f10, 0xb7b7b7, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.MOOSHROOM), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.MULE_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.MULE_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.MULE), 0x1b0200, 0x51331d, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.MULE), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.OCELOT_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.OCELOT_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.OCELOT), 0xefde7d, 0x564434, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.OCELOT), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.PANDA_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.PANDA_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.PANDA), 0xe7e7e7, 0x1b1b22, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.PANDA), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.PARROT_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.PARROT_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.PARROT), 0x0da70b, 0xff0000, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.PARROT), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.PHANTOM_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.PHANTOM_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.PHANTOM), 0x43518a, 0x88ff00, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.PHANTOM), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.PIG_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.PIG_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.PIG), 0xf0a5a2, 0xdb635f, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.PIG), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.PIGLIN_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.PIGLIN_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.PIGLIN), 0x995f40, 0xf9f3a4, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.PIGLIN), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.PIGLIN_BRUTE_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.PIGLIN_BRUTE_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.PIGLIN_BRUTE), 0x592a10, 0xf9f3a4, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.PIGLIN_BRUTE), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.PILLAGER_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.PILLAGER_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.PILLAGER), 0x532f36, 0x959b9b, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.PILLAGER), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.POLAR_BEAR_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.POLAR_BEAR_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.POLAR_BEAR), 0xeeeede, 0xd5d6cd, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.POLAR_BEAR), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.PUFFERFISH_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.PUFFERFISH_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.PUFFERFISH), 0xf6b201, 0x37c3f2, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.PUFFERFISH), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.RABBIT_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.RABBIT_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.RABBIT), 0x995f40, 0x734831, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.RABBIT), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.RAVAGER_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.RAVAGER_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.RAVAGER), 0x757470, 0x5b5049, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.RAVAGER), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.SALMON_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.SALMON_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SALMON), 0xa00f10, 0x0e8474, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SALMON), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.SHEEP_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.SHEEP_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SHEEP), 0xe7e7e7, 0xffb5b5, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SHEEP), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.SHULKER_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.SHULKER_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SHULKER), 0x946794, 0x4d3852, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SHULKER), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.SILVERFISH_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.SILVERFISH_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SILVERFISH), 0x6e6e6e, 0x303030, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SILVERFISH), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.SKELETON_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.SKELETON_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SKELETON), 0xc1c1c1, 0x494949, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SKELETON), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.SKELETON_HORSE_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.SKELETON_HORSE_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SKELETON_HORSE), 0x68684f, 0xe5e5d8, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SKELETON_HORSE), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.SLIME_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.SLIME_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SLIME), 0x51a03e, 0x7ebf6e, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SLIME), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.SNIFFER_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.SNIFFER_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SNIFFER), 0x871e09, 0x25ab70, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SNIFFER), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.SNOW_GOLEM_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.SNOW_GOLEM_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SNOW_GOLEM), 0xd9f2f2, 0x81a4a4, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SNOW_GOLEM), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.SPIDER_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.SPIDER_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SPIDER), 0x342d27, 0xa80e0e, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SPIDER), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.SQUID_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.SQUID_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SQUID), 0x223b4d, 0x708899, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.SQUID), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.STRAY_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.STRAY_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.STRAY), 0x617677, 0xddeaea, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.STRAY), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.STRIDER_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.STRIDER_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.STRIDER), 0x9c3436, 0x4d494d, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.STRIDER), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.TADPOLE_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.TADPOLE_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.TADPOLE), 0x6d533d, 0x160a00, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.TADPOLE), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.TRADER_LLAMA_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.TRADER_LLAMA_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.TRADER_LLAMA), 0xeaa430, 0x456296, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.TRADER_LLAMA), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.TROPICAL_FISH_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.TROPICAL_FISH_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.TROPICAL_FISH), 0xef6915, 0xfff9ef, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.TROPICAL_FISH), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.TURTLE_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.TURTLE_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.TURTLE), 0xe7e7e7, 0x00afaf, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.TURTLE), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.VEX_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.VEX_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.VEX), 0x7a90a4, 0xe8edf1, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.VEX), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.VILLAGER_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.VILLAGER_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.VILLAGER), 0x563c33, 0xbd8b72, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.VILLAGER), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.VINDICATOR_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.VINDICATOR_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.VINDICATOR), 0x959b9b, 0x275e61, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.VINDICATOR), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.WANDERING_TRADER_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.WANDERING_TRADER_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.WANDERING_TRADER), 0x456296, 0xeaa430, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.WANDERING_TRADER), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.WARDEN_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.WARDEN_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.WARDEN), 0x0f4649, 0x39d6e0, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.WARDEN), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.WITCH_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.WITCH_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.WITCH), 0x340000, 0x51a03e, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.WITCH), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.WITHER_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.WITHER_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.WITHER), 0x141414, 0x4d72a0, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.WITHER), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.WITHER_SKELETON_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.WITHER_SKELETON_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.WITHER_SKELETON), 0x141414, 0x474d4d, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.WITHER_SKELETON), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.WOLF_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.WOLF_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.WOLF), 0xd7d3d3, 0xceaf96, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.WOLF), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.ZOGLIN_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.ZOGLIN_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ZOGLIN), 0xc66e55, 0xe6e6e6, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ZOGLIN), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.ZOMBIE_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.ZOMBIE_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ZOMBIE), 0x00afaf, 0x799c65, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ZOMBIE), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.ZOMBIE_HORSE_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.ZOMBIE_HORSE_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ZOMBIE_HORSE), 0x315234, 0x97c284, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ZOMBIE_HORSE), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.ZOMBIE_VILLAGER_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.ZOMBIE_VILLAGER_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ZOMBIE_VILLAGER), 0x563c33, 0x799c65, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ZOMBIE_VILLAGER), this.dispenseBehaviors)) .build() )); this.registerable.register(ItemKeys.ZOMBIFIED_PIGLIN_SPAWN_EGG, create( ItemDisplay.Builder.forItem(ItemKeys.ZOMBIFIED_PIGLIN_SPAWN_EGG).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ZOMBIFIED_PIGLIN), 0xea9393, 0x4c7129, this.dispenseBehaviors)) + .with(SpawnEggItemComponent.from(this.entityTypes.getOrThrow(EntityTypeKeys.ZOMBIFIED_PIGLIN), this.dispenseBehaviors)) .build() )); } @@ -6338,8 +6406,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.OAK_LEAVES))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) - .with(TintedItemComponent.of(FoliageItemColor.of(this.biomes.getOrThrow(BiomeKeys.PLAINS)))) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.SPRUCE_LEAVES, create( @@ -6347,8 +6414,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SPRUCE_LEAVES))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) - .with(TintedItemComponent.of(ConstantItemColor.of(FoliageColors.getSpruceColor()))) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.BIRCH_LEAVES, create( @@ -6356,8 +6422,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BIRCH_LEAVES))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) - .with(TintedItemComponent.of(ConstantItemColor.of(FoliageColors.getBirchColor()))) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.JUNGLE_LEAVES, create( @@ -6365,8 +6430,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.JUNGLE_LEAVES))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) - .with(TintedItemComponent.of(FoliageItemColor.of(this.biomes.getOrThrow(BiomeKeys.PLAINS)))) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.ACACIA_LEAVES, create( @@ -6374,8 +6438,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.ACACIA_LEAVES))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) - .with(TintedItemComponent.of(FoliageItemColor.of(this.biomes.getOrThrow(BiomeKeys.PLAINS)))) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.CHERRY_LEAVES, create( @@ -6383,7 +6446,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CHERRY_LEAVES))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.DARK_OAK_LEAVES, create( @@ -6391,8 +6454,15 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.DARK_OAK_LEAVES))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) - .with(TintedItemComponent.of(FoliageItemColor.of(this.biomes.getOrThrow(BiomeKeys.PLAINS)))) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .build() + )); + this.registerable.register(ItemKeys.PALE_OAK_LEAVES, create( + ItemDisplay.Builder.forBlock(ItemKeys.PALE_OAK_LEAVES).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PALE_OAK_LEAVES))) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.MANGROVE_LEAVES, create( @@ -6400,8 +6470,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MANGROVE_LEAVES))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) - .with(TintedItemComponent.of(ConstantItemColor.of(FoliageColors.getMangroveColor()))) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.AZALEA_LEAVES, create( @@ -6409,7 +6478,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.AZALEA_LEAVES))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.OAK_SAPLING, create( @@ -6417,8 +6486,8 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.OAK_SAPLING))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.PLANT_FUEL_TIME)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .with(FuelItemComponent.of(FuelTimes.PLANT)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_OAK_SAPLING)) @@ -6429,8 +6498,8 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SPRUCE_SAPLING))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.PLANT_FUEL_TIME)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .with(FuelItemComponent.of(FuelTimes.PLANT)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_SPRUCE_SAPLING)) @@ -6441,8 +6510,8 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BIRCH_SAPLING))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.PLANT_FUEL_TIME)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .with(FuelItemComponent.of(FuelTimes.PLANT)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_BIRCH_SAPLING)) @@ -6453,8 +6522,8 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.JUNGLE_SAPLING))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.PLANT_FUEL_TIME)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .with(FuelItemComponent.of(FuelTimes.PLANT)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_JUNGLE_SAPLING)) @@ -6465,8 +6534,8 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.ACACIA_SAPLING))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.PLANT_FUEL_TIME)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .with(FuelItemComponent.of(FuelTimes.PLANT)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_ACACIA_SAPLING)) @@ -6477,8 +6546,8 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CHERRY_SAPLING))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.PLANT_FUEL_TIME)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .with(FuelItemComponent.of(FuelTimes.PLANT)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_CHERRY_SAPLING)) @@ -6489,20 +6558,32 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.DARK_OAK_SAPLING))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.PLANT_FUEL_TIME)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .with(FuelItemComponent.of(FuelTimes.PLANT)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_DARK_OAK_SAPLING)) .build() )); + this.registerable.register(ItemKeys.PALE_OAK_SAPLING, create( + ItemDisplay.Builder.forBlock(ItemKeys.PALE_OAK_SAPLING).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PALE_OAK_SAPLING))) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .with(FuelItemComponent.of(FuelTimes.PLANT)) + .build(), + ItemEventMap.builder() + .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_PALE_OAK_SAPLING)) + .build() + )); this.registerable.register(ItemKeys.MANGROVE_PROPAGULE, create( ItemDisplay.Builder.forBlock(ItemKeys.MANGROVE_PROPAGULE).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MANGROVE_PROPAGULE))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.PLANT_FUEL_TIME)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .with(FuelItemComponent.of(FuelTimes.PLANT)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_MANGROVE_PROPAGULE)) @@ -6513,8 +6594,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SHORT_GRASS))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) - .with(TintedItemComponent.of(GrassItemColor.of(this.biomes.getOrThrow(BiomeKeys.PLAINS)))) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.KELP, create( @@ -6522,7 +6602,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.KELP))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.MOSS_CARPET, create( @@ -6530,7 +6610,15 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MOSS_CARPET))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .build() + )); + this.registerable.register(ItemKeys.PALE_MOSS_CARPET, create( + ItemDisplay.Builder.forBlock(ItemKeys.PALE_MOSS_CARPET).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PALE_MOSS_CARPET))) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.PINK_PETALS, create( @@ -6538,7 +6626,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PINK_PETALS))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.HANGING_ROOTS, create( @@ -6546,7 +6634,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.HANGING_ROOTS))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.SMALL_DRIPLEAF, create( @@ -6554,7 +6642,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SMALL_DRIPLEAF))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.WHEAT_SEEDS, create( @@ -6562,7 +6650,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.WHEAT))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.PUMPKIN_SEEDS, create( @@ -6570,7 +6658,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PUMPKIN_STEM))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.MELON_SEEDS, create( @@ -6578,7 +6666,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MELON_STEM))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.TORCHFLOWER_SEEDS, create( @@ -6586,7 +6674,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.TORCHFLOWER_CROP))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.PITCHER_POD, create( @@ -6594,7 +6682,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PITCHER_CROP))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.BEETROOT_SEEDS, create( @@ -6602,7 +6690,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BEETROOTS))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.MANGROVE_ROOTS, create( @@ -6610,8 +6698,8 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MANGROVE_ROOTS))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.SEAGRASS, create( @@ -6619,7 +6707,47 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SEAGRASS))) - .with(CompostableItemComponent.of(ComposterBlockUtil.SMALL_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .build() + )); + this.registerable.register(ItemKeys.PALE_HANGING_MOSS, create( + ItemDisplay.Builder.forBlock(ItemKeys.PALE_HANGING_MOSS).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PALE_HANGING_MOSS))) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .build() + )); + this.registerable.register(ItemKeys.WILDFLOWERS, create( + ItemDisplay.Builder.forBlock(ItemKeys.WILDFLOWERS).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.WILDFLOWERS))) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .build() + )); + this.registerable.register(ItemKeys.BUSH, create( + ItemDisplay.Builder.forBlock(ItemKeys.BUSH).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BUSH))) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .build() + )); + this.registerable.register(ItemKeys.FIREFLY_BUSH, create( + ItemDisplay.Builder.forBlock(ItemKeys.FIREFLY_BUSH).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.FIREFLY_BUSH))) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .build() + )); + this.registerable.register(ItemKeys.CACTUS_FLOWER, create( + ItemDisplay.Builder.forBlock(ItemKeys.CACTUS_FLOWER).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CACTUS_FLOWER))) + .with(CompostableItemComponent.of(CompostChances.SMALL)) .build() )); this.registerable.register(ItemKeys.FLOWERING_AZALEA_LEAVES, create( @@ -6627,7 +6755,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.FLOWERING_AZALEA_LEAVES))) - .with(CompostableItemComponent.of(ComposterBlockUtil.HALF_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.FIFTY_FIFTY)) .build() )); this.registerable.register(ItemKeys.NETHER_SPROUTS, create( @@ -6635,7 +6763,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.NETHER_SPROUTS))) - .with(CompostableItemComponent.of(ComposterBlockUtil.HALF_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.FIFTY_FIFTY)) .build() )); this.registerable.register(ItemKeys.WEEPING_VINES, create( @@ -6643,7 +6771,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.WEEPING_VINES))) - .with(CompostableItemComponent.of(ComposterBlockUtil.HALF_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.FIFTY_FIFTY)) .build() )); this.registerable.register(ItemKeys.TWISTING_VINES, create( @@ -6651,7 +6779,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.TWISTING_VINES))) - .with(CompostableItemComponent.of(ComposterBlockUtil.HALF_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.FIFTY_FIFTY)) .build() )); this.registerable.register(ItemKeys.SUGAR_CANE, create( @@ -6659,7 +6787,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SUGAR_CANE))) - .with(CompostableItemComponent.of(ComposterBlockUtil.HALF_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.FIFTY_FIFTY)) .build() )); this.registerable.register(ItemKeys.VINE, create( @@ -6667,8 +6795,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.VINE))) - .with(CompostableItemComponent.of(ComposterBlockUtil.HALF_CHANCE_TO_COMPOST)) - .with(TintedItemComponent.of(FoliageItemColor.of(this.biomes.getOrThrow(BiomeKeys.PLAINS)))) + .with(CompostableItemComponent.of(CompostChances.FIFTY_FIFTY)) .build() )); this.registerable.register(ItemKeys.GLOW_LICHEN, create( @@ -6676,7 +6803,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.GLOW_LICHEN))) - .with(CompostableItemComponent.of(ComposterBlockUtil.HALF_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.FIFTY_FIFTY)) .build() )); this.registerable.register(ItemKeys.TALL_GRASS, create( @@ -6684,8 +6811,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.TALL_GRASS))) - .with(CompostableItemComponent.of(ComposterBlockUtil.HALF_CHANCE_TO_COMPOST)) - .with(TintedItemComponent.of(GrassItemColor.of(this.biomes.getOrThrow(BiomeKeys.PLAINS)))) + .with(CompostableItemComponent.of(CompostChances.FIFTY_FIFTY)) .build() )); this.registerable.register(ItemKeys.CACTUS, create( @@ -6693,7 +6819,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CACTUS))) - .with(CompostableItemComponent.of(ComposterBlockUtil.HALF_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.FIFTY_FIFTY)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_CACTUS)) @@ -6704,8 +6830,8 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.DRIED_KELP_BLOCK))) - .with(CompostableItemComponent.of(ComposterBlockUtil.HALF_CHANCE_TO_COMPOST)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.DRIED_KELP_BLOCK_FUEL_TIME)) + .with(CompostableItemComponent.of(CompostChances.FIFTY_FIFTY)) + .with(FuelItemComponent.of(FuelTimes.DRIED_KELP_BLOCK)) .build() )); this.registerable.register(ItemKeys.FERN, create( @@ -6713,8 +6839,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.FERN))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) - .with(TintedItemComponent.of(GrassItemColor.of(this.biomes.getOrThrow(BiomeKeys.PLAINS)))) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_FERN)) @@ -6725,8 +6850,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.LILY_PAD), BlockItemComponent.Pass.FLUID)) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) - .with(TintedItemComponent.of(ConstantItemColor.of(0xff71c35c))) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.NETHER_WART, create( @@ -6734,7 +6858,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.NETHER_WART))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.COCOA_BEANS, create( @@ -6742,7 +6866,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.COCOA))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.BIG_DRIPLEAF, create( @@ -6750,7 +6874,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BIG_DRIPLEAF))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.PUMPKIN, create( @@ -6758,7 +6882,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PUMPKIN))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.CARVED_PUMPKIN, create( @@ -6766,7 +6890,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CARVED_PUMPKIN))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .with(EquipmentItemComponent.of(EquippableComponent.builder(EquipmentSlot.HEAD) .swappable(false) .cameraOverlay(Identifier.ofVanilla("misc/pumpkinblur")) @@ -6779,7 +6903,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MELON))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.SEA_PICKLE, create( @@ -6787,14 +6911,14 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SEA_PICKLE))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.WHEAT, create( ItemDisplay.Builder.forItem(ItemKeys.WHEAT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.DANDELION, create( @@ -6802,7 +6926,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.DANDELION))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .with(SuspiciousEffectIngredientItemComponent.of( new SuspiciousStewEffectsComponent.StewEffect(this.statusEffects.getOrThrow(StatusEffectKeys.SATURATION), 140) )) @@ -6811,12 +6935,40 @@ private void bootstrapCompostables() { .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_DANDELION)) .build() )); + this.registerable.register(ItemKeys.OPEN_EYEBLOSSOM, create( + ItemDisplay.Builder.forBlock(ItemKeys.OPEN_EYEBLOSSOM).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.OPEN_EYEBLOSSOM))) + .with(CompostableItemComponent.of(CompostChances.BIG)) + .with(SuspiciousEffectIngredientItemComponent.of( + new SuspiciousStewEffectsComponent.StewEffect(this.statusEffects.getOrThrow(StatusEffectKeys.BLINDNESS), 140) + )) + .build(), + ItemEventMap.builder() + .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_OPEN_EYEBLOSSOM)) + .build() + )); + this.registerable.register(ItemKeys.CLOSED_EYEBLOSSOM, create( + ItemDisplay.Builder.forBlock(ItemKeys.CLOSED_EYEBLOSSOM).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CLOSED_EYEBLOSSOM))) + .with(CompostableItemComponent.of(CompostChances.BIG)) + .with(SuspiciousEffectIngredientItemComponent.of( + new SuspiciousStewEffectsComponent.StewEffect(this.statusEffects.getOrThrow(StatusEffectKeys.NAUSEA), 140) + )) + .build(), + ItemEventMap.builder() + .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_CLOSED_EYEBLOSSOM)) + .build() + )); this.registerable.register(ItemKeys.POPPY, create( ItemDisplay.Builder.forBlock(ItemKeys.POPPY).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.POPPY))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .with(SuspiciousEffectIngredientItemComponent.of( new SuspiciousStewEffectsComponent.StewEffect(this.statusEffects.getOrThrow(StatusEffectKeys.NIGHT_VISION), 100) )) @@ -6830,7 +6982,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BLUE_ORCHID))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .with(SuspiciousEffectIngredientItemComponent.of( new SuspiciousStewEffectsComponent.StewEffect(this.statusEffects.getOrThrow(StatusEffectKeys.SATURATION), 140) )) @@ -6844,7 +6996,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.ALLIUM))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .with(SuspiciousEffectIngredientItemComponent.of( new SuspiciousStewEffectsComponent.StewEffect(this.statusEffects.getOrThrow(StatusEffectKeys.FIRE_RESISTANCE), 80) )) @@ -6858,7 +7010,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.AZURE_BLUET))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .with(SuspiciousEffectIngredientItemComponent.of( new SuspiciousStewEffectsComponent.StewEffect(this.statusEffects.getOrThrow(StatusEffectKeys.BLINDNESS), 160) )) @@ -6872,7 +7024,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.RED_TULIP))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .with(SuspiciousEffectIngredientItemComponent.of( new SuspiciousStewEffectsComponent.StewEffect(this.statusEffects.getOrThrow(StatusEffectKeys.WEAKNESS), 180) )) @@ -6886,7 +7038,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.ORANGE_TULIP))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .with(SuspiciousEffectIngredientItemComponent.of( new SuspiciousStewEffectsComponent.StewEffect(this.statusEffects.getOrThrow(StatusEffectKeys.WEAKNESS), 180) )) @@ -6900,7 +7052,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.WHITE_TULIP))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .with(SuspiciousEffectIngredientItemComponent.of( new SuspiciousStewEffectsComponent.StewEffect(this.statusEffects.getOrThrow(StatusEffectKeys.WEAKNESS), 180) )) @@ -6914,7 +7066,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PINK_TULIP))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .with(SuspiciousEffectIngredientItemComponent.of( new SuspiciousStewEffectsComponent.StewEffect(this.statusEffects.getOrThrow(StatusEffectKeys.WEAKNESS), 180) )) @@ -6928,7 +7080,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.OXEYE_DAISY))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .with(SuspiciousEffectIngredientItemComponent.of( new SuspiciousStewEffectsComponent.StewEffect(this.statusEffects.getOrThrow(StatusEffectKeys.REGENERATION), 160) )) @@ -6942,7 +7094,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CORNFLOWER))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .with(SuspiciousEffectIngredientItemComponent.of( new SuspiciousStewEffectsComponent.StewEffect(this.statusEffects.getOrThrow(StatusEffectKeys.JUMP_BOOST), 120) )) @@ -6956,7 +7108,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.LILY_OF_THE_VALLEY))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .with(SuspiciousEffectIngredientItemComponent.of( new SuspiciousStewEffectsComponent.StewEffect(this.statusEffects.getOrThrow(StatusEffectKeys.POISON), 240) )) @@ -6970,7 +7122,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.WITHER_ROSE))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .with(SuspiciousEffectIngredientItemComponent.of( new SuspiciousStewEffectsComponent.StewEffect(this.statusEffects.getOrThrow(StatusEffectKeys.WITHER), 160) )) @@ -6984,8 +7136,8 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.AZALEA))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.PLANT_FUEL_TIME)) + .with(CompostableItemComponent.of(CompostChances.BIG)) + .with(FuelItemComponent.of(FuelTimes.PLANT)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_AZALEA_BUSH)) @@ -6996,7 +7148,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SUNFLOWER))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.LILAC, create( @@ -7004,7 +7156,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.LILAC))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.ROSE_BUSH, create( @@ -7012,7 +7164,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.ROSE_BUSH))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.PEONY, create( @@ -7020,7 +7172,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PEONY))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.LARGE_FERN, create( @@ -7028,8 +7180,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.LARGE_FERN))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) - .with(TintedItemComponent.of(GrassItemColor.of(this.biomes.getOrThrow(BiomeKeys.PLAINS)))) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.SPORE_BLOSSOM, create( @@ -7037,7 +7188,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SPORE_BLOSSOM))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.BROWN_MUSHROOM, create( @@ -7045,7 +7196,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BROWN_MUSHROOM))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_BROWN_MUSHROOM)) @@ -7056,7 +7207,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.RED_MUSHROOM))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_RED_MUSHROOM)) @@ -7067,7 +7218,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CRIMSON_FUNGUS))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_CRIMSON_FUNGUS)) @@ -7078,7 +7229,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.WARPED_FUNGUS))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_WARPED_FUNGUS)) @@ -7089,7 +7240,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CRIMSON_ROOTS))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_CRIMSON_ROOTS)) @@ -7100,7 +7251,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.WARPED_ROOTS))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_WARPED_ROOTS)) @@ -7111,7 +7262,15 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MOSS_BLOCK))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) + .build() + )); + this.registerable.register(ItemKeys.PALE_MOSS_BLOCK, create( + ItemDisplay.Builder.forBlock(ItemKeys.PALE_MOSS_BLOCK).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PALE_MOSS_BLOCK))) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.MUSHROOM_STEM, create( @@ -7119,7 +7278,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MUSHROOM_STEM))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.SHROOMLIGHT, create( @@ -7127,7 +7286,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SHROOMLIGHT))) - .with(CompostableItemComponent.of(ComposterBlockUtil.BIG_CHANCE_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.BIG)) .build() )); this.registerable.register(ItemKeys.NETHER_WART_BLOCK, create( @@ -7135,7 +7294,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.NETHER_WART_BLOCK))) - .with(CompostableItemComponent.of(ComposterBlockUtil.ALMOST_GUARANTEED_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.ALMOST_GUARANTEED)) .build() )); this.registerable.register(ItemKeys.WARPED_WART_BLOCK, create( @@ -7143,7 +7302,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.WARPED_WART_BLOCK))) - .with(CompostableItemComponent.of(ComposterBlockUtil.ALMOST_GUARANTEED_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.ALMOST_GUARANTEED)) .build() )); this.registerable.register(ItemKeys.HAY_BLOCK, create( @@ -7151,7 +7310,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.HAY_BLOCK))) - .with(CompostableItemComponent.of(ComposterBlockUtil.ALMOST_GUARANTEED_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.ALMOST_GUARANTEED)) .build() )); this.registerable.register(ItemKeys.FLOWERING_AZALEA, create( @@ -7159,8 +7318,8 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.FLOWERING_AZALEA))) - .with(CompostableItemComponent.of(ComposterBlockUtil.ALMOST_GUARANTEED_TO_COMPOST)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.PLANT_FUEL_TIME)) + .with(CompostableItemComponent.of(CompostChances.ALMOST_GUARANTEED)) + .with(FuelItemComponent.of(FuelTimes.PLANT)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_FLOWERING_AZALEA_BUSH)) @@ -7171,7 +7330,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.TORCHFLOWER))) - .with(CompostableItemComponent.of(ComposterBlockUtil.ALMOST_GUARANTEED_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.ALMOST_GUARANTEED)) .with(SuspiciousEffectIngredientItemComponent.of( new SuspiciousStewEffectsComponent.StewEffect(this.statusEffects.getOrThrow(StatusEffectKeys.NIGHT_VISION), 100) )) @@ -7185,7 +7344,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PITCHER_PLANT))) - .with(CompostableItemComponent.of(ComposterBlockUtil.ALMOST_GUARANTEED_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.ALMOST_GUARANTEED)) .build() )); this.registerable.register(ItemKeys.BROWN_MUSHROOM_BLOCK, create( @@ -7193,7 +7352,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BROWN_MUSHROOM_BLOCK))) - .with(CompostableItemComponent.of(ComposterBlockUtil.ALMOST_GUARANTEED_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.ALMOST_GUARANTEED)) .build() )); this.registerable.register(ItemKeys.RED_MUSHROOM_BLOCK, create( @@ -7201,7 +7360,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.RED_MUSHROOM_BLOCK))) - .with(CompostableItemComponent.of(ComposterBlockUtil.ALMOST_GUARANTEED_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.ALMOST_GUARANTEED)) .build() )); this.registerable.register(ItemKeys.CAKE, create( @@ -7209,7 +7368,7 @@ private void bootstrapCompostables() { ItemComponentSet.builder() .with(StackableItemComponent.of(1)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CAKE))) - .with(CompostableItemComponent.of(ComposterBlockUtil.GUARANTEED_TO_COMPOST)) + .with(CompostableItemComponent.of(CompostChances.GUARANTEED)) .build() )); } @@ -7225,13 +7384,17 @@ private void bootstrapEquipment() { .with(StackableItemComponent.of(1)) .with(DamageableItemComponent.ofPreserved(432)) .with(GliderItemComponent.of(ItemPredicate.Builder.create() - .subPredicate(ItemSubPredicateTypes.DAMAGE, DamagePredicate.durability( - NumberRange.IntRange.atLeast(2))) - .build())) + .components(ComponentsPredicate.Builder.create() + .partial( + ComponentPredicateTypes.DAMAGE, + DamagePredicate.durability(NumberRange.IntRange.atLeast(2)) + ).build() + ).build() + )) .with(EquipmentItemComponent.of(EquippableComponent.builder(EquipmentSlot.CHEST) .swappable(true) .equipSound(this.soundEvents.getOrThrow(SoundEventKeys.ARMOR_EQUIP_ELYTRA)) - .model(EquipmentModels.ELYTRA) + .model(EquipmentAssetKeys.ELYTRA) .build())) .with(RepairableItemComponent.of(RegistryEntryList.of( this.items.getOrThrow(ItemKeys.PHANTOM_MEMBRANE) @@ -7246,12 +7409,25 @@ private void bootstrapEquipment() { .with(UseableItemComponent.builder() .useIndefinitely() .animation(UseAction.BLOCK) - .build()) + .build() + ) .with(DamageableItemComponent.of(336)) + .with(AttackBlockingItemComponent.of(new BlocksAttacksComponent( + 0.25f, + 1.0f, + List.of( + new BlocksAttacksComponent.DamageReduction(90.0f, Optional.empty(), 0.0f, 1.0f) + ), + new BlocksAttacksComponent.ItemDamage(3.0f, 1.0f, 1.0f), + Optional.of(DamageTypeTags.BYPASSES_SHIELD), + Optional.of(this.soundEvents.getOrThrow(SoundEventKeys.SHIELD_BLOCK)), + Optional.of(this.soundEvents.getOrThrow(SoundEventKeys.SHIELD_BREAK)) + ))) .with(EquipmentItemComponent.of(EquippableComponent.builder(EquipmentSlot.OFFHAND) .equipSound(this.soundEvents.getOrThrow(SoundEventKeys.ARMOR_EQUIP_GENERIC)) .swappable(false) - .build())) + .build() + )) .with(RepairableItemComponent.of(this.items.getOrThrow(ItemTags.WOODEN_TOOL_MATERIALS))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .with(BannerPatternHolderItemComponent.of()) @@ -7262,59 +7438,55 @@ private void bootstrapEquipment() { private void bootstrapArmor() { this.registerable.register(ItemKeys.LEATHER_HELMET, create( ItemDisplay.Builder.forItem(ItemKeys.LEATHER_HELMET).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.LEATHER, EquipmentType.HELMET), + AttributeModifiers.armor(ArmorMaterials.LEATHER, EquipmentType.HELMET), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.LEATHER, EquipmentType.HELMET)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.LEATHER, EquipmentType.HELMET)) .with(EnchantableItemComponent.of(ArmorMaterials.LEATHER)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_LEATHER_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .with(DyeableItemComponent.of()) - .with(TintedItemComponent.of(DyeableItemColor.of(0))) .build() )); this.registerable.register(ItemKeys.LEATHER_CHESTPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.LEATHER_CHESTPLATE).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.LEATHER, EquipmentType.CHESTPLATE), + AttributeModifiers.armor(ArmorMaterials.LEATHER, EquipmentType.CHESTPLATE), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.LEATHER, EquipmentType.CHESTPLATE)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.LEATHER, EquipmentType.CHESTPLATE)) .with(EnchantableItemComponent.of(ArmorMaterials.LEATHER)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_LEATHER_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .with(DyeableItemComponent.of()) - .with(TintedItemComponent.of(DyeableItemColor.of(0))) .build() )); this.registerable.register(ItemKeys.LEATHER_LEGGINGS, create( ItemDisplay.Builder.forItem(ItemKeys.LEATHER_LEGGINGS).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.LEATHER, EquipmentType.LEGGINGS), + AttributeModifiers.armor(ArmorMaterials.LEATHER, EquipmentType.LEGGINGS), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.LEATHER, EquipmentType.LEGGINGS)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.LEATHER, EquipmentType.LEGGINGS)) .with(EnchantableItemComponent.of(ArmorMaterials.LEATHER)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_LEATHER_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .with(DyeableItemComponent.of()) - .with(TintedItemComponent.of(DyeableItemColor.of(0))) .build() )); this.registerable.register(ItemKeys.LEATHER_BOOTS, create( ItemDisplay.Builder.forItem(ItemKeys.LEATHER_BOOTS).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.LEATHER, EquipmentType.BOOTS), + AttributeModifiers.armor(ArmorMaterials.LEATHER, EquipmentType.BOOTS), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.LEATHER, EquipmentType.BOOTS)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.LEATHER, EquipmentType.BOOTS)) .with(EnchantableItemComponent.of(ArmorMaterials.LEATHER)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_LEATHER_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .with(DyeableItemComponent.of()) - .with(TintedItemComponent.of(DyeableItemColor.of(0))) .build() )); this.registerable.register(ItemKeys.CHAINMAIL_HELMET, create( ItemDisplay.Builder.forItem(ItemKeys.CHAINMAIL_HELMET) .rarity(Rarity.UNCOMMON) .build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.CHAIN, EquipmentType.HELMET), + AttributeModifiers.armor(ArmorMaterials.CHAIN, EquipmentType.HELMET), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.CHAIN, EquipmentType.HELMET)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.CHAIN, EquipmentType.HELMET)) .with(EnchantableItemComponent.of(ArmorMaterials.CHAIN)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_CHAINMAIL_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) @@ -7324,9 +7496,9 @@ private void bootstrapArmor() { ItemDisplay.Builder.forItem(ItemKeys.CHAINMAIL_CHESTPLATE) .rarity(Rarity.UNCOMMON) .build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.CHAIN, EquipmentType.CHESTPLATE), + AttributeModifiers.armor(ArmorMaterials.CHAIN, EquipmentType.CHESTPLATE), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.CHAIN, EquipmentType.CHESTPLATE)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.CHAIN, EquipmentType.CHESTPLATE)) .with(EnchantableItemComponent.of(ArmorMaterials.CHAIN)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_CHAINMAIL_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) @@ -7336,9 +7508,9 @@ private void bootstrapArmor() { ItemDisplay.Builder.forItem(ItemKeys.CHAINMAIL_LEGGINGS) .rarity(Rarity.UNCOMMON) .build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.CHAIN, EquipmentType.LEGGINGS), + AttributeModifiers.armor(ArmorMaterials.CHAIN, EquipmentType.LEGGINGS), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.CHAIN, EquipmentType.LEGGINGS)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.CHAIN, EquipmentType.LEGGINGS)) .with(EnchantableItemComponent.of(ArmorMaterials.CHAIN)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_CHAINMAIL_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) @@ -7348,9 +7520,9 @@ private void bootstrapArmor() { ItemDisplay.Builder.forItem(ItemKeys.CHAINMAIL_BOOTS) .rarity(Rarity.UNCOMMON) .build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.CHAIN, EquipmentType.BOOTS), + AttributeModifiers.armor(ArmorMaterials.CHAIN, EquipmentType.BOOTS), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.CHAIN, EquipmentType.BOOTS)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.CHAIN, EquipmentType.BOOTS)) .with(EnchantableItemComponent.of(ArmorMaterials.CHAIN)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_CHAINMAIL_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) @@ -7358,9 +7530,9 @@ private void bootstrapArmor() { )); this.registerable.register(ItemKeys.IRON_HELMET, create( ItemDisplay.Builder.forItem(ItemKeys.IRON_HELMET).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.IRON, EquipmentType.HELMET), + AttributeModifiers.armor(ArmorMaterials.IRON, EquipmentType.HELMET), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.IRON, EquipmentType.HELMET)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.IRON, EquipmentType.HELMET)) .with(EnchantableItemComponent.of(ArmorMaterials.IRON)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_IRON_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) @@ -7368,9 +7540,9 @@ private void bootstrapArmor() { )); this.registerable.register(ItemKeys.IRON_CHESTPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.IRON_CHESTPLATE).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.IRON, EquipmentType.CHESTPLATE), + AttributeModifiers.armor(ArmorMaterials.IRON, EquipmentType.CHESTPLATE), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.IRON, EquipmentType.CHESTPLATE)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.IRON, EquipmentType.CHESTPLATE)) .with(EnchantableItemComponent.of(ArmorMaterials.IRON)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_IRON_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) @@ -7378,9 +7550,9 @@ private void bootstrapArmor() { )); this.registerable.register(ItemKeys.IRON_LEGGINGS, create( ItemDisplay.Builder.forItem(ItemKeys.IRON_LEGGINGS).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.IRON, EquipmentType.LEGGINGS), + AttributeModifiers.armor(ArmorMaterials.IRON, EquipmentType.LEGGINGS), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.IRON, EquipmentType.LEGGINGS)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.IRON, EquipmentType.LEGGINGS)) .with(EnchantableItemComponent.of(ArmorMaterials.IRON)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_IRON_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) @@ -7388,9 +7560,9 @@ private void bootstrapArmor() { )); this.registerable.register(ItemKeys.IRON_BOOTS, create( ItemDisplay.Builder.forItem(ItemKeys.IRON_BOOTS).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.IRON, EquipmentType.BOOTS), + AttributeModifiers.armor(ArmorMaterials.IRON, EquipmentType.BOOTS), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.IRON, EquipmentType.BOOTS)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.IRON, EquipmentType.BOOTS)) .with(EnchantableItemComponent.of(ArmorMaterials.IRON)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_IRON_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) @@ -7398,9 +7570,9 @@ private void bootstrapArmor() { )); this.registerable.register(ItemKeys.DIAMOND_HELMET, create( ItemDisplay.Builder.forItem(ItemKeys.DIAMOND_HELMET).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.DIAMOND, EquipmentType.HELMET), + AttributeModifiers.armor(ArmorMaterials.DIAMOND, EquipmentType.HELMET), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.DIAMOND, EquipmentType.HELMET)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.DIAMOND, EquipmentType.HELMET)) .with(EnchantableItemComponent.of(ArmorMaterials.DIAMOND)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_DIAMOND_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) @@ -7408,9 +7580,9 @@ private void bootstrapArmor() { )); this.registerable.register(ItemKeys.DIAMOND_CHESTPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.DIAMOND_CHESTPLATE).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.DIAMOND, EquipmentType.CHESTPLATE), + AttributeModifiers.armor(ArmorMaterials.DIAMOND, EquipmentType.CHESTPLATE), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.DIAMOND, EquipmentType.CHESTPLATE)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.DIAMOND, EquipmentType.CHESTPLATE)) .with(EnchantableItemComponent.of(ArmorMaterials.DIAMOND)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_DIAMOND_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) @@ -7418,9 +7590,9 @@ private void bootstrapArmor() { )); this.registerable.register(ItemKeys.DIAMOND_LEGGINGS, create( ItemDisplay.Builder.forItem(ItemKeys.DIAMOND_LEGGINGS).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.DIAMOND, EquipmentType.LEGGINGS), + AttributeModifiers.armor(ArmorMaterials.DIAMOND, EquipmentType.LEGGINGS), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.DIAMOND, EquipmentType.LEGGINGS)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.DIAMOND, EquipmentType.LEGGINGS)) .with(EnchantableItemComponent.of(ArmorMaterials.DIAMOND)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_DIAMOND_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) @@ -7428,9 +7600,9 @@ private void bootstrapArmor() { )); this.registerable.register(ItemKeys.DIAMOND_BOOTS, create( ItemDisplay.Builder.forItem(ItemKeys.DIAMOND_BOOTS).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.DIAMOND, EquipmentType.BOOTS), + AttributeModifiers.armor(ArmorMaterials.DIAMOND, EquipmentType.BOOTS), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.DIAMOND, EquipmentType.BOOTS)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.DIAMOND, EquipmentType.BOOTS)) .with(EnchantableItemComponent.of(ArmorMaterials.DIAMOND)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_DIAMOND_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) @@ -7438,9 +7610,9 @@ private void bootstrapArmor() { )); this.registerable.register(ItemKeys.GOLDEN_HELMET, create( ItemDisplay.Builder.forItem(ItemKeys.GOLDEN_HELMET).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.GOLD, EquipmentType.HELMET), + AttributeModifiers.armor(ArmorMaterials.GOLD, EquipmentType.HELMET), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.GOLD, EquipmentType.HELMET)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.GOLD, EquipmentType.HELMET)) .with(EnchantableItemComponent.of(ArmorMaterials.GOLD)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_GOLDEN_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) @@ -7448,9 +7620,9 @@ private void bootstrapArmor() { )); this.registerable.register(ItemKeys.GOLDEN_CHESTPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.GOLDEN_CHESTPLATE).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.GOLD, EquipmentType.CHESTPLATE), + AttributeModifiers.armor(ArmorMaterials.GOLD, EquipmentType.CHESTPLATE), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.GOLD, EquipmentType.CHESTPLATE)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.GOLD, EquipmentType.CHESTPLATE)) .with(EnchantableItemComponent.of(ArmorMaterials.GOLD)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_GOLDEN_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) @@ -7458,9 +7630,9 @@ private void bootstrapArmor() { )); this.registerable.register(ItemKeys.GOLDEN_LEGGINGS, create( ItemDisplay.Builder.forItem(ItemKeys.GOLDEN_LEGGINGS).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.GOLD, EquipmentType.LEGGINGS), + AttributeModifiers.armor(ArmorMaterials.GOLD, EquipmentType.LEGGINGS), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.GOLD, EquipmentType.LEGGINGS)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.GOLD, EquipmentType.LEGGINGS)) .with(EnchantableItemComponent.of(ArmorMaterials.GOLD)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_GOLDEN_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) @@ -7468,9 +7640,9 @@ private void bootstrapArmor() { )); this.registerable.register(ItemKeys.GOLDEN_BOOTS, create( ItemDisplay.Builder.forItem(ItemKeys.GOLDEN_BOOTS).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.GOLD, EquipmentType.BOOTS), + AttributeModifiers.armor(ArmorMaterials.GOLD, EquipmentType.BOOTS), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.GOLD, EquipmentType.BOOTS)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.GOLD, EquipmentType.BOOTS)) .with(EnchantableItemComponent.of(ArmorMaterials.GOLD)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_GOLDEN_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) @@ -7478,9 +7650,9 @@ private void bootstrapArmor() { )); this.registerable.register(ItemKeys.NETHERITE_HELMET, create( ItemDisplay.Builder.forItem(ItemKeys.NETHERITE_HELMET).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.NETHERITE, EquipmentType.HELMET), + AttributeModifiers.armor(ArmorMaterials.NETHERITE, EquipmentType.HELMET), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.NETHERITE, EquipmentType.HELMET)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.NETHERITE, EquipmentType.HELMET)) .with(ImmuneToDamageItemComponent.of(DamageTypeTags.IS_FIRE)) .with(EnchantableItemComponent.of(ArmorMaterials.NETHERITE)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_NETHERITE_ARMOR))) @@ -7489,9 +7661,9 @@ private void bootstrapArmor() { )); this.registerable.register(ItemKeys.NETHERITE_CHESTPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.NETHERITE_CHESTPLATE).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.NETHERITE, EquipmentType.CHESTPLATE), + AttributeModifiers.armor(ArmorMaterials.NETHERITE, EquipmentType.CHESTPLATE), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.NETHERITE, EquipmentType.CHESTPLATE)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.NETHERITE, EquipmentType.CHESTPLATE)) .with(ImmuneToDamageItemComponent.of(DamageTypeTags.IS_FIRE)) .with(EnchantableItemComponent.of(ArmorMaterials.NETHERITE)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_NETHERITE_ARMOR))) @@ -7500,9 +7672,9 @@ private void bootstrapArmor() { )); this.registerable.register(ItemKeys.NETHERITE_LEGGINGS, create( ItemDisplay.Builder.forItem(ItemKeys.NETHERITE_LEGGINGS).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.NETHERITE, EquipmentType.LEGGINGS), + AttributeModifiers.armor(ArmorMaterials.NETHERITE, EquipmentType.LEGGINGS), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.NETHERITE, EquipmentType.LEGGINGS)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.NETHERITE, EquipmentType.LEGGINGS)) .with(ImmuneToDamageItemComponent.of(DamageTypeTags.IS_FIRE)) .with(EnchantableItemComponent.of(ArmorMaterials.NETHERITE)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_NETHERITE_ARMOR))) @@ -7511,9 +7683,9 @@ private void bootstrapArmor() { )); this.registerable.register(ItemKeys.NETHERITE_BOOTS, create( ItemDisplay.Builder.forItem(ItemKeys.NETHERITE_BOOTS).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.NETHERITE, EquipmentType.BOOTS), + AttributeModifiers.armor(ArmorMaterials.NETHERITE, EquipmentType.BOOTS), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.NETHERITE, EquipmentType.BOOTS)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.NETHERITE, EquipmentType.BOOTS)) .with(ImmuneToDamageItemComponent.of(DamageTypeTags.IS_FIRE)) .with(EnchantableItemComponent.of(ArmorMaterials.NETHERITE)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_NETHERITE_ARMOR))) @@ -7522,9 +7694,9 @@ private void bootstrapArmor() { )); this.registerable.register(ItemKeys.TURTLE_HELMET, create( ItemDisplay.Builder.forItem(ItemKeys.TURTLE_HELMET).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.TURTLE_SCUTE, EquipmentType.HELMET), + AttributeModifiers.armor(ArmorMaterials.TURTLE_SCUTE, EquipmentType.HELMET), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.TURTLE_SCUTE, EquipmentType.HELMET)) + .with(EquipmentItemComponent.forArmor(ArmorMaterials.TURTLE_SCUTE, EquipmentType.HELMET)) .with(EnchantableItemComponent.of(ArmorMaterials.TURTLE_SCUTE)) .with(RepairableItemComponent.of(this.items.getOrThrow(ItematicItemTags.REPAIRS_TURTLE_ARMOR))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) @@ -7532,45 +7704,62 @@ private void bootstrapArmor() { )); this.registerable.register(ItemKeys.LEATHER_HORSE_ARMOR, create( ItemDisplay.Builder.forItem(ItemKeys.LEATHER_HORSE_ARMOR).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.LEATHER, EquipmentType.BODY), + AttributeModifiers.armor(ArmorMaterials.LEATHER, EquipmentType.BODY), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.LEATHER, EquipmentType.BODY, AnimalArmorItem.Type.EQUESTRIAN)) + .with(StackableItemComponent.of(1)) + .with(EquipmentItemComponent.ofHorseArmor(ArmorMaterials.LEATHER, this.soundEvents, this.entityTypes)) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .with(DyeableItemComponent.of()) - .with(TintedItemComponent.of(DyeableItemColor.of(0))) .build() )); this.registerable.register(ItemKeys.IRON_HORSE_ARMOR, create( ItemDisplay.Builder.forItem(ItemKeys.IRON_HORSE_ARMOR).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.IRON, EquipmentType.BODY), + AttributeModifiers.armor(ArmorMaterials.IRON, EquipmentType.BODY), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.IRON, EquipmentType.BODY, AnimalArmorItem.Type.EQUESTRIAN)) + .with(StackableItemComponent.of(1)) + .with(EquipmentItemComponent.ofHorseArmor(ArmorMaterials.IRON, this.soundEvents, this.entityTypes)) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() )); this.registerable.register(ItemKeys.GOLDEN_HORSE_ARMOR, create( ItemDisplay.Builder.forItem(ItemKeys.GOLDEN_HORSE_ARMOR).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.GOLD, EquipmentType.BODY), + AttributeModifiers.armor(ArmorMaterials.GOLD, EquipmentType.BODY), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.GOLD, EquipmentType.BODY, AnimalArmorItem.Type.EQUESTRIAN)) + .with(StackableItemComponent.of(1)) + .with(EquipmentItemComponent.ofHorseArmor(ArmorMaterials.GOLD, this.soundEvents, this.entityTypes)) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() )); this.registerable.register(ItemKeys.DIAMOND_HORSE_ARMOR, create( ItemDisplay.Builder.forItem(ItemKeys.DIAMOND_HORSE_ARMOR).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.DIAMOND, EquipmentType.BODY), + AttributeModifiers.armor(ArmorMaterials.DIAMOND, EquipmentType.BODY), ItemComponentSet.builder() - .with(EquipmentItemComponent.from(ArmorMaterials.DIAMOND, EquipmentType.BODY, AnimalArmorItem.Type.EQUESTRIAN)) + .with(StackableItemComponent.of(1)) + .with(EquipmentItemComponent.ofHorseArmor(ArmorMaterials.DIAMOND, this.soundEvents, this.entityTypes)) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() )); this.registerable.register(ItemKeys.WOLF_ARMOR, create( ItemDisplay.Builder.forItem(ItemKeys.WOLF_ARMOR).build(), - AttributeModifiersComponentUtil.armor(ArmorMaterials.ARMADILLO_SCUTE, EquipmentType.BODY), + AttributeModifiers.armor(ArmorMaterials.ARMADILLO_SCUTE, EquipmentType.BODY), ItemComponentSet.builder() - .with(EquipmentItemComponent.fromDamageable(ArmorMaterials.ARMADILLO_SCUTE, EquipmentType.BODY, AnimalArmorItem.Type.CANINE)) + .with(StackableItemComponent.of(1)) + .with(DamageableItemComponent.of( + EquipmentType.BODY.getMaxDamage(ArmorMaterials.ARMADILLO_SCUTE.durability()), + this.soundEvents.getOrThrow(SoundEventKeys.WOLF_ARMOR_BREAK) + )) + .with(RepairableItemComponent.of( + this.items.getOrThrow(ArmorMaterials.ARMADILLO_SCUTE.repairIngredient()) + )) + .with(EquipmentItemComponent.of(EquippableComponent.builder(EquipmentSlot.BODY) + .equipSound(ArmorMaterials.ARMADILLO_SCUTE.equipSound()) + .model(ArmorMaterials.ARMADILLO_SCUTE.assetId()) + .allowedEntities(RegistryEntryList.of( + this.entityTypes.getOrThrow(EntityTypeKeys.WOLF) + )) + .build() + )) .with(DyeableItemComponent.of(0x000000)) - .with(TintedItemComponent.of(DyeableItemColor.of(1))) .build() )); } @@ -7582,7 +7771,7 @@ private void bootstrapSkulls() { .build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(EquipmentItemComponent.skull( + .with(EquipmentItemComponent.forSkull( this.blocks.getOrThrow(BlockKeys.SKELETON_SKULL), this.blocks.getOrThrow(BlockKeys.SKELETON_WALL_SKULL), this.dispenseBehaviors @@ -7595,7 +7784,7 @@ private void bootstrapSkulls() { .build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(EquipmentItemComponent.skull( + .with(EquipmentItemComponent.forSkull( this.blocks.getOrThrow(BlockKeys.WITHER_SKELETON_SKULL), this.blocks.getOrThrow(BlockKeys.WITHER_SKELETON_WALL_SKULL), this.dispenseBehaviors @@ -7608,7 +7797,7 @@ private void bootstrapSkulls() { .build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(EquipmentItemComponent.skull( + .with(EquipmentItemComponent.forSkull( this.blocks.getOrThrow(BlockKeys.PLAYER_HEAD), this.blocks.getOrThrow(BlockKeys.PLAYER_WALL_HEAD), this.dispenseBehaviors @@ -7621,7 +7810,7 @@ private void bootstrapSkulls() { .build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(EquipmentItemComponent.skull( + .with(EquipmentItemComponent.forSkull( this.blocks.getOrThrow(BlockKeys.ZOMBIE_HEAD), this.blocks.getOrThrow(BlockKeys.ZOMBIE_WALL_HEAD), this.dispenseBehaviors @@ -7634,7 +7823,7 @@ private void bootstrapSkulls() { .build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(EquipmentItemComponent.skull( + .with(EquipmentItemComponent.forSkull( this.blocks.getOrThrow(BlockKeys.CREEPER_HEAD), this.blocks.getOrThrow(BlockKeys.CREEPER_WALL_HEAD), this.dispenseBehaviors @@ -7647,7 +7836,7 @@ private void bootstrapSkulls() { .build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(EquipmentItemComponent.skull( + .with(EquipmentItemComponent.forSkull( this.blocks.getOrThrow(BlockKeys.DRAGON_HEAD), this.blocks.getOrThrow(BlockKeys.DRAGON_WALL_HEAD), this.dispenseBehaviors @@ -7660,7 +7849,7 @@ private void bootstrapSkulls() { .build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(EquipmentItemComponent.skull( + .with(EquipmentItemComponent.forSkull( this.blocks.getOrThrow(BlockKeys.PIGLIN_HEAD), this.blocks.getOrThrow(BlockKeys.PIGLIN_WALL_HEAD), this.dispenseBehaviors @@ -7675,28 +7864,28 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.COAL_BLOCK))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.COAL_BLOCK_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.COAL_BLOCK)) .build() )); this.registerable.register(ItemKeys.BLAZE_ROD, create( ItemDisplay.Builder.forItem(ItemKeys.BLAZE_ROD).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BLAZE_ROD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.BLAZE_ROD)) .build() )); this.registerable.register(ItemKeys.COAL, create( ItemDisplay.Builder.forItem(ItemKeys.COAL).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.COAL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.COAL)) .build() )); this.registerable.register(ItemKeys.CHARCOAL, create( ItemDisplay.Builder.forItem(ItemKeys.CHARCOAL).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.COAL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.COAL)) .build() )); this.registerable.register(ItemKeys.OAK_HANGING_SIGN, create( @@ -7704,7 +7893,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.OAK_HANGING_SIGN), this.blocks.getOrThrow(BlockKeys.OAK_WALL_HANGING_SIGN), Direction.UP)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.HANGING_SIGN_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.HANGING_SIGN)) .build() )); this.registerable.register(ItemKeys.SPRUCE_HANGING_SIGN, create( @@ -7712,7 +7901,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.SPRUCE_HANGING_SIGN), this.blocks.getOrThrow(BlockKeys.SPRUCE_WALL_HANGING_SIGN), Direction.UP)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.HANGING_SIGN_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.HANGING_SIGN)) .build() )); this.registerable.register(ItemKeys.BIRCH_HANGING_SIGN, create( @@ -7720,7 +7909,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.BIRCH_HANGING_SIGN), this.blocks.getOrThrow(BlockKeys.BIRCH_WALL_HANGING_SIGN), Direction.UP)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.HANGING_SIGN_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.HANGING_SIGN)) .build() )); this.registerable.register(ItemKeys.JUNGLE_HANGING_SIGN, create( @@ -7728,7 +7917,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.JUNGLE_HANGING_SIGN), this.blocks.getOrThrow(BlockKeys.JUNGLE_WALL_HANGING_SIGN), Direction.UP)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.HANGING_SIGN_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.HANGING_SIGN)) .build() )); this.registerable.register(ItemKeys.ACACIA_HANGING_SIGN, create( @@ -7736,7 +7925,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.ACACIA_HANGING_SIGN), this.blocks.getOrThrow(BlockKeys.ACACIA_WALL_HANGING_SIGN), Direction.UP)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.HANGING_SIGN_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.HANGING_SIGN)) .build() )); this.registerable.register(ItemKeys.CHERRY_HANGING_SIGN, create( @@ -7744,7 +7933,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.CHERRY_HANGING_SIGN), this.blocks.getOrThrow(BlockKeys.CHERRY_WALL_HANGING_SIGN), Direction.UP)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.HANGING_SIGN_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.HANGING_SIGN)) .build() )); this.registerable.register(ItemKeys.DARK_OAK_HANGING_SIGN, create( @@ -7752,7 +7941,15 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.DARK_OAK_HANGING_SIGN), this.blocks.getOrThrow(BlockKeys.DARK_OAK_WALL_HANGING_SIGN), Direction.UP)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.HANGING_SIGN_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.HANGING_SIGN)) + .build() + )); + this.registerable.register(ItemKeys.PALE_OAK_HANGING_SIGN, create( + ItemDisplay.Builder.forBlock(ItemKeys.PALE_OAK_HANGING_SIGN).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(16)) + .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.PALE_OAK_HANGING_SIGN), this.blocks.getOrThrow(BlockKeys.PALE_OAK_WALL_HANGING_SIGN), Direction.UP)) + .with(FuelItemComponent.of(FuelTimes.HANGING_SIGN)) .build() )); this.registerable.register(ItemKeys.MANGROVE_HANGING_SIGN, create( @@ -7760,7 +7957,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.MANGROVE_HANGING_SIGN), this.blocks.getOrThrow(BlockKeys.MANGROVE_WALL_HANGING_SIGN), Direction.UP)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.HANGING_SIGN_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.HANGING_SIGN)) .build() )); this.registerable.register(ItemKeys.BAMBOO_HANGING_SIGN, create( @@ -7768,7 +7965,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.BAMBOO_HANGING_SIGN), this.blocks.getOrThrow(BlockKeys.BAMBOO_WALL_HANGING_SIGN), Direction.UP)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.HANGING_SIGN_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.HANGING_SIGN)) .build() )); this.registerable.register(ItemKeys.OAK_SIGN, create( @@ -7776,7 +7973,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.OAK_SIGN), this.blocks.getOrThrow(BlockKeys.OAK_WALL_SIGN), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SIGN_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SIGN)) .build() )); this.registerable.register(ItemKeys.SPRUCE_SIGN, create( @@ -7784,7 +7981,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.SPRUCE_SIGN), this.blocks.getOrThrow(BlockKeys.SPRUCE_WALL_SIGN), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SIGN_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SIGN)) .build() )); this.registerable.register(ItemKeys.BIRCH_SIGN, create( @@ -7792,7 +7989,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.BIRCH_SIGN), this.blocks.getOrThrow(BlockKeys.BIRCH_WALL_SIGN), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SIGN_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SIGN)) .build() )); this.registerable.register(ItemKeys.JUNGLE_SIGN, create( @@ -7800,7 +7997,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.JUNGLE_SIGN), this.blocks.getOrThrow(BlockKeys.JUNGLE_WALL_SIGN), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SIGN_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SIGN)) .build() )); this.registerable.register(ItemKeys.ACACIA_SIGN, create( @@ -7808,7 +8005,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.ACACIA_SIGN), this.blocks.getOrThrow(BlockKeys.ACACIA_WALL_SIGN), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SIGN_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SIGN)) .build() )); this.registerable.register(ItemKeys.CHERRY_SIGN, create( @@ -7816,7 +8013,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.CHERRY_SIGN), this.blocks.getOrThrow(BlockKeys.CHERRY_WALL_SIGN), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SIGN_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SIGN)) .build() )); this.registerable.register(ItemKeys.DARK_OAK_SIGN, create( @@ -7824,7 +8021,15 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.DARK_OAK_SIGN), this.blocks.getOrThrow(BlockKeys.DARK_OAK_WALL_SIGN), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SIGN_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SIGN)) + .build() + )); + this.registerable.register(ItemKeys.PALE_OAK_SIGN, create( + ItemDisplay.Builder.forBlock(ItemKeys.PALE_OAK_SIGN).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(16)) + .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.PALE_OAK_SIGN), this.blocks.getOrThrow(BlockKeys.PALE_OAK_WALL_SIGN), Direction.DOWN)) + .with(FuelItemComponent.of(FuelTimes.SIGN)) .build() )); this.registerable.register(ItemKeys.MANGROVE_SIGN, create( @@ -7832,7 +8037,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.MANGROVE_SIGN), this.blocks.getOrThrow(BlockKeys.MANGROVE_WALL_SIGN), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SIGN_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SIGN)) .build() )); this.registerable.register(ItemKeys.BAMBOO_SIGN, create( @@ -7840,7 +8045,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.BAMBOO_SIGN), this.blocks.getOrThrow(BlockKeys.BAMBOO_WALL_SIGN), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SIGN_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SIGN)) .build() )); this.registerable.register(ItemKeys.OAK_PLANKS, create( @@ -7848,7 +8053,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.OAK_PLANKS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.SPRUCE_PLANKS, create( @@ -7856,7 +8061,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SPRUCE_PLANKS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BIRCH_PLANKS, create( @@ -7864,7 +8069,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BIRCH_PLANKS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.JUNGLE_PLANKS, create( @@ -7872,7 +8077,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.JUNGLE_PLANKS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.ACACIA_PLANKS, create( @@ -7880,7 +8085,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.ACACIA_PLANKS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.CHERRY_PLANKS, create( @@ -7888,7 +8093,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CHERRY_PLANKS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.DARK_OAK_PLANKS, create( @@ -7896,7 +8101,15 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.DARK_OAK_PLANKS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) + .build() + )); + this.registerable.register(ItemKeys.PALE_OAK_PLANKS, create( + ItemDisplay.Builder.forBlock(ItemKeys.PALE_OAK_PLANKS).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PALE_OAK_PLANKS))) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.MANGROVE_PLANKS, create( @@ -7904,7 +8117,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MANGROVE_PLANKS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BAMBOO_PLANKS, create( @@ -7912,7 +8125,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BAMBOO_PLANKS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BAMBOO_MOSAIC, create( @@ -7920,7 +8133,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BAMBOO_MOSAIC))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.OAK_LOG, create( @@ -7928,7 +8141,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.OAK_LOG))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.SPRUCE_LOG, create( @@ -7936,7 +8149,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SPRUCE_LOG))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BIRCH_LOG, create( @@ -7944,7 +8157,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BIRCH_LOG))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.JUNGLE_LOG, create( @@ -7952,7 +8165,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.JUNGLE_LOG))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.ACACIA_LOG, create( @@ -7960,7 +8173,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.ACACIA_LOG))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.CHERRY_LOG, create( @@ -7968,7 +8181,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CHERRY_LOG))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.DARK_OAK_LOG, create( @@ -7976,7 +8189,15 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.DARK_OAK_LOG))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) + .build() + )); + this.registerable.register(ItemKeys.PALE_OAK_LOG, create( + ItemDisplay.Builder.forBlock(ItemKeys.PALE_OAK_LOG).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PALE_OAK_LOG))) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.MANGROVE_LOG, create( @@ -7984,7 +8205,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MANGROVE_LOG))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BAMBOO_BLOCK, create( @@ -7992,7 +8213,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BAMBOO_BLOCK))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.STRIPPED_OAK_LOG, create( @@ -8000,7 +8221,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_OAK_LOG))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.STRIPPED_SPRUCE_LOG, create( @@ -8008,7 +8229,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_SPRUCE_LOG))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.STRIPPED_BIRCH_LOG, create( @@ -8016,7 +8237,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_BIRCH_LOG))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.STRIPPED_JUNGLE_LOG, create( @@ -8024,7 +8245,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_JUNGLE_LOG))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.STRIPPED_ACACIA_LOG, create( @@ -8032,7 +8253,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_ACACIA_LOG))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.STRIPPED_CHERRY_LOG, create( @@ -8040,7 +8261,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_CHERRY_LOG))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.STRIPPED_DARK_OAK_LOG, create( @@ -8048,7 +8269,15 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_DARK_OAK_LOG))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) + .build() + )); + this.registerable.register(ItemKeys.STRIPPED_PALE_OAK_LOG, create( + ItemDisplay.Builder.forBlock(ItemKeys.STRIPPED_PALE_OAK_LOG).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_PALE_OAK_LOG))) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.STRIPPED_MANGROVE_LOG, create( @@ -8056,7 +8285,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_MANGROVE_LOG))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.STRIPPED_OAK_WOOD, create( @@ -8064,7 +8293,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_OAK_WOOD))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.STRIPPED_SPRUCE_WOOD, create( @@ -8072,7 +8301,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_SPRUCE_WOOD))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.STRIPPED_BIRCH_WOOD, create( @@ -8080,7 +8309,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_BIRCH_WOOD))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.STRIPPED_JUNGLE_WOOD, create( @@ -8088,7 +8317,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_JUNGLE_WOOD))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.STRIPPED_ACACIA_WOOD, create( @@ -8096,7 +8325,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_ACACIA_WOOD))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.STRIPPED_CHERRY_WOOD, create( @@ -8104,7 +8333,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_CHERRY_WOOD))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.STRIPPED_DARK_OAK_WOOD, create( @@ -8112,7 +8341,15 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_DARK_OAK_WOOD))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) + .build() + )); + this.registerable.register(ItemKeys.STRIPPED_PALE_OAK_WOOD, create( + ItemDisplay.Builder.forBlock(ItemKeys.STRIPPED_PALE_OAK_WOOD).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_PALE_OAK_WOOD))) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.STRIPPED_MANGROVE_WOOD, create( @@ -8120,7 +8357,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_MANGROVE_WOOD))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.STRIPPED_BAMBOO_BLOCK, create( @@ -8128,7 +8365,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.STRIPPED_BAMBOO_BLOCK))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.OAK_WOOD, create( @@ -8136,7 +8373,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.OAK_WOOD))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.SPRUCE_WOOD, create( @@ -8144,7 +8381,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SPRUCE_WOOD))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BIRCH_WOOD, create( @@ -8152,7 +8389,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BIRCH_WOOD))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.JUNGLE_WOOD, create( @@ -8160,7 +8397,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.JUNGLE_WOOD))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.ACACIA_WOOD, create( @@ -8168,7 +8405,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.ACACIA_WOOD))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.CHERRY_WOOD, create( @@ -8176,7 +8413,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CHERRY_WOOD))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.DARK_OAK_WOOD, create( @@ -8184,7 +8421,15 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.DARK_OAK_WOOD))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) + .build() + )); + this.registerable.register(ItemKeys.PALE_OAK_WOOD, create( + ItemDisplay.Builder.forBlock(ItemKeys.PALE_OAK_WOOD).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PALE_OAK_WOOD))) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.MANGROVE_WOOD, create( @@ -8192,7 +8437,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MANGROVE_WOOD))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.OAK_FENCE, create( @@ -8200,7 +8445,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.OAK_FENCE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.SPRUCE_FENCE, create( @@ -8208,7 +8453,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SPRUCE_FENCE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BIRCH_FENCE, create( @@ -8216,7 +8461,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BIRCH_FENCE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.JUNGLE_FENCE, create( @@ -8224,7 +8469,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.JUNGLE_FENCE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.ACACIA_FENCE, create( @@ -8232,7 +8477,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.ACACIA_FENCE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.CHERRY_FENCE, create( @@ -8240,7 +8485,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CHERRY_FENCE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.DARK_OAK_FENCE, create( @@ -8248,7 +8493,15 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.DARK_OAK_FENCE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) + .build() + )); + this.registerable.register(ItemKeys.PALE_OAK_FENCE, create( + ItemDisplay.Builder.forBlock(ItemKeys.PALE_OAK_FENCE).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PALE_OAK_FENCE))) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.MANGROVE_FENCE, create( @@ -8256,7 +8509,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MANGROVE_FENCE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BAMBOO_FENCE, create( @@ -8264,7 +8517,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BAMBOO_FENCE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.OAK_STAIRS, create( @@ -8272,7 +8525,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.OAK_STAIRS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.SPRUCE_STAIRS, create( @@ -8280,7 +8533,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SPRUCE_STAIRS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BIRCH_STAIRS, create( @@ -8288,7 +8541,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BIRCH_STAIRS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.JUNGLE_STAIRS, create( @@ -8296,7 +8549,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.JUNGLE_STAIRS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.ACACIA_STAIRS, create( @@ -8304,7 +8557,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.ACACIA_STAIRS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.CHERRY_STAIRS, create( @@ -8312,7 +8565,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CHERRY_STAIRS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.DARK_OAK_STAIRS, create( @@ -8320,7 +8573,15 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.DARK_OAK_STAIRS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) + .build() + )); + this.registerable.register(ItemKeys.PALE_OAK_STAIRS, create( + ItemDisplay.Builder.forBlock(ItemKeys.PALE_OAK_STAIRS).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PALE_OAK_STAIRS))) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.MANGROVE_STAIRS, create( @@ -8328,7 +8589,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MANGROVE_STAIRS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BAMBOO_STAIRS, create( @@ -8336,7 +8597,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BAMBOO_STAIRS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BAMBOO_MOSAIC_STAIRS, create( @@ -8344,7 +8605,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BAMBOO_MOSAIC_STAIRS))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.OAK_PRESSURE_PLATE, create( @@ -8352,7 +8613,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.OAK_PRESSURE_PLATE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.SPRUCE_PRESSURE_PLATE, create( @@ -8360,7 +8621,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SPRUCE_PRESSURE_PLATE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BIRCH_PRESSURE_PLATE, create( @@ -8368,7 +8629,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BIRCH_PRESSURE_PLATE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.JUNGLE_PRESSURE_PLATE, create( @@ -8376,7 +8637,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.JUNGLE_PRESSURE_PLATE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.ACACIA_PRESSURE_PLATE, create( @@ -8384,7 +8645,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.ACACIA_PRESSURE_PLATE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.CHERRY_PRESSURE_PLATE, create( @@ -8392,7 +8653,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CHERRY_PRESSURE_PLATE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.DARK_OAK_PRESSURE_PLATE, create( @@ -8400,7 +8661,15 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.DARK_OAK_PRESSURE_PLATE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) + .build() + )); + this.registerable.register(ItemKeys.PALE_OAK_PRESSURE_PLATE, create( + ItemDisplay.Builder.forBlock(ItemKeys.PALE_OAK_PRESSURE_PLATE).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PALE_OAK_PRESSURE_PLATE))) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.MANGROVE_PRESSURE_PLATE, create( @@ -8408,7 +8677,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MANGROVE_PRESSURE_PLATE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BAMBOO_PRESSURE_PLATE, create( @@ -8416,7 +8685,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BAMBOO_PRESSURE_PLATE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.OAK_TRAPDOOR, create( @@ -8424,7 +8693,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.OAK_TRAPDOOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.SPRUCE_TRAPDOOR, create( @@ -8432,7 +8701,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SPRUCE_TRAPDOOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BIRCH_TRAPDOOR, create( @@ -8440,7 +8709,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BIRCH_TRAPDOOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.JUNGLE_TRAPDOOR, create( @@ -8448,7 +8717,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.JUNGLE_TRAPDOOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.ACACIA_TRAPDOOR, create( @@ -8456,7 +8725,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.ACACIA_TRAPDOOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.CHERRY_TRAPDOOR, create( @@ -8464,7 +8733,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CHERRY_TRAPDOOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.DARK_OAK_TRAPDOOR, create( @@ -8472,7 +8741,15 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.DARK_OAK_TRAPDOOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) + .build() + )); + this.registerable.register(ItemKeys.PALE_OAK_TRAPDOOR, create( + ItemDisplay.Builder.forBlock(ItemKeys.PALE_OAK_TRAPDOOR).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PALE_OAK_TRAPDOOR))) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.MANGROVE_TRAPDOOR, create( @@ -8480,7 +8757,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MANGROVE_TRAPDOOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BAMBOO_TRAPDOOR, create( @@ -8488,7 +8765,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BAMBOO_TRAPDOOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.OAK_FENCE_GATE, create( @@ -8496,7 +8773,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.OAK_FENCE_GATE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.SPRUCE_FENCE_GATE, create( @@ -8504,7 +8781,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SPRUCE_FENCE_GATE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BIRCH_FENCE_GATE, create( @@ -8512,7 +8789,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BIRCH_FENCE_GATE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.JUNGLE_FENCE_GATE, create( @@ -8520,7 +8797,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.JUNGLE_FENCE_GATE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.ACACIA_FENCE_GATE, create( @@ -8528,7 +8805,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.ACACIA_FENCE_GATE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.CHERRY_FENCE_GATE, create( @@ -8536,7 +8813,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CHERRY_FENCE_GATE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.DARK_OAK_FENCE_GATE, create( @@ -8544,7 +8821,15 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.DARK_OAK_FENCE_GATE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) + .build() + )); + this.registerable.register(ItemKeys.PALE_OAK_FENCE_GATE, create( + ItemDisplay.Builder.forBlock(ItemKeys.PALE_OAK_FENCE_GATE).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PALE_OAK_FENCE_GATE))) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.MANGROVE_FENCE_GATE, create( @@ -8552,7 +8837,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MANGROVE_FENCE_GATE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BAMBOO_FENCE_GATE, create( @@ -8560,7 +8845,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BAMBOO_FENCE_GATE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BOOKSHELF, create( @@ -8568,7 +8853,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BOOKSHELF))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.CHISELED_BOOKSHELF, create( @@ -8576,7 +8861,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CHISELED_BOOKSHELF))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.LECTERN, create( @@ -8584,7 +8869,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.LECTERN))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.CHEST, create( @@ -8592,7 +8877,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CHEST))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_CHEST))) .build() )); @@ -8601,7 +8886,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.TRAPPED_CHEST))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.LADDER, create( @@ -8609,7 +8894,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.LADDER))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.CRAFTING_TABLE, create( @@ -8617,7 +8902,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CRAFTING_TABLE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.JUKEBOX, create( @@ -8625,7 +8910,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.JUKEBOX))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.NOTE_BLOCK, create( @@ -8633,7 +8918,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.NOTE_BLOCK))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.LOOM, create( @@ -8641,7 +8926,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.LOOM))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.COMPOSTER, create( @@ -8649,7 +8934,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.COMPOSTER))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.BARREL, create( @@ -8657,7 +8942,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BARREL))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.CARTOGRAPHY_TABLE, create( @@ -8665,7 +8950,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CARTOGRAPHY_TABLE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.FLETCHING_TABLE, create( @@ -8673,7 +8958,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.FLETCHING_TABLE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.SMITHING_TABLE, create( @@ -8681,7 +8966,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SMITHING_TABLE))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.DAYLIGHT_DETECTOR, create( @@ -8689,7 +8974,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.DAYLIGHT_DETECTOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .build() )); this.registerable.register(ItemKeys.OAK_DOOR, create( @@ -8697,7 +8982,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.OAK_DOOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.DOOR_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.DOOR)) .build() )); this.registerable.register(ItemKeys.SPRUCE_DOOR, create( @@ -8705,7 +8990,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SPRUCE_DOOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.DOOR_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.DOOR)) .build() )); this.registerable.register(ItemKeys.BIRCH_DOOR, create( @@ -8713,7 +8998,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BIRCH_DOOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.DOOR_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.DOOR)) .build() )); this.registerable.register(ItemKeys.JUNGLE_DOOR, create( @@ -8721,7 +9006,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.JUNGLE_DOOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.DOOR_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.DOOR)) .build() )); this.registerable.register(ItemKeys.ACACIA_DOOR, create( @@ -8729,7 +9014,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.ACACIA_DOOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.DOOR_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.DOOR)) .build() )); this.registerable.register(ItemKeys.CHERRY_DOOR, create( @@ -8737,7 +9022,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CHERRY_DOOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.DOOR_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.DOOR)) .build() )); this.registerable.register(ItemKeys.DARK_OAK_DOOR, create( @@ -8745,7 +9030,15 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.DARK_OAK_DOOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.DOOR_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.DOOR)) + .build() + )); + this.registerable.register(ItemKeys.PALE_OAK_DOOR, create( + ItemDisplay.Builder.forBlock(ItemKeys.PALE_OAK_DOOR).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PALE_OAK_DOOR))) + .with(FuelItemComponent.of(FuelTimes.DOOR)) .build() )); this.registerable.register(ItemKeys.MANGROVE_DOOR, create( @@ -8753,7 +9046,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MANGROVE_DOOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.DOOR_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.DOOR)) .build() )); this.registerable.register(ItemKeys.BAMBOO_DOOR, create( @@ -8761,7 +9054,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BAMBOO_DOOR))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.DOOR_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.DOOR)) .build() )); this.registerable.register(ItemKeys.OAK_SLAB, create( @@ -8769,7 +9062,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.OAK_SLAB))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SLAB_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SLAB)) .build() )); this.registerable.register(ItemKeys.SPRUCE_SLAB, create( @@ -8777,7 +9070,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SPRUCE_SLAB))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SLAB_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SLAB)) .build() )); this.registerable.register(ItemKeys.BIRCH_SLAB, create( @@ -8785,7 +9078,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BIRCH_SLAB))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SLAB_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SLAB)) .build() )); this.registerable.register(ItemKeys.JUNGLE_SLAB, create( @@ -8793,7 +9086,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.JUNGLE_SLAB))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SLAB_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SLAB)) .build() )); this.registerable.register(ItemKeys.ACACIA_SLAB, create( @@ -8801,7 +9094,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.ACACIA_SLAB))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SLAB_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SLAB)) .build() )); this.registerable.register(ItemKeys.CHERRY_SLAB, create( @@ -8809,7 +9102,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CHERRY_SLAB))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SLAB_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SLAB)) .build() )); this.registerable.register(ItemKeys.DARK_OAK_SLAB, create( @@ -8817,7 +9110,15 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.DARK_OAK_SLAB))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SLAB_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SLAB)) + .build() + )); + this.registerable.register(ItemKeys.PALE_OAK_SLAB, create( + ItemDisplay.Builder.forBlock(ItemKeys.PALE_OAK_SLAB).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PALE_OAK_SLAB))) + .with(FuelItemComponent.of(FuelTimes.SLAB)) .build() )); this.registerable.register(ItemKeys.MANGROVE_SLAB, create( @@ -8825,7 +9126,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MANGROVE_SLAB))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SLAB_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SLAB)) .build() )); this.registerable.register(ItemKeys.BAMBOO_SLAB, create( @@ -8833,7 +9134,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BAMBOO_SLAB))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SLAB_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SLAB)) .build() )); this.registerable.register(ItemKeys.BAMBOO_MOSAIC_SLAB, create( @@ -8841,7 +9142,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BAMBOO_MOSAIC_SLAB))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SLAB_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SLAB)) .build() )); this.registerable.register(ItemKeys.DEAD_BUSH, create( @@ -8849,7 +9150,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.DEAD_BUSH))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.PLANT_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.PLANT)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_DEAD_BUSH)) @@ -8860,7 +9161,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.OAK_BUTTON))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BUTTON_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.BUTTON)) .build() )); this.registerable.register(ItemKeys.SPRUCE_BUTTON, create( @@ -8868,7 +9169,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SPRUCE_BUTTON))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BUTTON_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.BUTTON)) .build() )); this.registerable.register(ItemKeys.BIRCH_BUTTON, create( @@ -8876,7 +9177,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BIRCH_BUTTON))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BUTTON_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.BUTTON)) .build() )); this.registerable.register(ItemKeys.JUNGLE_BUTTON, create( @@ -8884,7 +9185,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.JUNGLE_BUTTON))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BUTTON_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.BUTTON)) .build() )); this.registerable.register(ItemKeys.ACACIA_BUTTON, create( @@ -8892,7 +9193,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.ACACIA_BUTTON))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BUTTON_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.BUTTON)) .build() )); this.registerable.register(ItemKeys.CHERRY_BUTTON, create( @@ -8900,7 +9201,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CHERRY_BUTTON))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BUTTON_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.BUTTON)) .build() )); this.registerable.register(ItemKeys.DARK_OAK_BUTTON, create( @@ -8908,7 +9209,15 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.DARK_OAK_BUTTON))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BUTTON_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.BUTTON)) + .build() + )); + this.registerable.register(ItemKeys.PALE_OAK_BUTTON, create( + ItemDisplay.Builder.forBlock(ItemKeys.PALE_OAK_BUTTON).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PALE_OAK_BUTTON))) + .with(FuelItemComponent.of(FuelTimes.BUTTON)) .build() )); this.registerable.register(ItemKeys.MANGROVE_BUTTON, create( @@ -8916,7 +9225,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MANGROVE_BUTTON))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BUTTON_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.BUTTON)) .build() )); this.registerable.register(ItemKeys.BAMBOO_BUTTON, create( @@ -8924,21 +9233,21 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BAMBOO_BUTTON))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BUTTON_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.BUTTON)) .build() )); this.registerable.register(ItemKeys.STICK, create( ItemDisplay.Builder.forItem(ItemKeys.STICK).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SMALL_WOODEN_ITEM_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SMALL_WOODEN_ITEM)) .build() )); this.registerable.register(ItemKeys.BOWL, create( ItemDisplay.Builder.forItem(ItemKeys.BOWL).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SMALL_WOODEN_ITEM_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SMALL_WOODEN_ITEM)) .build() )); this.registerable.register(ItemKeys.BAMBOO, create( @@ -8946,7 +9255,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BAMBOO))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.BAMBOO_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.BAMBOO)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, Actions.potBlock(this.blocks, BlockKeys.POTTED_BAMBOO)) @@ -8957,7 +9266,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SCAFFOLDING))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.SCAFFOLDING_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.SCAFFOLDING)) .build() )); this.registerable.register(ItemKeys.WHITE_WOOL, create( @@ -8965,7 +9274,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.WHITE_WOOL))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL)) .build() )); this.registerable.register(ItemKeys.ORANGE_WOOL, create( @@ -8973,7 +9282,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.ORANGE_WOOL))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL)) .build() )); this.registerable.register(ItemKeys.MAGENTA_WOOL, create( @@ -8981,7 +9290,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MAGENTA_WOOL))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL)) .build() )); this.registerable.register(ItemKeys.LIGHT_BLUE_WOOL, create( @@ -8989,7 +9298,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.LIGHT_BLUE_WOOL))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL)) .build() )); this.registerable.register(ItemKeys.YELLOW_WOOL, create( @@ -8997,7 +9306,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.YELLOW_WOOL))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL)) .build() )); this.registerable.register(ItemKeys.LIME_WOOL, create( @@ -9005,7 +9314,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.LIME_WOOL))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL)) .build() )); this.registerable.register(ItemKeys.PINK_WOOL, create( @@ -9013,7 +9322,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PINK_WOOL))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL)) .build() )); this.registerable.register(ItemKeys.GRAY_WOOL, create( @@ -9021,7 +9330,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.GRAY_WOOL))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL)) .build() )); this.registerable.register(ItemKeys.LIGHT_GRAY_WOOL, create( @@ -9029,7 +9338,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.LIGHT_GRAY_WOOL))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL)) .build() )); this.registerable.register(ItemKeys.CYAN_WOOL, create( @@ -9037,7 +9346,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CYAN_WOOL))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL)) .build() )); this.registerable.register(ItemKeys.PURPLE_WOOL, create( @@ -9045,7 +9354,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PURPLE_WOOL))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL)) .build() )); this.registerable.register(ItemKeys.BLUE_WOOL, create( @@ -9053,7 +9362,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BLUE_WOOL))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL)) .build() )); this.registerable.register(ItemKeys.BROWN_WOOL, create( @@ -9061,7 +9370,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BROWN_WOOL))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL)) .build() )); this.registerable.register(ItemKeys.GREEN_WOOL, create( @@ -9069,7 +9378,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.GREEN_WOOL))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL)) .build() )); this.registerable.register(ItemKeys.RED_WOOL, create( @@ -9077,7 +9386,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.RED_WOOL))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL)) .build() )); this.registerable.register(ItemKeys.BLACK_WOOL, create( @@ -9085,7 +9394,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BLACK_WOOL))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL)) .build() )); this.registerable.register(ItemKeys.WHITE_CARPET, create( @@ -9093,7 +9402,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.WHITE_CARPET))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_CARPET_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL_CARPET)) .with(EquipmentItemComponent.of(EquippableComponent.ofCarpet(DyeColor.WHITE))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() @@ -9103,7 +9412,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.ORANGE_CARPET))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_CARPET_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL_CARPET)) .with(EquipmentItemComponent.of(EquippableComponent.ofCarpet(DyeColor.ORANGE))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() @@ -9113,7 +9422,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.MAGENTA_CARPET))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_CARPET_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL_CARPET)) .with(EquipmentItemComponent.of(EquippableComponent.ofCarpet(DyeColor.MAGENTA))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() @@ -9123,7 +9432,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.LIGHT_BLUE_CARPET))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_CARPET_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL_CARPET)) .with(EquipmentItemComponent.of(EquippableComponent.ofCarpet(DyeColor.LIGHT_BLUE))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() @@ -9133,7 +9442,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.YELLOW_CARPET))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_CARPET_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL_CARPET)) .with(EquipmentItemComponent.of(EquippableComponent.ofCarpet(DyeColor.YELLOW))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() @@ -9143,7 +9452,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.LIME_CARPET))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_CARPET_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL_CARPET)) .with(EquipmentItemComponent.of(EquippableComponent.ofCarpet(DyeColor.LIME))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() @@ -9153,7 +9462,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PINK_CARPET))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_CARPET_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL_CARPET)) .with(EquipmentItemComponent.of(EquippableComponent.ofCarpet(DyeColor.PINK))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() @@ -9163,7 +9472,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.GRAY_CARPET))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_CARPET_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL_CARPET)) .with(EquipmentItemComponent.of(EquippableComponent.ofCarpet(DyeColor.GRAY))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() @@ -9173,7 +9482,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.LIGHT_GRAY_CARPET))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_CARPET_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL_CARPET)) .with(EquipmentItemComponent.of(EquippableComponent.ofCarpet(DyeColor.LIGHT_GRAY))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() @@ -9183,7 +9492,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.CYAN_CARPET))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_CARPET_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL_CARPET)) .with(EquipmentItemComponent.of(EquippableComponent.ofCarpet(DyeColor.CYAN))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() @@ -9193,7 +9502,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.PURPLE_CARPET))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_CARPET_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL_CARPET)) .with(EquipmentItemComponent.of(EquippableComponent.ofCarpet(DyeColor.PURPLE))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() @@ -9203,7 +9512,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BLUE_CARPET))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_CARPET_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL_CARPET)) .with(EquipmentItemComponent.of(EquippableComponent.ofCarpet(DyeColor.BLUE))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() @@ -9213,7 +9522,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BROWN_CARPET))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_CARPET_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL_CARPET)) .with(EquipmentItemComponent.of(EquippableComponent.ofCarpet(DyeColor.BROWN))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() @@ -9223,7 +9532,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.GREEN_CARPET))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_CARPET_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL_CARPET)) .with(EquipmentItemComponent.of(EquippableComponent.ofCarpet(DyeColor.GREEN))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() @@ -9233,7 +9542,7 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.RED_CARPET))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_CARPET_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL_CARPET)) .with(EquipmentItemComponent.of(EquippableComponent.ofCarpet(DyeColor.RED))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() @@ -9243,11 +9552,38 @@ private void bootstrapFuel() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.BLACK_CARPET))) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOL_CARPET_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOL_CARPET)) .with(EquipmentItemComponent.of(EquippableComponent.ofCarpet(DyeColor.BLACK))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) .build() )); + this.registerable.register(ItemKeys.SHORT_DRY_GRASS, create( + ItemDisplay.Builder.forBlock(ItemKeys.SHORT_DRY_GRASS).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.SHORT_DRY_GRASS))) + .with(FuelItemComponent.of(FuelTimes.PLANT)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .build() + )); + this.registerable.register(ItemKeys.TALL_DRY_GRASS, create( + ItemDisplay.Builder.forBlock(ItemKeys.TALL_DRY_GRASS).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.TALL_DRY_GRASS))) + .with(FuelItemComponent.of(FuelTimes.PLANT)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .build() + )); + this.registerable.register(ItemKeys.LEAF_LITTER, create( + ItemDisplay.Builder.forBlock(ItemKeys.LEAF_LITTER).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.LEAF_LITTER))) + .with(FuelItemComponent.of(FuelTimes.PLANT)) + .with(CompostableItemComponent.of(CompostChances.SMALL)) + .build() + )); } private void bootstrapProjectiles() { @@ -9255,7 +9591,7 @@ private void bootstrapProjectiles() { ItemDisplay.Builder.forItem(ItemKeys.ARROW).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(ProjectileItemComponent.persistentProjectile(EntityType.ARROW, ArrowEntity::new, ArrowEntity::new)) + .with(ProjectileItemComponent.of(this.entityTypes.getOrThrow(EntityTypeKeys.ARROW))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.SHOOT_PROJECTILE))) .build() )); @@ -9273,7 +9609,55 @@ private void bootstrapProjectiles() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(ThrowableItemComponent.of(1.5f)) - .with(ProjectileItemComponent.of(this.entityTypes.getOrThrow(EntityTypeKeys.EGG))) + .with(ProjectileItemComponent.of( + this.entityTypes.getOrThrow(EntityTypeKeys.EGG), + ComponentChanges.builder() + .add( + DataComponentTypes.CHICKEN_VARIANT, + new LazyRegistryEntryReference<>( + this.chickenVariants.getOrThrow(ChickenVariants.TEMPERATE) + ) + ) + .build() + )) + .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.SHOOT_PROJECTILE))) + .build() + )); + this.registerable.register(ItemKeys.BLUE_EGG, create( + ItemDisplay.Builder.forItem(ItemKeys.BLUE_EGG).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(16)) + .with(ThrowableItemComponent.of(1.5f)) + .with(ProjectileItemComponent.of( + this.entityTypes.getOrThrow(EntityTypeKeys.EGG), + ComponentChanges.builder() + .add( + DataComponentTypes.CHICKEN_VARIANT, + new LazyRegistryEntryReference<>( + this.chickenVariants.getOrThrow(ChickenVariants.COLD) + ) + ) + .build() + )) + .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.SHOOT_PROJECTILE))) + .build() + )); + this.registerable.register(ItemKeys.BROWN_EGG, create( + ItemDisplay.Builder.forItem(ItemKeys.BROWN_EGG).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(16)) + .with(ThrowableItemComponent.of(1.5f)) + .with(ProjectileItemComponent.of( + this.entityTypes.getOrThrow(EntityTypeKeys.EGG), + ComponentChanges.builder() + .add( + DataComponentTypes.CHICKEN_VARIANT, + new LazyRegistryEntryReference<>( + this.chickenVariants.getOrThrow(ChickenVariants.WARM) + ) + ) + .build() + )) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.SHOOT_PROJECTILE))) .build() )); @@ -9291,40 +9675,38 @@ private void bootstrapProjectiles() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(ThrowableItemComponent.of()) - .with(ProjectileItemComponent.of(EyeOfEnderEntityInitializer.INSTANCE)) + .with(ProjectileItemComponent.of(this.entityTypes.getOrThrow(EntityTypeKeys.EYE_OF_ENDER))) .with(PreventUseWhenUsedOnTargetItemComponent.forBlock()) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, ActionEntry.of( - ActionRequirements.of( - ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.TARGET), - LocationCheckLootCondition.builder( - LocationPredicate.Builder.create() - .block(BlockPredicate.Builder.create() - .blocks(this.blocks, this.blocks.getOrThrow(BlockKeys.END_PORTAL_FRAME).value()) - .state(StatePredicate.Builder.create() - .exactMatch(Properties.EYE, false)))) - .build() + LocationCheckLootConditionUtil.builder( + PositionTarget.INTERACTED_POSITION, + LocationPredicate.Builder.create() + .block(BlockPredicate.Builder.create() + .blocks(this.blocks, this.blocks.getOrThrow(BlockKeys.END_PORTAL_FRAME).value()) + .state(StatePredicate.Builder.create() + .exactMatch(Properties.EYE, false))) ), PassingSequenceHandler.builder() - .add(ModifyBlockStateAction.builder(ActionContextParameter.TARGET) + .add(ModifyBlockStateAction.builder(PositionTarget.INTERACTED_POSITION) .property(Properties.EYE, true) .pushEntitiesUpwards() .build()) .add(DecrementItemAction.of(1)) - .add(SwingHandAction.INSTANCE) - .add(PlaySoundAction.of(ActionContextParameter.TARGET, this.soundEvents.getOrThrow(SoundEventKeys.END_PORTAL_FRAME_FILL), SoundCategory.BLOCKS)) - .add(DisplayParticleAction.builder(ActionContextParameter.TARGET, ParticleTypes.SMOKE) + .add(SwingHandAction.of(LootContext.EntityTarget.THIS)) + .add(PlaySoundAction.of(PositionTarget.INTERACTED_POSITION, this.soundEvents.getOrThrow(SoundEventKeys.END_PORTAL_FRAME_FILL), SoundCategory.BLOCKS)) + .add(DisplayParticleAction.builder(PositionTarget.INTERACTED_POSITION, ParticleTypes.SMOKE) .count(16) .offset(Vec3dProvider.of( -0.1875d, 0.1875d, 0.8125d, 0.8125d, -0.1875d, 0.1875d)) .build()) - .addOptional(LightEndPortalAction.of(ActionContextParameter.TARGET)) + .addOptional(LightEndPortalAction.of(PositionTarget.INTERACTED_POSITION)) )) .add(ItemEvents.THROW_PROJECTILE, ActionEntry.of( - PlaySoundAction.builder(ActionContextParameter.THIS, this.soundEvents.getOrThrow(SoundEventKeys.ENDER_EYE_LAUNCH), SoundCategory.NEUTRAL) + PlaySoundAction.builder(PositionTarget.ORIGIN, this.soundEvents.getOrThrow(SoundEventKeys.ENDER_EYE_LAUNCH), SoundCategory.NEUTRAL) .pitch(0.33f, 0.5f) .build() )) @@ -9355,7 +9737,7 @@ private void bootstrapProjectiles() { PassingSequenceHandler.builder() .add(this.actions.getOrThrow(Actions.LIGHT_BLOCK)) .add(DecrementItemAction.of(1)) - .add(PlaySoundAction.builder(ActionContextParameter.TARGET, this.soundEvents.getOrThrow(SoundEventKeys.FIRE_CHARGE_USE), SoundCategory.BLOCKS) + .add(PlaySoundAction.builder(PositionTarget.INTERACTED_POSITION, this.soundEvents.getOrThrow(SoundEventKeys.FIRE_CHARGE_USE), SoundCategory.BLOCKS) .pitch(0.8f, 1.2f) .build()) )) @@ -9376,7 +9758,7 @@ private void bootstrapProjectiles() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(FireworkItemComponent.INSTANCE) - .with(ProjectileItemComponent.of(FireworkRocketEntityInitializer.INSTANCE)) + .with(ProjectileItemComponent.of(this.entityTypes.getOrThrow(EntityTypeKeys.FIREWORK_ROCKET))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.SHOOT_FIREWORK_ROCKET))) .build() )); @@ -9386,16 +9768,15 @@ private void bootstrapProjectiles() { .with(StackableItemComponent.of(1)) .with(PotionHolderItemComponent.of(1.0f)) .with(ThrowableItemComponent.of(0.5f, -20.0f)) - .with(ProjectileItemComponent.of(this.entityTypes.getOrThrow(EntityTypeKeys.POTION))) + .with(ProjectileItemComponent.of(this.entityTypes.getOrThrow(EntityTypeKeys.SPLASH_POTION))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.SHOOT_BOTTLE))) - .with(TintedItemComponent.of(PotionItemColor.INSTANCE)) .build() )); this.registerable.register(ItemKeys.SPECTRAL_ARROW, create( ItemDisplay.Builder.forItem(ItemKeys.SPECTRAL_ARROW).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(ProjectileItemComponent.persistentProjectile(EntityType.SPECTRAL_ARROW, SpectralArrowEntity::new, SpectralArrowEntity::new)) + .with(ProjectileItemComponent.of(this.entityTypes.getOrThrow(EntityTypeKeys.SPECTRAL_ARROW))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.SHOOT_PROJECTILE))) .build() )); @@ -9404,9 +9785,8 @@ private void bootstrapProjectiles() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(PotionHolderItemComponent.of(0.125f)) - .with(ProjectileItemComponent.persistentProjectile(EntityType.ARROW, ArrowEntity::new, ArrowEntity::new)) + .with(ProjectileItemComponent.of(this.entityTypes.getOrThrow(EntityTypeKeys.ARROW))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.SHOOT_PROJECTILE))) - .with(TintedItemComponent.of(PotionItemColor.INSTANCE)) .build() )); this.registerable.register(ItemKeys.LINGERING_POTION, create( @@ -9415,9 +9795,8 @@ private void bootstrapProjectiles() { .with(StackableItemComponent.of(1)) .with(PotionHolderItemComponent.of(0.25f)) .with(ThrowableItemComponent.of(0.5f, -20.0f)) - .with(ProjectileItemComponent.of(this.entityTypes.getOrThrow(EntityTypeKeys.POTION))) + .with(ProjectileItemComponent.of(this.entityTypes.getOrThrow(EntityTypeKeys.LINGERING_POTION))) .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.SHOOT_BOTTLE))) - .with(TintedItemComponent.of(PotionItemColor.INSTANCE)) .build() )); } @@ -9694,7 +10073,7 @@ private void bootstrapRecords() { this.registerable.register(ItemKeys.DISC_FRAGMENT_5, create( ItemDisplay.Builder.forItem(ItemKeys.DISC_FRAGMENT_5) .rarity(Rarity.UNCOMMON) - .tooltip(ItemKeys.DISC_FRAGMENT_5) + .tooltip(Tooltips.description(ItemKeys.DISC_FRAGMENT_5)) .build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) @@ -9720,7 +10099,7 @@ private void bootstrapBuckets() { ItemDisplay.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, this.items.getOrThrow(ItemKeys.BUCKET))) + .with(FuelItemComponent.of(FuelTimes.LAVA, this.items.getOrThrow(ItemKeys.BUCKET))) .build() )); this.registerable.register(ItemKeys.POWDER_SNOW_BUCKET, create( @@ -9771,153 +10150,191 @@ private void bootstrapSmithingTemplates() { this.registerable.register(ItemKeys.NETHERITE_UPGRADE_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.NETHERITE_UPGRADE_SMITHING_TEMPLATE) .rarity(Rarity.UNCOMMON) + .tooltip(Tooltips.smithingUpgrade(Identifier.ofVanilla("netherite_upgrade"))) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.NETHERITE_UPGRADE))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.ITEM_UPGRADE)) .build() )); this.registerable.register(ItemKeys.SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE) .rarity(Rarity.UNCOMMON) + .tooltip(Tooltips.smithingTrimPattern()) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.SENTRY_PATTERN))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.TRIM_PATTERN)) .build() )); this.registerable.register(ItemKeys.DUNE_ARMOR_TRIM_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.DUNE_ARMOR_TRIM_SMITHING_TEMPLATE) .rarity(Rarity.UNCOMMON) + .tooltip(Tooltips.smithingTrimPattern()) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.DUNE_PATTERN))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.TRIM_PATTERN)) .build() )); this.registerable.register(ItemKeys.COAST_ARMOR_TRIM_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.COAST_ARMOR_TRIM_SMITHING_TEMPLATE) .rarity(Rarity.UNCOMMON) + .tooltip(Tooltips.smithingTrimPattern()) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.COAST_PATTERN))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.TRIM_PATTERN)) .build() )); this.registerable.register(ItemKeys.WILD_ARMOR_TRIM_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.WILD_ARMOR_TRIM_SMITHING_TEMPLATE) .rarity(Rarity.UNCOMMON) + .tooltip(Tooltips.smithingTrimPattern()) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.WILD_PATTERN))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.TRIM_PATTERN)) .build() )); this.registerable.register(ItemKeys.WARD_ARMOR_TRIM_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.WARD_ARMOR_TRIM_SMITHING_TEMPLATE) .rarity(Rarity.UNCOMMON) + .tooltip(Tooltips.smithingTrimPattern()) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.WARD_PATTERN))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.TRIM_PATTERN)) .build() )); this.registerable.register(ItemKeys.EYE_ARMOR_TRIM_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.EYE_ARMOR_TRIM_SMITHING_TEMPLATE) .rarity(Rarity.UNCOMMON) + .tooltip(Tooltips.smithingTrimPattern()) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.EYE_PATTERN))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.TRIM_PATTERN)) .build() )); this.registerable.register(ItemKeys.VEX_ARMOR_TRIM_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.VEX_ARMOR_TRIM_SMITHING_TEMPLATE) .rarity(Rarity.UNCOMMON) + .tooltip(Tooltips.smithingTrimPattern()) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.VEX_PATTERN))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.TRIM_PATTERN)) .build() )); this.registerable.register(ItemKeys.TIDE_ARMOR_TRIM_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.TIDE_ARMOR_TRIM_SMITHING_TEMPLATE) .rarity(Rarity.UNCOMMON) + .tooltip(Tooltips.smithingTrimPattern()) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.TIDE_PATTERN))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.TRIM_PATTERN)) .build() )); this.registerable.register(ItemKeys.SNOUT_ARMOR_TRIM_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.SNOUT_ARMOR_TRIM_SMITHING_TEMPLATE) .rarity(Rarity.UNCOMMON) + .tooltip(Tooltips.smithingTrimPattern()) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.SNOUT_PATTERN))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.TRIM_PATTERN)) .build() )); this.registerable.register(ItemKeys.RIB_ARMOR_TRIM_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.RIB_ARMOR_TRIM_SMITHING_TEMPLATE) .rarity(Rarity.UNCOMMON) + .tooltip(Tooltips.smithingTrimPattern()) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.RIB_PATTERN))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.TRIM_PATTERN)) .build() )); this.registerable.register(ItemKeys.SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE) .rarity(Rarity.UNCOMMON) + .tooltip(Tooltips.smithingTrimPattern()) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.SPIRE_PATTERN))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.TRIM_PATTERN)) .build() )); this.registerable.register(ItemKeys.WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE) .rarity(Rarity.UNCOMMON) + .tooltip(Tooltips.smithingTrimPattern()) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.WAYFINDER_PATTERN))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.TRIM_PATTERN)) .build() )); this.registerable.register(ItemKeys.SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE) .rarity(Rarity.UNCOMMON) + .tooltip(Tooltips.smithingTrimPattern()) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.SHAPER_PATTERN))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.TRIM_PATTERN)) .build() )); this.registerable.register(ItemKeys.SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE) .rarity(Rarity.EPIC) + .tooltip(Tooltips.smithingTrimPattern()) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.SILENCE_PATTERN))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.TRIM_PATTERN)) .build() )); this.registerable.register(ItemKeys.RAISER_ARMOR_TRIM_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.RAISER_ARMOR_TRIM_SMITHING_TEMPLATE) .rarity(Rarity.UNCOMMON) + .tooltip(Tooltips.smithingTrimPattern()) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.RAISER_PATTERN))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.TRIM_PATTERN)) .build() )); this.registerable.register(ItemKeys.HOST_ARMOR_TRIM_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.HOST_ARMOR_TRIM_SMITHING_TEMPLATE) .rarity(Rarity.UNCOMMON) + .tooltip(Tooltips.smithingTrimPattern()) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.HOST_PATTERN))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.TRIM_PATTERN)) .build() )); this.registerable.register(ItemKeys.FLOW_ARMOR_TRIM_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.FLOW_ARMOR_TRIM_SMITHING_TEMPLATE) .rarity(Rarity.UNCOMMON) + .tooltip(Tooltips.smithingTrimPattern()) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.FLOW_PATTERN))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.TRIM_PATTERN)) .build() )); this.registerable.register(ItemKeys.BOLT_ARMOR_TRIM_SMITHING_TEMPLATE, create( ItemDisplay.Builder.forItem(ItemKeys.BOLT_ARMOR_TRIM_SMITHING_TEMPLATE) .rarity(Rarity.UNCOMMON) + .tooltip(Tooltips.smithingTrimPattern()) .build(), ItemComponentSet.builder() - .with(SmithingTemplateItemComponent.of(this.smithingTemplates.getOrThrow(SmithingTemplates.BOLT_PATTERN))) + .with(StackableItemComponent.of(64)) + .with(SmithingTemplateProviderItemComponent.of(SmithingTemplates.TRIM_PATTERN)) .build() )); } @@ -9929,7 +10346,7 @@ private void bootstrapBanners() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.WHITE_BANNER), this.blocks.getOrThrow(BlockKeys.WHITE_WALL_BANNER), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .with(BannerPatternHolderItemComponent.of(DyeColor.WHITE)) .build() )); @@ -9938,7 +10355,7 @@ private void bootstrapBanners() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.ORANGE_BANNER), this.blocks.getOrThrow(BlockKeys.ORANGE_WALL_BANNER), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .with(BannerPatternHolderItemComponent.of(DyeColor.ORANGE)) .build() )); @@ -9947,7 +10364,7 @@ private void bootstrapBanners() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.MAGENTA_BANNER), this.blocks.getOrThrow(BlockKeys.MAGENTA_WALL_BANNER), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .with(BannerPatternHolderItemComponent.of(DyeColor.MAGENTA)) .build() )); @@ -9956,7 +10373,7 @@ private void bootstrapBanners() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.LIGHT_BLUE_BANNER), this.blocks.getOrThrow(BlockKeys.LIGHT_BLUE_WALL_BANNER), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .with(BannerPatternHolderItemComponent.of(DyeColor.LIGHT_BLUE)) .build() )); @@ -9965,7 +10382,7 @@ private void bootstrapBanners() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.YELLOW_BANNER), this.blocks.getOrThrow(BlockKeys.YELLOW_WALL_BANNER), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .with(BannerPatternHolderItemComponent.of(DyeColor.YELLOW)) .build() )); @@ -9974,7 +10391,7 @@ private void bootstrapBanners() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.LIME_BANNER), this.blocks.getOrThrow(BlockKeys.LIME_WALL_BANNER), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .with(BannerPatternHolderItemComponent.of(DyeColor.LIME)) .build() )); @@ -9983,7 +10400,7 @@ private void bootstrapBanners() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.PINK_BANNER), this.blocks.getOrThrow(BlockKeys.PINK_WALL_BANNER), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .with(BannerPatternHolderItemComponent.of(DyeColor.PINK)) .build() )); @@ -9992,7 +10409,7 @@ private void bootstrapBanners() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.GRAY_BANNER), this.blocks.getOrThrow(BlockKeys.GRAY_WALL_BANNER), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .with(BannerPatternHolderItemComponent.of(DyeColor.GRAY)) .build() )); @@ -10001,7 +10418,7 @@ private void bootstrapBanners() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.LIGHT_GRAY_BANNER), this.blocks.getOrThrow(BlockKeys.LIGHT_GRAY_WALL_BANNER), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .with(BannerPatternHolderItemComponent.of(DyeColor.LIGHT_GRAY)) .build() )); @@ -10010,7 +10427,7 @@ private void bootstrapBanners() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.CYAN_BANNER), this.blocks.getOrThrow(BlockKeys.CYAN_WALL_BANNER), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .with(BannerPatternHolderItemComponent.of(DyeColor.CYAN)) .build() )); @@ -10019,7 +10436,7 @@ private void bootstrapBanners() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.PURPLE_BANNER), this.blocks.getOrThrow(BlockKeys.PURPLE_WALL_BANNER), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .with(BannerPatternHolderItemComponent.of(DyeColor.PURPLE)) .build() )); @@ -10028,7 +10445,7 @@ private void bootstrapBanners() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.BLUE_BANNER), this.blocks.getOrThrow(BlockKeys.BLUE_WALL_BANNER), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .with(BannerPatternHolderItemComponent.of(DyeColor.BLUE)) .build() )); @@ -10037,7 +10454,7 @@ private void bootstrapBanners() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.BROWN_BANNER), this.blocks.getOrThrow(BlockKeys.BROWN_WALL_BANNER), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .with(BannerPatternHolderItemComponent.of(DyeColor.BROWN)) .build() )); @@ -10046,7 +10463,7 @@ private void bootstrapBanners() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.GREEN_BANNER), this.blocks.getOrThrow(BlockKeys.GREEN_WALL_BANNER), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .with(BannerPatternHolderItemComponent.of(DyeColor.GREEN)) .build() )); @@ -10055,7 +10472,7 @@ private void bootstrapBanners() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.RED_BANNER), this.blocks.getOrThrow(BlockKeys.RED_WALL_BANNER), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .with(BannerPatternHolderItemComponent.of(DyeColor.RED)) .build() )); @@ -10064,7 +10481,7 @@ private void bootstrapBanners() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(BlockItemComponent.attachedToSide(this.blocks.getOrThrow(BlockKeys.BLACK_BANNER), this.blocks.getOrThrow(BlockKeys.BLACK_WALL_BANNER), Direction.DOWN)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.WOOD_FUEL_TIME)) + .with(FuelItemComponent.of(FuelTimes.WOOD)) .with(BannerPatternHolderItemComponent.of(DyeColor.BLACK)) .build() )); @@ -10365,6 +10782,7 @@ private void bootstrapImmuneToDamage() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(ImmuneToDamageItemComponent.of(DamageTypeTags.IS_FIRE)) + .with(TrimMaterialProviderItemComponent.of(this.trimMaterials.getOrThrow(ArmorTrimMaterials.NETHERITE))) .build() )); this.registerable.register(ItemKeys.NETHERITE_SCRAP, create( @@ -10386,92 +10804,124 @@ private void bootstrapImmuneToDamage() { )); } - private void bootstrapMiscellaneous() { - this.registerable.register(ItemKeys.AIR, create( - ItemDisplay.Builder.forBlock(ItemKeys.AIR).build() - )); - this.registerable.register(ItemKeys.SADDLE, create( - ItemDisplay.Builder.forItem(ItemKeys.SADDLE).build(), - ItemComponentSet.builder() - .with(StackableItemComponent.of(1)) - .with(SaddleItemComponent.INSTANCE) - .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.SADDLE))) - .build() - )); - this.registerable.register(ItemKeys.TURTLE_SCUTE, create( - ItemDisplay.Builder.forItem(ItemKeys.TURTLE_SCUTE).build(), - ItemComponentSet.builder() - .with(StackableItemComponent.of(64)) - .build() - )); - this.registerable.register(ItemKeys.ARMADILLO_SCUTE, create( - ItemDisplay.Builder.forItem(ItemKeys.ARMADILLO_SCUTE).build(), + private void bootstrapTrimMaterialProviders() { + this.registerable.register(ItemKeys.REDSTONE, create( + ItemDisplay.Builder.forItem(ItemKeys.REDSTONE).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) + .with(BlockItemComponent.of(this.blocks.getOrThrow(BlockKeys.REDSTONE_WIRE))) + .with(TrimMaterialProviderItemComponent.of(this.trimMaterials.getOrThrow(ArmorTrimMaterials.REDSTONE))) .build() )); this.registerable.register(ItemKeys.DIAMOND, create( ItemDisplay.Builder.forItem(ItemKeys.DIAMOND).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) + .with(TrimMaterialProviderItemComponent.of(this.trimMaterials.getOrThrow(ArmorTrimMaterials.DIAMOND))) .build() )); this.registerable.register(ItemKeys.EMERALD, create( ItemDisplay.Builder.forItem(ItemKeys.EMERALD).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) + .with(TrimMaterialProviderItemComponent.of(this.trimMaterials.getOrThrow(ArmorTrimMaterials.EMERALD))) .build() )); this.registerable.register(ItemKeys.LAPIS_LAZULI, create( ItemDisplay.Builder.forItem(ItemKeys.LAPIS_LAZULI).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) + .with(TrimMaterialProviderItemComponent.of(this.trimMaterials.getOrThrow(ArmorTrimMaterials.LAPIS))) .build() )); this.registerable.register(ItemKeys.QUARTZ, create( ItemDisplay.Builder.forItem(ItemKeys.QUARTZ).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) + .with(TrimMaterialProviderItemComponent.of(this.trimMaterials.getOrThrow(ArmorTrimMaterials.QUARTZ))) .build() )); this.registerable.register(ItemKeys.AMETHYST_SHARD, create( ItemDisplay.Builder.forItem(ItemKeys.AMETHYST_SHARD).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) + .with(TrimMaterialProviderItemComponent.of(this.trimMaterials.getOrThrow(ArmorTrimMaterials.AMETHYST))) .build() )); - this.registerable.register(ItemKeys.RAW_IRON, create( - ItemDisplay.Builder.forItem(ItemKeys.RAW_IRON).build(), + this.registerable.register(ItemKeys.IRON_INGOT, create( + ItemDisplay.Builder.forItem(ItemKeys.IRON_INGOT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) + .with(TrimMaterialProviderItemComponent.of(this.trimMaterials.getOrThrow(ArmorTrimMaterials.IRON))) .build() )); - this.registerable.register(ItemKeys.IRON_INGOT, create( - ItemDisplay.Builder.forItem(ItemKeys.IRON_INGOT).build(), + this.registerable.register(ItemKeys.COPPER_INGOT, create( + ItemDisplay.Builder.forItem(ItemKeys.COPPER_INGOT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) + .with(TrimMaterialProviderItemComponent.of(this.trimMaterials.getOrThrow(ArmorTrimMaterials.COPPER))) .build() )); - this.registerable.register(ItemKeys.RAW_COPPER, create( - ItemDisplay.Builder.forItem(ItemKeys.RAW_COPPER).build(), + this.registerable.register(ItemKeys.GOLD_INGOT, create( + ItemDisplay.Builder.forItem(ItemKeys.GOLD_INGOT).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) + .with(TrimMaterialProviderItemComponent.of(this.trimMaterials.getOrThrow(ArmorTrimMaterials.GOLD))) .build() )); - this.registerable.register(ItemKeys.COPPER_INGOT, create( - ItemDisplay.Builder.forItem(ItemKeys.COPPER_INGOT).build(), + this.registerable.register(ItemKeys.RESIN_BRICK, create( + ItemDisplay.Builder.forItem(ItemKeys.RESIN_BRICK).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) + .with(TrimMaterialProviderItemComponent.of(this.trimMaterials.getOrThrow(ArmorTrimMaterials.RESIN))) .build() )); - this.registerable.register(ItemKeys.RAW_GOLD, create( - ItemDisplay.Builder.forItem(ItemKeys.RAW_GOLD).build(), + } + + private void bootstrapMiscellaneous() { + this.registerable.register(ItemKeys.AIR, create( + ItemDisplay.Builder.forBlock(ItemKeys.AIR).build() + )); + this.registerable.register(ItemKeys.SADDLE, create( + ItemDisplay.Builder.forItem(ItemKeys.SADDLE).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(1)) + .with(EquipmentItemComponent.of(EquippableComponent.builder(EquipmentSlot.SADDLE) + .equipSound(SoundEvents.ENTITY_HORSE_SADDLE) + .model(EquipmentAssetKeys.SADDLE) + .allowedEntities(this.entityTypes.getOrThrow(EntityTypeTags.CAN_EQUIP_SADDLE)) + .equipOnInteract(true) + .build() + )) + .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.EQUIP_ENTITY))) + .build() + )); + this.registerable.register(ItemKeys.TURTLE_SCUTE, create( + ItemDisplay.Builder.forItem(ItemKeys.TURTLE_SCUTE).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .build() )); - this.registerable.register(ItemKeys.GOLD_INGOT, create( - ItemDisplay.Builder.forItem(ItemKeys.GOLD_INGOT).build(), + this.registerable.register(ItemKeys.ARMADILLO_SCUTE, create( + ItemDisplay.Builder.forItem(ItemKeys.ARMADILLO_SCUTE).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .build() + )); + this.registerable.register(ItemKeys.RAW_IRON, create( + ItemDisplay.Builder.forItem(ItemKeys.RAW_IRON).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .build() + )); + this.registerable.register(ItemKeys.RAW_COPPER, create( + ItemDisplay.Builder.forItem(ItemKeys.RAW_COPPER).build(), + ItemComponentSet.builder() + .with(StackableItemComponent.of(64)) + .build() + )); + this.registerable.register(ItemKeys.RAW_GOLD, create( + ItemDisplay.Builder.forItem(ItemKeys.RAW_GOLD).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .build() @@ -10530,21 +10980,35 @@ private void bootstrapMiscellaneous() { ItemDisplay.Builder.forItem(ItemKeys.COMPASS).build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(PointableItemComponent.of(this.pointers.getOrThrow(PointerKeys.SPAWN_LOCATION), Util.createTranslationKey("item", Identifier.ofVanilla("lodestone_compass")))) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, ActionEntry.of( - ActionRequirements.of( - ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.TARGET), - LocationCheckLootCondition.builder( - LocationPredicate.Builder.create() - .block(BlockPredicate.Builder.create() - .blocks(this.blocks, this.blocks.getOrThrow(BlockKeys.LODESTONE).value()))) - .build() + LocationCheckLootConditionUtil.builder( + PositionTarget.INTERACTED_POSITION, + LocationPredicate.Builder.create() + .block(BlockPredicate.Builder.create() + .blocks(this.blocks, this.blocks.getOrThrow(BlockKeys.LODESTONE).value())) ), PassingSequenceHandler.builder() - .add(SetItemPointerLocationAction.of(ActionContextParameter.TARGET)) - .add(SwingHandAction.INSTANCE) + .add(ModifyItemAction.of( + ItemStackTarget.TOOL, + SplitItemModifier.builder(1), + SetItemPointerLocationItemModifier.builder(PositionTarget.INTERACTED_POSITION), + SetNameLootFunction.builder( + Text.translatable(Util.createTranslationKey("item", Identifier.ofVanilla("lodestone_compass"))), + SetNameLootFunction.Target.ITEM_NAME + ), + SetComponentsLootFunction.builder( + DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, + true + ) + )) + .add(PlaySoundAction.of( + PositionTarget.INTERACTED_POSITION, + this.soundEvents.getOrThrow(SoundEventKeys.LODESTONE_COMPASS_LOCK), + SoundCategory.PLAYERS + )) + .add(SwingHandAction.of(LootContext.EntityTarget.THIS)) )) .build() )); @@ -10554,7 +11018,6 @@ private void bootstrapMiscellaneous() { .build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(PointableItemComponent.of(this.pointers.getOrThrow(PointerKeys.LAST_DEATH))) .build() )); this.registerable.register(ItemKeys.BUNDLE, create( @@ -10741,7 +11204,16 @@ private void bootstrapMiscellaneous() { .with(DispensableItemComponent.of(this.dispenseBehaviors.getOrThrow(DispenseBehaviors.USE_ITEM_ON_BLOCK))) .build(), ItemEventMap.builder() - .add(ItemEvents.USE_ON_BLOCK, ActionEntry.of(FertilizeAction.INSTANCE)) + .add(ItemEvents.USE_ON_BLOCK, ActionEntry.of( + PassingSequenceHandler.builder() + .add(FertilizeAction.of(PositionTarget.INTERACTED_POSITION)) + .add(InvokeGameEventAction.of( + GameEvent.ITEM_INTERACT_FINISH, + PositionTarget.ORIGIN, + LootContext.EntityTarget.THIS + )) + .add(DecrementItemAction.of(1)) + )) .build() )); this.registerable.register(ItemKeys.BONE, create( @@ -10761,13 +11233,12 @@ private void bootstrapMiscellaneous() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(MapHolderItemComponent.INSTANCE) - .with(TintedItemComponent.of(MapItemColor.INSTANCE)) .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, ActionEntry.of( PassingSequenceHandler.builder() - .add(MarkBannerOnItemAction.of(ActionContextParameter.TARGET)) - .add(SwingHandAction.INSTANCE) + .add(MarkBannerOnItemAction.of(PositionTarget.INTERACTED_POSITION)) + .add(SwingHandAction.of(LootContext.EntityTarget.THIS)) )) .build() )); @@ -10792,13 +11263,11 @@ private void bootstrapMiscellaneous() { .build(), ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, ActionEntry.of( - ActionRequirements.of( - ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.TARGET), - LocationCheckLootCondition.builder( - LocationPredicate.Builder.create() - .fluid(FluidPredicate.Builder.create() - .tag(this.fluids.getOrThrow(FluidTags.WATER))) - ).build() + LocationCheckLootConditionUtil.builder( + PositionTarget.INTERACTED_POSITION, + LocationPredicate.Builder.create() + .fluid(FluidPredicate.Builder.create() + .tag(this.fluids.getOrThrow(FluidTags.WATER))) ), UncheckedSequenceHandler.builder() .add(ExchangeItemAction.of( @@ -10806,9 +11275,9 @@ private void bootstrapMiscellaneous() { ComponentChanges.builder() .add(DataComponentTypes.POTION_CONTENTS, new PotionContentsComponent(this.potions.getOrThrow(PotionKeys.WATER))) .build())) - .add(InvokeGameEventAction.of(GameEvent.FLUID_PICKUP, ActionContextParameter.TARGET, ActionContextParameter.THIS)) - .add(PlaySoundAction.of(ActionContextParameter.THIS, this.soundEvents.getOrThrow(SoundEventKeys.BOTTLE_FILL), SoundCategory.NEUTRAL)) - .add(SwingHandAction.INSTANCE) + .add(InvokeGameEventAction.of(GameEvent.FLUID_PICKUP, PositionTarget.INTERACTED_POSITION, LootContext.EntityTarget.THIS)) + .add(PlaySoundAction.of(PositionTarget.ORIGIN, this.soundEvents.getOrThrow(SoundEventKeys.BOTTLE_FILL), SoundCategory.NEUTRAL)) + .add(SwingHandAction.of(LootContext.EntityTarget.THIS)) )) .build() )); @@ -10850,9 +11319,6 @@ private void bootstrapMiscellaneous() { ItemComponentSet.builder() .with(StackableItemComponent.of(16)) .with(TextHolderItemComponent.INSTANCE) - .build(), - ItemEventMap.builder() - .add(ItemEvents.USE, ActionEntry.of(OpenBookFromItemAction.INSTANCE)) .build() )); this.registerable.register(ItemKeys.MAP, create( @@ -10867,7 +11333,6 @@ private void bootstrapMiscellaneous() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(FireworkExplosionHolderItemComponent.INSTANCE) - .with(TintedItemComponent.of(FireworkItemColor.INSTANCE)) .build() )); this.registerable.register(ItemKeys.ENCHANTED_BOOK, create( @@ -10918,8 +11383,8 @@ private void bootstrapMiscellaneous() { ItemEventMap.builder() .add(ItemEvents.USE_ON_BLOCK, ActionEntry.of( PassingSequenceHandler.builder() - .add(AttachLeashedEntitiesOnBlockAction.INSTANCE) - .add(SwingHandAction.INSTANCE) + .add(AttachLeashedEntitiesOnBlockAction.of(PositionTarget.INTERACTED_POSITION)) + .add(SwingHandAction.of(LootContext.EntityTarget.THIS)) )) .build() )); @@ -10931,9 +11396,9 @@ private void bootstrapMiscellaneous() { ItemEventMap.builder() .add(ItemEvents.USE_ON_ENTITY, ActionEntry.of( PassingSequenceHandler.builder() - .add(SetEntityNameFromItemAction.of(ActionContextParameter.TARGET)) + .add(SetEntityNameFromItemAction.of(ItematicEntityTargets.TARGET_ENTITY)) .add(DecrementItemAction.of(1)) - .add(SwingHandAction.INSTANCE) + .add(SwingHandAction.of(LootContext.EntityTarget.THIS)) )) .build() )); @@ -11027,7 +11492,7 @@ private void bootstrapMiscellaneous() { .build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(PlayableItemComponent.of(InstrumentTags.GOAT_HORNS)) + .with(PlayableItemComponent.of(this.instruments.getOrThrow(Instruments.PONDER_GOAT_HORN))) .build() )); this.registerable.register(ItemKeys.HONEYCOMB, create( @@ -11041,9 +11506,9 @@ private void bootstrapMiscellaneous() { FirstToPassRequirementsSequenceHandler.builder() .add(Actions.waxSign(this.blocks, true)) .add(PassingSequenceHandler.builder() - .add(WaxBlockAction.of(ActionContextParameter.TARGET)) + .add(WaxBlockAction.of(PositionTarget.INTERACTED_POSITION)) .add(DecrementItemAction.of(1)) - .add(SwingHandAction.INSTANCE)))) + .add(SwingHandAction.of(LootContext.EntityTarget.THIS))))) .build() )); this.registerable.register(ItemKeys.ECHO_SHARD, create( diff --git a/src/main/java/net/errorcraft/itematic/item/ItematicItemTags.java b/src/main/java/net/errorcraft/itematic/item/ItematicItemTags.java index cc9242a4..c4ebe5ff 100644 --- a/src/main/java/net/errorcraft/itematic/item/ItematicItemTags.java +++ b/src/main/java/net/errorcraft/itematic/item/ItematicItemTags.java @@ -29,6 +29,7 @@ public class ItematicItemTags { public static final TagKey DARK_OAK_BUILDING_BLOCKS = of("item_group/dark_oak_building_blocks"); public static final TagKey MANGROVE_BUILDING_BLOCKS = of("item_group/mangrove_building_blocks"); public static final TagKey CHERRY_BUILDING_BLOCKS = of("item_group/cherry_building_blocks"); + public static final TagKey PALE_OAK_BUILDING_BLOCKS = of("item_group/pale_oak_building_blocks"); public static final TagKey BAMBOO_BUILDING_BLOCKS = of("item_group/bamboo_building_blocks"); public static final TagKey CRIMSON_BUILDING_BLOCKS = of("item_group/crimson_building_blocks"); public static final TagKey WARPED_BUILDING_BLOCKS = of("item_group/warped_building_blocks"); @@ -52,6 +53,7 @@ public class ItematicItemTags { public static final TagKey TUFF_BUILDING_BLOCKS = of("item_group/tuff_building_blocks"); public static final TagKey BRICK_BUILDING_BLOCKS = of("item_group/brick_building_blocks"); public static final TagKey MUD_BRICK_BUILDING_BLOCKS = of("item_group/mud_brick_building_blocks"); + public static final TagKey RESIN_BRICK_BUILDING_BLOCKS = of("item_group/resin_brick_building_blocks"); public static final TagKey SANDSTONE_BUILDING_BLOCKS = of("item_group/sandstone_building_blocks"); public static final TagKey SMOOTH_SANDSTONE_BUILDING_BLOCKS = of("item_group/smooth_sandstone_building_blocks"); public static final TagKey CUT_SANDSTONE_BUILDING_BLOCKS = of("item_group/cut_sandstone_building_blocks"); @@ -137,6 +139,7 @@ public class ItematicItemTags { public static final TagKey AXES = of("item_group/axes"); public static final TagKey ARMOR = of("item_group/armor"); public static final TagKey HORSE_ARMOR = of("item_group/horse_armor"); + public static final TagKey EGGS = of("item_group/eggs"); public static final TagKey FOOD = of("item_group/food"); public static final TagKey DYES = of("item_group/dyes"); public static final TagKey BREWING_INGREDIENTS = of("item_group/brewing_ingredients"); @@ -147,7 +150,6 @@ public class ItematicItemTags { public static final TagKey BANNED_BUNDLE_ITEMS = of("banned_bundle_items"); public static final TagKey SHULKER_BOXES = of("shulker_boxes"); - 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"); diff --git a/src/main/java/net/errorcraft/itematic/item/Tooltips.java b/src/main/java/net/errorcraft/itematic/item/Tooltips.java new file mode 100644 index 00000000..4fc7d770 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/item/Tooltips.java @@ -0,0 +1,44 @@ +package net.errorcraft.itematic.item; + +import net.errorcraft.itematic.mixin.item.SmithingTemplateItemAccessor; +import net.errorcraft.itematic.util.Util; +import net.minecraft.item.Item; +import net.minecraft.registry.RegistryKey; +import net.minecraft.screen.ScreenTexts; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.Identifier; + +public class Tooltips { + private Tooltips() {} + + public static Text description(RegistryKey item) { + return Text.translatable(Util.descriptionKey("item", item.getValue(), "desc")) + .formatted(Formatting.GRAY); + } + + public static Text[] smithingUpgrade(Identifier upgradeName) { + return smithing( + Text.translatable(Util.descriptionKey("smithing_template", upgradeName, "applies_to")), + Text.translatable(Util.descriptionKey("smithing_template", upgradeName, "ingredients")) + ); + } + + public static Text[] smithingTrimPattern() { + return smithing( + SmithingTemplateItemAccessor.trimPatternAppliesToLabel(), + SmithingTemplateItemAccessor.trimPatternIngredients() + ); + } + + private static Text[] smithing(Text appliesTo, Text ingredients) { + return new Text[] { + SmithingTemplateItemAccessor.smithingTemplateTitle(), + ScreenTexts.EMPTY, + SmithingTemplateItemAccessor.appliesToTitle(), + ScreenTexts.space().append(appliesTo), + SmithingTemplateItemAccessor.ingredientsTitle(), + ScreenTexts.space().append(ingredients) + }; + } +} diff --git a/src/main/java/net/errorcraft/itematic/item/color/ItemColor.java b/src/main/java/net/errorcraft/itematic/item/color/ItemColor.java deleted file mode 100644 index 85a4826d..00000000 --- a/src/main/java/net/errorcraft/itematic/item/color/ItemColor.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.errorcraft.itematic.item.color; - -import com.mojang.serialization.Codec; -import net.errorcraft.itematic.registry.ItematicRegistries; -import net.minecraft.item.ItemStack; - -public interface ItemColor> { - Codec> CODEC = ItematicRegistries.ITEM_COLOR_TYPE.getCodec().dispatch(ItemColor::type, ItemColorType::codec); - int DEFAULT_COLOR = 0xffffffff; - - ItemColorType type(); - int color(ItemStack stack, int tintIndex); -} diff --git a/src/main/java/net/errorcraft/itematic/item/color/ItemColorType.java b/src/main/java/net/errorcraft/itematic/item/color/ItemColorType.java deleted file mode 100644 index 0073e256..00000000 --- a/src/main/java/net/errorcraft/itematic/item/color/ItemColorType.java +++ /dev/null @@ -1,6 +0,0 @@ -package net.errorcraft.itematic.item.color; - -import com.mojang.serialization.MapCodec; - -public record ItemColorType>(MapCodec codec) { -} diff --git a/src/main/java/net/errorcraft/itematic/item/color/ItemColorTypeKeys.java b/src/main/java/net/errorcraft/itematic/item/color/ItemColorTypeKeys.java deleted file mode 100644 index 4f27a470..00000000 --- a/src/main/java/net/errorcraft/itematic/item/color/ItemColorTypeKeys.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.errorcraft.itematic.item.color; - -import net.errorcraft.itematic.registry.ItematicRegistryKeys; -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.Identifier; - -public class ItemColorTypeKeys { - public static final RegistryKey> DYEABLE = of("dyeable"); - public static final RegistryKey> INDEX = of("index"); - public static final RegistryKey> GRASS = of("grass"); - public static final RegistryKey> FOLIAGE = of("foliage"); - public static final RegistryKey> CONSTANT = of("constant"); - public static final RegistryKey> POTION = of("potion"); - public static final RegistryKey> FIREWORK = of("firework"); - public static final RegistryKey> MAP = of("map"); - - private static RegistryKey> of(String id) { - return RegistryKey.of(ItematicRegistryKeys.ITEM_COLOR_TYPE, Identifier.ofVanilla(id)); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/color/ItemColorTypes.java b/src/main/java/net/errorcraft/itematic/item/color/ItemColorTypes.java deleted file mode 100644 index 846376e2..00000000 --- a/src/main/java/net/errorcraft/itematic/item/color/ItemColorTypes.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.errorcraft.itematic.item.color; - -import net.errorcraft.itematic.item.color.colors.*; -import net.errorcraft.itematic.registry.ItematicRegistries; -import net.minecraft.registry.Registry; -import net.minecraft.registry.RegistryKey; - -public class ItemColorTypes { - public static final ItemColorType DYEABLE = register(ItemColorTypeKeys.DYEABLE, new ItemColorType<>(DyeableItemColor.CODEC)); - public static final ItemColorType INDEX = register(ItemColorTypeKeys.INDEX, new ItemColorType<>(IndexItemColor.CODEC)); - public static final ItemColorType GRASS = register(ItemColorTypeKeys.GRASS, new ItemColorType<>(GrassItemColor.CODEC)); - public static final ItemColorType FOLIAGE = register(ItemColorTypeKeys.FOLIAGE, new ItemColorType<>(FoliageItemColor.CODEC)); - public static final ItemColorType CONSTANT = register(ItemColorTypeKeys.CONSTANT, new ItemColorType<>(ConstantItemColor.CODEC)); - public static final ItemColorType POTION = register(ItemColorTypeKeys.POTION, new ItemColorType<>(PotionItemColor.CODEC)); - public static final ItemColorType FIREWORK = register(ItemColorTypeKeys.FIREWORK, new ItemColorType<>(FireworkItemColor.CODEC)); - public static final ItemColorType MAP = register(ItemColorTypeKeys.MAP, new ItemColorType<>(MapItemColor.CODEC)); - - private ItemColorTypes() {} - - public static void init() {} - - private static > ItemColorType register(RegistryKey> id, ItemColorType itemColor) { - return Registry.register(ItematicRegistries.ITEM_COLOR_TYPE, id, itemColor); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/color/colors/ConstantItemColor.java b/src/main/java/net/errorcraft/itematic/item/color/colors/ConstantItemColor.java deleted file mode 100644 index 0fc97696..00000000 --- a/src/main/java/net/errorcraft/itematic/item/color/colors/ConstantItemColor.java +++ /dev/null @@ -1,30 +0,0 @@ -package net.errorcraft.itematic.item.color.colors; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.item.color.ItemColor; -import net.errorcraft.itematic.item.color.ItemColorType; -import net.errorcraft.itematic.item.color.ItemColorTypes; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.ColorHelper; - -public record ConstantItemColor(int color) implements ItemColor { - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - Codec.INT.fieldOf("color").forGetter(ConstantItemColor::color) - ).apply(instance, ConstantItemColor::new)); - - public static ConstantItemColor of(int color) { - return new ConstantItemColor(color); - } - - @Override - public ItemColorType type() { - return ItemColorTypes.CONSTANT; - } - - @Override - public int color(ItemStack stack, int tintIndex) { - return ColorHelper.fullAlpha(this.color); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/color/colors/DyeableItemColor.java b/src/main/java/net/errorcraft/itematic/item/color/colors/DyeableItemColor.java deleted file mode 100644 index d737903b..00000000 --- a/src/main/java/net/errorcraft/itematic/item/color/colors/DyeableItemColor.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.errorcraft.itematic.item.color.colors; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.item.color.ItemColor; -import net.errorcraft.itematic.item.color.ItemColorType; -import net.errorcraft.itematic.item.color.ItemColorTypes; -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.minecraft.item.ItemStack; - -public record DyeableItemColor(int index) implements ItemColor { - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - Codec.INT.fieldOf("index").forGetter(DyeableItemColor::index) - ).apply(instance, DyeableItemColor::new)); - - public static DyeableItemColor of(int index) { - return new DyeableItemColor(index); - } - - @Override - public ItemColorType type() { - return ItemColorTypes.DYEABLE; - } - - @Override - public int color(ItemStack stack, int tintIndex) { - if (tintIndex != this.index) { - return DEFAULT_COLOR; - } - return stack.itematic$getBehavior(ItemComponentTypes.DYEABLE) - .map(c -> c.getColor(stack)) - .orElse(DEFAULT_COLOR); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/color/colors/FireworkItemColor.java b/src/main/java/net/errorcraft/itematic/item/color/colors/FireworkItemColor.java deleted file mode 100644 index 25c91364..00000000 --- a/src/main/java/net/errorcraft/itematic/item/color/colors/FireworkItemColor.java +++ /dev/null @@ -1,50 +0,0 @@ -package net.errorcraft.itematic.item.color.colors; - -import com.mojang.serialization.MapCodec; -import it.unimi.dsi.fastutil.ints.IntList; -import net.errorcraft.itematic.item.color.ItemColor; -import net.errorcraft.itematic.item.color.ItemColorType; -import net.errorcraft.itematic.item.color.ItemColorTypes; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.FireworkExplosionComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.ColorHelper; - -public record FireworkItemColor() implements ItemColor { - public static final FireworkItemColor INSTANCE = new FireworkItemColor(); - public static final MapCodec CODEC = MapCodec.unit(INSTANCE); - private static final int DEFAULT_FIREWORK_COLOR = 0xff8a8a8a; - - @Override - public ItemColorType type() { - return ItemColorTypes.FIREWORK; - } - - @Override - public int color(ItemStack stack, int tintIndex) { - if (tintIndex != 1) { - return DEFAULT_COLOR; - } - - IntList colors = stack.getOrDefault(DataComponentTypes.FIREWORK_EXPLOSION, FireworkExplosionComponent.DEFAULT).colors(); - if (colors.isEmpty()) { - return DEFAULT_FIREWORK_COLOR; - } - - int size = colors.size(); - if (size == 1) { - return ColorHelper.fullAlpha(colors.getInt(0)); - } - - int red = 0; - int green = 0; - int blue = 0; - for (int color : colors) { - red += ColorHelper.getRed(color); - green += ColorHelper.getGreen(color); - blue += ColorHelper.getBlue(color); - } - - return ColorHelper.getArgb(red / size, green / size, blue / size); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/color/colors/FoliageItemColor.java b/src/main/java/net/errorcraft/itematic/item/color/colors/FoliageItemColor.java deleted file mode 100644 index 9c4a8adf..00000000 --- a/src/main/java/net/errorcraft/itematic/item/color/colors/FoliageItemColor.java +++ /dev/null @@ -1,33 +0,0 @@ -package net.errorcraft.itematic.item.color.colors; - -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.item.color.ItemColor; -import net.errorcraft.itematic.item.color.ItemColorType; -import net.errorcraft.itematic.item.color.ItemColorTypes; -import net.minecraft.item.ItemStack; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.registry.entry.RegistryFixedCodec; -import net.minecraft.util.math.ColorHelper; -import net.minecraft.world.biome.Biome; - -public record FoliageItemColor(RegistryEntry biome) implements ItemColor { - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - RegistryFixedCodec.of(RegistryKeys.BIOME).fieldOf("biome").forGetter(FoliageItemColor::biome) - ).apply(instance, FoliageItemColor::new)); - - public static FoliageItemColor of(RegistryEntry biome) { - return new FoliageItemColor(biome); - } - - @Override - public ItemColorType type() { - return ItemColorTypes.FOLIAGE; - } - - @Override - public int color(ItemStack stack, int tintIndex) { - return ColorHelper.fullAlpha(this.biome.value().getFoliageColor()); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/color/colors/GrassItemColor.java b/src/main/java/net/errorcraft/itematic/item/color/colors/GrassItemColor.java deleted file mode 100644 index 4965f2b4..00000000 --- a/src/main/java/net/errorcraft/itematic/item/color/colors/GrassItemColor.java +++ /dev/null @@ -1,33 +0,0 @@ -package net.errorcraft.itematic.item.color.colors; - -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.item.color.ItemColor; -import net.errorcraft.itematic.item.color.ItemColorType; -import net.errorcraft.itematic.item.color.ItemColorTypes; -import net.minecraft.item.ItemStack; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.registry.entry.RegistryFixedCodec; -import net.minecraft.util.math.ColorHelper; -import net.minecraft.world.biome.Biome; - -public record GrassItemColor(RegistryEntry biome) implements ItemColor { - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - RegistryFixedCodec.of(RegistryKeys.BIOME).fieldOf("biome").forGetter(GrassItemColor::biome) - ).apply(instance, GrassItemColor::new)); - - public static GrassItemColor of(RegistryEntry biome) { - return new GrassItemColor(biome); - } - - @Override - public ItemColorType type() { - return ItemColorTypes.GRASS; - } - - @Override - public int color(ItemStack stack, int tintIndex) { - return ColorHelper.fullAlpha(this.biome.value().getGrassColorAt(0.0d, 0.0d)); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/color/colors/IndexItemColor.java b/src/main/java/net/errorcraft/itematic/item/color/colors/IndexItemColor.java deleted file mode 100644 index b8c6c219..00000000 --- a/src/main/java/net/errorcraft/itematic/item/color/colors/IndexItemColor.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.errorcraft.itematic.item.color.colors; - -import com.google.common.primitives.Ints; -import com.mojang.serialization.Codec; -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.item.color.ItemColor; -import net.errorcraft.itematic.item.color.ItemColorType; -import net.errorcraft.itematic.item.color.ItemColorTypes; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.ColorHelper; - -import java.util.List; - -public record IndexItemColor(List indices) implements ItemColor { - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - Codec.INT.listOf().fieldOf("indices").forGetter(IndexItemColor::indices) - ).apply(instance, IndexItemColor::new)); - - public static IndexItemColor of(int... indices) { - return new IndexItemColor(Ints.asList(indices)); - } - - @Override - public ItemColorType type() { - return ItemColorTypes.INDEX; - } - - @Override - public int color(ItemStack stack, int tintIndex) { - if (tintIndex < 0 || tintIndex >= indices.size()) { - return DEFAULT_COLOR; - } - - return ColorHelper.fullAlpha(this.indices.get(tintIndex)); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/color/colors/MapItemColor.java b/src/main/java/net/errorcraft/itematic/item/color/colors/MapItemColor.java deleted file mode 100644 index baa8bff3..00000000 --- a/src/main/java/net/errorcraft/itematic/item/color/colors/MapItemColor.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.errorcraft.itematic.item.color.colors; - -import com.mojang.serialization.MapCodec; -import net.errorcraft.itematic.item.color.ItemColor; -import net.errorcraft.itematic.item.color.ItemColorType; -import net.errorcraft.itematic.item.color.ItemColorTypes; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.MapColorComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.ColorHelper; - -public record MapItemColor() implements ItemColor { - public static final MapItemColor INSTANCE = new MapItemColor(); - public static final MapCodec CODEC = MapCodec.unit(INSTANCE); - - @Override - public ItemColorType type() { - return ItemColorTypes.MAP; - } - - @Override - public int color(ItemStack stack, int tintIndex) { - if (tintIndex == 0) { - return DEFAULT_COLOR; - } - - return ColorHelper.fullAlpha(stack.getOrDefault(DataComponentTypes.MAP_COLOR, MapColorComponent.DEFAULT).rgb()); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/color/colors/PotionItemColor.java b/src/main/java/net/errorcraft/itematic/item/color/colors/PotionItemColor.java deleted file mode 100644 index 60dab5af..00000000 --- a/src/main/java/net/errorcraft/itematic/item/color/colors/PotionItemColor.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.errorcraft.itematic.item.color.colors; - -import com.mojang.serialization.MapCodec; -import net.errorcraft.itematic.item.color.ItemColor; -import net.errorcraft.itematic.item.color.ItemColorType; -import net.errorcraft.itematic.item.color.ItemColorTypes; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.PotionContentsComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.ColorHelper; - -public record PotionItemColor() implements ItemColor { - public static final PotionItemColor INSTANCE = new PotionItemColor(); - public static final MapCodec CODEC = MapCodec.unit(INSTANCE); - - @Override - public ItemColorType type() { - return ItemColorTypes.POTION; - } - - @Override - public int color(ItemStack stack, int tintIndex) { - if (tintIndex != 0) { - return DEFAULT_COLOR; - } - - return ColorHelper.fullAlpha(stack.getOrDefault(DataComponentTypes.POTION_CONTENTS, PotionContentsComponent.DEFAULT).getColor()); - } -} 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 3105d90e..f247a0e4 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/ItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/ItemComponent.java @@ -2,12 +2,11 @@ import com.mojang.serialization.Codec; import net.errorcraft.itematic.item.ItemResult; -import net.errorcraft.itematic.item.ItemStackConsumer; import net.errorcraft.itematic.registry.ItematicRegistries; import net.errorcraft.itematic.serialization.SetMapCodec; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; import net.minecraft.block.BlockState; import net.minecraft.component.ComponentMap; -import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; @@ -21,8 +20,8 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import java.util.List; import java.util.Set; +import java.util.function.Consumer; public interface ItemComponent> { SetMapCodec, ItemComponent> SET_MAP_CODEC = SetMapCodec.ofRegistry(ItematicRegistries.ITEM_COMPONENT_TYPE, ItemComponentType::codec, ItemComponent::codec, ItemComponent::type); @@ -31,41 +30,38 @@ public interface ItemComponent> { ItemComponentType type(); Codec codec(); - default ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + default ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { return ItemResult.PASS; } - default ItemResult useOnBlock(ItemUsageContext context, ItemStackConsumer resultStackConsumer) { + default ItemResult useOnBlock(ItemUsageContext context, ItemStackExchanger stackExchanger) { return ItemResult.PASS; } - default ItemResult useOnEntity(PlayerEntity user, LivingEntity target, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + default ItemResult useOnEntity(PlayerEntity user, LivingEntity target, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { return ItemResult.PASS; } - default boolean postHit(ItemStack stack, LivingEntity target, LivingEntity attacker, ItemStackConsumer resultStackConsumer) { - return false; + default void postHit(ItemStack stack, LivingEntity target, LivingEntity attacker, ItemStackExchanger stackExchanger) { } - default boolean postMine(ItemStack stack, World world, BlockState state, BlockPos pos, LivingEntity miner, ItemStackConsumer resultStackConsumer) { + default boolean postMine(ItemStack stack, World world, BlockState state, BlockPos pos, LivingEntity miner, ItemStackExchanger stackExchanger) { return false; } default void using(ItemStack stack, World world, LivingEntity user, int usedTicks, int remainingUseTicks) {} - default boolean 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, ItemStackExchanger stackExchanger) { return false; } - default void finishUsing(World world, LivingEntity user, ItemStack stack, int usedTicks, ItemStackConsumer resultStackConsumer) {} - - default void inventoryTick(ItemStack stack, World world, Entity holder, int slot, boolean selected) {} + default void finishUsing(World world, LivingEntity user, ItemStack stack, int usedTicks, ItemStackExchanger stackExchanger) {} default boolean clickOnSlot(ItemStack stack, Slot slot, ClickType clickType, PlayerEntity user) { return false; } - default boolean clickedOnWithStack(ItemStack stack, ItemStack cursorStack, Slot slot, ClickType clickType, PlayerEntity user, ItemStackConsumer resultStackConsumer) { + default boolean clickedOnWithStack(ItemStack stack, ItemStack cursorStack, Slot slot, ClickType clickType, PlayerEntity user, ItemStackExchanger stackExchanger) { return false; } @@ -73,5 +69,5 @@ default void onCraft(ItemStack stack, World world) {} default void addComponents(ComponentMap.Builder builder) {} - default void appendTooltip(ItemStack stack, Item.TooltipContext context, List tooltip, TooltipType type) {} + default void appendTooltip(ItemStack stack, Item.TooltipContext context, Consumer builder, TooltipType type) {} } 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 2a328944..361b852a 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/ItemComponentTypes.java +++ b/src/main/java/net/errorcraft/itematic/item/component/ItemComponentTypes.java @@ -23,7 +23,6 @@ public class ItemComponentTypes { public static final ItemComponentType COOLDOWN = register("cooldown", new ItemComponentType<>(CooldownItemComponent.CODEC)); 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 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)); @@ -33,13 +32,10 @@ public class ItemComponentTypes { public static final ItemComponentType FIREWORK = register("firework", new ItemComponentType<>(FireworkItemComponent.CODEC)); public static final ItemComponentType BUCKET = register("bucket", new ItemComponentType<>(BucketItemComponent.CODEC)); public static final ItemComponentType CONSUMABLE = register("consumable", new ItemComponentType<>(ConsumableItemComponent.CODEC)); - public static final ItemComponentType POTION = register("potion", new ItemComponentType<>(PotionItemComponent.CODEC)); public static final ItemComponentType POTION_HOLDER = register("potion_holder", new ItemComponentType<>(PotionHolderItemComponent.CODEC)); - public static final ItemComponentType SADDLE = register("saddle", new ItemComponentType<>(SaddleItemComponent.CODEC)); public static final ItemComponentType STEERING = register("steering", new ItemComponentType<>(SteeringItemComponent.CODEC)); - public static final ItemComponentType POINTABLE = register("pointable", new ItemComponentType<>(PointableItemComponent.CODEC)); public static final ItemComponentType PREVENT_USE_WHEN_USED_ON_TARGET = register("prevent_use_when_used_on_target", new ItemComponentType<>(PreventUseWhenUsedOnTargetItemComponent.CODEC)); - public static final ItemComponentType SMITHING_TEMPLATE = register("smithing_template", new ItemComponentType<>(SmithingTemplateItemComponent.CODEC)); + public static final ItemComponentType SMITHING_TEMPLATE_PROVIDER = register("smithing_template_provider", new ItemComponentType<>(SmithingTemplateProviderItemComponent.CODEC)); public static final ItemComponentType BANNER_PATTERN = register("banner_pattern", new ItemComponentType<>(BannerPatternItemComponent.CODEC)); public static final ItemComponentType BANNER_PATTERN_HOLDER = register("banner_pattern_holder", new ItemComponentType<>(BannerPatternHolderItemComponent.CODEC)); public static final ItemComponentType WRITABLE = register("writable", new ItemComponentType<>(WritableItemComponent.CODEC)); @@ -59,6 +55,8 @@ public class ItemComponentTypes { public static final ItemComponentType STACKABLE = register("stackable", new ItemComponentType<>(StackableItemComponent.CODEC)); public static final ItemComponentType OMINOUS_EFFECT_PROVIDER = register("ominous_effect_provider", new ItemComponentType<>(OminousEffectProviderItemComponent.CODEC)); public static final ItemComponentType GLIDER = register("glider", new ItemComponentType<>(GliderItemComponent.CODEC)); + public static final ItemComponentType ATTACK_BLOCKING = register("attack_blocking", new ItemComponentType<>(AttackBlockingItemComponent.CODEC)); + public static final ItemComponentType TRIM_MATERIAL_PROVIDER = register("trim_material_provider", new ItemComponentType<>(TrimMaterialProviderItemComponent.CODEC)); private ItemComponentTypes() {} diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/AttackBlockingItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/AttackBlockingItemComponent.java new file mode 100644 index 00000000..33d9e2ad --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/item/component/components/AttackBlockingItemComponent.java @@ -0,0 +1,35 @@ +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.ItemComponentType; +import net.errorcraft.itematic.item.component.ItemComponentTypes; +import net.minecraft.component.ComponentMap; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.BlocksAttacksComponent; + +public record AttackBlockingItemComponent(BlocksAttacksComponent blocksAttacks) implements ItemComponent { + public static final Codec CODEC = BlocksAttacksComponent.CODEC.xmap( + AttackBlockingItemComponent::new, + AttackBlockingItemComponent::blocksAttacks + ); + + public static AttackBlockingItemComponent of(BlocksAttacksComponent blocksAttacks) { + return new AttackBlockingItemComponent(blocksAttacks); + } + + @Override + public ItemComponentType type() { + return ItemComponentTypes.ATTACK_BLOCKING; + } + + @Override + public Codec codec() { + return CODEC; + } + + @Override + public void addComponents(ComponentMap.Builder builder) { + builder.add(DataComponentTypes.BLOCKS_ATTACKS, this.blocksAttacks); + } +} diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/BannerPatternHolderItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/BannerPatternHolderItemComponent.java index bbed680d..a7550a1e 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/BannerPatternHolderItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/BannerPatternHolderItemComponent.java @@ -8,14 +8,9 @@ import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.BannerPatternsComponent; -import net.minecraft.item.BannerItem; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.text.Text; import net.minecraft.util.DyeColor; -import java.util.List; import java.util.Optional; public record BannerPatternHolderItemComponent(Optional color) implements ItemComponent { @@ -38,11 +33,6 @@ public void addComponents(ComponentMap.Builder builder) { builder.add(DataComponentTypes.BANNER_PATTERNS, BannerPatternsComponent.DEFAULT); } - @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, List tooltip, TooltipType type) { - BannerItem.appendBannerTooltip(stack, tooltip); - } - public boolean modifiable() { return this.color.isPresent(); } @@ -51,11 +41,13 @@ public Optional translationKey(ItemStack stack, String baseTranslationKe if (this.modifiable()) { return Optional.empty(); } + DyeColor baseColor = stack.get(DataComponentTypes.BASE_COLOR); if (baseColor == null) { return Optional.empty(); } - return Optional.of(baseTranslationKey + "." + baseColor.getName()); + + return Optional.of(baseTranslationKey + "." + baseColor.getId()); } public static BannerPatternHolderItemComponent of() { diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/BannerPatternItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/BannerPatternItemComponent.java index 63192597..ee51bdcb 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/BannerPatternItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/BannerPatternItemComponent.java @@ -6,6 +6,8 @@ import net.errorcraft.itematic.item.component.ItemComponentType; import net.errorcraft.itematic.item.component.ItemComponentTypes; import net.minecraft.block.entity.BannerPattern; +import net.minecraft.component.ComponentMap; +import net.minecraft.component.DataComponentTypes; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.tag.TagKey; @@ -30,4 +32,9 @@ public ItemComponentType type() { public Codec codec() { return CODEC; } + + @Override + public void addComponents(ComponentMap.Builder builder) { + builder.add(DataComponentTypes.PROVIDES_BANNER_PATTERNS, this.patterns); + } } 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 5a12028c..6939165a 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 @@ -3,7 +3,6 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.item.ItemResult; -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; @@ -13,6 +12,7 @@ import net.errorcraft.itematic.item.placement.block.picker.pickers.SimpleBlockPicker; import net.errorcraft.itematic.mixin.item.ItemAccessor; import net.errorcraft.itematic.serialization.SetCodec; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; import net.minecraft.block.Block; import net.minecraft.block.ShulkerBoxBlock; import net.minecraft.component.ComponentMap; @@ -20,13 +20,10 @@ import net.minecraft.component.type.ContainerComponent; import net.minecraft.entity.ItemEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUsage; import net.minecraft.item.ItemUsageContext; -import net.minecraft.item.tooltip.TooltipType; import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.text.Text; import net.minecraft.util.Hand; import net.minecraft.util.StringIdentifiable; import net.minecraft.util.hit.BlockHitResult; @@ -35,7 +32,6 @@ import net.minecraft.world.RaycastContext; import net.minecraft.world.World; -import java.util.List; import java.util.Set; public record BlockItemComponent(BlockPicker block, boolean operatorOnly, Set passes) implements ItemComponent { @@ -76,7 +72,7 @@ public Codec codec() { } @Override - public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { if (this.isUnuseable(Pass.FLUID)) { return ItemResult.PASS; } @@ -87,15 +83,16 @@ public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack } ItemUsageContext context = new ItemUsageContext(world, user, hand, stack, blockHitResult); - return this.place(context, resultStackConsumer); + return this.place(context, stackExchanger); } @Override - public ItemResult useOnBlock(ItemUsageContext context, ItemStackConsumer resultStackConsumer) { + public ItemResult useOnBlock(ItemUsageContext context, ItemStackExchanger stackExchanger) { if (this.isUnuseable(Pass.BLOCK)) { return ItemResult.PASS; } - return this.place(context, resultStackConsumer); + + return this.place(context, stackExchanger); } @Override @@ -103,11 +100,6 @@ public void addComponents(ComponentMap.Builder builder) { this.block.defaultBlock().value().itematic$addComponents(builder); } - @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, List tooltip, TooltipType type) { - this.block.defaultBlock().value().appendTooltip(stack, context, tooltip, type); - } - public boolean canBeNested() { return !(this.block.defaultBlock().value() instanceof ShulkerBoxBlock); } @@ -123,8 +115,8 @@ private boolean isUnuseable(Pass pass) { return !this.passes.contains(pass); } - private ItemResult place(ItemUsageContext context, ItemStackConsumer resultStackConsumer) { - return BlockPlacer.of(context, resultStackConsumer, this.block, this.operatorOnly, true) + private ItemResult place(ItemUsageContext context, ItemStackExchanger stackExchanger) { + return BlockPlacer.of(context, stackExchanger, this.block, this.operatorOnly, true) .place(); } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/BucketItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/BucketItemComponent.java index 96aadb63..27cef2ea 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/BucketItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/BucketItemComponent.java @@ -2,13 +2,9 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.entity.initializer.EntityInitializer; -import net.errorcraft.itematic.entity.initializer.initializers.SimpleEntityInitializer; import net.errorcraft.itematic.fluid.FluidKeys; -import net.errorcraft.itematic.inventory.StackReferenceUtil; import net.errorcraft.itematic.item.ItemKeys; import net.errorcraft.itematic.item.ItemResult; -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; @@ -21,6 +17,10 @@ import net.errorcraft.itematic.item.placement.block.picker.BlockPicker; import net.errorcraft.itematic.item.placement.block.picker.pickers.SimpleBlockPicker; import net.errorcraft.itematic.mixin.item.ItemAccessor; +import net.errorcraft.itematic.util.context.ItematicContextParameters; +import net.errorcraft.itematic.world.action.context.ActionContext; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; +import net.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.block.Block; import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; @@ -28,17 +28,19 @@ import net.minecraft.entity.Bucketable; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; +import net.minecraft.entity.SpawnReason; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.fluid.Fluid; -import net.minecraft.inventory.StackReference; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemUsage; import net.minecraft.item.ItemUsageContext; +import net.minecraft.loot.context.LootContextParameters; +import net.minecraft.registry.Registries; import net.minecraft.registry.RegistryEntryLookup; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.registry.entry.RegistryFixedCodec; +import net.minecraft.server.world.ServerWorld; import net.minecraft.sound.SoundEvent; import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; @@ -101,12 +103,13 @@ public Codec codec() { } @Override - public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { BlockHitResult blockHitResult = ItemAccessor.raycast(world, user, this.getFluidHandling()); if (blockHitResult.getType() != HitResult.Type.BLOCK) { return ItemResult.PASS; } - return this.place(world, user, hand, stack, resultStackConsumer, blockHitResult); + + return this.place(world, user, hand, stack, stackExchanger, blockHitResult); } @Override @@ -116,23 +119,23 @@ public void addComponents(ComponentMap.Builder builder) { } } - public ItemResult place(World world, @Nullable PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer, BlockHitResult blockHitResult) { - StackReference stackReference = StackReferenceUtil.of(stack); + public ItemResult place(World world, @Nullable PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger, BlockHitResult blockHitResult) { ItemResult result = ItemResult.PASS; if (this.fluid.isPresent()) { - FluidPlacer fluidPlacer = FluidPlacer.of(stack, stackReference::set, world, blockHitResult, user, this.fluid.get(), this.emptyingSound.orElse(null)); + FluidPlacer fluidPlacer = FluidPlacer.of(stack, stackExchanger, world, blockHitResult, user, this.fluid.get(), this.emptyingSound.orElse(null)); result = place(fluidPlacer, result); } if (this.block.isPresent()) { ItemUsageContext context = new ItemUsageContext(world, user, hand, stack, blockHitResult); - BlockPlacer blockPlacer = BlockPlacer.of(context, stackReference::set, this.block.get(), false, false); + BlockPlacer blockPlacer = BlockPlacer.of(context, stackExchanger, this.block.get(), false, false); result = place(blockPlacer, result); } - result = this.tryPlaceEntity(world, user, hand, stack, blockHitResult, stackReference, result); + result = this.tryPlaceEntity(world, user, hand, stack, blockHitResult, stackExchanger, result); if (result.succeeds()) { - resultStackConsumer.set(this.getResultStack(user, stack, stackReference.get())); + stack.decrementUnlessCreative(1, user); + this.transformsInto.map(ItemStack::new).ifPresent(stackExchanger::exchange); } return result; @@ -150,12 +153,13 @@ private RaycastContext.FluidHandling getFluidHandling() { return RaycastContext.FluidHandling.NONE; } - private ItemResult tryPlaceEntity(World world, @Nullable PlayerEntity user, Hand hand, ItemStack stack, BlockHitResult blockHitResult, StackReference stackReference, ItemResult currentResult) { + private ItemResult tryPlaceEntity(World world, @Nullable PlayerEntity user, Hand hand, ItemStack stack, BlockHitResult blockHitResult, ItemStackExchanger stackExchanger, ItemResult currentResult) { if (this.entity.isEmpty()) { return currentResult; } - if (this.entity.get().requireOtherSuccessfulPlacement && !currentResult.succeeds()) { + EntityTarget target = this.entity.get(); + if (target.requireOtherSuccessfulPlacement && !currentResult.succeeds()) { return currentResult; } @@ -163,8 +167,25 @@ private ItemResult tryPlaceEntity(World world, @Nullable PlayerEntity user, Hand return currentResult; } - EntityPlacer entityPlacer = EntityPlacer.bucket(stack, stackReference::set, world, blockHitResult, user, this.entity.get().entity, hand); - return place(entityPlacer, currentResult); + ActionContext context = ActionContext.builder((ServerWorld) world) + .stackExchanger(stackExchanger) + .addOptional(LootContextParameters.THIS_ENTITY, user) + .addOptional(LootContextParameters.ORIGIN, user, Entity::getPos) + .add(ItematicContextParameters.INTERACTED_POSITION, blockHitResult.getBlockPos().toCenterPos()) + .add(LootContextParameters.TOOL, stack) + .add(ItematicContextParameters.HAND, hand) + .add(ItematicContextParameters.SIDE, blockHitResult.getSide()) + .build(); + EntityPlacer.of( + target.entity.value(), + context, + false, + SpawnReason.BUCKET, + BucketItemComponent::initializeBucketEntity, + true, + PositionTarget.INTERACTED_POSITION + ).place(); + return ItemResult.CONSUME; } private static ItemResult place(Placer placer, ItemResult currentResult) { @@ -172,19 +193,6 @@ private static ItemResult place(Placer placer, ItemResult currentResult) { return currentResult.max(result); } - private ItemStack getResultStack(@Nullable PlayerEntity player, ItemStack currentStack, ItemStack possibleNewStack) { - if (currentStack == possibleNewStack) { - possibleNewStack = this.transformsInto.map(ItemStack::new).orElse(possibleNewStack); - } - - if (player == null) { - currentStack.decrement(1); - return possibleNewStack; - } - - return ItemUsage.exchangeStack(currentStack, player, possibleNewStack); - } - public static void initializeBucketEntity(Entity entity, ItemStack stack) { if (entity instanceof Bucketable bucketable) { bucketable.copyDataFromNbt(stack.getOrDefault(DataComponentTypes.BUCKET_ENTITY_DATA, NbtComponent.DEFAULT).copyNbt()); @@ -192,14 +200,14 @@ public static void initializeBucketEntity(Entity entity, ItemStack stack) { } } - public record EntityTarget(EntityInitializer entity, boolean requireOtherSuccessfulPlacement) { + public record EntityTarget(RegistryEntry> entity, boolean requireOtherSuccessfulPlacement) { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - EntityInitializer.CODEC.fieldOf("entity").forGetter(EntityTarget::entity), + Registries.ENTITY_TYPE.getEntryCodec().fieldOf("entity").forGetter(EntityTarget::entity), Codec.BOOL.optionalFieldOf("require_other_successful_placement", false).forGetter(EntityTarget::requireOtherSuccessfulPlacement) ).apply(instance, EntityTarget::new)); public static EntityTarget ofRequired(RegistryEntry> entity) { - return new EntityTarget(SimpleEntityInitializer.of(entity.value()), true); + return new EntityTarget(entity, true); } } } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/CastableItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/CastableItemComponent.java index d5a48c81..f95baf3f 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/CastableItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/CastableItemComponent.java @@ -2,16 +2,18 @@ import com.mojang.serialization.Codec; import net.errorcraft.itematic.item.ItemResult; -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.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; +import net.minecraft.SharedConstants; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.FishingBobberEntity; +import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.server.world.ServerWorld; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvents; @@ -20,10 +22,12 @@ import net.minecraft.world.World; import net.minecraft.world.event.GameEvent; -public record CastableItemComponent() implements ItemComponent { +public class CastableItemComponent implements ItemComponent { public static final CastableItemComponent INSTANCE = new CastableItemComponent(); public static final Codec CODEC = Codec.unit(INSTANCE); + private CastableItemComponent() {} + @Override public ItemComponentType type() { return ItemComponentTypes.CASTABLE; @@ -35,21 +39,25 @@ public Codec codec() { } @Override - public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { - if (!this.tryRetract(world, user, stack, resultStackConsumer)) { + public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { + if (!this.tryRetract(world, user, stack, stackExchanger)) { this.cast(world, user, stack); } + return ItemResult.SUCCEED; } - private boolean tryRetract(World world, PlayerEntity user, ItemStack stack, ItemStackConsumer resultStackConsumer) { + private boolean tryRetract(World world, PlayerEntity user, ItemStack stack, ItemStackExchanger stackExchanger) { if (user.fishHook == null) { return false; } if (world instanceof ServerWorld serverWorld) { - ActionContext context = ActionContext.builder(serverWorld, stack, resultStackConsumer) - .entityPosition(ActionContextParameter.THIS, user) + ActionContext context = ActionContext.builder(serverWorld) + .stackExchanger(stackExchanger) + .add(LootContextParameters.THIS_ENTITY, user) + .add(LootContextParameters.ORIGIN, user.getPos()) + .add(LootContextParameters.TOOL, stack) .build(); stack.itematic$damage(user.fishHook.use(stack), context); } @@ -63,8 +71,8 @@ private void cast(World world, PlayerEntity user, ItemStack stack) { world.playSound(null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENTITY_FISHING_BOBBER_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); if (world instanceof ServerWorld serverWorld) { int luck = EnchantmentHelper.getFishingLuckBonus(serverWorld, stack, user); - int speed = (int) (EnchantmentHelper.getFishingTimeReduction(serverWorld, stack, user) * 20); - world.spawnEntity(new FishingBobberEntity(user, world, luck, speed, stack)); + int speed = (int) (EnchantmentHelper.getFishingTimeReduction(serverWorld, stack, user) * SharedConstants.TICKS_PER_SECOND); + ProjectileEntity.spawn(new FishingBobberEntity(user, world, luck, speed), serverWorld, stack); } user.incrementStat(Stats.USED.itematic$getOrCreateStat(stack.getRegistryEntry())); 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 d5384498..5cbdf833 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 @@ -3,14 +3,14 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.component.type.UseDurationDataComponent; -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.event.ItemEvents; import net.errorcraft.itematic.mixin.component.type.ConsumableComponentAccessor; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; import net.minecraft.advancement.criterion.Criteria; import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; @@ -21,6 +21,7 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.consume.UseAction; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; @@ -76,19 +77,25 @@ public void addComponents(ComponentMap.Builder builder) { builder.add(DataComponentTypes.CONSUMABLE, new ConsumableComponent(0.0f, UseAction.NONE, this.sound, this.hasConsumeParticles, List.of())); } - public void consume(LivingEntity user, ItemStack stack, ItemStackConsumer resultStackConsumer, World world, Hand hand) { - if (!(user instanceof PlayerEntity player)) { - return; - } - + public void consume(LivingEntity user, ItemStack stack, ItemStackExchanger stackExchanger, World world, Hand hand) { if (world instanceof ServerWorld serverWorld) { - ActionContext context = ActionContext.builder(serverWorld, stack, resultStackConsumer, hand) - .entityPosition(ActionContextParameter.THIS, user) + ActionContext context = ActionContext.builder(serverWorld) + .stackExchanger(stackExchanger) + .add(LootContextParameters.THIS_ENTITY, user) + .add(LootContextParameters.ORIGIN, user.getPos()) + .add(LootContextParameters.TOOL, stack) + .add(ItematicContextParameters.HAND, hand) .build(); stack.itematic$invokeEvent(ItemEvents.CONSUME_ITEM, context); } stack.decrementUnlessCreative(1, user); + if (user instanceof PlayerEntity player) { + this.consumeForPlayer(player, stack); + } + } + + private void consumeForPlayer(PlayerEntity player, ItemStack stack) { if (player instanceof ServerPlayerEntity serverPlayer) { Criteria.CONSUME_ITEM.trigger(serverPlayer, stack); } 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 140fd577..17fb650b 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 @@ -3,10 +3,10 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.item.ItemResult; -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.world.action.context.ItemStackExchanger; import net.minecraft.SharedConstants; import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; @@ -41,7 +41,7 @@ public Codec codec() { } @Override - public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { UseCooldownComponent useCooldown = stack.get(DataComponentTypes.USE_COOLDOWN); if (useCooldown != null) { useCooldown.set(stack, user); 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 55034de6..cf091938 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 @@ -43,17 +43,18 @@ public static DamageableItemComponent ofPreserved(int durability) { } public static ItemComponent[] sword(RegistryEntryLookup blocks, ToolMaterial material, RegistryEntryList repairItems) { - double attackDamage = 4.0d + material.attackDamageBonus(); return new ItemComponent[] { StackableItemComponent.of(1), DamageableItemComponent.of(material.durability()), ToolItemComponent.builder(2) + .preventCreativeDestruction() .rule(ToolComponent.Rule.ofAlwaysDropping(RegistryEntryList.of(blocks.getOrThrow(BlockKeys.COBWEB)), 15.0f)) .rule(ToolComponent.Rule.of(blocks.getOrThrow(BlockTags.SWORD_EFFICIENT), 1.5f)) .build(), WeaponItemComponent.of( 1, - attackDamage, + 0.0f, + 4.0d + material.attackDamageBonus(), 0.4d ), EnchantableItemComponent.of(material), @@ -62,35 +63,30 @@ public static ItemComponent[] sword(RegistryEntryLookup blocks, ToolMa } public static ItemComponent[] shovel(RegistryEntryLookup blocks, ToolMaterial material, RegistryEntryList repairItems) { - return tool(blocks, material, 2.5d, 0.25d, BlockTags.SHOVEL_MINEABLE, repairItems); + return tool(blocks, material, 0.0f, 2.5d, 0.25d, BlockTags.SHOVEL_MINEABLE, repairItems); } public static ItemComponent[] pickaxe(RegistryEntryLookup blocks, ToolMaterial material, RegistryEntryList repairItems) { - return tool(blocks, material, 2.0d, 0.3d, BlockTags.PICKAXE_MINEABLE, repairItems); + return tool(blocks, material, 0.0f, 2.0d, 0.3d, BlockTags.PICKAXE_MINEABLE, repairItems); } public static ItemComponent[] axe(RegistryEntryLookup blocks, ToolMaterial material, double attackDamage, double attackSpeed, RegistryEntryList repairItems) { - return tool(blocks, material, attackDamage, attackSpeed, BlockTags.AXE_MINEABLE, repairItems); + return tool(blocks, material, 5.0f, attackDamage, attackSpeed, BlockTags.AXE_MINEABLE, repairItems); } public static ItemComponent[] hoe(RegistryEntryLookup blocks, ToolMaterial material, double attackDamage, double attackSpeed, RegistryEntryList repairItems) { - return tool(blocks, material, attackDamage, attackSpeed, BlockTags.HOE_MINEABLE, repairItems); + return tool(blocks, material, 0.0f, attackDamage, attackSpeed, BlockTags.HOE_MINEABLE, repairItems); } - @Override - public ItemComponentType type() { - return ItemComponentTypes.DAMAGEABLE; - } - - private static ItemComponent[] tool(RegistryEntryLookup blocks, ToolMaterial material, double attackDamage, double attackSpeed, TagKey mineableBlocks, RegistryEntryList repairItems) { - double realAttackDamage = attackDamage + material.attackDamageBonus(); + private static ItemComponent[] tool(RegistryEntryLookup blocks, ToolMaterial material, float disableBlockingForSeconds, double baseAttackDamage, double attackSpeed, TagKey mineableBlocks, RegistryEntryList repairItems) { return new ItemComponent[] { StackableItemComponent.of(1), DamageableItemComponent.of(material.durability()), ToolItemComponent.of(blocks, material, mineableBlocks), WeaponItemComponent.of( 2, - realAttackDamage, + disableBlockingForSeconds, + baseAttackDamage + material.attackDamageBonus(), attackSpeed ), EnchantableItemComponent.of(material), @@ -98,6 +94,11 @@ private static ItemComponent[] tool(RegistryEntryLookup blocks, ToolMa }; } + @Override + public ItemComponentType type() { + return ItemComponentTypes.DAMAGEABLE; + } + @Override public Codec codec() { return CODEC; @@ -107,6 +108,7 @@ public Codec codec() { public void addComponents(ComponentMap.Builder builder) { builder.add(DataComponentTypes.MAX_DAMAGE, this.durability); builder.add(DataComponentTypes.DAMAGE, 0); + this.breakSound.ifPresent(breakSound -> builder.add(DataComponentTypes.BREAK_SOUND, breakSound)); } public int maximumDamage(ItemStack stack) { diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/DebugStickItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/DebugStickItemComponent.java index 0ceeb852..b96fc462 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/DebugStickItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/DebugStickItemComponent.java @@ -2,29 +2,32 @@ import com.mojang.serialization.Codec; import net.errorcraft.itematic.item.ItemResult; -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.DebugStickItemAccessor; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; import net.minecraft.block.BlockState; import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.DebugStickStateComponent; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.DebugStickItem; import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUsageContext; -import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.WorldAccess; -public record DebugStickItemComponent() implements ItemComponent { +public class DebugStickItemComponent implements ItemComponent { public static final DebugStickItemComponent INSTANCE = new DebugStickItemComponent(); public static final Codec CODEC = Codec.unit(INSTANCE); private static final DebugStickItemAccessor DUMMY = (DebugStickItemAccessor) new DebugStickItem(new Item.Settings()); + private DebugStickItemComponent() {} + @Override public ItemComponentType type() { return ItemComponentTypes.DEBUG_STICK; @@ -36,19 +39,22 @@ public Codec codec() { } @Override - public ItemResult useOnBlock(ItemUsageContext context, ItemStackConsumer resultStackConsumer) { + public ItemResult useOnBlock(ItemUsageContext context, ItemStackExchanger stackExchanger) { World world = context.getWorld(); if (world.isClient()) { return ItemResult.PASS; } + PlayerEntity player = context.getPlayer(); if (player == null) { return ItemResult.PASS; } + BlockPos pos = context.getBlockPos(); - if (!DUMMY.callUse(player, world.getBlockState(pos), world, pos, true, context.getStack())) { + if (!DUMMY.itematic$use(player, world.getBlockState(pos), world, pos, true, context.getStack())) { return ItemResult.PASS; } + return ItemResult.SUCCEED; } @@ -57,9 +63,9 @@ public void addComponents(ComponentMap.Builder builder) { builder.add(DataComponentTypes.DEBUG_STICK_STATE, DebugStickStateComponent.DEFAULT); } - public void use(PlayerEntity miner, BlockState state, WorldAccess world, BlockPos pos) { - if (!world.isClient()) { - DUMMY.callUse(miner, state, world, pos, false, miner.getStackInHand(Hand.MAIN_HAND)); + public void use(LivingEntity user, BlockState state, WorldAccess world, BlockPos pos, ItemStack stack) { + if (!world.isClient() && user instanceof PlayerEntity playerUser) { + DUMMY.itematic$use(playerUser, state, world, pos, false, stack); } } } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/DyeItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/DyeItemComponent.java index c96c9f2e..8e27b50f 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/DyeItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/DyeItemComponent.java @@ -2,20 +2,29 @@ import com.mojang.serialization.Codec; import net.errorcraft.itematic.item.ItemResult; -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.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.actions.ModifySignAction; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; +import net.errorcraft.itematic.world.action.context.PositionTarget; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUsageContext; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.DyeColor; public record DyeItemComponent(DyeColor color) implements ItemComponent { public static final Codec CODEC = DyeColor.CODEC.xmap(DyeItemComponent::new, DyeItemComponent::color); + public static DyeItemComponent of(DyeColor color) { + return new DyeItemComponent(color); + } + @Override public ItemComponentType type() { return ItemComponentTypes.DYE; @@ -27,16 +36,21 @@ public Codec codec() { } @Override - public ItemResult useOnBlock(ItemUsageContext context, ItemStackConsumer resultStackConsumer) { + public ItemResult useOnBlock(ItemUsageContext context, ItemStackExchanger stackExchanger) { if (!(context.getWorld() instanceof ServerWorld world)) { return ItemResult.SUCCEED; } - ActionContext actionContext = ActionContext.builder(world, context.getStack(), resultStackConsumer) - .entityPosition(ActionContextParameter.THIS, context.getPlayer()) - .position(ActionContextParameter.TARGET, context.getBlockPos()) + PlayerEntity player = context.getPlayer(); + ItemStack stack = context.getStack(); + ActionContext actionContext = ActionContext.builder(world) + .possibleStackExchanger(player, stack) + .addOptional(LootContextParameters.THIS_ENTITY, player) + .addOptional(LootContextParameters.ORIGIN, player, Entity::getPos) + .add(ItematicContextParameters.INTERACTED_POSITION, context.getBlockPos().toCenterPos()) + .add(LootContextParameters.TOOL, stack) .build(); - ModifySignAction action = ModifySignAction.dye(ActionContextParameter.TARGET, this.color); + ModifySignAction action = ModifySignAction.dye(PositionTarget.INTERACTED_POSITION, this.color); if (action.execute(actionContext)) { context.getStack().decrementUnlessCreative(1, context.getPlayer()); return ItemResult.CONSUME; @@ -44,8 +58,4 @@ public ItemResult useOnBlock(ItemUsageContext context, ItemStackConsumer resultS return ItemResult.PASS; } - - public static DyeItemComponent of(DyeColor color) { - return new DyeItemComponent(color); - } } 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 0ba021c9..31846fb4 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 @@ -1,12 +1,8 @@ package net.errorcraft.itematic.item.component.components; import com.mojang.serialization.Codec; -import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.entity.initializer.EntityInitializer; -import net.errorcraft.itematic.entity.initializer.initializers.SimpleEntityInitializer; import net.errorcraft.itematic.item.ItemResult; -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; @@ -15,22 +11,30 @@ 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.errorcraft.itematic.util.context.ItematicContextParameters; +import net.errorcraft.itematic.world.action.context.ActionContext; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; +import net.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.NbtComponent; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; -import net.minecraft.entity.decoration.painting.PaintingEntity; +import net.minecraft.entity.SpawnReason; +import net.minecraft.entity.decoration.painting.PaintingVariant; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUsageContext; import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.nbt.NbtOps; +import net.minecraft.loot.context.LootContextParameters; +import net.minecraft.registry.Registries; import net.minecraft.registry.RegistryEntryLookup; +import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.server.world.ServerWorld; import net.minecraft.text.Text; -import net.minecraft.util.Formatting; import net.minecraft.util.Hand; import net.minecraft.util.StringIdentifiable; import net.minecraft.util.hit.BlockHitResult; @@ -38,28 +42,26 @@ import net.minecraft.world.RaycastContext; import net.minecraft.world.World; -import java.util.List; -import java.util.Optional; import java.util.Set; +import java.util.function.Consumer; -public record EntityItemComponent(EntityInitializer entity, boolean allowItemData, Set passes) implements ItemComponent { +public record EntityItemComponent(RegistryEntry> entity, boolean allowItemData, Set passes) implements ItemComponent { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - EntityInitializer.CODEC.fieldOf("entity").forGetter(EntityItemComponent::entity), + Registries.ENTITY_TYPE.getEntryCodec().fieldOf("entity").forGetter(EntityItemComponent::entity), 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) { + public static EntityItemComponent of(RegistryEntry> entity) { return new EntityItemComponent(entity, false, Pass.DEFAULT_PASSES); } - public static EntityItemComponent of(EntityInitializer entity, boolean allowItemData, Pass... passes) { + public static EntityItemComponent of(RegistryEntry> entity, boolean allowItemData, Pass... passes) { return new EntityItemComponent(entity, allowItemData, Set.of(passes)); } - public static ItemComponent[] from(EntityInitializer entity, RegistryEntryLookup dispenseBehaviors) { + public static ItemComponent[] from(RegistryEntry> entity, RegistryEntryLookup dispenseBehaviors) { return new ItemComponent[] { of(entity), DispensableItemComponent.of(dispenseBehaviors.getOrThrow(DispenseBehaviors.SPAWN_ENTITY_FROM_ITEM)) @@ -77,7 +79,7 @@ public Codec codec() { } @Override - public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { if (this.isUnuseable(Pass.FLUID)) { return ItemResult.PASS; } @@ -92,11 +94,12 @@ public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack } ItemUsageContext itemUsageContext = new ItemUsageContext(world, user, hand, stack, blockHitResult); - return this.place(itemUsageContext, resultStackConsumer); + this.place(itemUsageContext, stackExchanger); + return ItemResult.CONSUME; } @Override - public ItemResult useOnBlock(ItemUsageContext context, ItemStackConsumer resultStackConsumer) { + public ItemResult useOnBlock(ItemUsageContext context, ItemStackExchanger stackExchanger) { if (this.isUnuseable(Pass.BLOCK)) { return ItemResult.PASS; } @@ -105,59 +108,74 @@ public ItemResult useOnBlock(ItemUsageContext context, ItemStackConsumer resultS return ItemResult.SUCCEED; } - return this.place(context, resultStackConsumer); + this.place(context, stackExchanger); + return ItemResult.CONSUME; } @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, List tooltip, TooltipType type) { - if (this.entity.type() != EntityType.PAINTING) { + public void appendTooltip(ItemStack stack, Item.TooltipContext context, Consumer builder, TooltipType type) { + if (this.entity.value() != EntityType.PAINTING) { return; } - RegistryWrapper.WrapperLookup lookup = context.getRegistryLookup(); - if (lookup == null) { - return; - } - - NbtComponent entityData = stack.getOrDefault(DataComponentTypes.ENTITY_DATA, NbtComponent.DEFAULT); - if (!entityData.isEmpty()) { - entityData.get(lookup.getOps(NbtOps.INSTANCE), PaintingEntity.VARIANT_MAP_CODEC).result().ifPresentOrElse( - variant -> { - variant.getKey().ifPresent((key) -> { - tooltip.add(Text.translatable(key.getValue().toTranslationKey("painting", "title")).formatted(Formatting.YELLOW)); - tooltip.add(Text.translatable(key.getValue().toTranslationKey("painting", "author")).formatted(Formatting.GRAY)); - }); - tooltip.add(Text.translatable("painting.dimensions", variant.value().width(), variant.value().height())); - }, - () -> tooltip.add(RANDOM_TEXT) - ); - return; - } - - if (type.isCreative()) { - tooltip.add(RANDOM_TEXT); + RegistryEntry paintingVariant = stack.get(DataComponentTypes.PAINTING_VARIANT); + if (paintingVariant != null) { + paintingVariant.value().title().ifPresent(builder); + paintingVariant.value().author().ifPresent(builder); + builder.accept(Text.translatable("painting.dimensions", paintingVariant.value().width(), paintingVariant.value().height())); + } else if (type.isCreative()) { + builder.accept(RANDOM_TEXT); } } - public EntityInitializer getEntityInitializer(ItemStack stack) { + public EntityType entityType(ItemStack stack, RegistryWrapper.WrapperLookup registries) { if (!this.allowItemData) { - return this.entity; + return this.entity.value(); } 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); + EntityType entityType = entityData.getRegistryValueOfId(registries, RegistryKeys.ENTITY_TYPE); + if (entityType == null) { + return this.entity.value(); + } + + return entityType; } private boolean isUnuseable(Pass pass) { return !this.passes.contains(pass); } - private ItemResult place(ItemUsageContext context, ItemStackConsumer resultStackConsumer) { - return EntityPlacer.spawned(context, context.getStack(), resultStackConsumer, this) - .place(); + private void place(ItemUsageContext context, ItemStackExchanger stackExchanger) { + if (!(context.getWorld() instanceof ServerWorld world)) { + return; + } + + ActionContext actionContext = ActionContext.builder(world) + .stackExchanger(stackExchanger) + .addOptional(LootContextParameters.THIS_ENTITY, context.getPlayer()) + .addOptional(LootContextParameters.ORIGIN, context.getPlayer(), Entity::getPos) + .add(ItematicContextParameters.INTERACTED_POSITION, context.getBlockPos().toCenterPos()) + .add(LootContextParameters.TOOL, context.getStack()) + .add(ItematicContextParameters.HAND, context.getHand()) + .add(ItematicContextParameters.SIDE, context.getSide()) + .build(); + this.place(actionContext); + } + + public Entity place(ActionContext context) { + return EntityPlacer.of( + this.entityType( + context.getOrDefault(LootContextParameters.TOOL, ItemStack.EMPTY), + context.world().getRegistryManager() + ), + context, + true, + SpawnReason.SPAWN_ITEM_USE, + null, + this.allowItemData, + PositionTarget.INTERACTED_POSITION + ).place(); } public enum Pass implements StringIdentifiable { diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/EquipmentItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/EquipmentItemComponent.java index 45f4897e..ed61870c 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/EquipmentItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/EquipmentItemComponent.java @@ -2,29 +2,33 @@ import com.mojang.serialization.Codec; import net.errorcraft.itematic.item.ItemResult; -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.dispense.behavior.DispenseBehavior; import net.errorcraft.itematic.item.dispense.behavior.DispenseBehaviors; import net.errorcraft.itematic.item.event.ItemEvents; +import net.errorcraft.itematic.sound.SoundEventKeys; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; import net.minecraft.block.Block; import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.EquippableComponent; import net.minecraft.component.type.FireworkExplosionComponent; +import net.minecraft.entity.EntityType; import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.AnimalArmorItem; import net.minecraft.item.ItemStack; import net.minecraft.item.equipment.ArmorMaterial; import net.minecraft.item.equipment.EquipmentType; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.registry.RegistryEntryLookup; import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.tag.EntityTypeTags; import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundEvent; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.math.Direction; @@ -37,43 +41,29 @@ public static EquipmentItemComponent of(EquippableComponent equippable) { return new EquipmentItemComponent(equippable); } - private static EquipmentItemComponent of(ArmorMaterial material, EquipmentType type, AnimalArmorItem.Type animalType) { - return new EquipmentItemComponent(EquippableComponent.builder(type.getEquipmentSlot()) - .swappable(true) - .equipSound(material.equipSound()) - .model(material.modelId()) - .allowedEntities(animalType.itematic$allowedEntities()) - .build()); + public static EquipmentItemComponent ofHorseArmor(ArmorMaterial material, RegistryEntryLookup soundEvents, RegistryEntryLookup> entityTypes) { + return of(EquippableComponent.builder(EquipmentSlot.BODY) + .equipSound(soundEvents.getOrThrow(SoundEventKeys.HORSE_ARMOR)) + .model(material.assetId()) + .allowedEntities(entityTypes.getOrThrow(EntityTypeTags.CAN_WEAR_HORSE_ARMOR)) + .damageOnHurt(false) + .build() + ); } - public static ItemComponent[] from(ArmorMaterial material, EquipmentType type) { + public static ItemComponent[] forArmor(ArmorMaterial material, EquipmentType type) { return new ItemComponent[] { StackableItemComponent.of(1), of(EquippableComponent.builder(type.getEquipmentSlot()) .swappable(true) .equipSound(material.equipSound()) - .model(material.modelId()) + .model(material.assetId()) .build()), DamageableItemComponent.of(type.getMaxDamage(material.durability())), }; } - public static ItemComponent[] from(ArmorMaterial material, EquipmentType type, AnimalArmorItem.Type animalType) { - return new ItemComponent[] { - StackableItemComponent.of(1), - of(material, type, animalType) - }; - } - - public static ItemComponent[] fromDamageable(ArmorMaterial material, EquipmentType type, AnimalArmorItem.Type animalType) { - return new ItemComponent[] { - StackableItemComponent.of(1), - DamageableItemComponent.of(type.getMaxDamage(material.durability()), animalType.itematic$breakSound()), - of(material, type, animalType) - }; - } - - public static ItemComponent[] skull(RegistryEntry attachedBlock, RegistryEntry otherBlock, RegistryEntryLookup dispenseBehaviors) { + public static ItemComponent[] forSkull(RegistryEntry attachedBlock, RegistryEntry otherBlock, RegistryEntryLookup dispenseBehaviors) { return new ItemComponent[] { BlockItemComponent.attachedToSide(attachedBlock, otherBlock, Direction.DOWN), new EquipmentItemComponent(EquippableComponent.builder(EquipmentSlot.HEAD) @@ -95,7 +85,7 @@ public Codec codec() { } @Override - public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { EquippableComponent equippable = stack.get(DataComponentTypes.EQUIPPABLE); if (equippable == null) { return ItemResult.PASS; @@ -111,12 +101,16 @@ public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack } if (result instanceof ActionResult.Success success) { - resultStackConsumer.set(success.getNewHandStack()); + stackExchanger.exchange(success.getNewHandStack()); } if (world instanceof ServerWorld serverWorld) { - ActionContext context = ActionContext.builder(serverWorld, stack, resultStackConsumer, hand) - .entityPosition(ActionContextParameter.THIS, user) + ActionContext context = ActionContext.builder(serverWorld) + .stackExchanger(stackExchanger) + .add(LootContextParameters.THIS_ENTITY, user) + .add(LootContextParameters.ORIGIN, user.getPos()) + .add(LootContextParameters.TOOL, stack) + .add(ItematicContextParameters.HAND, hand) .build(); stack.itematic$invokeEvent(ItemEvents.EQUIP_ITEM, context); } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/FireworkExplosionHolderItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/FireworkExplosionHolderItemComponent.java index a24cd312..b601b22a 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/FireworkExplosionHolderItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/FireworkExplosionHolderItemComponent.java @@ -7,12 +7,6 @@ import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.FireworkExplosionComponent; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.text.Text; - -import java.util.List; public record FireworkExplosionHolderItemComponent() implements ItemComponent { public static final FireworkExplosionHolderItemComponent INSTANCE = new FireworkExplosionHolderItemComponent(); @@ -32,12 +26,4 @@ public Codec codec() { public void addComponents(ComponentMap.Builder builder) { builder.add(DataComponentTypes.FIREWORK_EXPLOSION, FireworkExplosionComponent.DEFAULT); } - - @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, List tooltip, TooltipType type) { - FireworkExplosionComponent explosion = stack.get(DataComponentTypes.FIREWORK_EXPLOSION); - if (explosion != null) { - explosion.appendTooltip(context, tooltip::add, type); - } - } } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/FireworkItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/FireworkItemComponent.java index 0d22c337..c062f77d 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/FireworkItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/FireworkItemComponent.java @@ -2,22 +2,19 @@ import com.mojang.serialization.Codec; import net.errorcraft.itematic.item.ItemResult; -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.world.action.context.ItemStackExchanger; import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.FireworksComponent; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.FireworkRocketEntity; import net.minecraft.item.FireworkRocketItem; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUsageContext; -import net.minecraft.item.tooltip.TooltipType; import net.minecraft.stat.Stats; -import net.minecraft.text.Text; import net.minecraft.util.Hand; import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; @@ -41,7 +38,7 @@ public Codec codec() { } @Override - public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { if (!user.isGliding()) { return ItemResult.PASS; } @@ -58,7 +55,7 @@ public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack } @Override - public ItemResult useOnBlock(ItemUsageContext context, ItemStackConsumer resultStackConsumer) { + public ItemResult useOnBlock(ItemUsageContext context, ItemStackExchanger stackExchanger) { World world = context.getWorld(); ItemStack stack = context.getStack(); if (world.isClient()) { @@ -76,14 +73,6 @@ public void addComponents(ComponentMap.Builder builder) { builder.add(DataComponentTypes.FIREWORKS, DEFAULT_DATA_COMPONENT); } - @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, List tooltip, TooltipType type) { - FireworksComponent fireworks = stack.get(DataComponentTypes.FIREWORKS); - if (fireworks != null) { - fireworks.appendTooltip(context, tooltip::add, type); - } - } - private static FireworkRocketEntity createFireworkEntity(World world, ItemStack stack, ItemUsageContext context) { Direction direction = context.getSide(); Vec3d position = context.getHitPos().add( 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 1db58158..1bcac9b3 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 @@ -2,19 +2,20 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -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.event.ItemEvents; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.FoodComponent; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.server.world.ServerWorld; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvents; @@ -44,7 +45,7 @@ public Codec codec() { } @Override - public void finishUsing(World world, LivingEntity user, ItemStack stack, int usedTicks, ItemStackConsumer resultStackConsumer) { + public void finishUsing(World world, LivingEntity user, ItemStack stack, int usedTicks, ItemStackExchanger stackExchanger) { FoodComponent food = stack.get(DataComponentTypes.FOOD); if (user instanceof PlayerEntity player) { player.getHungerManager().eat(food); @@ -52,8 +53,12 @@ public void finishUsing(World world, LivingEntity user, ItemStack stack, int use } if (world instanceof ServerWorld serverWorld) { - ActionContext context = ActionContext.builder(serverWorld, stack, resultStackConsumer, user.getActiveHand()) - .entityPosition(ActionContextParameter.THIS, user) + ActionContext context = ActionContext.builder(serverWorld) + .stackExchanger(stackExchanger) + .add(LootContextParameters.THIS_ENTITY, user) + .add(LootContextParameters.ORIGIN, user.getPos()) + .add(LootContextParameters.TOOL, stack) + .add(ItematicContextParameters.HAND, user.getActiveHand()) .build(); stack.itematic$invokeEvent(ItemEvents.EAT_ITEM, context); } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/ItemHolderItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/ItemHolderItemComponent.java index 85938433..c2293e23 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/ItemHolderItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/ItemHolderItemComponent.java @@ -3,7 +3,6 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.component.ItematicDataComponentTypes; -import net.errorcraft.itematic.item.ItemStackConsumer; import net.errorcraft.itematic.item.ItematicItemTags; import net.errorcraft.itematic.item.component.ItemComponent; import net.errorcraft.itematic.item.component.ItemComponentType; @@ -16,6 +15,7 @@ import net.errorcraft.itematic.mixin.item.BundleItemAccessor; import net.errorcraft.itematic.serialization.ItematicCodecs; import net.errorcraft.itematic.sound.SoundEventKeys; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.BundleContentsComponent; @@ -126,7 +126,7 @@ public boolean clickOnSlot(ItemStack stack, Slot slot, ClickType clickType, Play } @Override - public boolean clickedOnWithStack(ItemStack stack, ItemStack cursorStack, Slot slot, ClickType clickType, PlayerEntity user, ItemStackConsumer resultStackConsumer) { + public boolean clickedOnWithStack(ItemStack stack, ItemStack cursorStack, Slot slot, ClickType clickType, PlayerEntity user, ItemStackExchanger stackExchanger) { if (clickType != ClickType.RIGHT || !slot.canTakePartial(user)) { return false; } @@ -137,7 +137,7 @@ public boolean clickedOnWithStack(ItemStack stack, ItemStack cursorStack, Slot s } if (cursorStack.isEmpty()) { - this.remove(user, newBuilder, resultStackConsumer::set); + this.remove(user, newBuilder, stackExchanger::exchange); } else { this.add(newBuilder, cursorStack, user); } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/MapHolderItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/MapHolderItemComponent.java index b31cd038..f3bbc166 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/MapHolderItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/MapHolderItemComponent.java @@ -8,20 +8,17 @@ import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.MapColorComponent; import net.minecraft.component.type.MapDecorationsComponent; -import net.minecraft.entity.Entity; import net.minecraft.item.FilledMapItem; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.text.Text; import net.minecraft.world.World; -import java.util.List; - -public record MapHolderItemComponent() implements ItemComponent { +public class MapHolderItemComponent implements ItemComponent { public static final MapHolderItemComponent INSTANCE = new MapHolderItemComponent(); public static final Codec CODEC = Codec.unit(INSTANCE); - private static final FilledMapItem DUMMY = new FilledMapItem(new Item.Settings()); + public static final FilledMapItem DUMMY = new FilledMapItem(new Item.Settings()); + + private MapHolderItemComponent() {} @Override public ItemComponentType type() { @@ -39,18 +36,8 @@ public void addComponents(ComponentMap.Builder builder) { builder.add(DataComponentTypes.MAP_DECORATIONS, MapDecorationsComponent.DEFAULT); } - @Override - public void inventoryTick(ItemStack stack, World world, Entity holder, int slot, boolean selected) { - DUMMY.inventoryTick(stack, world, holder, slot, selected); - } - @Override public void onCraft(ItemStack stack, World world) { DUMMY.onCraft(stack, world); } - - @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, List tooltip, TooltipType type) { - DUMMY.appendTooltip(stack, context, tooltip, type); - } } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/MappableItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/MappableItemComponent.java index 66c2d9da..f164a6a7 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/MappableItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/MappableItemComponent.java @@ -3,12 +3,11 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.item.ItemResult; -import net.errorcraft.itematic.item.ItemStackConsumer; -import net.errorcraft.itematic.item.ItemUsageUtil; 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.FilledMapItemAccessor; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.MapIdComponent; import net.minecraft.entity.player.PlayerEntity; @@ -17,6 +16,7 @@ import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.registry.entry.RegistryFixedCodec; +import net.minecraft.server.world.ServerWorld; import net.minecraft.sound.SoundEvents; import net.minecraft.stat.Stats; import net.minecraft.util.Hand; @@ -27,6 +27,9 @@ public record MappableItemComponent(RegistryEntry transformsInto) implemen RegistryFixedCodec.of(RegistryKeys.ITEM).fieldOf("transforms_into").forGetter(MappableItemComponent::transformsInto) ).apply(instance, MappableItemComponent::new)); + public static MappableItemComponent of(RegistryEntry transformsInto) { + return new MappableItemComponent(transformsInto); + } @Override public ItemComponentType type() { @@ -39,25 +42,23 @@ public Codec codec() { } @Override - public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { - if (world.isClient()) { + public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { + if (!(world instanceof ServerWorld serverWorld)) { return ItemResult.SUCCEED; } + user.incrementStat(Stats.USED.itematic$getOrCreateStat(stack.getRegistryEntry())); - user.getWorld().playSoundFromEntity(null, user, SoundEvents.UI_CARTOGRAPHY_TABLE_TAKE_RESULT, user.getSoundCategory(), 1.0f, 1.0f); - ItemStack resultStack = this.createStack(world, user.getBlockX(), user.getBlockZ(), 0, true, false); - resultStackConsumer.set(ItemUsageUtil.exchangeStack(stack, user, resultStack, true, true)); + world.playSoundFromEntity(null, user, SoundEvents.UI_CARTOGRAPHY_TABLE_TAKE_RESULT, user.getSoundCategory(), 1.0f, 1.0f); + ItemStack resultStack = this.createStack(serverWorld, user.getBlockX(), user.getBlockZ(), 0, true, false); + stack.decrementUnlessCreative(1, user); + stackExchanger.exchange(resultStack); return ItemResult.CONSUME; } - public ItemStack createStack(World world, int x, int z, int scale, boolean showIcons, boolean unlimitedTracking) { + public ItemStack createStack(ServerWorld world, int x, int z, int scale, boolean showIcons, boolean unlimitedTracking) { ItemStack resultStack = new ItemStack(this.transformsInto); MapIdComponent mapId = FilledMapItemAccessor.allocateMapId(world, x, z, scale, showIcons, unlimitedTracking, world.getRegistryKey()); resultStack.set(DataComponentTypes.MAP_ID, mapId); return resultStack; } - - public static MappableItemComponent of(RegistryEntry transformsInto) { - return new MappableItemComponent(transformsInto); - } } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/OminousEffectProviderItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/OminousEffectProviderItemComponent.java index 83c59a78..2ee15b4a 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/OminousEffectProviderItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/OminousEffectProviderItemComponent.java @@ -1,21 +1,16 @@ 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.world.action.context.ItemStackExchanger; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.OminousBottleAmplifierComponent; import net.minecraft.entity.LivingEntity; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.text.Text; import net.minecraft.world.World; -import java.util.List; - public class OminousEffectProviderItemComponent implements ItemComponent { public static final OminousEffectProviderItemComponent INSTANCE = new OminousEffectProviderItemComponent(); public static final Codec CODEC = Codec.unit(INSTANCE); @@ -33,18 +28,10 @@ public Codec codec() { } @Override - public void finishUsing(World world, LivingEntity user, ItemStack stack, int usedTicks, ItemStackConsumer resultStackConsumer) { + public void finishUsing(World world, LivingEntity user, ItemStack stack, int usedTicks, ItemStackExchanger stackExchanger) { OminousBottleAmplifierComponent ominousAmplifier = stack.get(DataComponentTypes.OMINOUS_BOTTLE_AMPLIFIER); if (ominousAmplifier != null) { ominousAmplifier.onConsume(world, user, stack, null); } } - - @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, List tooltip, TooltipType type) { - OminousBottleAmplifierComponent ominousAmplifier = stack.get(DataComponentTypes.OMINOUS_BOTTLE_AMPLIFIER); - if (ominousAmplifier != null) { - ominousAmplifier.appendTooltip(context, tooltip::add, type); - } - } } 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 156f27bb..2cf14d5c 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 @@ -3,50 +3,43 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.item.ItemResult; -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.providers.PlayableIntegerProvider; import net.errorcraft.itematic.mixin.item.GoatHornItemAccessor; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; import net.minecraft.SharedConstants; +import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.InstrumentComponent; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Instrument; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.consume.UseAction; -import net.minecraft.item.tooltip.TooltipType; -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.registry.entry.RegistryFixedCodec; import net.minecraft.stat.Stats; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; import net.minecraft.util.Hand; -import net.minecraft.util.Util; import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; -import java.util.List; import java.util.Optional; -import java.util.stream.Stream; -public record PlayableItemComponent(TagKey instruments) implements ItemComponent { +public record PlayableItemComponent(RegistryEntry defaultInstrument) implements ItemComponent { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - TagKey.unprefixedCodec(RegistryKeys.INSTRUMENT).fieldOf("instruments").forGetter(PlayableItemComponent::instruments) + RegistryFixedCodec.of(RegistryKeys.INSTRUMENT).fieldOf("default_instrument").forGetter(PlayableItemComponent::defaultInstrument) ).apply(instance, PlayableItemComponent::new)); - public static ItemComponent[] of(TagKey instruments) { + public static ItemComponent[] of(RegistryEntry defaultInstrument) { return new ItemComponent[] { UseableItemComponent.builder() .useFor(PlayableIntegerProvider.INSTANCE) .animation(UseAction.TOOT_HORN) .build(), - new PlayableItemComponent(instruments) + new PlayableItemComponent(defaultInstrument) }; } @@ -61,7 +54,7 @@ public Codec codec() { } @Override - public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { return this.instrument(stack, user.getRegistryManager()) .map(RegistryEntry::value) .map(instrument -> { @@ -73,27 +66,16 @@ public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack } @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, List tooltip, TooltipType type) { - RegistryWrapper.WrapperLookup lookup = context.getRegistryLookup(); - if (lookup == null) { - return; - } - - this.instrument(stack, lookup) - .flatMap(RegistryEntry::getKey) - .map(RegistryKey::getValue) - .ifPresent(id -> tooltip.add(Text.translatable(Util.createTranslationKey("instrument", id)).formatted(Formatting.GRAY))); + public void addComponents(ComponentMap.Builder builder) { + builder.add(DataComponentTypes.INSTRUMENT, new InstrumentComponent(this.defaultInstrument)); } - public Optional> instrument(ItemStack stack, RegistryWrapper.WrapperLookup lookup) { - RegistryEntry instrument = stack.get(DataComponentTypes.INSTRUMENT); - if (instrument != null) { - return Optional.of(instrument); + public Optional> instrument(ItemStack stack, RegistryWrapper.WrapperLookup lookup) { + InstrumentComponent instrument = stack.get(DataComponentTypes.INSTRUMENT); + if (instrument == null) { + return Optional.empty(); } - return lookup.getOrThrow(RegistryKeys.INSTRUMENT) - .getOptional(this.instruments) - .map(RegistryEntryList::stream) - .flatMap(Stream::findFirst); + return instrument.getInstrument(lookup); } } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/PlayableSongItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/PlayableSongItemComponent.java index bcd34972..19db9afd 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/PlayableSongItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/PlayableSongItemComponent.java @@ -8,7 +8,7 @@ import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.JukeboxPlayableComponent; -import net.minecraft.registry.RegistryPair; +import net.minecraft.registry.entry.LazyRegistryEntryReference; import net.minecraft.registry.entry.RegistryEntry; public record PlayableSongItemComponent(RegistryEntry song) implements ItemComponent { @@ -33,6 +33,6 @@ public Codec codec() { @Override public void addComponents(ComponentMap.Builder builder) { - builder.add(DataComponentTypes.JUKEBOX_PLAYABLE, new JukeboxPlayableComponent(new RegistryPair<>(this.song), true)); + builder.add(DataComponentTypes.JUKEBOX_PLAYABLE, new JukeboxPlayableComponent(new LazyRegistryEntryReference<>(this.song))); } } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/PointableItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/PointableItemComponent.java deleted file mode 100644 index 62805cc4..00000000 --- a/src/main/java/net/errorcraft/itematic/item/component/components/PointableItemComponent.java +++ /dev/null @@ -1,67 +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.errorcraft.itematic.item.pointer.Pointer; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.LodestoneTrackerComponent; -import net.minecraft.entity.Entity; -import net.minecraft.item.ItemStack; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.world.World; - -import java.util.Optional; - -public record PointableItemComponent(RegistryEntry pointsTo, Optional lodestoneTranslationKey) implements ItemComponent { - public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - Pointer.ENTRY_CODEC.fieldOf("points_to").forGetter(PointableItemComponent::pointsTo), - Codec.STRING.optionalFieldOf("lodestone_translation_key").forGetter(PointableItemComponent::lodestoneTranslationKey) - ).apply(instance, PointableItemComponent::new)); - - @Override - public ItemComponentType type() { - return ItemComponentTypes.POINTABLE; - } - - @Override - public Codec codec() { - return CODEC; - } - - @Override - public void inventoryTick(ItemStack stack, World world, Entity holder, int slot, boolean selected) { - if (this.lodestoneTranslationKey.isEmpty()) { - return; - } - if (!(world instanceof ServerWorld serverWorld)) { - return; - } - LodestoneTrackerComponent lodestoneTracker = stack.get(DataComponentTypes.LODESTONE_TRACKER); - if (lodestoneTracker == null) { - return; - } - LodestoneTrackerComponent lodestoneTrackerForCurrentWorld = lodestoneTracker.forWorld(serverWorld); - if (lodestoneTrackerForCurrentWorld != lodestoneTracker) { - stack.set(DataComponentTypes.LODESTONE_TRACKER, lodestoneTrackerForCurrentWorld); - } - } - - public Optional lodestoneTranslationKey(ItemStack stack) { - if (stack.contains(DataComponentTypes.LODESTONE_TRACKER)) { - return this.lodestoneTranslationKey; - } - return Optional.empty(); - } - - public static PointableItemComponent of(RegistryEntry pointsTo) { - return new PointableItemComponent(pointsTo, Optional.empty()); - } - - public static PointableItemComponent of(RegistryEntry pointsTo, String lodestoneTranslationKey) { - return new PointableItemComponent(pointsTo, Optional.of(lodestoneTranslationKey)); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/PotionHolderItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/PotionHolderItemComponent.java index c9fe7e8e..f04a51f1 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/PotionHolderItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/PotionHolderItemComponent.java @@ -5,22 +5,24 @@ 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.world.action.context.ItemStackExchanger; import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.PotionContentsComponent; -import net.minecraft.item.Item; +import net.minecraft.entity.LivingEntity; import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.text.Text; import net.minecraft.util.dynamic.Codecs; - -import java.util.List; +import net.minecraft.world.World; public record PotionHolderItemComponent(float durationMultiplier) implements ItemComponent { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( Codecs.POSITIVE_FLOAT.fieldOf("duration_multiplier").forGetter(PotionHolderItemComponent::durationMultiplier) ).apply(instance, PotionHolderItemComponent::new)); + public static PotionHolderItemComponent of(float durationMultiplier) { + return new PotionHolderItemComponent(durationMultiplier); + } + @Override public ItemComponentType type() { return ItemComponentTypes.POTION_HOLDER; @@ -32,26 +34,23 @@ public Codec codec() { } @Override - public void addComponents(ComponentMap.Builder builder) { - builder.add(DataComponentTypes.POTION_CONTENTS, PotionContentsComponent.DEFAULT); - } - - @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, List tooltip, TooltipType type) { + public void finishUsing(World world, LivingEntity user, ItemStack stack, int usedTicks, ItemStackExchanger stackExchanger) { PotionContentsComponent potionContents = stack.get(DataComponentTypes.POTION_CONTENTS); if (potionContents != null) { - potionContents.buildTooltip(tooltip::add, this.durationMultiplier, context.getUpdateTickRate()); + potionContents.apply(user, stack.getOrDefault(DataComponentTypes.POTION_DURATION_SCALE, 1.0f)); } } + @Override + public void addComponents(ComponentMap.Builder builder) { + builder.add(DataComponentTypes.POTION_CONTENTS, PotionContentsComponent.DEFAULT); + builder.add(DataComponentTypes.POTION_DURATION_SCALE, this.durationMultiplier); + } + public String translationKey(ItemStack stack, String baseTranslationKey) { return stack.getOrDefault(DataComponentTypes.POTION_CONTENTS, PotionContentsComponent.DEFAULT) .potion() .map(potion -> baseTranslationKey + ".effect." + potion.value().getBaseName()) .orElseGet(() -> baseTranslationKey + ".effect.empty"); } - - public static PotionHolderItemComponent of(float durationMultiplier) { - return new PotionHolderItemComponent(durationMultiplier); - } } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/PotionItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/PotionItemComponent.java deleted file mode 100644 index 6fee6ffc..00000000 --- a/src/main/java/net/errorcraft/itematic/item/component/components/PotionItemComponent.java +++ /dev/null @@ -1,35 +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.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.PotionContentsComponent; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; - -public record PotionItemComponent() implements ItemComponent { - public static final PotionItemComponent INSTANCE = new PotionItemComponent(); - public static final Codec CODEC = Codec.unit(INSTANCE); - - @Override - public ItemComponentType type() { - return ItemComponentTypes.POTION; - } - - @Override - public Codec codec() { - return CODEC; - } - - @Override - public void finishUsing(World world, LivingEntity user, ItemStack stack, int usedTicks, ItemStackConsumer resultStackConsumer) { - PotionContentsComponent potionContents = stack.get(DataComponentTypes.POTION_CONTENTS); - if (potionContents != null) { - potionContents.apply(user); - } - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/PreventUseWhenUsedOnTargetItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/PreventUseWhenUsedOnTargetItemComponent.java index f235864d..7377d77d 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/PreventUseWhenUsedOnTargetItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/PreventUseWhenUsedOnTargetItemComponent.java @@ -3,10 +3,10 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.item.ItemResult; -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.world.action.context.ItemStackExchanger; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; @@ -34,12 +34,12 @@ public Codec codec() { } @Override - public ItemResult useOnBlock(ItemUsageContext context, ItemStackConsumer resultStackConsumer) { + public ItemResult useOnBlock(ItemUsageContext context, ItemStackExchanger stackExchanger) { return this.block ? ItemResult.CONSUME : ItemResult.PASS; } @Override - public ItemResult useOnEntity(PlayerEntity user, LivingEntity target, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + public ItemResult useOnEntity(PlayerEntity user, LivingEntity target, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { return this.entity ? ItemResult.CONSUME : ItemResult.PASS; } } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/ProjectileItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/ProjectileItemComponent.java index 494ac5bb..99ce80a7 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/ProjectileItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/ProjectileItemComponent.java @@ -2,17 +2,17 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.entity.initializer.EntityInitializer; -import net.errorcraft.itematic.entity.initializer.initializers.PersistentProjectileEntityInitializer; -import net.errorcraft.itematic.entity.initializer.initializers.SimpleEntityInitializer; -import net.errorcraft.itematic.item.ItemStackConsumer; +import net.errorcraft.itematic.entity.EntitySpawner; 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.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; +import net.errorcraft.itematic.world.action.context.PositionTarget; +import net.minecraft.component.ComponentChanges; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.SpawnReason; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.ExplosiveProjectileEntity; @@ -20,27 +20,25 @@ import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.entity.projectile.thrown.ThrownItemEntity; import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Position; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -public record ProjectileItemComponent(EntityInitializer entity) implements ItemComponent { +public record ProjectileItemComponent(EntitySpawner entity) implements ItemComponent { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - EntityInitializer.CODEC.fieldOf("entity").forGetter(ProjectileItemComponent::entity) + EntitySpawner.CODEC.forGetter(ProjectileItemComponent::entity) ).apply(instance, ProjectileItemComponent::new)); - public static ProjectileItemComponent of(EntityInitializer entity) { - return new ProjectileItemComponent(entity); - } - public static ProjectileItemComponent of(RegistryEntry> entity) { - return of(SimpleEntityInitializer.of(entity.value())); + return new ProjectileItemComponent(EntitySpawner.of(entity)); } - public static ProjectileItemComponent persistentProjectile(EntityType entityType, PersistentProjectileEntityInitializer.OwnerCreator ownerCreator, PersistentProjectileEntityInitializer.SimpleCreator simpleCreator) { - return of(new PersistentProjectileEntityInitializer<>(entityType, ownerCreator, simpleCreator)); + public static ProjectileItemComponent of(RegistryEntry> entity, ComponentChanges components) { + return new ProjectileItemComponent(EntitySpawner.of(entity, components)); } @Override @@ -53,42 +51,36 @@ public Codec codec() { return CODEC; } - public Entity createEntity(World world, Entity user, ItemStack stack, float angleOffset, float speed) { + public Entity createEntity(World world, LivingEntity user, ItemStack stack, float angleOffset, float speed) { if (world.isClient()) { return null; } - return this.createEntity((ServerWorld) world, user, stack, ItemStackConsumer.EMPTY, angleOffset, speed, 1.0f); - } - - public Entity createEntity(ServerWorld world, Entity user, ItemStack stack, ItemStackConsumer resultStackConsumer, float angleOffset, float speed, float uncertainty) { - ActionContext context = ActionContext.builder(world, stack, resultStackConsumer) - .entityPosition(ActionContextParameter.THIS, user) - .position(ActionContextParameter.TARGET, user.getEyePos().add(0.0d, -0.1d, 0.0d)) + ActionContext context = ActionContext.builder((ServerWorld) world) + .stackExchanger(user, stack) + .add(LootContextParameters.TOOL, stack) + .add(LootContextParameters.THIS_ENTITY, user) + .add(LootContextParameters.ORIGIN, user.getPos()) + .add(ItematicContextParameters.INTERACTED_POSITION, user.getEyePos().add(0.0d, -0.1d, 0.0d)) .build(); - return this.createEntity(context, ActionContextParameter.TARGET, angleOffset, speed, uncertainty); + return this.createEntity(context, PositionTarget.INTERACTED_POSITION, angleOffset, speed, 1.0f); } - public Entity createEntity(World world, Position position, ItemStack stack, float speed, float uncertainty) { - if (world.isClient()) { + public Entity createEntity(ActionContext context, PositionTarget position, float angleOffset, float speed, float uncertainty) { + Vec3d pos = context.get(position.parameter()); + if (pos == null) { return null; } - ActionContext context = ActionContext.builder((ServerWorld) world, stack, ItemStackConsumer.EMPTY) - .position(ActionContextParameter.TARGET, position) - .build(); - return this.createEntity(context, ActionContextParameter.TARGET, 0.0f, speed, uncertainty); - } - - public Entity createEntity(ActionContext context, ActionContextParameter position, float angleOffset, float speed, float uncertainty) { - Entity entity = this.entity.create(context, SpawnReason.SPAWN_ITEM_USE); + Entity entity = this.entity.create(context, BlockPos.ofFloored(pos), SpawnReason.SPAWN_ITEM_USE); if (entity == null) { return null; } - entity.refreshPositionAfterTeleport(context.position(position)); - if (entity instanceof ThrownItemEntity thrownItemEntity) { - thrownItemEntity.setItem(context.stack()); + entity.refreshPositionAfterTeleport(pos); + ItemStack stack = context.get(LootContextParameters.TOOL); + if (stack != null && entity instanceof ThrownItemEntity thrownItemEntity) { + thrownItemEntity.setItem(stack); } if (entity instanceof ProjectileEntity projectileEntity) { @@ -99,10 +91,12 @@ public Entity createEntity(ActionContext context, ActionContextParameter positio } private void initializeProjectile(ActionContext context, ProjectileEntity projectileEntity, float angleOffset, float speed, float uncertainty) { - context.entity(ActionContextParameter.THIS).ifPresentOrElse( - user -> this.initializeProjectile(projectileEntity, user, angleOffset, speed, uncertainty), - () -> this.initializeProjectile(projectileEntity, context.side(), speed, uncertainty) - ); + Entity user = context.get(LootContextParameters.THIS_ENTITY); + if (user != null) { + this.initializeProjectile(projectileEntity, user, angleOffset, speed, uncertainty); + } else { + this.initializeProjectile(projectileEntity, context.getOrDefault(ItematicContextParameters.SIDE, Direction.UP), speed, uncertainty); + } } private void initializeProjectile(ProjectileEntity entity, Entity user, float angleOffset, float speed, float uncertainty) { diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/SaddleItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/SaddleItemComponent.java deleted file mode 100644 index 189019c9..00000000 --- a/src/main/java/net/errorcraft/itematic/item/component/components/SaddleItemComponent.java +++ /dev/null @@ -1,57 +0,0 @@ -package net.errorcraft.itematic.item.component.components; - -import com.mojang.serialization.Codec; -import net.errorcraft.itematic.item.ItemResult; -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.minecraft.entity.LivingEntity; -import net.minecraft.entity.Saddleable; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.sound.SoundCategory; -import net.minecraft.util.Hand; -import net.minecraft.world.World; -import net.minecraft.world.event.GameEvent; - -public record SaddleItemComponent() implements ItemComponent { - public static final SaddleItemComponent INSTANCE = new SaddleItemComponent(); - public static final Codec CODEC = Codec.unit(INSTANCE); - - @Override - public ItemComponentType type() { - return ItemComponentTypes.SADDLE; - } - - @Override - public Codec codec() { - return CODEC; - } - - @Override - public ItemResult useOnEntity(PlayerEntity user, LivingEntity target, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { - if (this.trySaddle(target, user.getWorld(), stack, SoundCategory.NEUTRAL)) { - return ItemResult.SUCCEED; - } - - return ItemResult.PASS; - } - - public boolean trySaddle(LivingEntity target, World world, ItemStack stack, SoundCategory soundCategory) { - if (!(target instanceof Saddleable saddleable)) { - return false; - } - - if (!target.isAlive() || saddleable.isSaddled() || !saddleable.canBeSaddled()) { - return false; - } - - if (!world.isClient()) { - saddleable.saddle(stack.split(1), soundCategory); - target.getWorld().emitGameEvent(target, GameEvent.EQUIP, target.getPos()); - } - - return true; - } -} 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 ca3f0ebf..1e2dddef 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 @@ -6,14 +6,14 @@ import net.errorcraft.itematic.component.type.ItemDamageRulesDataComponent; import net.errorcraft.itematic.component.type.ItemListDataComponent; import net.errorcraft.itematic.item.ItemResult; -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.shooter.method.ShooterMethod; import net.errorcraft.itematic.item.use.provider.providers.ShooterIntegerProvider; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; import net.minecraft.component.ComponentMap; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.Entity; @@ -23,6 +23,7 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.consume.UseAction; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.registry.RegistryCodecs; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntryList; @@ -72,7 +73,7 @@ public Codec codec() { } @Override - public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { if (this.method.tryShoot(this, stack, world, user, hand)) { return ItemResult.CONSUME; } @@ -86,7 +87,7 @@ public void using(ItemStack stack, World world, LivingEntity user, int usedTicks } @Override - public boolean 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, ItemStackExchanger stackExchanger) { return this.method.stop(this, stack, world, user, usedTicks); } @@ -134,9 +135,11 @@ private void damageItem(ItemStack stack, ServerWorld world, Hand hand, LivingEnt } ActionContext context = ActionContext.builder(world) - .stack(stack) - .hand(hand) - .entityPosition(ActionContextParameter.THIS, shooter) + .stackExchanger(shooter, stack) + .add(LootContextParameters.THIS_ENTITY, shooter) + .add(LootContextParameters.ORIGIN, shooter.getPos()) + .add(LootContextParameters.TOOL, stack) + .add(ItematicContextParameters.HAND, hand) .build(); stack.itematic$damage(damage, context); } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/SmithingTemplateItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/SmithingTemplateItemComponent.java deleted file mode 100644 index 57b0c536..00000000 --- a/src/main/java/net/errorcraft/itematic/item/component/components/SmithingTemplateItemComponent.java +++ /dev/null @@ -1,58 +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.errorcraft.itematic.item.smithing.template.SmithingTemplate; -import net.errorcraft.itematic.mixin.item.SmithingTemplateItemAccessor; -import net.errorcraft.itematic.registry.ItematicRegistryKeys; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.registry.entry.RegistryFixedCodec; -import net.minecraft.screen.ScreenTexts; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; - -import java.util.List; - -public record SmithingTemplateItemComponent(RegistryEntry template) implements ItemComponent { - public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - RegistryFixedCodec.of(ItematicRegistryKeys.SMITHING_TEMPLATE).fieldOf("template").forGetter(SmithingTemplateItemComponent::template) - ).apply(instance, SmithingTemplateItemComponent::new)); - private static final Formatting DESCRIPTION_FORMATTING = SmithingTemplateItemAccessor.getDescriptionFormatting(); - private static final Text SMITHING_TEMPLATE_TEXT = SmithingTemplateItemAccessor.getSmithingTemplateText(); - private static final Text APPLIES_TO_TEXT = SmithingTemplateItemAccessor.getAppliesToText(); - private static final Text INGREDIENTS_TEXT = SmithingTemplateItemAccessor.getIngredientsText(); - - public static ItemComponent[] of(RegistryEntry template) { - return new ItemComponent[] { - StackableItemComponent.of(64), - new SmithingTemplateItemComponent(template) - }; - } - - @Override - public ItemComponentType type() { - return ItemComponentTypes.SMITHING_TEMPLATE; - } - - @Override - public Codec codec() { - return CODEC; - } - - @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, List tooltip, TooltipType type) { - SmithingTemplate template = this.template.value(); - tooltip.add(SMITHING_TEMPLATE_TEXT); - tooltip.add(ScreenTexts.EMPTY); - tooltip.add(APPLIES_TO_TEXT); - tooltip.add(ScreenTexts.space().append(template.appliesToText().formatted(DESCRIPTION_FORMATTING))); - tooltip.add(INGREDIENTS_TEXT); - tooltip.add(ScreenTexts.space().append(template.ingredientsText().formatted(DESCRIPTION_FORMATTING))); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/SmithingTemplateProviderItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/SmithingTemplateProviderItemComponent.java new file mode 100644 index 00000000..2b0ca189 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/item/component/components/SmithingTemplateProviderItemComponent.java @@ -0,0 +1,28 @@ +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.ItemComponentType; +import net.errorcraft.itematic.item.component.ItemComponentTypes; +import net.errorcraft.itematic.item.smithing.template.SmithingTemplate; + +public record SmithingTemplateProviderItemComponent(SmithingTemplate template) implements ItemComponent { + public static final Codec CODEC = SmithingTemplate.CODEC.xmap( + SmithingTemplateProviderItemComponent::new, + SmithingTemplateProviderItemComponent::template + ); + + public static SmithingTemplateProviderItemComponent of(SmithingTemplate template) { + return new SmithingTemplateProviderItemComponent(template); + } + + @Override + public ItemComponentType type() { + return ItemComponentTypes.SMITHING_TEMPLATE_PROVIDER; + } + + @Override + public Codec codec() { + return CODEC; + } +} 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 7417d08e..fd020897 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 @@ -1,8 +1,6 @@ package net.errorcraft.itematic.item.component.components; import com.mojang.serialization.Codec; -import net.errorcraft.itematic.entity.initializer.initializers.SimpleEntityInitializer; -import net.errorcraft.itematic.item.color.colors.IndexItemColor; import net.errorcraft.itematic.item.component.ItemComponent; import net.errorcraft.itematic.item.component.ItemComponentType; import net.errorcraft.itematic.item.component.ItemComponentTypes; @@ -23,19 +21,25 @@ import java.util.Optional; -public record SpawnEggItemComponent() implements ItemComponent { +public class SpawnEggItemComponent implements ItemComponent { public static final SpawnEggItemComponent INSTANCE = new SpawnEggItemComponent(); public static final Codec CODEC = Codec.unit(INSTANCE); - public static ItemComponent[] from(RegistryEntry> entity, int primaryColor, int secondaryColor, RegistryEntryLookup dispenseBehaviors) { + public static ItemComponent[] from(RegistryEntry> entity, RegistryEntryLookup dispenseBehaviors) { return new ItemComponent[] { - EntityItemComponent.of(SimpleEntityInitializer.of(entity.value()), true, EntityItemComponent.Pass.BLOCK, EntityItemComponent.Pass.FLUID), + EntityItemComponent.of( + entity, + true, + EntityItemComponent.Pass.BLOCK, + EntityItemComponent.Pass.FLUID + ), INSTANCE, - TintedItemComponent.of(IndexItemColor.of(primaryColor, secondaryColor)), DispensableItemComponent.of(dispenseBehaviors.getOrThrow(DispenseBehaviors.SPAWN_ENTITY_FROM_ITEM)) }; } + private SpawnEggItemComponent() {} + @Override public ItemComponentType type() { return ItemComponentTypes.SPAWN_EGG; @@ -52,7 +56,7 @@ public Optional spawnBaby(PlayerEntity user, MobEntity entity, Entity return Optional.empty(); } - if (entityItemComponent.get().getEntityInitializer(stack).type() != entityType) { + if (entityItemComponent.get().entityType(stack, world.getRegistryManager()) != entityType) { return Optional.empty(); } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/SteeringItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/SteeringItemComponent.java index 3ce85361..b2e8e20f 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/SteeringItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/SteeringItemComponent.java @@ -3,17 +3,18 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.item.ItemResult; -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.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.ItemSteerable; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.registry.Registries; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntry; @@ -30,6 +31,10 @@ public record SteeringItemComponent(RegistryEntry> target, int dam Codecs.NON_NEGATIVE_INT.optionalFieldOf("damage_per_use", 1).forGetter(SteeringItemComponent::damagePerUse) ).apply(instance, SteeringItemComponent::new)); + public static SteeringItemComponent of(RegistryEntry> target, int damage) { + return new SteeringItemComponent(target, damage); + } + @Override public ItemComponentType type() { return ItemComponentTypes.STEERING; @@ -41,35 +46,40 @@ public Codec codec() { } @Override - public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { if (world.isClient()) { return ItemResult.PASS; } - ActionContext context = ActionContext.builder((ServerWorld) world, stack, resultStackConsumer, hand) - .entityPosition(ActionContextParameter.THIS, user) + + ActionContext context = ActionContext.builder((ServerWorld) world) + .stackExchanger(stackExchanger) + .add(LootContextParameters.THIS_ENTITY, user) + .add(LootContextParameters.ORIGIN, user.getPos()) + .add(LootContextParameters.TOOL, stack) + .add(ItematicContextParameters.HAND, hand) .build(); if (this.apply(user, stack, context)) { return ItemResult.SUCCEED; } + user.incrementStat(Stats.USED.itematic$getOrCreateStat(stack.getRegistryEntry())); return ItemResult.PASS; } - public static SteeringItemComponent of(RegistryEntry> target, int damage) { - return new SteeringItemComponent(target, damage); - } - private boolean apply(PlayerEntity user, ItemStack stack, ActionContext context) { Entity vehicle = user.getControllingVehicle(); if (!user.hasVehicle() || !(vehicle instanceof ItemSteerable itemSteerable)) { return false; } + if (!this.matchesEntityType(vehicle)) { return false; } + if (!itemSteerable.consumeOnAStickItem()) { return false; } + stack.itematic$damage(this.damagePerUse, context); return true; } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/TextHolderItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/TextHolderItemComponent.java index 52a84c7f..88eb4b21 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/TextHolderItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/TextHolderItemComponent.java @@ -1,24 +1,23 @@ package net.errorcraft.itematic.item.component.components; import com.mojang.serialization.Codec; +import net.errorcraft.itematic.item.ItemResult; import net.errorcraft.itematic.item.component.ItemComponent; import net.errorcraft.itematic.item.component.ItemComponentType; import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.WrittenBookContentComponent; -import net.minecraft.item.Item; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.StringHelper; +import net.minecraft.stat.Stats; +import net.minecraft.util.Hand; +import net.minecraft.world.World; -import java.util.List; - -public record TextHolderItemComponent() implements ItemComponent { +public class TextHolderItemComponent implements ItemComponent { public static final TextHolderItemComponent INSTANCE = new TextHolderItemComponent(); public static final Codec CODEC = Codec.unit(INSTANCE); + private TextHolderItemComponent() {} + @Override public ItemComponentType type() { return ItemComponentTypes.TEXT_HOLDER; @@ -30,14 +29,9 @@ public Codec codec() { } @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, List tooltip, TooltipType type) { - WrittenBookContentComponent writtenBookContent = stack.get(DataComponentTypes.WRITTEN_BOOK_CONTENT); - if (writtenBookContent == null) { - return; - } - if (!StringHelper.isBlank(writtenBookContent.author())) { - tooltip.add(Text.translatable("book.byAuthor", writtenBookContent.author()).formatted(Formatting.GRAY)); - } - tooltip.add(Text.translatable("book.generation." + writtenBookContent.generation()).formatted(Formatting.GRAY)); + public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { + user.useBook(stack, hand); + user.incrementStat(Stats.USED.itematic$getOrCreateStat(stack.getRegistryEntry())); + return ItemResult.SUCCEED; } } 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 54cd48de..f55b8500 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 @@ -3,19 +3,22 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.item.ItemResult; -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.event.ItemEvents; import net.errorcraft.itematic.item.use.provider.providers.TridentIntegerProvider; import net.errorcraft.itematic.serialization.ItematicCodecs; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; +import net.errorcraft.itematic.world.action.context.PositionTarget; +import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.item.consume.UseAction; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.predicate.NumberRange; import net.minecraft.server.world.ServerWorld; import net.minecraft.stat.Stats; @@ -64,17 +67,19 @@ public Codec codec() { } @Override - public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { if (this.drawDuration.isPresent()) { return ItemResult.PASS; } - return this.createEntity(world, user, stack, resultStackConsumer); + + this.createEntity(world, user, stack, stackExchanger); + return ItemResult.SUCCEED; } @Override - public boolean 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, ItemStackExchanger stackExchanger) { if (this.drawDuration.filter(drawDuration -> drawDuration.test(usedTicks)).isPresent()) { - this.createEntity(world, user, stack, resultStackConsumer); + this.createEntity(world, user, stack, stackExchanger); if (user instanceof PlayerEntity player) { player.incrementStat(Stats.USED.itematic$getOrCreateStat(stack.getRegistryEntry())); } @@ -85,27 +90,38 @@ public boolean stopUsing(ItemStack stack, World world, LivingEntity user, int us return false; } - private ItemResult createEntity(World world, LivingEntity user, ItemStack stack, ItemStackConsumer resultStackConsumer) { + private void createEntity(World world, LivingEntity user, ItemStack stack, ItemStackExchanger stackExchanger) { if (world instanceof ServerWorld serverWorld) { - ActionContext context = ActionContext.builder(serverWorld, stack, resultStackConsumer) - .entityPosition(ActionContextParameter.THIS, user) - .position(ActionContextParameter.TARGET, user.getEyePos().add(0.0d, -0.1d, 0.0d)) - .build(); - this.createEntity(context); + ActionContext.Builder contextBuilder = ActionContext.builder(serverWorld) + .stackExchanger(stackExchanger) + .add(LootContextParameters.TOOL, stack) + .add(LootContextParameters.THIS_ENTITY, user) + .add(LootContextParameters.ORIGIN, user.getPos()) + .add(ItematicContextParameters.INTERACTED_POSITION, user.getEyePos().add(0.0d, -0.1d, 0.0d)); + this.createEntity(contextBuilder, serverWorld, stack); } - - return ItemResult.SUCCEED; } - private void createEntity(ActionContext context) { - context.stack().itematic$getBehavior(ItemComponentTypes.PROJECTILE) - .map(c -> c.createEntity(context, ActionContextParameter.TARGET, this.angleOffset, this.speed, 1.0f)) - .ifPresent(projectile -> { - context.world().spawnEntity(projectile); - ActionContext projectileContext = context.builderForCopy() - .entityPosition(ActionContextParameter.TARGET, projectile) - .build(); - context.stack().itematic$invokeEvent(ItemEvents.THROW_PROJECTILE, projectileContext); - }); + private void createEntity(ActionContext.Builder contextBuilder, ServerWorld world, ItemStack stack) { + ProjectileItemComponent projectile = stack.itematic$getBehavior(ItemComponentTypes.PROJECTILE).orElse(null); + if (projectile == null) { + return; + } + + Entity projectileEntity = projectile.createEntity( + contextBuilder.build(), + PositionTarget.INTERACTED_POSITION, + this.angleOffset, + this.speed, + 1.0f + ); + if (projectileEntity == null) { + return; + } + + world.spawnEntity(projectileEntity); + ActionContext projectileContext = contextBuilder.add(ItematicContextParameters.TARGET_ENTITY, projectileEntity) + .build(); + stack.itematic$invokeEvent(ItemEvents.THROW_PROJECTILE, projectileContext); } } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/TintedItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/TintedItemComponent.java deleted file mode 100644 index a68580ae..00000000 --- a/src/main/java/net/errorcraft/itematic/item/component/components/TintedItemComponent.java +++ /dev/null @@ -1,28 +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.color.ItemColor; -import net.errorcraft.itematic.item.component.ItemComponent; -import net.errorcraft.itematic.item.component.ItemComponentType; -import net.errorcraft.itematic.item.component.ItemComponentTypes; - -public record TintedItemComponent(ItemColor tint) implements ItemComponent { - public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - ItemColor.CODEC.fieldOf("tint").forGetter(TintedItemComponent::tint) - ).apply(instance, TintedItemComponent::new)); - - public static TintedItemComponent of(ItemColor tint) { - return new TintedItemComponent(tint); - } - - @Override - public ItemComponentType type() { - return ItemComponentTypes.TINTED; - } - - @Override - public Codec codec() { - return CODEC; - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/ToolItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/ToolItemComponent.java index 8cd9d532..4bfacfe2 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/ToolItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/ToolItemComponent.java @@ -1,13 +1,13 @@ 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.item.event.ItemEvents; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.component.ComponentMap; @@ -17,6 +17,7 @@ import net.minecraft.entity.LivingEntity; import net.minecraft.item.ItemStack; import net.minecraft.item.ToolMaterial; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.registry.RegistryEntryLookup; import net.minecraft.registry.tag.TagKey; import net.minecraft.server.world.ServerWorld; @@ -30,15 +31,15 @@ public record ToolItemComponent(ToolComponent tool) implements ItemComponent CODEC = ToolComponent.CODEC.xmap(ToolItemComponent::new, ToolItemComponent::tool); public static ToolItemComponent of(RegistryEntryLookup blocks, ToolMaterial material, TagKey mineableBlocks) { - ToolComponent tool = new ToolComponent( + return new ToolItemComponent(new ToolComponent( List.of( ToolComponent.Rule.ofNeverDropping(blocks.getOrThrow(material.incorrectBlocksForDrops())), ToolComponent.Rule.ofAlwaysDropping(blocks.getOrThrow(mineableBlocks), material.speed()) ), 1.0f, - 1 - ); - return new ToolItemComponent(tool); + 1, + true + )); } public static Builder builder(int damage) { @@ -56,10 +57,11 @@ public Codec codec() { } @Override - public boolean postMine(ItemStack stack, World world, BlockState state, BlockPos pos, LivingEntity miner, ItemStackConsumer resultStackConsumer) { + public boolean postMine(ItemStack stack, World world, BlockState state, BlockPos pos, LivingEntity miner, ItemStackExchanger stackExchanger) { if (!world.isClient() && state.getHardness(world, pos) != 0.0f) { - this.useTool(stack, world, pos, miner, resultStackConsumer); + this.useTool(stack, world, pos, miner, stackExchanger); } + return true; } @@ -68,17 +70,23 @@ public void addComponents(ComponentMap.Builder builder) { builder.add(DataComponentTypes.TOOL, this.tool); } - private void useTool(ItemStack stack, World world, BlockPos pos, LivingEntity miner, ItemStackConsumer resultStackConsumer) { + private void useTool(ItemStack stack, World world, BlockPos pos, LivingEntity miner, ItemStackExchanger stackExchanger) { if (!(world instanceof ServerWorld serverWorld)) { return; } + ToolComponent tool = stack.get(DataComponentTypes.TOOL); if (tool == null) { return; } - ActionContext context = ActionContext.builder(serverWorld, stack, resultStackConsumer, EquipmentSlot.MAINHAND) - .entityPosition(ActionContextParameter.THIS, miner) - .position(ActionContextParameter.TARGET, pos.toCenterPos()) + + ActionContext context = ActionContext.builder(serverWorld) + .stackExchanger(stackExchanger) + .add(LootContextParameters.THIS_ENTITY, miner) + .add(LootContextParameters.ORIGIN, miner.getPos()) + .add(ItematicContextParameters.INTERACTED_POSITION, pos.toCenterPos()) + .add(LootContextParameters.TOOL, stack) + .add(ItematicContextParameters.EQUIPMENT_SLOT, EquipmentSlot.MAINHAND) .build(); stack.itematic$invokeEvent(ItemEvents.USE_TOOL, context); stack.itematic$damage(tool.damagePerBlock(), context); @@ -87,13 +95,24 @@ private void useTool(ItemStack stack, World world, BlockPos pos, LivingEntity mi public static class Builder { private final int damage; private final List rules = new ArrayList<>(); + private boolean canDestroyBlocksInCreative = true; public Builder(int damage) { this.damage = damage; } public ToolItemComponent build() { - return new ToolItemComponent(new ToolComponent(this.rules, 1.0f, this.damage)); + return new ToolItemComponent(new ToolComponent( + this.rules, + 1.0f, + this.damage, + this.canDestroyBlocksInCreative + )); + } + + public Builder preventCreativeDestruction() { + this.canDestroyBlocksInCreative = false; + return this; } public Builder rule(ToolComponent.Rule rule) { diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/TrimMaterialProviderItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/TrimMaterialProviderItemComponent.java new file mode 100644 index 00000000..686520bf --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/item/component/components/TrimMaterialProviderItemComponent.java @@ -0,0 +1,37 @@ +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.ItemComponentType; +import net.errorcraft.itematic.item.component.ItemComponentTypes; +import net.minecraft.component.ComponentMap; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.ProvidesTrimMaterialComponent; +import net.minecraft.item.equipment.trim.ArmorTrimMaterial; +import net.minecraft.registry.entry.RegistryEntry; + +public record TrimMaterialProviderItemComponent(RegistryEntry trimMaterial) implements ItemComponent { + public static final Codec CODEC = ArmorTrimMaterial.ENTRY_CODEC.xmap( + TrimMaterialProviderItemComponent::new, + TrimMaterialProviderItemComponent::trimMaterial + ); + + public static TrimMaterialProviderItemComponent of(RegistryEntry trimMaterial) { + return new TrimMaterialProviderItemComponent(trimMaterial); + } + + @Override + public ItemComponentType type() { + return ItemComponentTypes.TRIM_MATERIAL_PROVIDER; + } + + @Override + public Codec codec() { + return CODEC; + } + + @Override + public void addComponents(ComponentMap.Builder builder) { + builder.add(DataComponentTypes.PROVIDES_TRIM_MATERIAL, new ProvidesTrimMaterialComponent(this.trimMaterial)); + } +} diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/UnlockRecipesItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/UnlockRecipesItemComponent.java index 090c46e4..63729955 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/UnlockRecipesItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/UnlockRecipesItemComponent.java @@ -2,10 +2,10 @@ import com.mojang.serialization.Codec; import net.errorcraft.itematic.item.ItemResult; -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.world.action.context.ItemStackExchanger; import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; import net.minecraft.entity.player.PlayerEntity; @@ -33,7 +33,7 @@ public Codec codec() { } @Override - public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { return DUMMY.use(world, user, hand).isAccepted() ? ItemResult.SUCCEED : ItemResult.PASS; } 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 7d9d5b45..567a6e20 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 @@ -5,7 +5,6 @@ import net.errorcraft.itematic.component.ItematicDataComponentTypes; import net.errorcraft.itematic.component.type.UseDurationDataComponent; import net.errorcraft.itematic.item.ItemResult; -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; @@ -13,6 +12,7 @@ import net.errorcraft.itematic.item.use.provider.providers.ConstantIntegerProvider; import net.errorcraft.itematic.item.use.provider.providers.IndefiniteIntegerProvider; import net.errorcraft.itematic.serialization.SetCodec; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.UseRemainderComponent; @@ -53,7 +53,7 @@ public Codec codec() { } @Override - public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { if (this.isUnuseable(Pass.NORMAL)) { return ItemResult.PASS; } @@ -62,7 +62,7 @@ public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack } @Override - public ItemResult useOnBlock(ItemUsageContext context, ItemStackConsumer resultStackConsumer) { + public ItemResult useOnBlock(ItemUsageContext context, ItemStackExchanger stackExchanger) { if (this.isUnuseable(Pass.BLOCK)) { return ItemResult.PASS; } @@ -71,7 +71,7 @@ public ItemResult useOnBlock(ItemUsageContext context, ItemStackConsumer resultS } @Override - public ItemResult useOnEntity(PlayerEntity user, LivingEntity target, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + public ItemResult useOnEntity(PlayerEntity user, LivingEntity target, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { if (this.isUnuseable(Pass.ENTITY)) { return ItemResult.PASS; } 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 bbc8f896..b8747b8a 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 @@ -4,54 +4,55 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.component.ItematicDataComponentTypes; import net.errorcraft.itematic.component.type.WeaponAttackDamageDataComponent; -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.event.ItemEvents; import net.errorcraft.itematic.serialization.ItematicCodecs; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; import net.minecraft.component.ComponentMap; -import net.minecraft.component.type.AttributeModifiersComponent; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.WeaponComponent; import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.MaceItem; -import net.minecraft.item.tooltip.TooltipType; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.server.world.ServerWorld; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; import net.minecraft.util.dynamic.Codecs; import java.util.List; -public record WeaponItemComponent(int damagePerHit, WeaponAttackDamageDataComponent attackDamage, double attackSpeed, boolean maySmash) implements ItemComponent { +public record WeaponItemComponent(int itemDamagePerAttack, float disableBlockingForSeconds, boolean maySmash, WeaponAttackDamageDataComponent attackDamage, double attackSpeed) implements ItemComponent { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - Codecs.NON_NEGATIVE_INT.optionalFieldOf("damage_per_hit", 1).forGetter(WeaponItemComponent::damagePerHit), + Codecs.NON_NEGATIVE_INT.optionalFieldOf("item_damage_per_attack", 1).forGetter(WeaponItemComponent::itemDamagePerAttack), + Codecs.NON_NEGATIVE_FLOAT.optionalFieldOf("disable_blocking_for_seconds", 0.0f).forGetter(WeaponItemComponent::disableBlockingForSeconds), + Codec.BOOL.optionalFieldOf("may_smash", false).forGetter(WeaponItemComponent::maySmash), WeaponAttackDamageDataComponent.CODEC.fieldOf("attack_damage").forGetter(WeaponItemComponent::attackDamage), - ItematicCodecs.NON_NEGATIVE_DOUBLE.fieldOf("attack_speed").forGetter(WeaponItemComponent::attackSpeed), - Codec.BOOL.optionalFieldOf("may_smash", false).forGetter(WeaponItemComponent::maySmash) + ItematicCodecs.NON_NEGATIVE_DOUBLE.fieldOf("attack_speed").forGetter(WeaponItemComponent::attackSpeed) ).apply(instance, WeaponItemComponent::new)); private static final MaceItem DUMMY = new MaceItem(new Item.Settings()); - public static WeaponItemComponent of(int damagePerHit, double attackDamage, double attackSpeed) { + public static WeaponItemComponent of(int damagePerHit, float disableBlockingForSeconds, double attackDamage, double attackSpeed) { return new WeaponItemComponent( damagePerHit, + disableBlockingForSeconds, + false, new WeaponAttackDamageDataComponent(List.of(), attackDamage), - attackSpeed, - false + attackSpeed ); } public static WeaponItemComponent ofSmashing(int damagePerHit, double attackDamage, double attackSpeed) { return new WeaponItemComponent( damagePerHit, + 0.0f, + true, new WeaponAttackDamageDataComponent(List.of(), attackDamage), - attackSpeed, - true + attackSpeed ); } @@ -66,48 +67,35 @@ public Codec codec() { } @Override - public boolean postHit(ItemStack stack, LivingEntity target, LivingEntity attacker, ItemStackConsumer resultStackConsumer) { - if (this.maySmash && !DUMMY.postHit(stack, target, attacker)) { - return false; + public void postHit(ItemStack stack, LivingEntity target, LivingEntity attacker, ItemStackExchanger stackExchanger) { + if (this.maySmash) { + DUMMY.postHit(stack, target, attacker); } if (!(attacker.getWorld() instanceof ServerWorld serverWorld)) { - return true; + return; } - ActionContext context = ActionContext.builder(serverWorld, stack, resultStackConsumer, EquipmentSlot.MAINHAND) - .entityPosition(ActionContextParameter.THIS, attacker) - .entityPosition(ActionContextParameter.TARGET, target) + ActionContext context = ActionContext.builder(serverWorld) + .stackExchanger(stackExchanger) + .add(LootContextParameters.THIS_ENTITY, attacker) + .add(LootContextParameters.ORIGIN, attacker.getPos()) + .add(ItematicContextParameters.TARGET_ENTITY, target) + .add(ItematicContextParameters.INTERACTED_POSITION, target.getPos()) + .add(LootContextParameters.TOOL, stack) + .add(ItematicContextParameters.EQUIPMENT_SLOT, EquipmentSlot.MAINHAND) .build(); stack.itematic$invokeEvent(ItemEvents.USE_WEAPON, context); - stack.itematic$damage(this.damagePerHit, context); - return true; + WeaponComponent weapon = stack.get(DataComponentTypes.WEAPON); + if (weapon != null) { + stack.itematic$damage(weapon.itemDamagePerAttack(), context); + } } @Override public void addComponents(ComponentMap.Builder builder) { + builder.add(DataComponentTypes.WEAPON, new WeaponComponent(this.itemDamagePerAttack, this.disableBlockingForSeconds)); builder.add(ItematicDataComponentTypes.WEAPON_ATTACK_DAMAGE, this.attackDamage); builder.add(ItematicDataComponentTypes.ATTACK_SPEED_MULTIPLIER, this.attackSpeed); } - - @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, List tooltip, TooltipType type) { - WeaponAttackDamageDataComponent weaponAttackDamage = stack.get(ItematicDataComponentTypes.WEAPON_ATTACK_DAMAGE); - if (weaponAttackDamage != null) { - tooltip.add( - Text.translatable( - "attribute.modifier.equals.0", - AttributeModifiersComponent.DECIMAL_FORMAT.format(weaponAttackDamage.defaultDamage()), - Text.translatable(EntityAttributes.ATTACK_DAMAGE.value().getTranslationKey()) - ).formatted(Formatting.DARK_GREEN) - ); - } - tooltip.add( - Text.translatable( - "attribute.modifier.equals.0", - AttributeModifiersComponent.DECIMAL_FORMAT.format(this.attackSpeed), - Text.translatable(EntityAttributes.ATTACK_SPEED.value().getTranslationKey()) - ).formatted(Formatting.DARK_GREEN) - ); - } } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/WritableItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/WritableItemComponent.java index 15b7a631..af3498d2 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/WritableItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/WritableItemComponent.java @@ -3,10 +3,10 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.item.ItemResult; -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.world.action.context.ItemStackExchanger; import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.WritableBookContentComponent; @@ -36,7 +36,7 @@ public Codec codec() { } @Override - public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { user.useBook(stack, hand); user.incrementStat(Stats.USED.itematic$getOrCreateStat(stack.getRegistryEntry())); return ItemResult.SUCCEED; 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 f8534f8b..e5b90fad 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 @@ -3,11 +3,11 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.item.ItemResult; -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.serialization.ItematicCodecs; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; @@ -39,20 +39,20 @@ public Codec codec() { } @Override - public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + public ItemResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { user.playSound(this.startUsingSound.value(), 1.0f, 1.0f); user.incrementStat(Stats.USED.itematic$getOrCreateStat(stack.getRegistryEntry())); return ItemResult.PASS; } @Override - public boolean 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, ItemStackExchanger stackExchanger) { this.playStopSound(user); return true; } @Override - public void finishUsing(World world, LivingEntity user, ItemStack stack, int usedTicks, ItemStackConsumer resultStackConsumer) { + public void finishUsing(World world, LivingEntity user, ItemStack stack, int usedTicks, ItemStackExchanger stackExchanger) { this.playStopSound(user); } diff --git a/src/main/java/net/errorcraft/itematic/item/composting/CompostChances.java b/src/main/java/net/errorcraft/itematic/item/composting/CompostChances.java new file mode 100644 index 00000000..68c6b9af --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/item/composting/CompostChances.java @@ -0,0 +1,11 @@ +package net.errorcraft.itematic.item.composting; + +public class CompostChances { + public static final float SMALL = 0.3f; + public static final float FIFTY_FIFTY = 0.5f; + public static final float BIG = 0.65f; + public static final float ALMOST_GUARANTEED = 0.85f; + public static final float GUARANTEED = 1.0f; + + private CompostChances() {} +} diff --git a/src/main/java/net/errorcraft/itematic/item/data/InventoryTickListener.java b/src/main/java/net/errorcraft/itematic/item/data/InventoryTickListener.java new file mode 100644 index 00000000..71d4454a --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/item/data/InventoryTickListener.java @@ -0,0 +1,11 @@ +package net.errorcraft.itematic.item.data; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.item.ItemStack; +import net.minecraft.server.world.ServerWorld; +import org.jetbrains.annotations.Nullable; + +public interface InventoryTickListener { + void itematic$onInventoryTick(ServerWorld world, ItemStack stack, Entity owner, @Nullable EquipmentSlot slot); +} diff --git a/src/main/java/net/errorcraft/itematic/item/dispense/behavior/DispenseBehavior.java b/src/main/java/net/errorcraft/itematic/item/dispense/behavior/DispenseBehavior.java index 4aff2f9d..367bb94f 100644 --- a/src/main/java/net/errorcraft/itematic/item/dispense/behavior/DispenseBehavior.java +++ b/src/main/java/net/errorcraft/itematic/item/dispense/behavior/DispenseBehavior.java @@ -2,21 +2,19 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.inventory.StackReferenceUtil; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.Action; import net.errorcraft.itematic.world.action.ActionEntry; import net.errorcraft.itematic.world.action.actions.SequenceAction; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; import net.errorcraft.itematic.world.action.sequence.handler.SequenceHandler; import net.minecraft.block.DispenserBlock; import net.minecraft.block.dispenser.FallibleItemDispenserBehavior; -import net.minecraft.inventory.StackReference; import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.util.math.BlockPointer; import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Position; import net.minecraft.util.math.Vec3d; import java.util.Optional; @@ -57,11 +55,14 @@ public DispenseBehavior(RegistryEntry entry, boolean dispenseAsItem @Override protected ItemStack dispenseSilently(BlockPointer pointer, ItemStack stack) { Direction side = pointer.state().get(DispenserBlock.FACING); - StackReference stackReference = StackReferenceUtil.of(stack); - ActionContext context = ActionContext.builder(pointer.world(), stack, stackReference::set) - .position(ActionContextParameter.THIS, pointer.pos()) - .position(ActionContextParameter.TARGET, this.offset.position(pointer)) - .side(side) + Vec3d outputPos = this.offset.position(pointer); + ActionContext context = ActionContext.builder(pointer.world()) + .stackExchanger(side, outputPos, stack) + .add(LootContextParameters.ORIGIN, pointer.centerPos()) + .add(ItematicContextParameters.INTERACTED_POSITION, outputPos) + .add(ItematicContextParameters.SIDE, side) + .add(LootContextParameters.TOOL, stack) + .add(LootContextParameters.BLOCK_ENTITY, pointer.blockEntity()) .build(); Optional result = this.entry.value().execute(context); if (result.isEmpty()) { @@ -69,7 +70,7 @@ protected ItemStack dispenseSilently(BlockPointer pointer, ItemStack stack) { } if (result.get()) { - return this.succeed(pointer, stack, stackReference.get()); + return this.succeed(pointer, stack, context.resultStack()); } return this.fail(pointer, stack); @@ -121,7 +122,7 @@ public static Offset of(double side, double constantX, double constantY, double return new Offset(new Vec3d(side, side, side), new Vec3d(constantX, constantY, constantZ)); } - public Position position(BlockPointer pointer) { + public Vec3d position(BlockPointer pointer) { Direction side = pointer.state().get(DispenserBlock.FACING); double offsetX = this.sideFactor.getX() * side.getOffsetX() + this.constant.getX(); double offsetY = this.sideFactor.getY() * side.getOffsetY() + this.constant.getY(); diff --git a/src/main/java/net/errorcraft/itematic/item/dispense/behavior/DispenseBehaviors.java b/src/main/java/net/errorcraft/itematic/item/dispense/behavior/DispenseBehaviors.java index a7c5623e..15e3d40c 100644 --- a/src/main/java/net/errorcraft/itematic/item/dispense/behavior/DispenseBehaviors.java +++ b/src/main/java/net/errorcraft/itematic/item/dispense/behavior/DispenseBehaviors.java @@ -1,17 +1,16 @@ package net.errorcraft.itematic.item.dispense.behavior; import net.errorcraft.itematic.block.BlockKeys; -import net.errorcraft.itematic.entity.initializer.initializers.SimpleEntityInitializer; +import net.errorcraft.itematic.entity.EntityTypeKeys; import net.errorcraft.itematic.item.ItemKeys; import net.errorcraft.itematic.item.event.ItemEvents; +import net.errorcraft.itematic.loot.condition.LocationCheckLootConditionUtil; import net.errorcraft.itematic.registry.ItematicRegistryKeys; import net.errorcraft.itematic.sound.SoundEventKeys; import net.errorcraft.itematic.world.action.Action; import net.errorcraft.itematic.world.action.ActionEntry; -import net.errorcraft.itematic.world.action.ActionRequirements; import net.errorcraft.itematic.world.action.actions.*; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameters; +import net.errorcraft.itematic.world.action.context.PositionTarget; import net.errorcraft.itematic.world.action.sequence.handler.SequenceHandler; import net.errorcraft.itematic.world.action.sequence.handler.handlers.FirstToPassRequirementsSequenceHandler; import net.errorcraft.itematic.world.action.sequence.handler.handlers.FirstToSucceedSequenceHandler; @@ -23,7 +22,6 @@ import net.minecraft.block.dispenser.ItemDispenserBehavior; import net.minecraft.entity.EntityType; import net.minecraft.item.Item; -import net.minecraft.loot.condition.LocationCheckLootCondition; import net.minecraft.predicate.BlockPredicate; import net.minecraft.predicate.StatePredicate; import net.minecraft.predicate.entity.LocationPredicate; @@ -65,132 +63,104 @@ public static void bootstrap(Registerable registerable) { RegistryEntryLookup blocks = registerable.getRegistryLookup(RegistryKeys.BLOCK); RegistryEntryLookup items = registerable.getRegistryLookup(RegistryKeys.ITEM); RegistryEntryLookup soundEvents = registerable.getRegistryLookup(RegistryKeys.SOUND_EVENT); + RegistryEntryLookup> entityTypes = registerable.getRegistryLookup(RegistryKeys.ENTITY_TYPE); registerable.register(BRUSH, DispenseBehavior.builder( PassingSequenceHandler.builder() - .add(BrushArmadilloAtPositionAction.of(ActionContextParameter.TARGET)) - .add(DamageItemAction.of(16))) - .doNotDispenseOnFailure() - .build() - ); + .add(BrushArmadilloAtPositionAction.of(PositionTarget.INTERACTED_POSITION)) + .add(DamageItemAction.of(16)) + ).doNotDispenseOnFailure().build()); registerable.register(CHARGE_RESPAWN_ANCHOR, DispenseBehavior.builder( ActionEntry.of( - ActionRequirements.of( - ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.TARGET), - LocationCheckLootCondition.builder( - LocationPredicate.Builder.create() - .block(BlockPredicate.Builder.create() - .blocks(blocks, blocks.getOrThrow(BlockKeys.RESPAWN_ANCHOR).value()))) - .build() + LocationCheckLootConditionUtil.builder( + PositionTarget.INTERACTED_POSITION, + LocationPredicate.Builder.create() + .block(BlockPredicate.Builder.create() + .blocks(blocks, blocks.getOrThrow(BlockKeys.RESPAWN_ANCHOR).value())) ), - decrement(ChargeRespawnAnchorAction.of(ActionContextParameter.TARGET)))) - .doNotDispenseOnFailure() - .build() - ); + decrement(ChargeRespawnAnchorAction.of(PositionTarget.INTERACTED_POSITION))) + ).doNotDispenseOnFailure().build()); registerable.register(EQUIP_CHEST, DispenseBehavior.builder( - decrement(EquipHorseWithChestAtPositionAction.of(ActionContextParameter.TARGET))) - .build() - ); + decrement(EquipHorseWithChestAtPositionAction.of(PositionTarget.INTERACTED_POSITION)) + ).build()); registerable.register(EQUIP_ENTITY, DispenseBehavior.builder( - decrement(EquipEntityAtPositionAction.of(ActionContextParameter.TARGET))) - .build() - ); + decrement(EquipEntityAtPositionAction.of(PositionTarget.INTERACTED_POSITION)) + ).build()); registerable.register(EQUIP_ENTITY_HEAD, DispenseBehavior.builder( - decrement(EquipEntityAtPositionAction.of(ActionContextParameter.TARGET))) - .doNotDispenseOnFailure() - .build() - ); + decrement(EquipEntityAtPositionAction.of(PositionTarget.INTERACTED_POSITION)) + ).doNotDispenseOnFailure().build()); registerable.register(GLASS_BOTTLE, DispenseBehavior.builder( FirstToPassRequirementsSequenceHandler.builder() .add( - ActionRequirements.of( - ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.TARGET), - LocationCheckLootCondition.builder( - LocationPredicate.Builder.create() - .block(BlockPredicate.Builder.create() - .state(StatePredicate.Builder.create() - .exactMatch(BeehiveBlock.HONEY_LEVEL, BeehiveBlock.FULL_HONEY_LEVEL)))) - .build() + LocationCheckLootConditionUtil.builder( + PositionTarget.INTERACTED_POSITION, + LocationPredicate.Builder.create() + .block(BlockPredicate.Builder.create() + .state(StatePredicate.Builder.create() + .exactMatch(BeehiveBlock.HONEY_LEVEL, BeehiveBlock.FULL_HONEY_LEVEL))) ), UncheckedSequenceHandler.builder() - .add(TakeHoneyAction.of(ActionContextParameter.TARGET)) - .add(ExchangeItemAction.of(items.getOrThrow(ItemKeys.HONEY_BOTTLE)))) - .add(InvokeItemEventAction.of(ItemEvents.USE_ON_BLOCK))) - .build() - ); + .add(TakeHoneyAction.of(PositionTarget.INTERACTED_POSITION)) + .add(ExchangeItemAction.of(items.getOrThrow(ItemKeys.HONEY_BOTTLE))) + ) + .add(InvokeItemEventAction.of(ItemEvents.USE_ON_BLOCK)) + ).build()); registerable.register(PLACE_BLOCK_FROM_ITEM, DispenseBehavior.builder( - PlaceBlockFromItemAction.of(ActionContextParameter.TARGET, true)) - .doNotDispenseOnFailure() - .build() - ); + PlaceBlockFromItemAction.of(PositionTarget.INTERACTED_POSITION, true) + ).doNotDispenseOnFailure().build()); registerable.register(PLACE_CARVED_PUMPKIN, DispenseBehavior.builder( decrement(FirstToSucceedSequenceHandler.builder() - .add(PlaceCarvedPumpkinAction.of(ActionContextParameter.TARGET)) - .add(EquipEntityAtPositionAction.of(ActionContextParameter.TARGET)))) - .doNotDispenseOnFailure() - .build() - ); - registerable.register(SADDLE, DispenseBehavior.builder( - SaddleEntityAtPositionAction.of(ActionContextParameter.TARGET)) - .build() - ); + .add(PlaceCarvedPumpkinAction.of(PositionTarget.INTERACTED_POSITION)) + .add(EquipEntityAtPositionAction.of(PositionTarget.INTERACTED_POSITION))) + ).doNotDispenseOnFailure().build()); registerable.register(SHEAR, DispenseBehavior.builder( PassingSequenceHandler.builder() - .add(ShearAtPositionAction.of(ActionContextParameter.TARGET)) - .add(DamageItemAction.of(1))) - .doNotDispenseOnFailure() - .build() - ); + .add(ShearAtPositionAction.of(PositionTarget.INTERACTED_POSITION)) + .add(DamageItemAction.of(1)) + ).doNotDispenseOnFailure().build()); registerable.register(SHOOT_BOTTLE, DispenseBehavior.builder( - shootProjectile(1.1f * 1.25f, 6.0f * 0.5f)) - .offset(DispenseBehavior.Offset.of(0.7d, 0.0d, 0.1d, 0.0d)) - .build() - ); + shootProjectile(1.1f * 1.25f, 6.0f * 0.5f) + ).offset(DispenseBehavior.Offset.of(0.7d, 0.0d, 0.1d, 0.0d)).build()); registerable.register(SHOOT_CHARGE, DispenseBehavior.builder( - shootProjectile(1.0f, 20.0f / 3.0f)) - .build() - ); + shootProjectile(1.0f, 20.0f / 3.0f) + ).build()); registerable.register(SHOOT_FIREWORK_ROCKET, DispenseBehavior.builder( - shootProjectile(1.0f, 0.5f)) - .offset(DispenseBehavior.Offset.ofSide( - 0.5d - EntityType.FIREWORK_ROCKET.getWidth() * 0.5d, - -EntityType.FIREWORK_ROCKET.getHeight() + 0.5d, - 0.5d - EntityType.FIREWORK_ROCKET.getWidth() * 0.5d - )) - .build() - ); + shootProjectile(1.0f, 0.5f) + ).offset(DispenseBehavior.Offset.ofSide( + 0.5d - EntityType.FIREWORK_ROCKET.getWidth() * 0.5d, + -EntityType.FIREWORK_ROCKET.getHeight() + 0.5d, + 0.5d - EntityType.FIREWORK_ROCKET.getWidth() * 0.5d + )).build()); registerable.register(SHOOT_PROJECTILE, DispenseBehavior.builder( - shootProjectile(1.1f, 6.0f)) - .offset(DispenseBehavior.Offset.of(0.7d, 0.0d, 0.1d, 0.0d)) - .build() - ); + shootProjectile(1.1f, 6.0f) + ).offset(DispenseBehavior.Offset.of(0.7d, 0.0d, 0.1d, 0.0d)).build()); registerable.register(SPAWN_ENTITY_FROM_ITEM, DispenseBehavior.builder( - SpawnEntityFromItemAction.of(ActionContextParameter.TARGET)) - .build() - ); + SpawnEntityFromItemAction.of(PositionTarget.INTERACTED_POSITION) + ).build()); registerable.register(SPAWN_TNT, DispenseBehavior.builder( PassingSequenceHandler.builder() - .add(SpawnEntityAction.of(ActionContextParameter.TARGET, SimpleEntityInitializer.of(EntityType.TNT))) - .add(PlaySoundAction.of(ActionContextParameter.TARGET, soundEvents.getOrThrow(SoundEventKeys.TNT_PRIMED), SoundCategory.BLOCKS))) - .build() - ); + .add(SpawnEntityAction.of( + PositionTarget.INTERACTED_POSITION, + entityTypes.getOrThrow(EntityTypeKeys.TNT) + )) + .add(PlaySoundAction.of( + PositionTarget.INTERACTED_POSITION, + soundEvents.getOrThrow(SoundEventKeys.TNT_PRIMED), + SoundCategory.BLOCKS + )) + ).build()); registerable.register(USE_BUCKET, DispenseBehavior.builder( - UseBucketAction.of(ActionContextParameter.TARGET)) - .build() - ); + UseBucketAction.of(PositionTarget.INTERACTED_POSITION) + ).build()); registerable.register(USE_ITEM_ON_BLOCK, DispenseBehavior.builder( - InvokeItemEventAction.of(ItemEvents.USE_ON_BLOCK)) - .doNotDispenseOnFailure() - .build() - ); + InvokeItemEventAction.of(ItemEvents.USE_ON_BLOCK) + ).doNotDispenseOnFailure().build()); registerable.register(USE_ITEM_ON_BLOCK_OR_DISPENSE_ITEM, DispenseBehavior.builder( - InvokeItemEventAction.of(ItemEvents.USE_ON_BLOCK)) - .build() - ); + InvokeItemEventAction.of(ItemEvents.USE_ON_BLOCK) + ).build()); registerable.register(WAX_BLOCK, DispenseBehavior.builder( - decrement(WaxBlockAction.of(ActionContextParameter.TARGET))) - .build() - ); + decrement(WaxBlockAction.of(PositionTarget.INTERACTED_POSITION)) + ).build()); } private static RegistryKey of(String id) { @@ -198,7 +168,7 @@ private static RegistryKey of(String id) { } private static PassingSequenceHandler.Builder shootProjectile(float power, float uncertainty) { - return decrement(ShootProjectileFromItemAction.of(ActionContextParameter.TARGET, power, uncertainty)); + return decrement(ShootProjectileFromItemAction.of(PositionTarget.INTERACTED_POSITION, power, uncertainty)); } private static PassingSequenceHandler.Builder decrement(Action action) { diff --git a/src/main/java/net/errorcraft/itematic/item/fuel/FuelTimes.java b/src/main/java/net/errorcraft/itematic/item/fuel/FuelTimes.java new file mode 100644 index 00000000..65914a77 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/item/fuel/FuelTimes.java @@ -0,0 +1,26 @@ +package net.errorcraft.itematic.item.fuel; + +public class FuelTimes { + private static final int BASE = 200; + public static final int LAVA = BASE * 100; + public static final int COAL_BLOCK = BASE * 80; + public static final int DRIED_KELP_BLOCK = BASE * 20 + 1; + public static final int BLAZE_ROD = BASE * 12; + public static final int COAL = BASE * 8; + public static final int BOAT = BASE * 6; + public static final int HANGING_SIGN = BASE * 4; + public static final int SIGN = BASE; + public static final int WOOD = BASE * 3 / 2; + public static final int DOOR = BASE; + public static final int SLAB = BASE * 3 / 4; + public static final int PLANT = BASE / 2; + public static final int BUTTON = BASE / 2; + public static final int SMALL_WOODEN_ITEM = BASE / 2; + public static final int BAMBOO = BASE / 4; + public static final int SCAFFOLDING = BASE / 4; + public static final int TOOL = BASE; + public static final int WOOL = BASE / 2; + public static final int WOOL_CARPET = BASE / 3 + 1; + + private FuelTimes() {} +} diff --git a/src/main/java/net/errorcraft/itematic/item/group/entry/entries/InstrumentItemGroupEntry.java b/src/main/java/net/errorcraft/itematic/item/group/entry/entries/InstrumentItemGroupEntry.java index 8444456c..00f05f18 100644 --- a/src/main/java/net/errorcraft/itematic/item/group/entry/entries/InstrumentItemGroupEntry.java +++ b/src/main/java/net/errorcraft/itematic/item/group/entry/entries/InstrumentItemGroupEntry.java @@ -5,6 +5,7 @@ import net.errorcraft.itematic.item.group.entry.ItemGroupEntryType; import net.errorcraft.itematic.item.group.entry.PossiblyHiddenItemGroupEntry; import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.InstrumentComponent; import net.minecraft.item.Instrument; import net.minecraft.item.Item; import net.minecraft.item.ItemGroup; @@ -52,7 +53,7 @@ protected Collection createStacks(ItemGroup.DisplayContext context) { .stream() .map(instrument -> { ItemStack stack = new ItemStack(this.item); - stack.set(DataComponentTypes.INSTRUMENT, instrument); + stack.set(DataComponentTypes.INSTRUMENT, new InstrumentComponent(instrument)); return stack; }) .toList(); diff --git a/src/main/java/net/errorcraft/itematic/item/group/entry/entries/PaintingVariantItemGroupEntry.java b/src/main/java/net/errorcraft/itematic/item/group/entry/entries/PaintingVariantItemGroupEntry.java index 0f4b7af2..7e2432c9 100644 --- a/src/main/java/net/errorcraft/itematic/item/group/entry/entries/PaintingVariantItemGroupEntry.java +++ b/src/main/java/net/errorcraft/itematic/item/group/entry/entries/PaintingVariantItemGroupEntry.java @@ -1,34 +1,23 @@ package net.errorcraft.itematic.item.group.entry.entries; -import com.mojang.logging.LogUtils; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.entity.EntityTypeKeys; import net.errorcraft.itematic.item.group.entry.ItemGroupEntryType; import net.errorcraft.itematic.item.group.entry.PossiblyHiddenItemGroupEntry; import net.errorcraft.itematic.mixin.item.ItemGroupsAccessor; import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.NbtComponent; -import net.minecraft.entity.Entity; -import net.minecraft.entity.decoration.painting.PaintingEntity; import net.minecraft.entity.decoration.painting.PaintingVariant; import net.minecraft.item.Item; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtElement; -import net.minecraft.nbt.NbtOps; import net.minecraft.predicate.TagPredicate; import net.minecraft.registry.RegistryKeys; -import net.minecraft.registry.RegistryOps; -import net.minecraft.registry.RegistryWrapper; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.registry.entry.RegistryFixedCodec; import net.minecraft.registry.tag.TagKey; -import org.slf4j.Logger; import java.util.Collection; import java.util.Comparator; -import java.util.Optional; public class PaintingVariantItemGroupEntry extends PossiblyHiddenItemGroupEntry { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> createCodec(instance).and(instance.group( @@ -36,7 +25,6 @@ public class PaintingVariantItemGroupEntry extends PossiblyHiddenItemGroupEntry TagPredicate.createCodec(RegistryKeys.PAINTING_VARIANT).fieldOf("tag").forGetter(entry -> entry.tag) )).apply(instance, PaintingVariantItemGroupEntry::new)); private static final Comparator> PAINTING_VARIANT_COMPARATOR = ItemGroupsAccessor.paintingVariantComparator(); - private static final Logger LOGGER = LogUtils.getLogger(); private final RegistryEntry item; private final TagPredicate tag; @@ -66,18 +54,14 @@ public ItemGroupEntryType type() { @Override protected Collection createStacks(ItemGroup.DisplayContext context) { - RegistryWrapper.WrapperLookup lookup = context.lookup(); - RegistryOps ops = lookup.getOps(NbtOps.INSTANCE); - return lookup.getOrThrow(RegistryKeys.PAINTING_VARIANT) + return context.lookup() + .getOrThrow(RegistryKeys.PAINTING_VARIANT) .streamEntries() .filter(this.tag::test) .sorted(PAINTING_VARIANT_COMPARATOR) - .map(variant -> NbtComponent.DEFAULT.with(ops, PaintingEntity.VARIANT_MAP_CODEC, variant).resultOrPartial(LOGGER::error)) - .flatMap(Optional::stream) - .map(nbt -> nbt.apply(newNbt -> newNbt.putString(Entity.ID_KEY, EntityTypeKeys.PAINTING.getValue().toString()))) - .map(nbt -> { + .map(paintingVariant -> { ItemStack stack = new ItemStack(this.item); - stack.set(DataComponentTypes.ENTITY_DATA, nbt); + stack.set(DataComponentTypes.PAINTING_VARIANT, paintingVariant); return stack; }) .toList(); diff --git a/src/main/java/net/errorcraft/itematic/item/group/entry/provider/ItemGroupEntryProviders.java b/src/main/java/net/errorcraft/itematic/item/group/entry/provider/ItemGroupEntryProviders.java index 768a5f05..f2a34071 100644 --- a/src/main/java/net/errorcraft/itematic/item/group/entry/provider/ItemGroupEntryProviders.java +++ b/src/main/java/net/errorcraft/itematic/item/group/entry/provider/ItemGroupEntryProviders.java @@ -93,6 +93,7 @@ public static void bootstrap(Registerable registerable) ItemGroupEntry.simple(items.getOrThrow(ItemKeys.HONEYCOMB_BLOCK)), ItemGroupEntry.simple(items.getOrThrow(ItemKeys.SLIME_BLOCK)), ItemGroupEntry.simple(items.getOrThrow(ItemKeys.HONEY_BLOCK)), + ItemGroupEntry.simple(items.getOrThrow(ItemKeys.RESIN_BLOCK)), ItemGroupEntry.tag(ItematicItemTags.FROGLIGHTS), ItemGroupEntry.tag(ItematicItemTags.SCULK), ItemGroupEntry.simple(items.getOrThrow(ItemKeys.COBWEB)), @@ -272,7 +273,7 @@ public static void bootstrap(Registerable registerable) .add(items.getOrThrow(ItemKeys.TNT)) .add(items.getOrThrow(ItemKeys.END_CRYSTAL)) .add(items.getOrThrow(ItemKeys.SNOWBALL)) - .add(items.getOrThrow(ItemKeys.EGG)) + .add(ItematicItemTags.EGGS) .add(items.getOrThrow(ItemKeys.WIND_CHARGE)) .add(items.getOrThrow(ItemKeys.BOW)) .add(items.getOrThrow(ItemKeys.CROSSBOW)) @@ -305,6 +306,7 @@ public static void bootstrap(Registerable registerable) .add(items.getOrThrow(ItemKeys.ANCIENT_DEBRIS)) .add(items.getOrThrow(ItemKeys.QUARTZ)) .add(items.getOrThrow(ItemKeys.AMETHYST_SHARD)) + .add(items.getOrThrow(ItemKeys.RESIN_CLUMP)) .add(items.getOrThrow(ItemKeys.IRON_NUGGET)) .add(items.getOrThrow(ItemKeys.GOLD_NUGGET)) .add(items.getOrThrow(ItemKeys.IRON_INGOT)) @@ -320,7 +322,7 @@ public static void bootstrap(Registerable registerable) .add(items.getOrThrow(ItemKeys.STRING)) .add(items.getOrThrow(ItemKeys.FEATHER)) .add(items.getOrThrow(ItemKeys.SNOWBALL)) - .add(items.getOrThrow(ItemKeys.EGG)) + .add(ItematicItemTags.EGGS) .add(items.getOrThrow(ItemKeys.LEATHER)) .add(items.getOrThrow(ItemKeys.RABBIT_HIDE)) .add(items.getOrThrow(ItemKeys.HONEYCOMB)) @@ -349,6 +351,7 @@ public static void bootstrap(Registerable registerable) .add(items.getOrThrow(ItemKeys.BOWL)) .add(items.getOrThrow(ItemKeys.BRICK)) .add(items.getOrThrow(ItemKeys.NETHER_BRICK)) + .add(items.getOrThrow(ItemKeys.RESIN_BRICK)) .add(items.getOrThrow(ItemKeys.PAPER)) .add(items.getOrThrow(ItemKeys.BOOK)) .add(items.getOrThrow(ItemKeys.FIREWORK_STAR)) @@ -364,6 +367,7 @@ public static void bootstrap(Registerable registerable) ); registerable.register(ItemGroupEntryProviderKeys.SPAWN_EGGS, ItemGroupEntryProvider.of( ItemGroupEntry.tag(ItematicItemTags.SPAWNERS), + ItemGroupEntry.simple(items.getOrThrow(ItemKeys.CREAKING_HEART)), ItemGroupEntry.simple(items.getOrThrow(ItemKeys.ALLAY_SPAWN_EGG)), ItemGroupEntry.simple(items.getOrThrow(ItemKeys.ARMADILLO_SPAWN_EGG)), ItemGroupEntry.simple(items.getOrThrow(ItemKeys.AXOLOTL_SPAWN_EGG)), @@ -378,6 +382,7 @@ public static void bootstrap(Registerable registerable) ItemGroupEntry.simple(items.getOrThrow(ItemKeys.CHICKEN_SPAWN_EGG)), ItemGroupEntry.simple(items.getOrThrow(ItemKeys.COD_SPAWN_EGG)), ItemGroupEntry.simple(items.getOrThrow(ItemKeys.COW_SPAWN_EGG)), + ItemGroupEntry.simple(items.getOrThrow(ItemKeys.CREAKING_SPAWN_EGG)), ItemGroupEntry.simple(items.getOrThrow(ItemKeys.CREEPER_SPAWN_EGG)), ItemGroupEntry.simple(items.getOrThrow(ItemKeys.DOLPHIN_SPAWN_EGG)), ItemGroupEntry.simple(items.getOrThrow(ItemKeys.DONKEY_SPAWN_EGG)), diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/ClampedModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/ClampedModelOverride.java deleted file mode 100644 index 2a1d3bdf..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/ClampedModelOverride.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.errorcraft.itematic.item.model.override; - -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.MathHelper; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public interface ClampedModelOverride extends ModelOverride { - default float apply(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - return MathHelper.clamp(this.applyUnclamped(stack, world, target, seed), 0.0f, 1.0f); - } - - float applyUnclamped(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed); -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/ModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/ModelOverride.java deleted file mode 100644 index d98e14b2..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/ModelOverride.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.errorcraft.itematic.item.model.override; - -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public interface ModelOverride { - float apply(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed); - default boolean isApplicable(ItemStack stack) { - return true; - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/ModelOverrideKeys.java b/src/main/java/net/errorcraft/itematic/item/model/override/ModelOverrideKeys.java deleted file mode 100644 index 611007e3..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/ModelOverrideKeys.java +++ /dev/null @@ -1,32 +0,0 @@ -package net.errorcraft.itematic.item.model.override; - -import net.errorcraft.itematic.registry.ItematicRegistryKeys; -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.Identifier; - -public class ModelOverrideKeys { - public static final RegistryKey LEFT_HANDED = of("lefthanded"); - public static final RegistryKey COOLDOWN = of("cooldown"); - public static final RegistryKey CUSTOM_MODEL_DATA = of("custom_model_data"); - public static final RegistryKey TRIM_TYPE = of("trim_type"); - public static final RegistryKey DAMAGED = of("damaged"); - public static final RegistryKey DAMAGE = of("damage"); - public static final RegistryKey PULL = of("pull"); - public static final RegistryKey PULLING = of("pulling"); - public static final RegistryKey CHARGED = of("charged"); - public static final RegistryKey FIREWORK = of("firework"); - public static final RegistryKey BROKEN = of("broken"); - public static final RegistryKey CAST = of("cast"); - public static final RegistryKey BLOCKING = of("blocking"); - public static final RegistryKey TIME = of("time"); - public static final RegistryKey ANGLE = of("angle"); - public static final RegistryKey TOOTING = of("tooting"); - public static final RegistryKey THROWING = of("throwing"); - public static final RegistryKey BRUSHING = of("brushing"); - public static final RegistryKey FILLED = of("filled"); - public static final RegistryKey LEVEL = of("level"); - - private static RegistryKey of(String id) { - return RegistryKey.of(ItematicRegistryKeys.MODEL_OVERRIDE, Identifier.ofVanilla(id)); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/ModelOverrides.java b/src/main/java/net/errorcraft/itematic/item/model/override/ModelOverrides.java deleted file mode 100644 index e630277f..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/ModelOverrides.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.errorcraft.itematic.item.model.override; - -import net.errorcraft.itematic.item.model.override.overrides.*; -import net.errorcraft.itematic.registry.ItematicRegistries; -import net.minecraft.registry.Registry; -import net.minecraft.registry.RegistryKey; - -public class ModelOverrides { - public static final ModelOverride LEFT_HANDED = register(ModelOverrideKeys.LEFT_HANDED, new LeftHandedModelOverride()); - public static final ModelOverride COOLDOWN = register(ModelOverrideKeys.COOLDOWN, new CooldownModelOverride()); - public static final ModelOverride CUSTOM_MODEL_DATA = register(ModelOverrideKeys.CUSTOM_MODEL_DATA, new CustomModelDataModelOverride()); - public static final ModelOverride TRIM_TYPE = register(ModelOverrideKeys.TRIM_TYPE, new TrimTypeModelOverride()); - public static final ModelOverride DAMAGED = register(ModelOverrideKeys.DAMAGED, new DamagedModelOverride()); - public static final ModelOverride DAMAGE = register(ModelOverrideKeys.DAMAGE, new DamageModelOverride()); - public static final ModelOverride PULL = register(ModelOverrideKeys.PULL, new PullModelOverride()); - public static final ModelOverride PULLING = register(ModelOverrideKeys.PULLING, new PullingModelOverride()); - public static final ModelOverride CHARGED = register(ModelOverrideKeys.CHARGED, new ChargedModelOverride()); - public static final ModelOverride FIREWORK = register(ModelOverrideKeys.FIREWORK, new FireworkModelOverride()); - public static final ModelOverride BROKEN = register(ModelOverrideKeys.BROKEN, new BrokenModelOverride()); - public static final ModelOverride CAST = register(ModelOverrideKeys.CAST, new CastModelOverride()); - public static final ModelOverride BLOCKING = register(ModelOverrideKeys.BLOCKING, new BlockingModelOverride()); - public static final ModelOverride TIME = register(ModelOverrideKeys.TIME, new TimeModelOverride()); - public static final ModelOverride ANGLE = register(ModelOverrideKeys.ANGLE, new AngleModelOverride()); - public static final ModelOverride TOOTING = register(ModelOverrideKeys.TOOTING, new TootingModelOverride()); - public static final ModelOverride THROWING = register(ModelOverrideKeys.THROWING, new ThrowingModelOverride()); - public static final ModelOverride BRUSHING = register(ModelOverrideKeys.BRUSHING, new BrushingModelOverride()); - public static final ModelOverride FILLED = register(ModelOverrideKeys.FILLED, new FilledModelOverride()); - public static final ModelOverride LEVEL = register(ModelOverrideKeys.LEVEL, new LevelModelOverride()); - - private ModelOverrides() {} - - public static void init() {} - - private static ModelOverride register(RegistryKey id, ModelOverride override) { - return Registry.register(ItematicRegistries.MODEL_OVERRIDE, id, override); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/AngleModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/AngleModelOverride.java deleted file mode 100644 index 8865fd03..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/AngleModelOverride.java +++ /dev/null @@ -1,95 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.component.components.PointableItemComponent; -import net.errorcraft.itematic.item.model.override.ModelOverride; -import net.minecraft.entity.Entity; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.GlobalPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class AngleModelOverride implements ModelOverride { - private static final float INTERPOLATION_FACTOR = 0.8f; - private static final double DISTANCE_EPSILON = 0.00001d; - private static final Interpolator INTERPOLATOR = new Interpolator(INTERPOLATION_FACTOR); - private static final Interpolator AIMLESS_INTERPOLATOR = new Interpolator(INTERPOLATION_FACTOR); - - @Override - public float apply(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - if (world == null) { - return 0.0f; - } - if (target == null) { - return 0.0f; - } - return stack.itematic$getBehavior(ItemComponentTypes.POINTABLE) - .map(PointableItemComponent::pointsTo) - .map(RegistryEntry::value) - .map(p -> this.getAngle(p.createPos(stack, world, target), target, world)) - .orElse(0.0f); - } - - @Override - public boolean isApplicable(ItemStack stack) { - return stack.itematic$hasBehavior(ItemComponentTypes.POINTABLE); - } - - private float getAngle(GlobalPos pos, Entity target, World world) { - if (this.canPointTo(target, pos)) { - return this.getAngle(pos.pos(), target, world); - } - return AIMLESS_INTERPOLATOR.update(world, world.getRandom().nextFloat()); - } - - private boolean canPointTo(Entity target, GlobalPos pos) { - return pos != null - && pos.dimension() == target.getWorld().getRegistryKey() - && pos.pos().getSquaredDistance(target.getPos()) >= DISTANCE_EPSILON; - } - - private float getAngle(BlockPos pos, Entity target, World world) { - float entityAngle = this.getNormalizedAngle(target, pos); - float entityRotation = this.getNormalizedEntityRotation(target); - float interpolatedAngle = INTERPOLATOR.update(world, 0.5f - (entityRotation - 0.25f)); - return MathHelper.floorMod(entityAngle + interpolatedAngle, 1.0f); - } - - private float getNormalizedAngle(Entity target, BlockPos pos) { - Vec3d centerPos = Vec3d.ofCenter(pos); - return (float) (Math.atan2( centerPos.getZ() - target.getZ(), centerPos.getX() - target.getX()) / (2.0d * Math.PI)); - } - - private float getNormalizedEntityRotation(Entity target) { - return MathHelper.floorMod(target.getBodyYaw() / 360.0f, 1.0f); - } - - public static class Interpolator { - private final float interpolationFactor; - private long lastTick; - private float value; - private float speed; - - public Interpolator(float interpolationFactor) { - this.interpolationFactor = interpolationFactor; - } - - public float update(World world, float angle) { - long currentTick = world.getTime(); - if (currentTick == this.lastTick) { - return this.value; - } - - this.lastTick = currentTick; - float deltaValue = MathHelper.floorMod(angle - this.value + 0.5f, 1.0f) - 0.5f; - this.speed += deltaValue * 0.1f; - this.speed *= this.interpolationFactor; - return this.value = MathHelper.floorMod(this.value + this.speed, 1.0f); - } - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/BlockingModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/BlockingModelOverride.java deleted file mode 100644 index 89932845..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/BlockingModelOverride.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.ItemKeys; -import net.errorcraft.itematic.item.model.override.ModelOverride; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class BlockingModelOverride implements ModelOverride { - @Override - public float apply(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - if (target == null) { - return 0.0f; - } - if (!target.isUsingItem()) { - return 0.0f; - } - if (target.getActiveItem() != stack) { - return 0.0f; - } - return 1.0f; - } - - @Override - public boolean isApplicable(ItemStack stack) { - return stack.itematic$isOf(ItemKeys.SHIELD); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/BrokenModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/BrokenModelOverride.java deleted file mode 100644 index a12fd7db..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/BrokenModelOverride.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.model.override.ModelOverride; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class BrokenModelOverride implements ModelOverride { - @Override - public float apply(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - return stack.itematic$getBehavior(ItemComponentTypes.DAMAGEABLE) - .map(c -> c.isUsable(stack) ? 0.0f : 1.0f) - .orElse(0.0f); - } - - @Override - public boolean isApplicable(ItemStack stack) { - return stack.itematic$hasBehavior(ItemComponentTypes.DAMAGEABLE); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/BrushingModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/BrushingModelOverride.java deleted file mode 100644 index 7b278bad..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/BrushingModelOverride.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.ItemKeys; -import net.errorcraft.itematic.item.model.override.ModelOverride; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.BrushItem; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class BrushingModelOverride implements ModelOverride { - private static final float DURATION = BrushItem.ANIMATION_DURATION; - - @Override - public float apply(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - if (target == null) { - return 0.0f; - } - if (target.getActiveItem() != stack) { - return 0.0f; - } - return (target.getItemUseTimeLeft() % DURATION) / DURATION; - } - - @Override - public boolean isApplicable(ItemStack stack) { - return stack.itematic$isOf(ItemKeys.BRUSH); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/CastModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/CastModelOverride.java deleted file mode 100644 index 14c280bd..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/CastModelOverride.java +++ /dev/null @@ -1,44 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.ItemKeys; -import net.errorcraft.itematic.item.model.override.ModelOverride; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class CastModelOverride implements ModelOverride { - @Override - public float apply(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - if (target == null) { - return 0.0f; - } - if (!this.isValidStack(stack, target)) { - return 0.0f; - } - if (!(target instanceof PlayerEntity player)) { - return 0.0f; - } - if (player.fishHook == null) { - return 0.0f; - } - return 1.0f; - } - - private boolean isValidStack(ItemStack stack, LivingEntity target) { - ItemStack mainHandStack = target.getMainHandStack(); - if (mainHandStack == stack) { - return true; - } - if (target.getOffHandStack() == stack) { - return !this.isApplicable(mainHandStack); - } - return false; - } - - @Override - public boolean isApplicable(ItemStack stack) { - return stack.itematic$isOf(ItemKeys.FISHING_ROD); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/ChargedModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/ChargedModelOverride.java deleted file mode 100644 index 3768f5de..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/ChargedModelOverride.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.model.override.ModelOverride; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.CrossbowItem; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class ChargedModelOverride implements ModelOverride { - @Override - public float apply(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - if (CrossbowItem.isCharged(stack)) { - return 1.0f; - } - - return 0.0f; - } - - @Override - public boolean isApplicable(ItemStack stack) { - return stack.itematic$hasBehavior(ItemComponentTypes.SHOOTER); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/CooldownModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/CooldownModelOverride.java deleted file mode 100644 index a3f92a20..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/CooldownModelOverride.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.model.override.ClampedModelOverride; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class CooldownModelOverride implements ClampedModelOverride { - @Override - public float applyUnclamped(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - if (target instanceof PlayerEntity player) { - player.getItemCooldownManager().getCooldownProgress(stack, 0.0f); - } - - return 0.0f; - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/CustomModelDataModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/CustomModelDataModelOverride.java deleted file mode 100644 index 4eeb0c09..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/CustomModelDataModelOverride.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.model.override.ModelOverride; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.CustomModelDataComponent; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class CustomModelDataModelOverride implements ModelOverride { - @Override - public float apply(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - return stack.getOrDefault(DataComponentTypes.CUSTOM_MODEL_DATA, CustomModelDataComponent.DEFAULT).value(); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/DamageModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/DamageModelOverride.java deleted file mode 100644 index 4b46be6d..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/DamageModelOverride.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.model.override.ClampedModelOverride; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class DamageModelOverride implements ClampedModelOverride { - @Override - public float applyUnclamped(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - return (float)stack.getDamage() / stack.getMaxDamage(); - } - - @Override - public boolean isApplicable(ItemStack stack) { - return stack.itematic$hasBehavior(ItemComponentTypes.DAMAGEABLE); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/DamagedModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/DamagedModelOverride.java deleted file mode 100644 index 38637b71..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/DamagedModelOverride.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.model.override.ModelOverride; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class DamagedModelOverride implements ModelOverride { - @Override - public float apply(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - return stack.isDamaged() ? 1.0f : 0.0f; - } - - @Override - public boolean isApplicable(ItemStack stack) { - return stack.itematic$hasBehavior(ItemComponentTypes.DAMAGEABLE); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/FilledModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/FilledModelOverride.java deleted file mode 100644 index 952183ad..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/FilledModelOverride.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.model.override.ClampedModelOverride; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.apache.commons.lang3.math.Fraction; -import org.jetbrains.annotations.Nullable; - -public class FilledModelOverride implements ClampedModelOverride { - @Override - public float applyUnclamped(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - return stack.itematic$getBehavior(ItemComponentTypes.ITEM_HOLDER) - .map(c -> c.occupancy(stack)) - .map(Fraction::floatValue) - .orElse(0.0f); - } - - @Override - public boolean isApplicable(ItemStack stack) { - return stack.itematic$hasBehavior(ItemComponentTypes.ITEM_HOLDER); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/FireworkModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/FireworkModelOverride.java deleted file mode 100644 index 57eb3697..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/FireworkModelOverride.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.ItemKeys; -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.model.override.ModelOverride; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.ChargedProjectilesComponent; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class FireworkModelOverride implements ModelOverride { - @Override - public float apply(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - if (stack.getOrDefault(DataComponentTypes.CHARGED_PROJECTILES, ChargedProjectilesComponent.DEFAULT).itematic$contains(ItemKeys.FIREWORK_ROCKET)) { - return 1.0f; - } - return 0.0f; - } - - @Override - public boolean isApplicable(ItemStack stack) { - return stack.itematic$hasBehavior(ItemComponentTypes.SHOOTER); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/LeftHandedModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/LeftHandedModelOverride.java deleted file mode 100644 index ce16d0c1..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/LeftHandedModelOverride.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.model.override.ModelOverride; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.util.Arm; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class LeftHandedModelOverride implements ModelOverride { - @Override - public float apply(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - return target == null || target.getMainArm() == Arm.LEFT ? 1.0f : 0.0f; - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/LevelModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/LevelModelOverride.java deleted file mode 100644 index f20fdaf1..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/LevelModelOverride.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.ItemKeys; -import net.errorcraft.itematic.item.model.override.ClampedModelOverride; -import net.minecraft.block.LightBlock; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.BlockStateComponent; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class LevelModelOverride implements ClampedModelOverride { - @Override - public float applyUnclamped(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - BlockStateComponent blockState = stack.getOrDefault(DataComponentTypes.BLOCK_STATE, BlockStateComponent.DEFAULT); - Integer level = blockState.getValue(LightBlock.LEVEL_15); - if (level == null) { - return 1.0f; - } - - return level / 16.0f; - } - - @Override - public boolean isApplicable(ItemStack stack) { - return stack.itematic$isOf(ItemKeys.LIGHT); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/PullModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/PullModelOverride.java deleted file mode 100644 index eb8f1b33..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/PullModelOverride.java +++ /dev/null @@ -1,30 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.model.override.ClampedModelOverride; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class PullModelOverride implements ClampedModelOverride { - @Override - public float applyUnclamped(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - if (target == null) { - return 0.0f; - } - - if (target.getActiveItem() != stack) { - return 0.0f; - } - - return stack.itematic$getBehavior(ItemComponentTypes.SHOOTER) - .map(shooter -> shooter.method().pullProgress(stack, target, target.itematic$itemUsedTicks())) - .orElse(0.0f); - } - - @Override - public boolean isApplicable(ItemStack stack) { - return stack.itematic$hasBehavior(ItemComponentTypes.SHOOTER); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/PullingModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/PullingModelOverride.java deleted file mode 100644 index 99a989ab..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/PullingModelOverride.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.model.override.ModelOverride; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.CrossbowItem; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class PullingModelOverride implements ModelOverride { - @Override - public float apply(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - if (target == null) { - return 0.0f; - } - - if (!target.isUsingItem()) { - return 0.0f; - } - - if (target.getActiveItem() != stack) { - return 0.0f; - } - - if (CrossbowItem.isCharged(stack)) { - return 0.0f; - } - - return 1.0f; - } - - @Override - public boolean isApplicable(ItemStack stack) { - return stack.itematic$hasBehavior(ItemComponentTypes.SHOOTER); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/ThrowingModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/ThrowingModelOverride.java deleted file mode 100644 index 4c033cca..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/ThrowingModelOverride.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.ItemKeys; -import net.errorcraft.itematic.item.model.override.ModelOverride; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class ThrowingModelOverride implements ModelOverride { - @Override - public float apply(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - if (target == null) { - return 0.0f; - } - if (!target.isUsingItem()) { - return 0.0f; - } - if (target.getActiveItem() != stack) { - return 0.0f; - } - return 1.0f; - } - - @Override - public boolean isApplicable(ItemStack stack) { - return stack.itematic$isOf(ItemKeys.TRIDENT); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/TimeModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/TimeModelOverride.java deleted file mode 100644 index fc3ec5b0..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/TimeModelOverride.java +++ /dev/null @@ -1,33 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.ItemKeys; -import net.errorcraft.itematic.item.model.override.ModelOverride; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class TimeModelOverride implements ModelOverride { - private static final AngleModelOverride.Interpolator INTERPOLATOR = new AngleModelOverride.Interpolator(0.9f); - - @Override - public float apply(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - if (world == null) { - return 0.0f; - } - float angle = this.getAngle(world); - return INTERPOLATOR.update(world, angle); - } - - @Override - public boolean isApplicable(ItemStack stack) { - return stack.itematic$isOf(ItemKeys.CLOCK); - } - - private float getAngle(World world) { - if (world.getDimension().natural()) { - return world.getSkyAngle(1.0f); - } - return world.getRandom().nextFloat(); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/TootingModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/TootingModelOverride.java deleted file mode 100644 index 833a665d..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/TootingModelOverride.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.model.override.ModelOverride; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class TootingModelOverride implements ModelOverride { - @Override - public float apply(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - if (target == null) { - return 0.0f; - } - if (!target.isUsingItem()) { - return 0.0f; - } - if (target.getActiveItem() != stack) { - return 0.0f; - } - return 1.0f; - } - - @Override - public boolean isApplicable(ItemStack stack) { - return stack.itematic$hasBehavior(ItemComponentTypes.PLAYABLE); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/TrimTypeModelOverride.java b/src/main/java/net/errorcraft/itematic/item/model/override/overrides/TrimTypeModelOverride.java deleted file mode 100644 index 8cd07d14..00000000 --- a/src/main/java/net/errorcraft/itematic/item/model/override/overrides/TrimTypeModelOverride.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.errorcraft.itematic.item.model.override.overrides; - -import net.errorcraft.itematic.item.model.override.ClampedModelOverride; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.item.equipment.trim.ArmorTrim; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class TrimTypeModelOverride implements ClampedModelOverride { - @Override - public float applyUnclamped(ItemStack stack, @Nullable World world, @Nullable LivingEntity target, int seed) { - ArmorTrim trim = stack.get(DataComponentTypes.TRIM); - if (trim == null) { - return 0.0f; - } - - return trim.material().value().itemModelIndex(); - } - - @Override - public boolean isApplicable(ItemStack stack) { - return stack.contains(DataComponentTypes.TRIM); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/placement/BlockPlacer.java b/src/main/java/net/errorcraft/itematic/item/placement/BlockPlacer.java index 291892c4..a38618ae 100644 --- a/src/main/java/net/errorcraft/itematic/item/placement/BlockPlacer.java +++ b/src/main/java/net/errorcraft/itematic/item/placement/BlockPlacer.java @@ -1,15 +1,14 @@ package net.errorcraft.itematic.item.placement; -import net.errorcraft.itematic.access.block.entity.BlockEntityAccess; -import net.errorcraft.itematic.block.BlockStateUtil; import net.errorcraft.itematic.block.ShapeContextUtil; import net.errorcraft.itematic.item.ItemResult; -import net.errorcraft.itematic.item.ItemStackConsumer; import net.errorcraft.itematic.item.event.ItemEvents; import net.errorcraft.itematic.item.placement.block.picker.BlockPicker; import net.errorcraft.itematic.mixin.block.BlockItemAccessor; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; +import net.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.advancement.criterion.Criteria; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -22,49 +21,67 @@ import net.minecraft.item.ItemPlacementContext; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUsageContext; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.sound.BlockSoundGroup; import net.minecraft.sound.SoundCategory; -import net.minecraft.state.StateManager; -import net.minecraft.state.property.Property; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; import net.minecraft.world.event.GameEvent; import org.jetbrains.annotations.Nullable; -import java.util.Map; - public class BlockPlacer extends Placer { private final BlockPicker block; private final ItemPlacementContext context; private final boolean operatorOnly; private final boolean decrementStack; - public BlockPlacer(ItemStack stack, ItemStackConsumer resultStackConsumer, World world, BlockPos blockPos, BlockState blockState, PlayerEntity player, BlockPicker block, ItemPlacementContext context, boolean operatorOnly, boolean decrementStack) { - super(stack, resultStackConsumer, world, blockPos, blockState, player); + private BlockPlacer(ItemStack stack, ItemStackExchanger stackExchanger, World world, BlockPos blockPos, BlockState blockState, PlayerEntity player, BlockPicker block, ItemPlacementContext context, boolean operatorOnly, boolean decrementStack) { + super(stack, stackExchanger, world, blockPos, blockState, player); this.block = block; this.context = context; this.operatorOnly = operatorOnly; this.decrementStack = decrementStack; } - public static BlockPlacer of(ActionContext context, ActionContextParameter position, BlockPicker block, boolean operatorOnly, boolean decrementStack) { - return of(context.createItemPlacementContext(position, block.defaultBlock()), context.resultStackConsumer(), block, operatorOnly, decrementStack); + public static BlockPlacer action(ActionContext context, PositionTarget position, BlockPicker block, boolean decrementCount) { + ItemPlacementContext placeContext = context.blockPlaceContext(position, block); + if (placeContext == null) { + return null; + } + + BlockPos pos = context.getBlockPos(position.parameter()); + if (pos == null) { + return null; + } + + return new BlockPlacer( + context.getOrDefault(LootContextParameters.TOOL, ItemStack.EMPTY), + context.stackExchanger(), + context.world(), + pos, + context.world().getBlockState(pos), + context.get(LootContextParameters.THIS_ENTITY) instanceof PlayerEntity player ? player : null, + block, + placeContext, + false, + decrementCount + ); } - public static BlockPlacer of(ItemUsageContext context, ItemStackConsumer resultStackConsumer, BlockPicker block, boolean operatorOnly, boolean decrementStack) { + public static BlockPlacer of(ItemUsageContext context, ItemStackExchanger stackExchanger, BlockPicker block, boolean operatorOnly, boolean decrementStack) { World world = context.getWorld(); BlockPos pos = context.getBlockPos(); Direction side = context.getSide(); ItemPlacementContext placementContext = block.placementContext(context.getPlayer() != null ? new ItemPlacementContext(context) : new AutomaticItemPlacementContext(world, pos, side, context.getStack(), world.isAir(pos.down()) ? side : Direction.UP)); - return of(placementContext, resultStackConsumer, block, operatorOnly, decrementStack); + return of(placementContext, stackExchanger, block, operatorOnly, decrementStack); } - public static BlockPlacer of(ItemPlacementContext context, ItemStackConsumer resultStackConsumer, BlockPicker block, boolean operatorOnly, boolean decrementStack) { + public static BlockPlacer of(ItemPlacementContext context, ItemStackExchanger stackExchanger, BlockPicker block, boolean operatorOnly, boolean decrementStack) { World world = context.getWorld(); BlockPos blockPos = context.getBlockPos(); - return new BlockPlacer(context.getStack(), resultStackConsumer, world, blockPos, world.getBlockState(blockPos), context.getPlayer(), block, context, operatorOnly, decrementStack); + return new BlockPlacer(context.getStack(), stackExchanger, world, blockPos, world.getBlockState(blockPos), context.getPlayer(), block, context, operatorOnly, decrementStack); } @Override @@ -72,10 +89,12 @@ public ItemResult place() { if (!this.context.canPlace()) { return ItemResult.PASS; } + BlockState blockState = this.getPlacementState(); if (blockState == null) { return ItemResult.PASS; } + if (!this.world.setBlockState(this.blockPos, blockState, Block.NOTIFY_ALL_AND_REDRAW)) { return ItemResult.PASS; } @@ -88,15 +107,20 @@ private void placed(BlockState blockState) { blockState = this.placeFromNbt(blockState); BlockEntity blockEntity = this.world.getBlockEntity(this.blockPos); if (blockEntity != null) { - ((BlockEntityAccess) blockEntity).itematic$placedFromItemStack(this.world, this.player, blockState, this.blockPos, this.stack); + blockEntity.itematic$placedFromItemStack(this.world, this.player, blockState, this.blockPos, this.stack); } + BlockItemAccessor.copyComponentsToBlockEntity(this.world, this.blockPos, this.stack); blockState.getBlock().onPlaced(this.world, this.blockPos, blockState, this.player, this.stack); if (this.player instanceof ServerPlayerEntity serverPlayer) { Criteria.PLACED_BLOCK.trigger(serverPlayer, this.blockPos, this.stack); - ActionContext context = ActionContext.builder(serverPlayer.getServerWorld(), this.stack, this.resultStackConsumer, this.context.getHand()) - .entityPosition(ActionContextParameter.THIS, serverPlayer) - .position(ActionContextParameter.TARGET, this.blockPos) + ActionContext context = ActionContext.builder(serverPlayer.getServerWorld()) + .stackExchanger(this.stackExchanger) + .add(LootContextParameters.THIS_ENTITY, serverPlayer) + .add(LootContextParameters.ORIGIN, serverPlayer.getPos()) + .add(ItematicContextParameters.INTERACTED_POSITION, this.blockPos.toCenterPos()) + .add(LootContextParameters.TOOL, this.stack) + .add(ItematicContextParameters.HAND, this.context.getHand()) .build(); this.stack.itematic$invokeEvent(ItemEvents.PLACED_BLOCK, context); } @@ -114,6 +138,7 @@ private BlockState getPlacementState() { if (this.operatorOnly && this.player != null && !this.player.isCreativeLevelTwoOp()) { return null; } + BlockState state = this.block.placementState(this.context); return this.canPlace(state) ? state : null; } @@ -122,28 +147,22 @@ private boolean canPlace(BlockState state) { if (state == null) { return false; } + ShapeContext shapeContext = ShapeContextUtil.ofNullable(this.player); return state.canPlaceAt(this.world, this.blockPos) && this.world.canPlace(state, this.blockPos, shapeContext); } private BlockState placeFromNbt(BlockState state) { - BlockState blockState = state; - BlockStateComponent blockStates = this.stack.get(DataComponentTypes.BLOCK_STATE); - if (blockStates != null) { - StateManager stateManager = state.getBlock().getStateManager(); - - for (Map.Entry entry : blockStates.properties().entrySet()) { - Property property = stateManager.getProperty(entry.getKey()); - if (property != null) { - blockState = BlockStateUtil.with(blockState, property, entry.getValue()); - } - } + BlockStateComponent blockStateProperties = this.stack.getOrDefault(DataComponentTypes.BLOCK_STATE, BlockStateComponent.DEFAULT); + if (blockStateProperties.isEmpty()) { + return state; } - if (blockState != state) { - this.world.setBlockState(this.blockPos, blockState, Block.NOTIFY_LISTENERS); + BlockState modifiedState = blockStateProperties.applyToState(state); + if (modifiedState != state) { + this.world.setBlockState(this.blockPos, modifiedState, Block.NOTIFY_LISTENERS); } - return blockState; + return modifiedState; } } diff --git a/src/main/java/net/errorcraft/itematic/item/placement/EntityPlacer.java b/src/main/java/net/errorcraft/itematic/item/placement/EntityPlacer.java index 193031e1..b5648388 100644 --- a/src/main/java/net/errorcraft/itematic/item/placement/EntityPlacer.java +++ b/src/main/java/net/errorcraft/itematic/item/placement/EntityPlacer.java @@ -1,148 +1,145 @@ package net.errorcraft.itematic.item.placement; -import net.errorcraft.itematic.entity.initializer.EntityInitializer; -import net.errorcraft.itematic.item.ItemResult; -import net.errorcraft.itematic.item.ItemStackConsumer; +import net.errorcraft.itematic.entity.EntitySpawnCallback; import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.component.components.BucketItemComponent; -import net.errorcraft.itematic.item.component.components.EntityItemComponent; import net.errorcraft.itematic.item.event.ItemEvents; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; +import net.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.block.entity.MobSpawnerBlockEntity; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.SpawnReason; -import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemUsageContext; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.Hand; -import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.World; import net.minecraft.world.event.GameEvent; import java.util.Objects; import java.util.Optional; -import java.util.function.BiConsumer; -public class EntityPlacer extends Placer { - private final EntityInitializer initializer; - private final Direction direction; +public class EntityPlacer { + private final EntityType type; + private final ActionContext context; private final boolean mayModifyBlock; private final SpawnReason spawnReason; - private final BiConsumer spawnCallback; + private final EntitySpawnCallback spawnCallback; private final boolean allowItemData; - private final Hand hand; + private final PositionTarget position; + private final ItemStack stack; - public EntityPlacer(ItemStack stack, ItemStackConsumer resultStackConsumer, World world, BlockPos blockPos, BlockState blockState, PlayerEntity player, EntityInitializer initializer, Direction direction, boolean mayModifyBlock, SpawnReason spawnReason, BiConsumer spawnCallback, boolean allowItemData, Hand hand) { - super(stack, resultStackConsumer, world, blockPos, blockState, player); - this.initializer = initializer; - this.direction = direction; + private EntityPlacer(EntityType type, ActionContext context, boolean mayModifyBlock, SpawnReason spawnReason, EntitySpawnCallback spawnCallback, boolean allowItemData, PositionTarget position) { + this.type = type; + this.context = context; this.mayModifyBlock = mayModifyBlock; this.spawnReason = spawnReason; this.spawnCallback = spawnCallback; this.allowItemData = allowItemData; - this.hand = hand; + this.position = position; + this.stack = context.getOrDefault(LootContextParameters.TOOL, ItemStack.EMPTY); } - public static EntityPlacer spawned(ItemUsageContext context, ItemStack stack, ItemStackConsumer resultStackConsumer, EntityItemComponent entityItemComponent) { - World world = context.getWorld(); - BlockPos blockPos = context.getBlockPos(); - return new EntityPlacer(context.getStack(), resultStackConsumer, world, blockPos, world.getBlockState(blockPos), context.getPlayer(), entityItemComponent.getEntityInitializer(stack), context.getSide(), true, SpawnReason.SPAWN_ITEM_USE, null, entityItemComponent.allowItemData(), context.getHand()); + public static EntityPlacer of(EntityType type, ActionContext context, boolean mayModifyBlock, SpawnReason spawnReason, EntitySpawnCallback spawnCallback, boolean allowItemData, PositionTarget position) { + return new EntityPlacer<>(type, context, mayModifyBlock, spawnReason, spawnCallback, allowItemData, position); } - public static EntityPlacer action(ActionContext context, ActionContextParameter position, EntityItemComponent entityItemComponent) { - ItemStack stack = context.stack(); - BlockPos pos = context.blockPos(position); - return new EntityPlacer(stack, context.resultStackConsumer(), context.world(), pos, context.world().getBlockState(pos), context.player(ActionContextParameter.THIS).orElse(null), entityItemComponent.getEntityInitializer(stack), context.side(), false, SpawnReason.COMMAND, null, entityItemComponent.allowItemData(), context.hand()); - } - - public static EntityPlacer action(ActionContext context, ActionContextParameter position, EntityInitializer entityInitializer) { - ItemStack stack = context.stack(); - BlockPos pos = context.blockPos(position); - return new EntityPlacer(stack, context.resultStackConsumer(), context.world(), pos, context.world().getBlockState(pos), context.player(ActionContextParameter.THIS).orElse(null), entityInitializer, context.side(), false, SpawnReason.COMMAND, null, false, context.hand()); - } - - public static EntityPlacer bucket(ItemStack stack, ItemStackConsumer resultStackConsumer, World world, BlockHitResult result, PlayerEntity player, EntityInitializer initializer, Hand hand) { - BlockPos blockPos = result.getBlockPos(); - return new EntityPlacer(stack, resultStackConsumer, world, blockPos, world.getBlockState(blockPos), player, initializer, result.getSide(), false, SpawnReason.BUCKET, BucketItemComponent::initializeBucketEntity, true, hand); - } + public T place() { + BlockPos pos = this.context.getBlockPos(this.position.parameter()); + if (pos == null) { + return null; + } - @Override - public ItemResult place() { - if (!this.mayModifyBlock || !this.tryModifySpawnerBlock()) { - this.placeEntity(); + BlockState state = this.context.world().getBlockState(pos); + if (this.mayModifyBlock && this.modifySpawnerBlock(pos, state)) { + return null; } - return ItemResult.CONSUME; + + return this.spawn(pos, state); } - private boolean tryModifySpawnerBlock() { + private boolean modifySpawnerBlock(BlockPos pos, BlockState state) { if (!this.stack.itematic$hasBehavior(ItemComponentTypes.SPAWN_EGG)) { return false; } - if (!this.blockState.isOf(Blocks.SPAWNER)) { + + ServerWorld world = this.context.world(); + if (!state.isOf(Blocks.SPAWNER)) { return false; } - Optional optionalBlockEntity = this.world.getBlockEntity(this.blockPos, BlockEntityType.MOB_SPAWNER); - if (optionalBlockEntity.isEmpty()) { + + Optional blockEntity = world.getBlockEntity(pos, BlockEntityType.MOB_SPAWNER); + if (blockEntity.isEmpty()) { return false; } - this.modifySpawnerBlock(optionalBlockEntity.get()); - this.tryDecrementStack(); + + this.modifySpawnerBlock(world, blockEntity.get(), pos, state); + this.decrementStack(); return true; } - private void modifySpawnerBlock(MobSpawnerBlockEntity blockEntity) { - blockEntity.setEntityType(this.initializer.type(), this.world.getRandom()); + private void modifySpawnerBlock(ServerWorld world, MobSpawnerBlockEntity blockEntity, BlockPos pos, BlockState state) { + blockEntity.setEntityType(this.type, world.getRandom()); blockEntity.markDirty(); - this.world.updateListeners(this.blockPos, this.blockState, this.blockState, Block.NOTIFY_ALL); - this.world.emitGameEvent(this.player, GameEvent.BLOCK_CHANGE, this.blockPos); + world.updateListeners(pos, state, state, Block.NOTIFY_ALL); + world.emitGameEvent( + this.context.get(LootContextParameters.THIS_ENTITY), + GameEvent.BLOCK_CHANGE, + pos + ); } - private void placeEntity() { - if (!(this.world instanceof ServerWorld serverWorld)) { - return; - } - BlockPos offset = this.blockState.getCollisionShape(this.world, this.blockPos).isEmpty() ? this.blockPos : this.blockPos.offset(this.direction); - ActionContext context = ActionContext.builder(serverWorld, this.stack, this.resultStackConsumer, this.hand) - .entityPosition(ActionContextParameter.THIS, this.player) - .position(ActionContextParameter.TARGET, offset) - .side(this.direction) - .build(); - Entity entity = this.createEntity(offset, context); + private T spawn(BlockPos pos, BlockState state) { + ServerWorld world = this.context.world(); + Direction side = this.context.get(ItematicContextParameters.SIDE); + BlockPos offset = state.getCollisionShape(world, pos).isEmpty() || side == null + ? pos + : pos.offset(side); + T entity = this.spawn(offset, !Objects.equals(pos, offset) && side == Direction.UP); if (entity == null) { - return; - } - if (this.spawnCallback != null) { - this.spawnCallback.accept(entity, this.stack); + return null; } - this.tryDecrementStack(); - this.world.emitGameEvent(this.player, GameEvent.ENTITY_PLACE, entity.getBlockPos()); - this.stack.itematic$invokeEvent(ItemEvents.SPAWN_ENTITY, context.builderForCopy().entity(ActionContextParameter.TARGET, entity).build()); + + this.decrementStack(); + world.emitGameEvent( + this.context.get(LootContextParameters.THIS_ENTITY), + GameEvent.ENTITY_PLACE, + entity.getBlockPos() + ); + ActionContext extendedContext = this.context.extend() + .add(ItematicContextParameters.TARGET_ENTITY, entity) + .build(); + this.stack.itematic$invokeEvent(ItemEvents.SPAWN_ENTITY, extendedContext); + return entity; } - private Entity createEntity(BlockPos offset, ActionContext context) { - if (this.world.isClient()) { + private T spawn(BlockPos pos, boolean invertY) { + T entity = this.type.itematic$create( + this.context, + this.spawnReason, + pos, + this.spawnCallback, + this.allowItemData, + invertY + ); + if (entity == null) { return null; } - if (this.allowItemData) { - this.initializer.type().itematic$setInitializer(this.initializer, context); - Entity entity = this.initializer.type().spawnFromItemStack((ServerWorld) this.world, this.stack, this.player, offset, this.spawnReason, true, !Objects.equals(this.blockPos, offset) && this.direction == Direction.UP); - this.initializer.type().itematic$setInitializer(null, null); - return entity; - } - Entity entity = this.initializer.create(context, this.spawnReason); - if (entity != null) { - entity.refreshPositionAfterTeleport(Vec3d.ofBottomCenter(offset)); - ((ServerWorld) this.world).spawnEntityAndPassengers(entity); - } + + this.context.world().spawnEntityAndPassengers(entity); return entity; } + + private void decrementStack() { + this.stack.decrementUnlessCreative( + 1, + this.context.get(LootContextParameters.THIS_ENTITY, LivingEntity.class) + ); + } } diff --git a/src/main/java/net/errorcraft/itematic/item/placement/FluidPlacer.java b/src/main/java/net/errorcraft/itematic/item/placement/FluidPlacer.java index bcca8b7c..1f8d381b 100644 --- a/src/main/java/net/errorcraft/itematic/item/placement/FluidPlacer.java +++ b/src/main/java/net/errorcraft/itematic/item/placement/FluidPlacer.java @@ -2,7 +2,7 @@ import net.errorcraft.itematic.fluid.FluidKeys; import net.errorcraft.itematic.item.ItemResult; -import net.errorcraft.itematic.item.ItemStackConsumer; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; import net.minecraft.advancement.criterion.Criteria; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -32,23 +32,23 @@ public class FluidPlacer extends Placer { private final Direction direction; private final boolean allowOffset; - protected FluidPlacer(ItemStack stack, ItemStackConsumer resultStackConsumer, World world, BlockPos blockPos, BlockState blockState, PlayerEntity player, RegistryEntry fluid, RegistryEntry emptyingSound, Direction direction, boolean allowOffset) { - super(stack, resultStackConsumer, world, blockPos, blockState, player); + private FluidPlacer(ItemStack stack, ItemStackExchanger stackExchanger, World world, BlockPos blockPos, BlockState blockState, PlayerEntity player, RegistryEntry fluid, RegistryEntry emptyingSound, Direction direction, boolean allowOffset) { + super(stack, stackExchanger, world, blockPos, blockState, player); this.fluid = fluid; this.emptyingSound = emptyingSound; this.direction = direction; this.allowOffset = allowOffset; } - public static FluidPlacer of(ItemStack stack, ItemStackConsumer resultStackConsumer, World world, BlockHitResult hitResult, PlayerEntity player, RegistryEntry fluid, RegistryEntry emptyingSound) { + public static FluidPlacer of(ItemStack stack, ItemStackExchanger stackExchanger, World world, BlockHitResult hitResult, PlayerEntity player, RegistryEntry fluid, RegistryEntry emptyingSound) { BlockPos blockPos = hitResult.getBlockPos(); - return new FluidPlacer(stack, resultStackConsumer, world, blockPos, world.getBlockState(blockPos), player, fluid, emptyingSound, hitResult.getSide(), !hitResult.isInsideBlock()); + return new FluidPlacer(stack, stackExchanger, world, blockPos, world.getBlockState(blockPos), player, fluid, emptyingSound, hitResult.getSide(), !hitResult.isInsideBlock()); } @Override public ItemResult place() { BlockPos offset = this.blockPos.offset(this.direction); - if (this.player != null && (!this.world.canPlayerModifyAt(this.player, this.blockPos) || !this.player.canPlaceOn(offset, this.direction, this.stack))) { + if (this.player != null && (!this.world.canEntityModifyAt(this.player, this.blockPos) || !this.player.canPlaceOn(offset, this.direction, this.stack))) { return ItemResult.PASS; } @@ -88,7 +88,7 @@ private ItemResult tryDrainFluid() { this.applyPlayerEffects(fluidDrainable, drainedItemStack); this.world.emitGameEvent(this.player, GameEvent.FLUID_PICKUP, this.blockPos); - this.resultStackConsumer.set(drainedItemStack); + this.stackExchanger.exchange(drainedItemStack); return ItemResult.SUCCEED; } @@ -148,7 +148,15 @@ private boolean tryEvaporate(BlockPos pos) { this.world.playSound(this.player, pos, SoundEvents.BLOCK_FIRE_EXTINGUISH, SoundCategory.BLOCKS, 0.5f, 2.6f + (this.world.random.nextFloat() - this.world.random.nextFloat()) * 0.8f); for (int i = 0; i < 8; i++) { - this.world.addParticle(ParticleTypes.LARGE_SMOKE, pos.getX() + Math.random(), pos.getY() + Math.random(), pos.getZ() + Math.random(), 0.0d, 0.0d, 0.0d); + this.world.addParticleClient( + ParticleTypes.LARGE_SMOKE, + pos.getX() + Math.random(), + pos.getY() + Math.random(), + pos.getZ() + Math.random(), + 0.0d, + 0.0d, + 0.0d + ); } return true; diff --git a/src/main/java/net/errorcraft/itematic/item/placement/Placer.java b/src/main/java/net/errorcraft/itematic/item/placement/Placer.java index cee323af..8ab192c6 100644 --- a/src/main/java/net/errorcraft/itematic/item/placement/Placer.java +++ b/src/main/java/net/errorcraft/itematic/item/placement/Placer.java @@ -1,7 +1,7 @@ package net.errorcraft.itematic.item.placement; import net.errorcraft.itematic.item.ItemResult; -import net.errorcraft.itematic.item.ItemStackConsumer; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; @@ -11,16 +11,16 @@ public abstract class Placer { protected final ItemStack stack; - protected final ItemStackConsumer resultStackConsumer; + protected final ItemStackExchanger stackExchanger; protected final World world; protected final BlockPos blockPos; protected final BlockState blockState; @Nullable protected final PlayerEntity player; - protected Placer(ItemStack stack, ItemStackConsumer resultStackConsumer, World world, BlockPos blockPos, BlockState blockState, @Nullable PlayerEntity player) { + protected Placer(ItemStack stack, ItemStackExchanger stackExchanger, World world, BlockPos blockPos, BlockState blockState, @Nullable PlayerEntity player) { this.stack = stack; - this.resultStackConsumer = resultStackConsumer; + this.stackExchanger = stackExchanger; this.world = world; this.blockPos = blockPos; this.blockState = blockState; diff --git a/src/main/java/net/errorcraft/itematic/item/pointer/Pointer.java b/src/main/java/net/errorcraft/itematic/item/pointer/Pointer.java deleted file mode 100644 index f672fee7..00000000 --- a/src/main/java/net/errorcraft/itematic/item/pointer/Pointer.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.errorcraft.itematic.item.pointer; - -import com.mojang.serialization.Codec; -import net.errorcraft.itematic.registry.ItematicRegistryKeys; -import net.minecraft.entity.Entity; -import net.minecraft.item.ItemStack; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.registry.entry.RegistryFixedCodec; -import net.minecraft.util.math.GlobalPos; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public interface Pointer { - Codec> ENTRY_CODEC = RegistryFixedCodec.of(ItematicRegistryKeys.POINTER); - - @Nullable - GlobalPos createPos(ItemStack stack, World world, Entity target); -} diff --git a/src/main/java/net/errorcraft/itematic/item/pointer/PointerKeys.java b/src/main/java/net/errorcraft/itematic/item/pointer/PointerKeys.java deleted file mode 100644 index 5328a84a..00000000 --- a/src/main/java/net/errorcraft/itematic/item/pointer/PointerKeys.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.errorcraft.itematic.item.pointer; - -import net.errorcraft.itematic.registry.ItematicRegistryKeys; -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.Identifier; - -public class PointerKeys { - public static final RegistryKey SPAWN_LOCATION = of("spawn_location"); - public static final RegistryKey LAST_DEATH = of("last_death"); - - private PointerKeys() {} - - private static RegistryKey of(String id) { - return RegistryKey.of(ItematicRegistryKeys.POINTER, Identifier.ofVanilla(id)); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/pointer/Pointers.java b/src/main/java/net/errorcraft/itematic/item/pointer/Pointers.java deleted file mode 100644 index 29d87098..00000000 --- a/src/main/java/net/errorcraft/itematic/item/pointer/Pointers.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.errorcraft.itematic.item.pointer; - -import net.errorcraft.itematic.item.pointer.pointers.LastDeathPointer; -import net.errorcraft.itematic.item.pointer.pointers.SpawnLocationPointer; -import net.errorcraft.itematic.registry.ItematicRegistries; -import net.minecraft.registry.Registry; -import net.minecraft.registry.RegistryKey; - -public class Pointers { - public static final Pointer SPAWN_LOCATION = register(PointerKeys.SPAWN_LOCATION, new SpawnLocationPointer()); - public static final Pointer LAST_DEATH = register(PointerKeys.LAST_DEATH, new LastDeathPointer()); - - public static void init() {} - - private static Pointer register(RegistryKey id, Pointer pointer) { - return Registry.register(ItematicRegistries.POINTER, id, pointer); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/pointer/pointers/LastDeathPointer.java b/src/main/java/net/errorcraft/itematic/item/pointer/pointers/LastDeathPointer.java deleted file mode 100644 index 5a55aef8..00000000 --- a/src/main/java/net/errorcraft/itematic/item/pointer/pointers/LastDeathPointer.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.errorcraft.itematic.item.pointer.pointers; - -import net.errorcraft.itematic.item.pointer.Pointer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.GlobalPos; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class LastDeathPointer implements Pointer { - @Override - public @Nullable GlobalPos createPos(ItemStack stack, World world, Entity target) { - if (target instanceof PlayerEntity player) { - return player.getLastDeathPos().orElse(null); - } - return null; - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/pointer/pointers/SpawnLocationPointer.java b/src/main/java/net/errorcraft/itematic/item/pointer/pointers/SpawnLocationPointer.java deleted file mode 100644 index ee307ba4..00000000 --- a/src/main/java/net/errorcraft/itematic/item/pointer/pointers/SpawnLocationPointer.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.errorcraft.itematic.item.pointer.pointers; - -import net.errorcraft.itematic.item.pointer.Pointer; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.LodestoneTrackerComponent; -import net.minecraft.entity.Entity; -import net.minecraft.item.CompassItem; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.GlobalPos; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; - -public class SpawnLocationPointer implements Pointer { - @Override - public @Nullable GlobalPos createPos(ItemStack stack, World world, Entity target) { - LodestoneTrackerComponent lodestoneTracker = stack.get(DataComponentTypes.LODESTONE_TRACKER); - if (lodestoneTracker != null) { - return lodestoneTracker.target().orElse(null); - } - return CompassItem.createSpawnPos(world); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/smithing/template/SmithingTemplate.java b/src/main/java/net/errorcraft/itematic/item/smithing/template/SmithingTemplate.java index bc87e381..7f2dc6b6 100644 --- a/src/main/java/net/errorcraft/itematic/item/smithing/template/SmithingTemplate.java +++ b/src/main/java/net/errorcraft/itematic/item/smithing/template/SmithingTemplate.java @@ -2,19 +2,14 @@ import com.mojang.serialization.Codec; import net.errorcraft.itematic.registry.ItematicRegistries; -import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import java.util.List; public interface SmithingTemplate { - Codec CODEC = ItematicRegistries.SMITHING_TEMPLATE_TYPE.getCodec().dispatch(SmithingTemplate::type, SmithingTemplateType::codec); + Codec CODEC = ItematicRegistries.SMITHING_TEMPLATE.getCodec(); - SmithingTemplateType type(); - MutableText titleText(); - MutableText appliesToText(); - MutableText ingredientsText(); List emptyBaseSlotTextures(); List emptyAdditionsSlotTextures(); Text baseSlotDescription(); diff --git a/src/main/java/net/errorcraft/itematic/item/smithing/template/SmithingTemplateType.java b/src/main/java/net/errorcraft/itematic/item/smithing/template/SmithingTemplateType.java deleted file mode 100644 index 98f00973..00000000 --- a/src/main/java/net/errorcraft/itematic/item/smithing/template/SmithingTemplateType.java +++ /dev/null @@ -1,6 +0,0 @@ -package net.errorcraft.itematic.item.smithing.template; - -import com.mojang.serialization.MapCodec; - -public record SmithingTemplateType(MapCodec codec) { -} diff --git a/src/main/java/net/errorcraft/itematic/item/smithing/template/SmithingTemplateTypeKeys.java b/src/main/java/net/errorcraft/itematic/item/smithing/template/SmithingTemplateTypeKeys.java deleted file mode 100644 index a5c57717..00000000 --- a/src/main/java/net/errorcraft/itematic/item/smithing/template/SmithingTemplateTypeKeys.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.errorcraft.itematic.item.smithing.template; - -import net.errorcraft.itematic.registry.ItematicRegistryKeys; -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.Identifier; - -public class SmithingTemplateTypeKeys { - public static final RegistryKey> TRIM_PATTERN = of("trim_pattern"); - public static final RegistryKey> ITEM_UPGRADE = of("item_upgrade"); - - private SmithingTemplateTypeKeys() {} - - private static RegistryKey> of(String id) { - return RegistryKey.of(ItematicRegistryKeys.SMITHING_TEMPLATE_TYPE, Identifier.ofVanilla(id)); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/smithing/template/SmithingTemplateTypes.java b/src/main/java/net/errorcraft/itematic/item/smithing/template/SmithingTemplateTypes.java deleted file mode 100644 index ce857861..00000000 --- a/src/main/java/net/errorcraft/itematic/item/smithing/template/SmithingTemplateTypes.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.errorcraft.itematic.item.smithing.template; - -import net.errorcraft.itematic.item.smithing.template.templates.ItemUpgradeSmithingTemplate; -import net.errorcraft.itematic.item.smithing.template.templates.TrimPatternSmithingTemplate; -import net.errorcraft.itematic.registry.ItematicRegistries; -import net.minecraft.registry.Registry; -import net.minecraft.registry.RegistryKey; - -public class SmithingTemplateTypes { - public static final SmithingTemplateType TRIM_PATTERN = register(SmithingTemplateTypeKeys.TRIM_PATTERN, new SmithingTemplateType<>(TrimPatternSmithingTemplate.CODEC)); - public static final SmithingTemplateType ITEM_UPGRADE = register(SmithingTemplateTypeKeys.ITEM_UPGRADE, new SmithingTemplateType<>(ItemUpgradeSmithingTemplate.CODEC)); - - private SmithingTemplateTypes() {} - - public static void init() {} - - private static SmithingTemplateType register(RegistryKey> id, SmithingTemplateType type) { - return Registry.register(ItematicRegistries.SMITHING_TEMPLATE_TYPE, id, type); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/smithing/template/SmithingTemplates.java b/src/main/java/net/errorcraft/itematic/item/smithing/template/SmithingTemplates.java index f73dac69..c9e14fdf 100644 --- a/src/main/java/net/errorcraft/itematic/item/smithing/template/SmithingTemplates.java +++ b/src/main/java/net/errorcraft/itematic/item/smithing/template/SmithingTemplates.java @@ -1,67 +1,19 @@ package net.errorcraft.itematic.item.smithing.template; -import net.errorcraft.itematic.item.ItemKeys; import net.errorcraft.itematic.item.smithing.template.templates.ItemUpgradeSmithingTemplate; import net.errorcraft.itematic.item.smithing.template.templates.TrimPatternSmithingTemplate; -import net.errorcraft.itematic.registry.ItematicRegistryKeys; -import net.minecraft.item.Item; -import net.minecraft.item.equipment.trim.ArmorTrimPattern; -import net.minecraft.item.equipment.trim.ArmorTrimPatterns; -import net.minecraft.registry.Registerable; -import net.minecraft.registry.RegistryEntryLookup; -import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.util.Identifier; +import net.errorcraft.itematic.registry.ItematicRegistries; +import net.minecraft.registry.Registry; public class SmithingTemplates { - public static final RegistryKey NETHERITE_UPGRADE = of("netherite_upgrade"); - public static final RegistryKey BOLT_PATTERN = of("bolt_pattern"); - public static final RegistryKey COAST_PATTERN = of("coast_pattern"); - public static final RegistryKey DUNE_PATTERN = of("dune_pattern"); - public static final RegistryKey EYE_PATTERN = of("eye_pattern"); - public static final RegistryKey FLOW_PATTERN = of("flow_pattern"); - public static final RegistryKey HOST_PATTERN = of("host_pattern"); - public static final RegistryKey RAISER_PATTERN = of("raiser_pattern"); - public static final RegistryKey RIB_PATTERN = of("rib_pattern"); - public static final RegistryKey SENTRY_PATTERN = of("sentry_pattern"); - public static final RegistryKey SHAPER_PATTERN = of("shaper_pattern"); - public static final RegistryKey SILENCE_PATTERN = of("silence_pattern"); - public static final RegistryKey SNOUT_PATTERN = of("snout_pattern"); - public static final RegistryKey SPIRE_PATTERN = of("spire_pattern"); - public static final RegistryKey TIDE_PATTERN = of("tide_pattern"); - public static final RegistryKey VEX_PATTERN = of("vex_pattern"); - public static final RegistryKey WARD_PATTERN = of("ward_pattern"); - public static final RegistryKey WAYFINDER_PATTERN = of("wayfinder_pattern"); - public static final RegistryKey WILD_PATTERN = of("wild_pattern"); + public static final SmithingTemplate TRIM_PATTERN = register("trim_pattern", new TrimPatternSmithingTemplate()); + public static final SmithingTemplate ITEM_UPGRADE = register("item_upgrade", new ItemUpgradeSmithingTemplate()); private SmithingTemplates() {} - public static void bootstrap(Registerable registerable) { - RegistryEntryLookup items = registerable.getRegistryLookup(RegistryKeys.ITEM); - RegistryEntryLookup trimPatterns = registerable.getRegistryLookup(RegistryKeys.TRIM_PATTERN); + public static void init() {} - registerable.register(NETHERITE_UPGRADE, new ItemUpgradeSmithingTemplate(items.getOrThrow(ItemKeys.NETHERITE_INGOT), Identifier.ofVanilla("netherite_upgrade"))); - registerable.register(BOLT_PATTERN, new TrimPatternSmithingTemplate(trimPatterns.getOrThrow(ArmorTrimPatterns.BOLT))); - registerable.register(COAST_PATTERN, new TrimPatternSmithingTemplate(trimPatterns.getOrThrow(ArmorTrimPatterns.COAST))); - registerable.register(DUNE_PATTERN, new TrimPatternSmithingTemplate(trimPatterns.getOrThrow(ArmorTrimPatterns.DUNE))); - registerable.register(EYE_PATTERN, new TrimPatternSmithingTemplate(trimPatterns.getOrThrow(ArmorTrimPatterns.EYE))); - registerable.register(FLOW_PATTERN, new TrimPatternSmithingTemplate(trimPatterns.getOrThrow(ArmorTrimPatterns.FLOW))); - registerable.register(HOST_PATTERN, new TrimPatternSmithingTemplate(trimPatterns.getOrThrow(ArmorTrimPatterns.HOST))); - registerable.register(RAISER_PATTERN, new TrimPatternSmithingTemplate(trimPatterns.getOrThrow(ArmorTrimPatterns.RAISER))); - registerable.register(RIB_PATTERN, new TrimPatternSmithingTemplate(trimPatterns.getOrThrow(ArmorTrimPatterns.RIB))); - registerable.register(SENTRY_PATTERN, new TrimPatternSmithingTemplate(trimPatterns.getOrThrow(ArmorTrimPatterns.SENTRY))); - registerable.register(SHAPER_PATTERN, new TrimPatternSmithingTemplate(trimPatterns.getOrThrow(ArmorTrimPatterns.SHAPER))); - registerable.register(SILENCE_PATTERN, new TrimPatternSmithingTemplate(trimPatterns.getOrThrow(ArmorTrimPatterns.SILENCE))); - registerable.register(SNOUT_PATTERN, new TrimPatternSmithingTemplate(trimPatterns.getOrThrow(ArmorTrimPatterns.SNOUT))); - registerable.register(SPIRE_PATTERN, new TrimPatternSmithingTemplate(trimPatterns.getOrThrow(ArmorTrimPatterns.SPIRE))); - registerable.register(TIDE_PATTERN, new TrimPatternSmithingTemplate(trimPatterns.getOrThrow(ArmorTrimPatterns.TIDE))); - registerable.register(VEX_PATTERN, new TrimPatternSmithingTemplate(trimPatterns.getOrThrow(ArmorTrimPatterns.VEX))); - registerable.register(WARD_PATTERN, new TrimPatternSmithingTemplate(trimPatterns.getOrThrow(ArmorTrimPatterns.WARD))); - registerable.register(WAYFINDER_PATTERN, new TrimPatternSmithingTemplate(trimPatterns.getOrThrow(ArmorTrimPatterns.WAYFINDER))); - registerable.register(WILD_PATTERN, new TrimPatternSmithingTemplate(trimPatterns.getOrThrow(ArmorTrimPatterns.WILD))); - } - - private static RegistryKey of(String id) { - return RegistryKey.of(ItematicRegistryKeys.SMITHING_TEMPLATE, Identifier.ofVanilla(id)); + private static SmithingTemplate register(String id, SmithingTemplate type) { + return Registry.register(ItematicRegistries.SMITHING_TEMPLATE, id, type); } } diff --git a/src/main/java/net/errorcraft/itematic/item/smithing/template/templates/ItemUpgradeSmithingTemplate.java b/src/main/java/net/errorcraft/itematic/item/smithing/template/templates/ItemUpgradeSmithingTemplate.java index 4201a67d..11c26a89 100644 --- a/src/main/java/net/errorcraft/itematic/item/smithing/template/templates/ItemUpgradeSmithingTemplate.java +++ b/src/main/java/net/errorcraft/itematic/item/smithing/template/templates/ItemUpgradeSmithingTemplate.java @@ -1,51 +1,17 @@ package net.errorcraft.itematic.item.smithing.template.templates; -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.item.smithing.template.SmithingTemplate; -import net.errorcraft.itematic.item.smithing.template.SmithingTemplateType; -import net.errorcraft.itematic.item.smithing.template.SmithingTemplateTypes; import net.errorcraft.itematic.mixin.item.SmithingTemplateItemAccessor; -import net.minecraft.item.Item; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.registry.entry.RegistryFixedCodec; -import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Identifier; -import net.minecraft.util.Util; import java.util.List; -public record ItemUpgradeSmithingTemplate(RegistryEntry item, Identifier translationKeyId) implements SmithingTemplate { - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - RegistryFixedCodec.of(RegistryKeys.ITEM).fieldOf("item").forGetter(ItemUpgradeSmithingTemplate::item), - Identifier.CODEC.fieldOf("translation_key_id").forGetter(ItemUpgradeSmithingTemplate::translationKeyId) - ).apply(instance, ItemUpgradeSmithingTemplate::new)); - private static final List EMPTY_BASE_SLOT_TEXTURES = SmithingTemplateItemAccessor.getItemUpgradeEmptyBaseSlotTextures(); - private static final List EMPTY_ADDITIONS_SLOT_TEXTURES = SmithingTemplateItemAccessor.getItemUpgradeEmptyAdditionsSlotTextures(); - private static final Text BASE_SLOT_DESCRIPTION = SmithingTemplateItemAccessor.getItemUpgradeBaseSlotDescriptionText(); - private static final Text ADDITIONS_SLOT_DESCRIPTION = SmithingTemplateItemAccessor.getItemUpgradeAdditionsSlotDescriptionText(); - - @Override - public SmithingTemplateType type() { - return SmithingTemplateTypes.ITEM_UPGRADE; - } - - @Override - public MutableText titleText() { - return Text.translatable(Util.createTranslationKey("upgrade", this.translationKeyId)); - } - - @Override - public MutableText appliesToText() { - return Text.translatable(this.createTranslationKey("applies_to")); - } - - @Override - public MutableText ingredientsText() { - return Text.translatable(this.createTranslationKey("ingredients")); - } +public class ItemUpgradeSmithingTemplate implements SmithingTemplate { + private static final List EMPTY_BASE_SLOT_TEXTURES = SmithingTemplateItemAccessor.itemUpgradeEmptyBaseSlotTextures(); + private static final List EMPTY_ADDITIONS_SLOT_TEXTURES = SmithingTemplateItemAccessor.itemUpgradeEmptyAdditionsSlotTextures(); + private static final Text BASE_SLOT_DESCRIPTION = SmithingTemplateItemAccessor.itemUpgradeBaseSlotDescription(); + private static final Text ADDITIONS_SLOT_DESCRIPTION = SmithingTemplateItemAccessor.itemUpgradeAdditionsSlotDescription(); @Override public List emptyBaseSlotTextures() { @@ -66,8 +32,4 @@ public Text baseSlotDescription() { public Text additionsSlotDescription() { return ADDITIONS_SLOT_DESCRIPTION; } - - private String createTranslationKey(String type) { - return Util.createTranslationKey("item", this.translationKeyId.withPath(id -> "smithing_template." + id + "." + type)); - } } diff --git a/src/main/java/net/errorcraft/itematic/item/smithing/template/templates/TrimPatternSmithingTemplate.java b/src/main/java/net/errorcraft/itematic/item/smithing/template/templates/TrimPatternSmithingTemplate.java index 80e1fad0..1d391e4e 100644 --- a/src/main/java/net/errorcraft/itematic/item/smithing/template/templates/TrimPatternSmithingTemplate.java +++ b/src/main/java/net/errorcraft/itematic/item/smithing/template/templates/TrimPatternSmithingTemplate.java @@ -1,54 +1,17 @@ package net.errorcraft.itematic.item.smithing.template.templates; -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.item.smithing.template.SmithingTemplate; -import net.errorcraft.itematic.item.smithing.template.SmithingTemplateType; -import net.errorcraft.itematic.item.smithing.template.SmithingTemplateTypes; import net.errorcraft.itematic.mixin.item.SmithingTemplateItemAccessor; -import net.minecraft.item.equipment.trim.ArmorTrimPattern; -import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.registry.entry.RegistryFixedCodec; -import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Identifier; -import net.minecraft.util.Util; import java.util.List; -public record TrimPatternSmithingTemplate(RegistryEntry trimPattern) implements SmithingTemplate { - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - RegistryFixedCodec.of(RegistryKeys.TRIM_PATTERN).fieldOf("trim_pattern").forGetter(TrimPatternSmithingTemplate::trimPattern) - ).apply(instance, TrimPatternSmithingTemplate::new)); - private static final MutableText APPLIES_TO_TEXT = (MutableText) SmithingTemplateItemAccessor.getTrimPatternAppliesToText(); - private static final MutableText INGREDIENTS_TEXT = (MutableText) SmithingTemplateItemAccessor.getTrimPatternIngredientsText(); - private static final List EMPTY_BASE_SLOT_TEXTURES = SmithingTemplateItemAccessor.getTrimPatternEmptyBaseSlotTextures(); - private static final List EMPTY_ADDITIONS_SLOT_TEXTURES = SmithingTemplateItemAccessor.getTrimPatternEmptyAdditionsSlotTextures(); - private static final Text BASE_SLOT_DESCRIPTION = SmithingTemplateItemAccessor.getTrimPatternBaseSlotDescriptionText(); - private static final Text ADDITIONS_SLOT_DESCRIPTION = SmithingTemplateItemAccessor.getTrimPatternAdditionsSlotDescriptionText(); - - @Override - public SmithingTemplateType type() { - return SmithingTemplateTypes.TRIM_PATTERN; - } - - @Override - public MutableText titleText() { - Identifier id = this.trimPattern.getKey().map(RegistryKey::getValue).orElse(null); - return Text.translatable(Util.createTranslationKey("trim_pattern", id)); - } - - @Override - public MutableText appliesToText() { - return APPLIES_TO_TEXT; - } - - @Override - public MutableText ingredientsText() { - return INGREDIENTS_TEXT; - } +public class TrimPatternSmithingTemplate implements SmithingTemplate { + private static final List EMPTY_BASE_SLOT_TEXTURES = SmithingTemplateItemAccessor.trimPatternEmptyBaseSlotTextures(); + private static final List EMPTY_ADDITIONS_SLOT_TEXTURES = SmithingTemplateItemAccessor.trimPatternEmptyAdditionsSlotTextures(); + private static final Text BASE_SLOT_DESCRIPTION = SmithingTemplateItemAccessor.trimPatternBaseSlotDescription(); + private static final Text ADDITIONS_SLOT_DESCRIPTION = SmithingTemplateItemAccessor.trimPatternAdditionsSlotDescription(); @Override public List emptyBaseSlotTextures() { diff --git a/src/main/java/net/errorcraft/itematic/loot/condition/LocationCheckLootConditionExtraFields.java b/src/main/java/net/errorcraft/itematic/loot/condition/LocationCheckLootConditionExtraFields.java new file mode 100644 index 00000000..97e3af85 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/loot/condition/LocationCheckLootConditionExtraFields.java @@ -0,0 +1,12 @@ +package net.errorcraft.itematic.loot.condition; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.errorcraft.itematic.world.action.context.PositionTarget; + +public record LocationCheckLootConditionExtraFields(PositionTarget position) { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + PositionTarget.CODEC.optionalFieldOf("position", PositionTarget.ORIGIN).forGetter(LocationCheckLootConditionExtraFields::position) + ).apply(instance, LocationCheckLootConditionExtraFields::new)); + public static final LocationCheckLootConditionExtraFields DEFAULT = new LocationCheckLootConditionExtraFields(PositionTarget.ORIGIN); +} diff --git a/src/main/java/net/errorcraft/itematic/loot/condition/LocationCheckLootConditionUtil.java b/src/main/java/net/errorcraft/itematic/loot/condition/LocationCheckLootConditionUtil.java new file mode 100644 index 00000000..5a354162 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/loot/condition/LocationCheckLootConditionUtil.java @@ -0,0 +1,29 @@ +package net.errorcraft.itematic.loot.condition; + +import net.errorcraft.itematic.world.action.context.PositionTarget; +import net.minecraft.loot.condition.LocationCheckLootCondition; +import net.minecraft.loot.condition.LootCondition; +import net.minecraft.predicate.entity.LocationPredicate; +import net.minecraft.util.math.BlockPos; + +import java.util.Optional; + +public class LocationCheckLootConditionUtil { + private LocationCheckLootConditionUtil() {} + + public static LootCondition.Builder builder(PositionTarget position, LocationPredicate.Builder builder) { + return () -> { + LocationCheckLootCondition predicate = new LocationCheckLootCondition(Optional.of(builder.build()), BlockPos.ORIGIN); + predicate.itematic$setExtraFields(new LocationCheckLootConditionExtraFields(position)); + return predicate; + }; + } + + public static LootCondition.Builder builder(PositionTarget position, LocationPredicate.Builder builder, BlockPos offset) { + return () -> { + LocationCheckLootCondition predicate = new LocationCheckLootCondition(Optional.of(builder.build()), offset); + predicate.itematic$setExtraFields(new LocationCheckLootConditionExtraFields(position)); + return predicate; + }; + } +} diff --git a/src/main/java/net/errorcraft/itematic/loot/function/ItematicItemModifierTypes.java b/src/main/java/net/errorcraft/itematic/loot/function/ItematicItemModifierTypes.java index 8dd42133..edfd7c0e 100644 --- a/src/main/java/net/errorcraft/itematic/loot/function/ItematicItemModifierTypes.java +++ b/src/main/java/net/errorcraft/itematic/loot/function/ItematicItemModifierTypes.java @@ -6,6 +6,8 @@ public class ItematicItemModifierTypes { public static final LootFunctionType DYE = LootFunctionTypesAccessor.register("dye", DyeItemModifier.CODEC); public static final LootFunctionType SET_RANDOM_POTION = LootFunctionTypesAccessor.register("set_random_potion", SetRandomPotionItemModifier.CODEC); + public static final LootFunctionType SPLIT = LootFunctionTypesAccessor.register("split", SplitItemModifier.CODEC); + public static final LootFunctionType SET_ITEM_POINTER_LOCATION = LootFunctionTypesAccessor.register("set_item_pointer_location", SetItemPointerLocationItemModifier.CODEC); private ItematicItemModifierTypes() {} diff --git a/src/main/java/net/errorcraft/itematic/loot/function/SetItemPointerLocationItemModifier.java b/src/main/java/net/errorcraft/itematic/loot/function/SetItemPointerLocationItemModifier.java new file mode 100644 index 00000000..6abdce41 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/loot/function/SetItemPointerLocationItemModifier.java @@ -0,0 +1,64 @@ +package net.errorcraft.itematic.loot.function; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.errorcraft.itematic.world.action.context.PositionTarget; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.LodestoneTrackerComponent; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.condition.LootCondition; +import net.minecraft.loot.context.LootContext; +import net.minecraft.loot.function.ConditionalLootFunction; +import net.minecraft.loot.function.LootFunctionType; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.GlobalPos; +import net.minecraft.util.math.Vec3d; + +import java.util.List; +import java.util.Optional; + +public class SetItemPointerLocationItemModifier extends ConditionalLootFunction { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> addConditionsField(instance).and( + PositionTarget.CODEC.fieldOf("position").forGetter(split -> split.position) + ).apply(instance, SetItemPointerLocationItemModifier::new)); + + private final PositionTarget position; + + public SetItemPointerLocationItemModifier(PositionTarget position) { + this(List.of(), position); + } + + public SetItemPointerLocationItemModifier(List conditions, PositionTarget position) { + super(conditions); + this.position = position; + } + + public static Builder builder(PositionTarget position) { + return builder(conditions -> new SetItemPointerLocationItemModifier(conditions, position)); + } + + @Override + public LootFunctionType getType() { + return ItematicItemModifierTypes.SET_ITEM_POINTER_LOCATION; + } + + @Override + protected ItemStack process(ItemStack stack, LootContext context) { + Vec3d pos = context.get(this.position.parameter()); + if (pos == null) { + return stack; + } + + stack.set( + DataComponentTypes.LODESTONE_TRACKER, + new LodestoneTrackerComponent( + Optional.of(GlobalPos.create( + context.getWorld().getRegistryKey(), + BlockPos.ofFloored(pos) + )), + true + ) + ); + return stack; + } +} diff --git a/src/main/java/net/errorcraft/itematic/loot/function/SplitItemModifier.java b/src/main/java/net/errorcraft/itematic/loot/function/SplitItemModifier.java new file mode 100644 index 00000000..690b4f43 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/loot/function/SplitItemModifier.java @@ -0,0 +1,48 @@ +package net.errorcraft.itematic.loot.function; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.condition.LootCondition; +import net.minecraft.loot.context.LootContext; +import net.minecraft.loot.context.LootContextParameters; +import net.minecraft.loot.function.ConditionalLootFunction; +import net.minecraft.loot.function.LootFunctionType; +import net.minecraft.loot.provider.number.ConstantLootNumberProvider; +import net.minecraft.loot.provider.number.LootNumberProvider; +import net.minecraft.loot.provider.number.LootNumberProviderTypes; + +import java.util.List; + +public class SplitItemModifier extends ConditionalLootFunction { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> addConditionsField(instance).and( + LootNumberProviderTypes.CODEC.fieldOf("count").forGetter(split -> split.count) + ).apply(instance, SplitItemModifier::new)); + + private final LootNumberProvider count; + + public SplitItemModifier(LootNumberProvider count) { + this(List.of(), count); + } + + public SplitItemModifier(List conditions, LootNumberProvider count) { + super(conditions); + this.count = count; + } + + public static Builder builder(int count) { + return builder(conditions -> new SplitItemModifier(conditions, ConstantLootNumberProvider.create(count))); + } + + @Override + public LootFunctionType getType() { + return ItematicItemModifierTypes.SPLIT; + } + + @Override + protected ItemStack process(ItemStack stack, LootContext context) { + LivingEntity holder = context.get(LootContextParameters.THIS_ENTITY) instanceof LivingEntity target ? target : null; + return stack.itematic$copyOrSplit(holder, this.count.nextInt(context)); + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/AbstractBannerBlockExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/AbstractBannerBlockExtender.java index 02ec0380..ee863fa4 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/block/AbstractBannerBlockExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/block/AbstractBannerBlockExtender.java @@ -25,7 +25,7 @@ protected AbstractBannerBlockExtender(Settings settings) { target = "Lnet/minecraft/block/entity/BannerBlockEntity;getPickStack()Lnet/minecraft/item/ItemStack;" ) ) - private ItemStack getPickStackUseCreateStack(BannerBlockEntity instance, WorldView world, BlockPos pos, BlockState state) { - return ((BannerBlockEntityAccess) instance).itematic$getPickStack(super.getPickStack(world, pos, state)); + private ItemStack getPickStackUseCreateStack(BannerBlockEntity instance, WorldView world, BlockPos pos, BlockState state, boolean includeData) { + return ((BannerBlockEntityAccess) instance).itematic$getPickStack(super.getPickStack(world, pos, state, includeData)); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/AbstractBlockExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/AbstractBlockExtender.java index cf59f0c1..c26753c7 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/block/AbstractBlockExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/block/AbstractBlockExtender.java @@ -1,20 +1,32 @@ package net.errorcraft.itematic.mixin.block; +import net.errorcraft.itematic.access.block.AbstractBlockAccess; import net.errorcraft.itematic.item.ItemUtil; import net.minecraft.block.AbstractBlock; import net.minecraft.block.Block; import net.minecraft.item.Item; +import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; +import net.minecraft.registry.Registries; +import net.minecraft.registry.RegistryKey; +import net.minecraft.world.WorldView; import org.spongepowered.asm.mixin.Mixin; 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.Redirect; @Mixin(AbstractBlock.class) -public abstract class AbstractBlockExtender { +public abstract class AbstractBlockExtender implements AbstractBlockAccess { + @Shadow + public abstract Item asItem(); + @Shadow protected abstract Block asBlock(); + @Unique + private RegistryKey itemKey; + @Redirect( method = "canReplace", at = @At( @@ -23,6 +35,32 @@ public abstract class AbstractBlockExtender { ) ) private boolean isOfUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemUtil.keyFromBlock(this.asBlock())); + return instance.itematic$isOf(this.itematic$asItemKey()); + } + + @Redirect( + method = "getPickStack", + at = @At( + value = "NEW", + target = "(Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/item/ItemStack;" + ) + ) + private ItemStack newItemStackUseCreateStack(ItemConvertible item, WorldView world) { + return world.itematic$createStack(this.itematic$asItemKey()); + } + + @Override + public RegistryKey itematic$asItemKey() { + if (this.itemKey == null) { + this.itemKey = Registries.ITEM.getKey(this.asItem()) + .orElseGet(() -> ItemUtil.keyFromBlock(this.asBlock())); + } + + return this.itemKey; + } + + @Override + public void itematic$setAsItemKey(RegistryKey pickBlockKey) { + this.itemKey = pickBlockKey; } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/BeehiveBlockExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/BeehiveBlockExtender.java index b464ef01..7f474865 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/block/BeehiveBlockExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/block/BeehiveBlockExtender.java @@ -1,11 +1,12 @@ package net.errorcraft.itematic.mixin.block; import com.llamalad7.mixinextras.sugar.Local; -import net.errorcraft.itematic.access.block.BlockAccess; +import net.errorcraft.itematic.access.block.AbstractBlockAccess; import net.errorcraft.itematic.item.ItemKeys; import net.minecraft.block.BeehiveBlock; import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.BeesComponent; import net.minecraft.item.Item; import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; @@ -19,7 +20,7 @@ import java.util.List; @Mixin(BeehiveBlock.class) -public class BeehiveBlockExtender implements BlockAccess { +public class BeehiveBlockExtender implements AbstractBlockAccess { @Redirect( method = "onUseWithItem", at = @At( @@ -93,6 +94,6 @@ private ItemStack newItemStackUseCreateStack(ItemConvertible item, World world) @Override public void itematic$addComponents(ComponentMap.Builder builder) { - builder.add(DataComponentTypes.BEES, List.of()); + builder.add(DataComponentTypes.BEES, new BeesComponent(List.of())); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/BlockExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/BlockExtender.java deleted file mode 100644 index d5aeee7e..00000000 --- a/src/main/java/net/errorcraft/itematic/mixin/block/BlockExtender.java +++ /dev/null @@ -1,44 +0,0 @@ -package net.errorcraft.itematic.mixin.block; - -import net.errorcraft.itematic.access.block.BlockAccess; -import net.errorcraft.itematic.item.ItemUtil; -import net.minecraft.block.Block; -import net.minecraft.item.Item; -import net.minecraft.item.ItemConvertible; -import net.minecraft.item.ItemStack; -import net.minecraft.registry.RegistryKey; -import net.minecraft.world.WorldView; -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.Redirect; - -@Mixin(Block.class) -public abstract class BlockExtender implements BlockAccess { - @Unique - private RegistryKey itemKey; - - @Redirect( - method = "getPickStack", - at = @At( - value = "NEW", - target = "(Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/item/ItemStack;" - ) - ) - private ItemStack newItemStackUseCreateStack(ItemConvertible item, WorldView world) { - return world.itematic$createStack(this.itematic$asItemKey()); - } - - @Override - public RegistryKey itematic$asItemKey() { - if (this.itemKey != null) { - return this.itemKey; - } - return ItemUtil.keyFromBlock((Block)(Object) this); - } - - @Override - public void itematic$setAsItemKey(RegistryKey pickBlockKey) { - this.itemKey = pickBlockKey; - } -} diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/BlocksExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/BlocksExtender.java index 45f2cc59..34f11b0f 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/block/BlocksExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/block/BlocksExtender.java @@ -110,6 +110,10 @@ public class BlocksExtender { @Final public static Block DARK_OAK_WALL_SIGN; + @Shadow + @Final + public static Block PALE_OAK_WALL_SIGN; + @Shadow @Final public static Block MANGROVE_WALL_SIGN; @@ -154,6 +158,10 @@ public class BlocksExtender { @Final public static Block DARK_OAK_WALL_HANGING_SIGN; + @Shadow + @Final + public static Block PALE_OAK_WALL_HANGING_SIGN; + @Shadow @Final public static Block MANGROVE_WALL_HANGING_SIGN; @@ -610,6 +618,14 @@ public class BlocksExtender { @Final public static Block BLACK_CANDLE_CAKE; + @Shadow + @Final + public static Block POTTED_OPEN_EYEBLOSSOM; + + @Shadow + @Final + public static Block POTTED_CLOSED_EYEBLOSSOM; + static { CAVE_AIR.itematic$setAsItemKey(ItemKeys.AIR); VOID_AIR.itematic$setAsItemKey(ItemKeys.AIR); @@ -636,6 +652,7 @@ public class BlocksExtender { CHERRY_WALL_SIGN.itematic$setAsItemKey(ItemKeys.CHERRY_SIGN); JUNGLE_WALL_SIGN.itematic$setAsItemKey(ItemKeys.JUNGLE_SIGN); DARK_OAK_WALL_SIGN.itematic$setAsItemKey(ItemKeys.DARK_OAK_SIGN); + PALE_OAK_WALL_SIGN.itematic$setAsItemKey(ItemKeys.PALE_OAK_SIGN); MANGROVE_WALL_SIGN.itematic$setAsItemKey(ItemKeys.MANGROVE_SIGN); CRIMSON_WALL_SIGN.itematic$setAsItemKey(ItemKeys.CRIMSON_SIGN); WARPED_WALL_SIGN.itematic$setAsItemKey(ItemKeys.WARPED_SIGN); @@ -647,6 +664,7 @@ public class BlocksExtender { CHERRY_WALL_HANGING_SIGN.itematic$setAsItemKey(ItemKeys.CHERRY_HANGING_SIGN); JUNGLE_WALL_HANGING_SIGN.itematic$setAsItemKey(ItemKeys.JUNGLE_HANGING_SIGN); DARK_OAK_WALL_HANGING_SIGN.itematic$setAsItemKey(ItemKeys.DARK_OAK_HANGING_SIGN); + PALE_OAK_WALL_HANGING_SIGN.itematic$setAsItemKey(ItemKeys.PALE_OAK_HANGING_SIGN); MANGROVE_WALL_HANGING_SIGN.itematic$setAsItemKey(ItemKeys.MANGROVE_HANGING_SIGN); CRIMSON_WALL_HANGING_SIGN.itematic$setAsItemKey(ItemKeys.CRIMSON_HANGING_SIGN); WARPED_WALL_HANGING_SIGN.itematic$setAsItemKey(ItemKeys.WARPED_HANGING_SIGN); @@ -689,6 +707,8 @@ public class BlocksExtender { POTTED_WARPED_ROOTS.itematic$setAsItemKey(ItemKeys.WARPED_ROOTS); POTTED_AZALEA_BUSH.itematic$setAsItemKey(ItemKeys.AZALEA); POTTED_FLOWERING_AZALEA_BUSH.itematic$setAsItemKey(ItemKeys.FLOWERING_AZALEA); + POTTED_OPEN_EYEBLOSSOM.itematic$setAsItemKey(ItemKeys.OPEN_EYEBLOSSOM); + POTTED_CLOSED_EYEBLOSSOM.itematic$setAsItemKey(ItemKeys.CLOSED_EYEBLOSSOM); SKELETON_WALL_SKULL.itematic$setAsItemKey(ItemKeys.SKELETON_SKULL); WITHER_SKELETON_WALL_SKULL.itematic$setAsItemKey(ItemKeys.WITHER_SKELETON_SKULL); ZOMBIE_WALL_HEAD.itematic$setAsItemKey(ItemKeys.ZOMBIE_HEAD); diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/CanReplaceBlockExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/CanReplaceBlockExtender.java index 1edd9aeb..b0c7eff2 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/block/CanReplaceBlockExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/block/CanReplaceBlockExtender.java @@ -1,6 +1,5 @@ package net.errorcraft.itematic.mixin.block; -import net.errorcraft.itematic.item.ItemUtil; import net.minecraft.block.*; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -8,7 +7,13 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin({ FlowerbedBlock.class, ScaffoldingBlock.class, SeaPickleBlock.class, SlabBlock.class, SnowBlock.class, TurtleEggBlock.class }) +@Mixin({ + ScaffoldingBlock.class, + SeaPickleBlock.class, + SlabBlock.class, + SnowBlock.class, + TurtleEggBlock.class +}) public class CanReplaceBlockExtender extends Block { public CanReplaceBlockExtender(Settings settings) { super(settings); @@ -22,6 +27,6 @@ public CanReplaceBlockExtender(Settings settings) { ) ) private boolean isOfUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemUtil.keyFromBlock(this)); + return instance.itematic$isOf(this.itematic$asItemKey()); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/DecoratedPotBlockExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/DecoratedPotBlockExtender.java index 01fa2591..5a657ee8 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/block/DecoratedPotBlockExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/block/DecoratedPotBlockExtender.java @@ -1,8 +1,9 @@ package net.errorcraft.itematic.mixin.block; -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.sugar.Local; -import net.errorcraft.itematic.access.block.BlockAccess; +import net.errorcraft.itematic.access.block.AbstractBlockAccess; +import net.errorcraft.itematic.block.entity.SherdsUtil; +import net.errorcraft.itematic.item.ItemKeys; import net.minecraft.block.DecoratedPotBlock; import net.minecraft.block.entity.DecoratedPotBlockEntity; import net.minecraft.block.entity.Sherds; @@ -11,9 +12,7 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.screen.ScreenTexts; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; +import net.minecraft.world.WorldView; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @@ -22,25 +21,7 @@ import java.util.List; @Mixin(DecoratedPotBlock.class) -public class DecoratedPotBlockExtender implements BlockAccess { - @ModifyExpressionValue( - method = "appendTooltip", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/block/entity/Sherds;equals(Ljava/lang/Object;)Z" - ) - ) - private boolean defaultSherdsAlwaysTrue(boolean original, @Local(argsOnly = true) Item.TooltipContext context, @Local(argsOnly = true) List tooltip, @Local Sherds sherds) { - if (!original) { - tooltip.add(ScreenTexts.EMPTY); - for (RegistryEntry entry : sherds.itematic$entriesForwards(context.getRegistryLookup())) { - tooltip.add(new ItemStack(entry).getName().copyContentOnly().formatted(Formatting.GRAY)); - } - } - - return true; - } - +public class DecoratedPotBlockExtender implements AbstractBlockAccess { @Redirect( method = "method_49815", at = @At( @@ -75,6 +56,18 @@ private static ItemStack newItemStackUseRegistryEntry(Item instance, @Local Iter return new ItemStack(iterator.next()); } + @Redirect( + method = "getPickStack", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/block/entity/DecoratedPotBlockEntity;getStackWith(Lnet/minecraft/block/entity/Sherds;)Lnet/minecraft/item/ItemStack;" + ) + ) + private ItemStack getStackWithUseCreateStack(Sherds sherds, WorldView world) { + ItemStack stack = world.itematic$createStack(ItemKeys.DECORATED_POT); + return SherdsUtil.addSherdsToStack(stack, sherds); + } + @Override public void itematic$addComponents(ComponentMap.Builder builder) { builder.add(DataComponentTypes.POT_DECORATIONS, Sherds.DEFAULT); diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/FlowerPotBlockExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/FlowerPotBlockExtender.java index 0317e692..14d9ecc1 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/block/FlowerPotBlockExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/block/FlowerPotBlockExtender.java @@ -19,7 +19,7 @@ import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(FlowerPotBlock.class) -public class FlowerPotBlockExtender extends BlockExtender { +public abstract class FlowerPotBlockExtender extends AbstractBlockExtender { /** * @author ErrorCraft * @reason Uses the Action implementation for data-driven items. diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/GlowLichenBlockExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/MultifaceBlockExtender.java similarity index 54% rename from src/main/java/net/errorcraft/itematic/mixin/block/GlowLichenBlockExtender.java rename to src/main/java/net/errorcraft/itematic/mixin/block/MultifaceBlockExtender.java index 6a9d1ddc..c493c4ed 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/block/GlowLichenBlockExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/block/MultifaceBlockExtender.java @@ -1,15 +1,19 @@ package net.errorcraft.itematic.mixin.block; -import net.errorcraft.itematic.item.ItemKeys; -import net.minecraft.block.GlowLichenBlock; +import net.minecraft.block.Block; +import net.minecraft.block.MultifaceBlock; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(GlowLichenBlock.class) -public class GlowLichenBlockExtender { +@Mixin(MultifaceBlock.class) +public class MultifaceBlockExtender extends Block { + public MultifaceBlockExtender(Settings settings) { + super(settings); + } + @Redirect( method = "canReplace", at = @At( @@ -17,7 +21,7 @@ public class GlowLichenBlockExtender { target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" ) ) - private boolean isOfForGlowLichenUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.GLOW_LICHEN); + private boolean isOfUseRegistryKeyCheck(ItemStack instance, Item item) { + return instance.itematic$isOf(this.itematic$asItemKey()); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/ScaffoldingBlockExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/ScaffoldingBlockExtender.java index 331d0683..122aa5a5 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/block/ScaffoldingBlockExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/block/ScaffoldingBlockExtender.java @@ -1,7 +1,7 @@ package net.errorcraft.itematic.mixin.block; import com.llamalad7.mixinextras.sugar.Local; -import net.errorcraft.itematic.access.block.BlockAccess; +import net.errorcraft.itematic.access.block.AbstractBlockAccess; import net.errorcraft.itematic.item.ItemAccess; import net.errorcraft.itematic.item.UnplaceableItemPlacementContext; import net.minecraft.block.Block; @@ -25,7 +25,7 @@ import org.spongepowered.asm.mixin.injection.ModifyArg; @Mixin(ScaffoldingBlock.class) -public class ScaffoldingBlockExtender extends Block implements BlockAccess { +public class ScaffoldingBlockExtender extends Block implements AbstractBlockAccess { @Shadow @Final public static int MAX_DISTANCE; @@ -47,6 +47,7 @@ private Item getLightUseDynamicRegistry(Item item, @Local(argsOnly = true) Block .map(RegistryEntry::value) .orElse(null); } + return null; } @@ -57,9 +58,11 @@ private Item getLightUseDynamicRegistry(Item item, @Local(argsOnly = true) Block if (world.getBlockState(pos).isOf(this)) { return this.scaffoldingPlacementContext(context, world, pos); } + if (ScaffoldingBlock.calculateDistance(world, pos) == MAX_DISTANCE) { return UnplaceableItemPlacementContext.of(context); } + return context; } @@ -72,15 +75,18 @@ private ItemPlacementContext scaffoldingPlacementContext(ItemPlacementContext co if (this.tooHigh(context, world, mutable)) { break; } + BlockState state = world.getBlockState(mutable); if (!state.isOf(this)) { return this.offsetPlacementContext(context, state, mutable, direction); } + mutable.move(direction); if (direction.getAxis().isHorizontal()) { distance++; } } + return UnplaceableItemPlacementContext.of(context); } @@ -89,9 +95,11 @@ private Direction scaffoldingDirection(ItemPlacementContext context) { if (context.shouldCancelInteraction()) { return context.hitsInsideBlock() ? context.getSide().getOpposite() : context.getSide(); } + if (context.getSide() == Direction.UP) { return context.getHorizontalPlayerFacing(); } + return Direction.UP; } @@ -114,6 +122,7 @@ private ItemPlacementContext offsetPlacementContext(ItemPlacementContext context if (state.canReplace(context)) { return ItemPlacementContext.offset(context, pos, direction); } + return UnplaceableItemPlacementContext.of(context); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/SculkVeinBlockExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/SegmentedExtender.java similarity index 53% rename from src/main/java/net/errorcraft/itematic/mixin/block/SculkVeinBlockExtender.java rename to src/main/java/net/errorcraft/itematic/mixin/block/SegmentedExtender.java index daa68bc4..29244989 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/block/SculkVeinBlockExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/block/SegmentedExtender.java @@ -1,23 +1,23 @@ package net.errorcraft.itematic.mixin.block; -import net.errorcraft.itematic.item.ItemKeys; -import net.minecraft.block.SculkVeinBlock; +import net.errorcraft.itematic.access.block.AbstractBlockAccess; +import net.minecraft.block.Segmented; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(SculkVeinBlock.class) -public class SculkVeinBlockExtender { +@Mixin(Segmented.class) +public interface SegmentedExtender extends AbstractBlockAccess { @Redirect( - method = "canReplace", + method = "shouldAddSegment", at = @At( value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" ) ) - private boolean isOfForSculkVeinBlockUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.SCULK_VEIN); + private boolean isOfUseRegistryKeyCheck(ItemStack instance, Item item) { + return instance.itematic$isOf(this.itematic$asItemKey()); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/ShulkerBoxBlockExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/ShulkerBoxBlockExtender.java index 3537b8b5..21b8240d 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/block/ShulkerBoxBlockExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/block/ShulkerBoxBlockExtender.java @@ -1,6 +1,6 @@ package net.errorcraft.itematic.mixin.block; -import net.errorcraft.itematic.access.block.BlockAccess; +import net.errorcraft.itematic.access.block.AbstractBlockAccess; import net.minecraft.block.ShulkerBoxBlock; import net.minecraft.component.ComponentMap; import net.minecraft.component.DataComponentTypes; @@ -13,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(ShulkerBoxBlock.class) -public class ShulkerBoxBlockExtender implements BlockAccess { +public class ShulkerBoxBlockExtender implements AbstractBlockAccess { @Redirect( method = "onBreak", at = @At( diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/TntBlockAccessor.java b/src/main/java/net/errorcraft/itematic/mixin/block/TntBlockAccessor.java new file mode 100644 index 00000000..64087af2 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/block/TntBlockAccessor.java @@ -0,0 +1,17 @@ +package net.errorcraft.itematic.mixin.block; + +import net.minecraft.block.TntBlock; +import net.minecraft.entity.LivingEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(TntBlock.class) +public interface TntBlockAccessor { + @Invoker("primeTnt") + static boolean primeTnt(World world, BlockPos pos, @Nullable LivingEntity igniter) { + throw new AssertionError(); + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/TntBlockExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/TntBlockExtender.java index f77d803e..83530a33 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/block/TntBlockExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/block/TntBlockExtender.java @@ -1,9 +1,16 @@ package net.errorcraft.itematic.mixin.block; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import net.errorcraft.itematic.item.ItemKeys; import net.minecraft.block.TntBlock; +import net.minecraft.entity.Entity; +import net.minecraft.entity.TntEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @@ -27,4 +34,25 @@ public class TntBlockExtender { private boolean isOfForFlintAndSteelUseRegistryKeyCheck(ItemStack instance, Item item) { return instance.itematic$isOf(ItemKeys.FLINT_AND_STEEL); } + + @ModifyExpressionValue( + method = "primeTnt(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/LivingEntity;)Z", + at = @At( + value = "NEW", + target = "(Lnet/minecraft/world/World;DDDLnet/minecraft/entity/LivingEntity;)Lnet/minecraft/entity/TntEntity;" + ) + ) + private static TntEntity setBlockState(TntEntity original, World world, BlockPos pos) { + original.setBlockState(world.getBlockState(pos)); + return original; + } + + @Redirect( + method = "primeTnt(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/LivingEntity;)Z", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/World;playSound(Lnet/minecraft/entity/Entity;DDDLnet/minecraft/sound/SoundEvent;Lnet/minecraft/sound/SoundCategory;FF)V" + ) + ) + private static void doNotPlaySound(World instance, Entity source, double x, double y, double z, SoundEvent sound, SoundCategory category, float volume, float pitch) {} } diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/UseableOnFluidBlockExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/UseableOnFluidBlockExtender.java index 6c9a962c..1afb23b5 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/block/UseableOnFluidBlockExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/block/UseableOnFluidBlockExtender.java @@ -1,6 +1,6 @@ package net.errorcraft.itematic.mixin.block; -import net.errorcraft.itematic.access.block.BlockAccess; +import net.errorcraft.itematic.access.block.AbstractBlockAccess; import net.errorcraft.itematic.access.item.ItemPlacementContextAccess; import net.minecraft.block.FrogspawnBlock; import net.minecraft.block.LilyPadBlock; @@ -8,7 +8,7 @@ import org.spongepowered.asm.mixin.Mixin; @Mixin({ LilyPadBlock.class, FrogspawnBlock.class }) -public class UseableOnFluidBlockExtender implements BlockAccess { +public class UseableOnFluidBlockExtender implements AbstractBlockAccess { @Override public ItemPlacementContext itematic$placementContext(ItemPlacementContext context) { return ((ItemPlacementContextAccess) context).itematic$offset(0, 1, 0); diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/entity/BlockEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/entity/BlockEntityExtender.java deleted file mode 100644 index f06885d6..00000000 --- a/src/main/java/net/errorcraft/itematic/mixin/block/entity/BlockEntityExtender.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.errorcraft.itematic.mixin.block.entity; - -import net.errorcraft.itematic.access.block.entity.BlockEntityAccess; -import net.minecraft.block.entity.BlockEntity; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(BlockEntity.class) -public class BlockEntityExtender implements BlockEntityAccess { -} diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/entity/DecoratedPotBlockEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/entity/DecoratedPotBlockEntityExtender.java index 60d83b0c..42017525 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/block/entity/DecoratedPotBlockEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/block/entity/DecoratedPotBlockEntityExtender.java @@ -1,59 +1,46 @@ package net.errorcraft.itematic.mixin.block.entity; import com.llamalad7.mixinextras.sugar.Local; -import net.errorcraft.itematic.block.entity.SherdsUtil; -import net.errorcraft.itematic.item.ItemKeys; +import com.mojang.serialization.Codec; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.block.entity.DecoratedPotBlockEntity; -import net.minecraft.block.entity.Sherds; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtOps; import net.minecraft.registry.RegistryWrapper; import net.minecraft.util.math.BlockPos; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; +import java.util.Optional; + @Mixin(DecoratedPotBlockEntity.class) public class DecoratedPotBlockEntityExtender extends BlockEntity { public DecoratedPotBlockEntityExtender(BlockEntityType type, BlockPos pos, BlockState state) { super(type, pos, state); } - @Redirect( - method = "asStack", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/Item;getDefaultStack()Lnet/minecraft/item/ItemStack;" - ) - ) - @SuppressWarnings("DataFlowIssue") - private ItemStack newItemStackUseCreateStack(Item instance) { - return this.world.itematic$createStack(ItemKeys.DECORATED_POT); - } - @Redirect( method = "readNbt", at = @At( value = "INVOKE", - target = "Lnet/minecraft/block/entity/Sherds;fromNbt(Lnet/minecraft/nbt/NbtCompound;)Lnet/minecraft/block/entity/Sherds;" + target = "Lnet/minecraft/nbt/NbtCompound;get(Ljava/lang/String;Lcom/mojang/serialization/Codec;)Ljava/util/Optional;" ) ) - private Sherds fromNbtUseDynamicRegistry(NbtCompound nbt, @Local(argsOnly = true) RegistryWrapper.WrapperLookup lookup) { - return SherdsUtil.fromNbt(nbt, lookup); + private Optional getUseRegistryOps(NbtCompound instance, String key, Codec codec, @Local(argsOnly = true) RegistryWrapper.WrapperLookup lookup) { + return instance.get(key, codec, lookup.getOps(NbtOps.INSTANCE)); } @Redirect( method = "writeNbt", at = @At( value = "INVOKE", - target = "Lnet/minecraft/block/entity/Sherds;toNbt(Lnet/minecraft/nbt/NbtCompound;)Lnet/minecraft/nbt/NbtCompound;" + target = "Lnet/minecraft/nbt/NbtCompound;put(Ljava/lang/String;Lcom/mojang/serialization/Codec;Ljava/lang/Object;)V" ) ) - private NbtCompound toNbtUseDynamicRegistry(Sherds instance, NbtCompound nbt, @Local(argsOnly = true) RegistryWrapper.WrapperLookup lookup) { - return instance.itematic$toNbt(nbt, lookup); + private void putUseRegistryOps(NbtCompound instance, String key, Codec codec, T value, @Local(argsOnly = true) RegistryWrapper.WrapperLookup lookup) { + instance.put(key, codec, lookup.getOps(NbtOps.INSTANCE), value); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/entity/SherdsExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/entity/SherdsExtender.java index 84875f91..e13fdac6 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/block/entity/SherdsExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/block/entity/SherdsExtender.java @@ -1,22 +1,23 @@ package net.errorcraft.itematic.mixin.block.entity; +import com.llamalad7.mixinextras.injector.ModifyReturnValue; import com.mojang.serialization.Codec; import net.errorcraft.itematic.access.block.entity.SherdsAccess; import net.errorcraft.itematic.item.ItemKeys; import net.minecraft.block.entity.Sherds; import net.minecraft.item.Item; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtOps; +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.registry.*; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.registry.entry.RegistryFixedCodec; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; import net.minecraft.util.dynamic.Codecs; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; @@ -24,6 +25,7 @@ import java.util.List; import java.util.Optional; +import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Stream; @@ -125,40 +127,17 @@ private static Function>>> xmapFromShe return Sherds::itematic$optionalEntries; } - /** - * @author ErrorCraft - * @reason Uses a registry entry for data-driven items. - */ - @Overwrite - public Optional back() { - return this.back.map(RegistryEntry::value); - } - - /** - * @author ErrorCraft - * @reason Uses a registry entry for data-driven items. - */ - @Overwrite - public Optional left() { - return this.left.map(RegistryEntry::value); - } - - /** - * @author ErrorCraft - * @reason Uses a registry entry for data-driven items. - */ - @Overwrite - public Optional right() { - return this.right.map(RegistryEntry::value); - } - - /** - * @author ErrorCraft - * @reason Uses a registry entry for data-driven items. - */ - @Overwrite - public Optional front() { - return this.front.map(RegistryEntry::value); + @ModifyReturnValue( + method = { + "back", + "left", + "right", + "front" + }, + at = @At("TAIL") + ) + private Optional mapToItem(Optional> original) { + return original.map(RegistryEntry::value); } @Redirect( @@ -183,15 +162,19 @@ private static Optional> optionalUseValueFromList(T valu return sherds.get(index); } - @Override - @SuppressWarnings("EqualsBetweenInconvertibleTypes") - public NbtCompound itematic$toNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup lookup) { - if (this.equals(DEFAULT)) { - return nbt; - } - - nbt.put("sherds", CODEC.encodeStart(lookup.getOps(NbtOps.INSTANCE), (Sherds)(Object) this).getOrThrow()); - return nbt; + @Redirect( + method = "appendTooltip", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/block/entity/Sherds;appendSherdTooltip(Ljava/util/function/Consumer;Ljava/util/Optional;)V" + ) + ) + private void appendSherdTooltipUseRegistryEntry(Consumer textConsumer, Optional> sherd) { + sherd.map(ItemStack::new) + .map(ItemStack::getName) + .map(Text::copyContentOnly) + .map(text -> text.formatted(Formatting.GRAY)) + .ifPresent(textConsumer); } @Override @@ -206,12 +189,4 @@ private static Optional> optionalUseValueFromList(T valu .map(optional -> optional.orElse(items.getOrThrow(ItemKeys.BRICK))) .toList(); } - - @Override - public List> itematic$entriesForwards(RegistryWrapper.WrapperLookup lookup) { - RegistryWrapper.Impl items = lookup.getOrThrow(RegistryKeys.ITEM); - return Stream.of(this.front, this.left, this.right, this.back) - .map(optional -> optional.orElse(items.getOrThrow(ItemKeys.BRICK))) - .toList(); - } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/command/argument/ScoreboardCriterionArgumentTypeExtender.java b/src/main/java/net/errorcraft/itematic/mixin/command/argument/ScoreboardCriterionArgumentTypeExtender.java index 8a6e4eef..afa88ffe 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/command/argument/ScoreboardCriterionArgumentTypeExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/command/argument/ScoreboardCriterionArgumentTypeExtender.java @@ -2,44 +2,39 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.sugar.Local; -import com.mojang.brigadier.StringReader; +import com.mojang.serialization.JsonOps; import net.errorcraft.itematic.access.command.argument.ScoreboardCriterionArgumentTypeAccess; import net.errorcraft.itematic.scoreboard.ScoreboardCriterionUtil; import net.errorcraft.itematic.stat.StatUtil; import net.minecraft.command.CommandRegistryAccess; import net.minecraft.command.argument.ScoreboardCriterionArgumentType; +import net.minecraft.registry.RegistryOps; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.scoreboard.ScoreboardCriterion; import net.minecraft.stat.StatType; 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.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Slice; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.Iterator; +import java.util.Optional; @Mixin(ScoreboardCriterionArgumentType.class) public class ScoreboardCriterionArgumentTypeExtender implements ScoreboardCriterionArgumentTypeAccess { @Unique private CommandRegistryAccess registryAccess; - @Inject( - method = "parse(Lcom/mojang/brigadier/StringReader;)Lnet/minecraft/scoreboard/ScoreboardCriterion;", - at = @At("HEAD") - ) - private void setLookup(StringReader reader, CallbackInfoReturnable info) { - ScoreboardCriterionUtil.setLookup(this.registryAccess); - } - - @Inject( + @Redirect( method = "parse(Lcom/mojang/brigadier/StringReader;)Lnet/minecraft/scoreboard/ScoreboardCriterion;", - at = @At("RETURN") + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/scoreboard/ScoreboardCriterion;getOrCreateStatCriterion(Ljava/lang/String;)Ljava/util/Optional;" + ) ) - private void resetLookup(StringReader reader, CallbackInfoReturnable info) { - ScoreboardCriterionUtil.setLookup(null); + private Optional useDynamicRegistry(String name) { + return ScoreboardCriterionUtil.byName(name, RegistryOps.of(JsonOps.INSTANCE, this.registryAccess)); } @ModifyExpressionValue( diff --git a/src/main/java/net/errorcraft/itematic/mixin/component/type/LodestoneTrackerComponentExtender.java b/src/main/java/net/errorcraft/itematic/mixin/component/type/LodestoneTrackerComponentExtender.java new file mode 100644 index 00000000..17e29440 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/component/type/LodestoneTrackerComponentExtender.java @@ -0,0 +1,27 @@ +package net.errorcraft.itematic.mixin.component.type; + +import net.errorcraft.itematic.item.data.InventoryTickListener; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.LodestoneTrackerComponent; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.item.ItemStack; +import net.minecraft.server.world.ServerWorld; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(LodestoneTrackerComponent.class) +public abstract class LodestoneTrackerComponentExtender implements InventoryTickListener { + @Shadow + public abstract LodestoneTrackerComponent forWorld(ServerWorld world); + + @Override + @SuppressWarnings("ConstantValue") + public void itematic$onInventoryTick(ServerWorld world, ItemStack stack, Entity owner, @Nullable EquipmentSlot slot) { + LodestoneTrackerComponent newTracker = this.forWorld(world); + if ((Object) this != newTracker) { + stack.set(DataComponentTypes.LODESTONE_TRACKER, newTracker); + } + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/component/type/MapIdComponentExtender.java b/src/main/java/net/errorcraft/itematic/mixin/component/type/MapIdComponentExtender.java new file mode 100644 index 00000000..3f63f489 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/component/type/MapIdComponentExtender.java @@ -0,0 +1,32 @@ +package net.errorcraft.itematic.mixin.component.type; + +import net.errorcraft.itematic.item.component.components.MapHolderItemComponent; +import net.errorcraft.itematic.item.data.InventoryTickListener; +import net.minecraft.component.type.MapIdComponent; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.map.MapState; +import net.minecraft.server.world.ServerWorld; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(MapIdComponent.class) +public class MapIdComponentExtender implements InventoryTickListener { + @Override + public void itematic$onInventoryTick(ServerWorld world, ItemStack stack, Entity owner, @Nullable EquipmentSlot slot) { + MapState mapState = world.getMapState((MapIdComponent)(Object) this); + if (mapState == null) { + return; + } + + if (owner instanceof PlayerEntity playerOwner) { + mapState.update(playerOwner, stack); + } + + if (!mapState.locked && slot != null && slot.getType() == EquipmentSlot.Type.HAND) { + MapHolderItemComponent.DUMMY.updateColors(world, owner, mapState); + } + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/enchantment/EnchantmentHelperAccessor.java b/src/main/java/net/errorcraft/itematic/mixin/enchantment/EnchantmentHelperAccessor.java new file mode 100644 index 00000000..2f021410 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/enchantment/EnchantmentHelperAccessor.java @@ -0,0 +1,16 @@ +package net.errorcraft.itematic.mixin.enchantment; + +import net.minecraft.component.ComponentType; +import net.minecraft.component.type.ItemEnchantmentsComponent; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(EnchantmentHelper.class) +public interface EnchantmentHelperAccessor { + @Invoker("getEnchantmentsComponentType") + static ComponentType getComponentType(ItemStack stack) { + throw new AssertionError(); + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/EntityAccessor.java b/src/main/java/net/errorcraft/itematic/mixin/entity/EntityAccessor.java new file mode 100644 index 00000000..a04f3cec --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/EntityAccessor.java @@ -0,0 +1,12 @@ +package net.errorcraft.itematic.mixin.entity; + +import net.minecraft.component.ComponentsAccess; +import net.minecraft.entity.Entity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(Entity.class) +public interface EntityAccessor { + @Invoker("copyComponentsFrom") + void itematic$copyComponentsFrom(ComponentsAccess from); +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/EntityTypeExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/EntityTypeExtender.java index 7f385c00..45f15810 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/EntityTypeExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/EntityTypeExtender.java @@ -1,17 +1,18 @@ package net.errorcraft.itematic.mixin.entity; import com.llamalad7.mixinextras.injector.ModifyReturnValue; -import com.mojang.serialization.MapCodec; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Local; import net.errorcraft.itematic.access.entity.EntityTypeAccess; import net.errorcraft.itematic.access.entity.EntityTypeBuilderAccess; +import net.errorcraft.itematic.entity.EntitySpawnCallback; import net.errorcraft.itematic.entity.initializer.EntityInitializer; -import net.errorcraft.itematic.entity.initializer.EntityInitializerCodecCreator; +import net.errorcraft.itematic.entity.initializer.EntityInitializerSupplier; import net.errorcraft.itematic.entity.initializer.initializers.*; +import net.errorcraft.itematic.item.ItemStackUtil; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.EyeOfEnderEntity; -import net.minecraft.entity.SpawnReason; +import net.minecraft.entity.*; import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.entity.decoration.EndCrystalEntity; import net.minecraft.entity.decoration.GlowItemFrameEntity; @@ -19,23 +20,35 @@ import net.minecraft.entity.decoration.painting.PaintingEntity; import net.minecraft.entity.projectile.*; import net.minecraft.entity.vehicle.*; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; +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.ModifyArg; import org.spongepowered.asm.mixin.injection.Slice; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Objects; +import java.util.function.Consumer; @Mixin(EntityType.class) -@SuppressWarnings("unchecked") -public abstract class EntityTypeExtender implements EntityTypeAccess { - @Unique - private MapCodec> initializerCodec; +public abstract class EntityTypeExtender implements EntityTypeAccess { + @Shadow + public static Consumer copier(Consumer chained, World world, ItemStack stack, @Nullable LivingEntity spawner) { + return null; + } + + @Shadow + @Nullable + public abstract T create(ServerWorld world, @Nullable Consumer afterConsumer, BlockPos pos, SpawnReason reason, boolean alignPosition, boolean invertY); @Unique - private EntityInitializer initializer; + private EntityInitializer initializer; @Unique private ActionContext actionContext; @@ -54,9 +67,9 @@ public abstract class EntityTypeExtender implements EntityType ) ) ) - private static EntityType.Builder setMinecartInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(minecartInitializerCodecCreator()); - return type; + private static EntityType.Builder setMinecartInitializer(EntityType.Builder builder) { + builder.itematic$initializer(MinecartEntityInitializer::new); + return builder; } @ModifyArg( @@ -73,9 +86,9 @@ private static EntityType.Builder setMinecartInitializerCodec(En ) ) ) - private static EntityType.Builder setChestMinecartInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(minecartInitializerCodecCreator()); - return type; + private static EntityType.Builder setChestMinecartInitializer(EntityType.Builder builder) { + builder.itematic$initializer(MinecartEntityInitializer::new); + return builder; } @ModifyArg( @@ -92,9 +105,9 @@ private static EntityType.Builder setChestMinecartInitializ ) ) ) - private static EntityType.Builder setFurnaceMinecartInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(minecartInitializerCodecCreator()); - return type; + private static EntityType.Builder setFurnaceMinecartInitializer(EntityType.Builder builder) { + builder.itematic$initializer(MinecartEntityInitializer::new); + return builder; } @ModifyArg( @@ -111,9 +124,9 @@ private static EntityType.Builder setFurnaceMinecartIniti ) ) ) - private static EntityType.Builder setTntMinecartInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(minecartInitializerCodecCreator()); - return type; + private static EntityType.Builder setTntMinecartInitializer(EntityType.Builder builder) { + builder.itematic$initializer(MinecartEntityInitializer::new); + return builder; } @ModifyArg( @@ -130,9 +143,9 @@ private static EntityType.Builder setTntMinecartInitializerCo ) ) ) - private static EntityType.Builder setSpawnerMinecartInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(minecartInitializerCodecCreator()); - return type; + private static EntityType.Builder setSpawnerMinecartInitializer(EntityType.Builder builder) { + builder.itematic$initializer(MinecartEntityInitializer::new); + return builder; } @ModifyArg( @@ -149,9 +162,9 @@ private static EntityType.Builder setSpawnerMinecartIniti ) ) ) - private static EntityType.Builder setHopperMinecartInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(minecartInitializerCodecCreator()); - return type; + private static EntityType.Builder setHopperMinecartInitializer(EntityType.Builder builder) { + builder.itematic$initializer(MinecartEntityInitializer::new); + return builder; } @ModifyArg( @@ -168,9 +181,9 @@ private static EntityType.Builder setHopperMinecartInitial ) ) ) - private static EntityType.Builder setCommandBlockMinecartInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(minecartInitializerCodecCreator()); - return type; + private static EntityType.Builder setCommandBlockMinecartInitializer(EntityType.Builder builder) { + builder.itematic$initializer(MinecartEntityInitializer::new); + return builder; } @ModifyArg( @@ -187,9 +200,9 @@ private static EntityType.Builder setCommandBlockMin ) ) ) - private static EntityType.Builder setEndCrystalInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(EndCrystalEntityInitializer.CODEC); - return type; + private static EntityType.Builder setEndCrystalInitializer(EntityType.Builder builder) { + builder.itematic$initializer(EndCrystalEntityInitializer.INSTANCE); + return builder; } @ModifyArg( @@ -206,9 +219,9 @@ private static EntityType.Builder setEndCrystalInitializerCode ) ) ) - private static EntityType.Builder setArmorStandInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(ArmorStandEntityInitializer.CODEC); - return type; + private static EntityType.Builder setArmorStandInitializer(EntityType.Builder builder) { + builder.itematic$initializer(ArmorStandEntityInitializer.INSTANCE); + return builder; } @ModifyArg( @@ -225,9 +238,9 @@ private static EntityType.Builder setArmorStandInitializerCode ) ) ) - private static EntityType.Builder setPaintingInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(entityType -> MapCodec.unit(DecorationEntityInitializer.createPainting(entityType))); - return type; + private static EntityType.Builder setPaintingInitializer(EntityType.Builder builder) { + builder.itematic$initializer(DecorationEntityInitializer.ofPainting()); + return builder; } @ModifyArg( @@ -244,9 +257,9 @@ private static EntityType.Builder setPaintingInitializerCodec(En ) ) ) - private static EntityType.Builder setItemFrameInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(decorationInitializerCodecCreator(ItemFrameEntity::new)); - return type; + private static EntityType.Builder setItemFrameInitializer(EntityType.Builder builder) { + builder.itematic$initializer(DecorationEntityInitializer.ofItemFrame(ItemFrameEntity::new)); + return builder; } @ModifyArg( @@ -263,9 +276,9 @@ private static EntityType.Builder setItemFrameInitializerCodec( ) ) ) - private static EntityType.Builder setGlowItemFrameInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(decorationInitializerCodecCreator(GlowItemFrameEntity::new)); - return type; + private static EntityType.Builder setGlowItemFrameInitializer(EntityType.Builder builder) { + builder.itematic$initializer(DecorationEntityInitializer.ofItemFrame(GlowItemFrameEntity::new)); + return builder; } @ModifyArg( @@ -282,9 +295,12 @@ private static EntityType.Builder setGlowItemFrameInitializ ) ) ) - private static EntityType.Builder setArrowInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(entityType -> PersistentProjectileEntityInitializer.createCodec(entityType, ArrowEntity::new, ArrowEntity::new)); - return type; + private static EntityType.Builder setArrowInitializer(EntityType.Builder builder) { + builder.itematic$initializer(PersistentProjectileEntityInitializer.of( + ArrowEntity::new, + ArrowEntity::new + )); + return builder; } @ModifyArg( @@ -301,9 +317,12 @@ private static EntityType.Builder setArrowInitializerCodec(EntityTy ) ) ) - private static EntityType.Builder setSpectralArrowInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(entityType -> PersistentProjectileEntityInitializer.createCodec(entityType, SpectralArrowEntity::new, SpectralArrowEntity::new)); - return type; + private static EntityType.Builder setSpectralArrowInitializer(EntityType.Builder builder) { + builder.itematic$initializer(PersistentProjectileEntityInitializer.of( + SpectralArrowEntity::new, + SpectralArrowEntity::new + )); + return builder; } @ModifyArg( @@ -320,9 +339,9 @@ private static EntityType.Builder setSpectralArrowInitializ ) ) ) - private static EntityType.Builder setTridentInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(TridentEntityInitializer.CODEC); - return type; + private static EntityType.Builder setTridentInitializer(EntityType.Builder builder) { + builder.itematic$initializer(TridentEntityInitializer.INSTANCE); + return builder; } @ModifyArg( @@ -339,9 +358,9 @@ private static EntityType.Builder setTridentInitializerCodec(Enti ) ) ) - private static EntityType.Builder setFireworkRocketInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(FireworkRocketEntityInitializer.CODEC); - return type; + private static EntityType.Builder setFireworkRocketInitializer(EntityType.Builder builder) { + builder.itematic$initializer(FireworkRocketEntityInitializer.INSTANCE); + return builder; } @ModifyArg( @@ -358,9 +377,9 @@ private static EntityType.Builder setFireworkRocketInitial ) ) ) - private static EntityType.Builder setEyeOfEnderInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(EyeOfEnderEntityInitializer.CODEC); - return type; + private static EntityType.Builder setEyeOfEnderInitializer(EntityType.Builder builder) { + builder.itematic$initializer(EyeOfEnderEntityInitializer.INSTANCE); + return builder; } @ModifyArg( @@ -377,9 +396,9 @@ private static EntityType.Builder setEyeOfEnderInitializerCode ) ) ) - private static EntityType.Builder setSmallFireballInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(SmallFireballEntityInitializer.CODEC); - return type; + private static EntityType.Builder setSmallFireballInitializer(EntityType.Builder builder) { + builder.itematic$initializer(SmallFireballEntityInitializer.INSTANCE); + return builder; } @ModifyArg( @@ -396,78 +415,86 @@ private static EntityType.Builder setSmallFireballInitializ ) ) ) - private static EntityType.Builder setWindChargeInitializerCodec(EntityType.Builder type) { - type.itematic$initializerCodec(WindChargeEntityInitializer.CODEC); - return type; + private static EntityType.Builder setWindChargeInitializer(EntityType.Builder builder) { + builder.itematic$initializer(WindChargeEntityInitializer.INSTANCE); + return builder; } - @Inject( + @WrapOperation( method = "create(Lnet/minecraft/world/World;Lnet/minecraft/entity/SpawnReason;)Lnet/minecraft/entity/Entity;", at = @At( value = "INVOKE", target = "Lnet/minecraft/entity/EntityType$EntityFactory;create(Lnet/minecraft/entity/EntityType;Lnet/minecraft/world/World;)Lnet/minecraft/entity/Entity;" - ), - cancellable = true + ) ) - private void createUseEntityInitializerIfPresent(World world, SpawnReason reason, CallbackInfoReturnable info) { - if (this.initializer == null) { - return; + private T useEntityInitializer(EntityType.EntityFactory instance, EntityType type, World world, Operation original, @Local(argsOnly = true) SpawnReason reason) { + if (this.actionContext == null) { + return original.call(instance, type, world); } - EntityInitializer initializer = this.initializer; // Copy to a local and set the field to null, so we don't get a StackOverflowError - this.initializer = null; - info.setReturnValue((T) initializer.create(this.actionContext, reason)); + // Copy to a local and set the field to null so we don't get a StackOverflowError + ActionContext context = this.actionContext; this.actionContext = null; + return this.initializer.create(context, reason); } @Override - public MapCodec> itematic$initializerCodec() { - return this.initializerCodec; - } - - @Override - public void itematic$setInitializerCodec(MapCodec> initializerCodec) { - this.initializerCodec = initializerCodec; + public void itematic$setInitializer(EntityInitializer initializer) { + this.initializer = initializer; } @Override - public void itematic$setInitializer(EntityInitializer initializer, ActionContext actionContext) { - this.initializer = initializer; - this.actionContext = actionContext; + public T itematic$create(ActionContext context, SpawnReason reason, BlockPos pos, @Nullable EntitySpawnCallback callback, boolean allowItemData, boolean invertY) { + this.actionContext = context; + return this.create( + context.world(), + copier(context, callback, allowItemData), + pos, + reason, + true, + invertY + ); } @Unique - private static EntityInitializerCodecCreator minecartInitializerCodecCreator() { - return type -> MapCodec.unit(new MinecartEntityInitializer<>(type)); - } + @Nullable + private static Consumer copier(ActionContext context, @Nullable EntitySpawnCallback callback, boolean allowItemData) { + ItemStack stack = context.get(LootContextParameters.TOOL); + if (!allowItemData || ItemStackUtil.isNullOrEmpty(stack)) { + return callback == null ? null : entity -> callback.accept(entity, stack); + } - @Unique - private static EntityInitializerCodecCreator decorationInitializerCodecCreator(DecorationEntityInitializer.Creator creator) { - return type -> MapCodec.unit(DecorationEntityInitializer.createItemFrame(type, creator)); + return copier( + callback == null ?entity -> {} : entity -> callback.accept(entity, stack), + context.world(), + stack, + context.get(LootContextParameters.THIS_ENTITY, LivingEntity.class) + ); } @Mixin(EntityType.Builder.class) public static class BuilderExtender implements EntityTypeBuilderAccess { @Unique - private EntityInitializerCodecCreator creator; + private EntityInitializerSupplier initializer = SimpleEntityInitializer::new; @ModifyReturnValue( method = "build", at = @At("TAIL") ) - private EntityType buildSetInitializerCodec(EntityType original) { - original.itematic$setInitializerCodec(this.creator == null ? SimpleEntityInitializer.createCodec(original) : this.creator.create(original)); + private EntityType setInitializer(EntityType original) { + original.itematic$setInitializer(this.initializer.create(original)); return original; } @Override - public void itematic$initializerCodec(MapCodec> codec) { - this.creator = type -> codec; + public void itematic$initializer(EntityInitializer initializer) { + Objects.requireNonNull(initializer); + this.initializer = type -> initializer; } @Override - public void itematic$initializerCodec(EntityInitializerCodecCreator creator) { - this.creator = creator; + public void itematic$initializer(EntityInitializerSupplier initializer) { + this.initializer = Objects.requireNonNull(initializer); } } } 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 05f73d51..ebb467c4 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/LivingEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/LivingEntityExtender.java @@ -14,7 +14,6 @@ import net.errorcraft.itematic.item.component.components.ConsumableItemComponent; import net.errorcraft.itematic.item.event.ItemEvents; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; import net.minecraft.component.ComponentType; import net.minecraft.component.type.DeathProtectionComponent; import net.minecraft.component.type.EquippableComponent; @@ -29,9 +28,9 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.registry.tag.ItemTags; import net.minecraft.server.world.ServerWorld; import net.minecraft.stat.Stat; import net.minecraft.stat.StatType; @@ -40,7 +39,6 @@ import net.minecraft.world.World; import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -244,8 +242,10 @@ private void invokeBeforeDeathHolderEvent(DeathProtectionComponent instance, Ite } ActionContext context = ActionContext.builder(serverWorld) - .entityPosition(ActionContextParameter.THIS, entity) - .stack(stack) + .stackExchanger(entity, stack) + .add(LootContextParameters.THIS_ENTITY, entity) + .add(LootContextParameters.ORIGIN, entity.getPos()) + .add(LootContextParameters.TOOL, stack) .build(); stack.itematic$invokeEvent(ItemEvents.BEFORE_DEATH_HOLDER, context); } @@ -431,15 +431,6 @@ private int getItemUseTimeUseField(int original) { return this.itemUsedTicks; } - /** - * @author ErrorCraft - * @reason Uses an item tag check instead of an instanceof check. - */ - @Overwrite - public boolean disablesShield() { - return this.getMainHandStack().isIn(ItemTags.AXES); - } - @Override public boolean itematic$isHolding(RegistryKey key) { return this.isHolding(stack -> stack.itematic$isOf(key)); diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/ai/brain/task/GatherItemsVillagerTaskExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/ai/brain/task/GatherItemsVillagerTaskExtender.java index 6af17c0d..f3bff071 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/ai/brain/task/GatherItemsVillagerTaskExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/ai/brain/task/GatherItemsVillagerTaskExtender.java @@ -12,7 +12,6 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; -import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.registry.entry.RegistryEntryList; @@ -26,7 +25,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.Map; import java.util.Set; @@ -54,15 +52,8 @@ private Map getItemFoodPointsUseRegistryKey(ServerWorld serverWor Map.Entry::getValue )); } - return this.itemFoodPointsCache; - } - @Inject( - method = "getGatherableItems", - at = @At("HEAD") - ) - private static void storeItemAccess(VillagerEntity entity, VillagerEntity target, CallbackInfoReturnable> info, @Share("itemAccess")LocalRef> itemRegistry) { - itemRegistry.set(entity.getWorld().getRegistryManager().getOrThrow(RegistryKeys.ITEM)); + return this.itemFoodPointsCache; } @Redirect( @@ -72,13 +63,14 @@ private static void storeItemAccess(VillagerEntity entity, VillagerEntity target target = "Lnet/minecraft/village/VillagerProfession;gatherableItems()Lcom/google/common/collect/ImmutableSet;" ) ) - private static ImmutableSet gatherableItemsUseDynamicRegistry(VillagerProfession instance, VillagerEntity entity, @Share("itemAccess")LocalRef> itemRegistry) { - TagKey tag = instance.itematic$gatherableItemsTag(); + private static ImmutableSet gatherableItemsUseDynamicRegistry(VillagerProfession instance, VillagerEntity entity) { + TagKey tag = instance.itematic$gatherableItems(); if (tag == null) { return ImmutableSet.of(); } - return itemRegistry.get() + return entity.getRegistryManager() + .getOrThrow(RegistryKeys.ITEM) .getOptional(tag) .stream() .flatMap(RegistryEntryList::stream) @@ -105,7 +97,7 @@ private Item keepRunningGetWheatUseDynamicRegistry(ServerWorld serverWorld) { target = "Lnet/minecraft/item/ItemStack;getItem()Lnet/minecraft/item/Item;" ) ) - private static void storeInventoryStackEntry(VillagerEntity villager, Set validItems, LivingEntity target, CallbackInfo info, @Local(ordinal = 1) ItemStack inventoryStack, @Share("registryEntry") LocalRef> foundItem) { + private static void storeInventoryStackRegistryEntry(VillagerEntity villager, Set validItems, LivingEntity target, CallbackInfo info, @Local(ordinal = 1) ItemStack inventoryStack, @Share("registryEntry") LocalRef> foundItem) { foundItem.set(inventoryStack.getRegistryEntry()); } diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/ai/brain/task/RemoveOffHandItemTaskExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/ai/brain/task/RemoveOffHandItemTaskExtender.java index de5a0783..56eeb9e0 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/ai/brain/task/RemoveOffHandItemTaskExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/ai/brain/task/RemoveOffHandItemTaskExtender.java @@ -1,23 +1,23 @@ package net.errorcraft.itematic.mixin.entity.ai.brain.task; -import net.errorcraft.itematic.item.ItemKeys; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.sugar.Local; +import net.errorcraft.itematic.item.component.ItemComponentTypes; import net.minecraft.entity.ai.brain.task.RemoveOffHandItemTask; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; +import net.minecraft.entity.mob.PiglinEntity; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(RemoveOffHandItemTask.class) public class RemoveOffHandItemTaskExtender { - @Redirect( + @ModifyExpressionValue( method = "method_47299", at = @At( value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" + target = "Lnet/minecraft/item/ItemStack;contains(Lnet/minecraft/component/ComponentType;)Z" ) ) - private static boolean isOfForShieldUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.SHIELD); + private static boolean containsBlocksAttacksDataComponentAlsoCheckItemBehaviorComponent(boolean original, @Local(argsOnly = true) PiglinEntity piglin) { + return original && piglin.getOffHandStack().itematic$hasBehavior(ItemComponentTypes.ATTACK_BLOCKING); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/mob/CreakingEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/mob/CreakingEntityExtender.java new file mode 100644 index 00000000..47582d52 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/mob/CreakingEntityExtender.java @@ -0,0 +1,23 @@ +package net.errorcraft.itematic.mixin.entity.mob; + +import net.errorcraft.itematic.item.ItemKeys; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.mob.CreakingEntity; +import net.minecraft.item.Item; +import net.minecraft.registry.RegistryKey; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(CreakingEntity.class) +public abstract class CreakingEntityExtender extends MobEntityExtender { + protected CreakingEntityExtender(EntityType entityType, World world) { + super(entityType, world); + } + + @Override + protected @Nullable RegistryKey pickBlockKey() { + return ItemKeys.CREAKING_SPAWN_EGG; + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/mob/DrownedEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/mob/DrownedEntityExtender.java index 6ad11ffd..64b9739b 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/mob/DrownedEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/mob/DrownedEntityExtender.java @@ -10,6 +10,7 @@ import net.minecraft.registry.RegistryKey; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; +import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @@ -33,7 +34,10 @@ private ItemStack newItemStackForNautilusShellUseCreateStack(ItemConvertible ite } @Redirect( - method = { "initEquipment", "shootAt" }, + method = { + "initEquipment", + "shootAt" + }, at = @At( value = "NEW", target = "(Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/item/ItemStack;", @@ -54,7 +58,8 @@ private ItemStack newItemStackForTridentUseCreateStack(ItemConvertible item) { slice = @Slice( from = @At( value = "FIELD", - target = "Lnet/minecraft/item/Items;TRIDENT:Lnet/minecraft/item/Item;" + target = "Lnet/minecraft/item/Items;TRIDENT:Lnet/minecraft/item/Item;", + opcode = Opcodes.GETSTATIC ) ) ) @@ -72,7 +77,8 @@ private ItemStack newItemStackForFishingRodUseCreateStack(ItemConvertible item) slice = @Slice( from = @At( value = "FIELD", - target = "Lnet/minecraft/item/Items;NAUTILUS_SHELL:Lnet/minecraft/item/Item;" + target = "Lnet/minecraft/item/Items;NAUTILUS_SHELL:Lnet/minecraft/item/Item;", + opcode = Opcodes.GETSTATIC ) ) ) @@ -80,23 +86,6 @@ private boolean isOfForNautilusShellUseRegistryKeyCheck(ItemStack instance, Item return instance.itematic$isOf(ItemKeys.NAUTILUS_SHELL); } - @Redirect( - method = "prefersNewEquipment", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" - ), - slice = @Slice( - from = @At( - value = "FIELD", - target = "Lnet/minecraft/item/Items;TRIDENT:Lnet/minecraft/item/Item;" - ) - ) - ) - private boolean isOfForTridentUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.TRIDENT); - } - @Override protected @Nullable RegistryKey pickBlockKey() { return ItemKeys.DROWNED_SPAWN_EGG; diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/mob/PiglinEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/mob/PiglinEntityExtender.java index 4d8d4efa..2e0c0df1 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/mob/PiglinEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/mob/PiglinEntityExtender.java @@ -12,6 +12,7 @@ import net.minecraft.registry.RegistryKey; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; +import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @@ -55,7 +56,8 @@ private ItemStack newItemStackForCrossbowUseCreateStack(ItemConvertible item) { slice = @Slice( from = @At( value = "FIELD", - target = "Lnet/minecraft/item/Items;CROSSBOW:Lnet/minecraft/item/Item;" + target = "Lnet/minecraft/item/Items;CROSSBOW:Lnet/minecraft/item/Item;", + opcode = Opcodes.GETSTATIC ) ) ) @@ -74,17 +76,6 @@ private boolean isHoldingForCrossbowUseRegistryKeyCheck(PiglinEntity instance, I return instance.itematic$isHolding(ItemKeys.CROSSBOW); } - @Redirect( - method = "prefersNewEquipment", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" - ) - ) - private boolean isOfForCrossbowUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.CROSSBOW); - } - @Redirect( method = "equipToOffHand", at = @At( @@ -106,7 +97,8 @@ private boolean isOfForGoldIngotUseRegistryKeyCheck(ItemStack instance, Item ite slice = @Slice( from = @At( value = "FIELD", - target = "Lnet/minecraft/entity/EquipmentSlot;HEAD:Lnet/minecraft/entity/EquipmentSlot;" + target = "Lnet/minecraft/entity/EquipmentSlot;HEAD:Lnet/minecraft/entity/EquipmentSlot;", + opcode = Opcodes.GETSTATIC ) ) ) @@ -124,7 +116,8 @@ private ItemStack newItemStackForGoldenHelmetUseCreateStack(ItemConvertible item slice = @Slice( from = @At( value = "FIELD", - target = "Lnet/minecraft/entity/EquipmentSlot;CHEST:Lnet/minecraft/entity/EquipmentSlot;" + target = "Lnet/minecraft/entity/EquipmentSlot;CHEST:Lnet/minecraft/entity/EquipmentSlot;", + opcode = Opcodes.GETSTATIC ) ) ) @@ -142,7 +135,8 @@ private ItemStack newItemStackForGoldenChestplateUseCreateStack(ItemConvertible slice = @Slice( from = @At( value = "FIELD", - target = "Lnet/minecraft/entity/EquipmentSlot;LEGS:Lnet/minecraft/entity/EquipmentSlot;" + target = "Lnet/minecraft/entity/EquipmentSlot;LEGS:Lnet/minecraft/entity/EquipmentSlot;", + opcode = Opcodes.GETSTATIC ) ) ) @@ -160,7 +154,8 @@ private ItemStack newItemStackForGoldenLeggingsUseCreateStack(ItemConvertible it slice = @Slice( from = @At( value = "FIELD", - target = "Lnet/minecraft/entity/EquipmentSlot;FEET:Lnet/minecraft/entity/EquipmentSlot;" + target = "Lnet/minecraft/entity/EquipmentSlot;FEET:Lnet/minecraft/entity/EquipmentSlot;", + opcode = Opcodes.GETSTATIC ) ) ) diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/mob/ZombieEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/mob/ZombieEntityExtender.java index d39e7320..a89993cf 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/mob/ZombieEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/mob/ZombieEntityExtender.java @@ -14,6 +14,7 @@ import net.minecraft.world.ServerWorldAccess; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; +import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @@ -25,17 +26,6 @@ protected ZombieEntityExtender(EntityType entityType, W super(entityType, world); } - @Redirect( - method = "canPickupItem", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" - ) - ) - private boolean isOfForEggUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.EGG); - } - @ModifyExpressionValue( method = "initialize", at = @At( @@ -113,7 +103,8 @@ private ItemStack newItemStackForIronSwordUseCreateStack(ItemConvertible item) { slice = @Slice( from = @At( value = "FIELD", - target = "Lnet/minecraft/item/Items;IRON_SWORD:Lnet/minecraft/item/Item;" + target = "Lnet/minecraft/item/Items;IRON_SWORD:Lnet/minecraft/item/Item;", + opcode = Opcodes.GETSTATIC ) ) ) diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/AbstractHorseEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/AbstractHorseEntityExtender.java index 7baee081..eb495593 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/AbstractHorseEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/AbstractHorseEntityExtender.java @@ -144,29 +144,4 @@ private boolean isOfForGoldenAppleUseRegistryKeyCheck(ItemStack instance, Item i private boolean isOfForEnchantedGoldenAppleUseRegistryKeyCheck(ItemStack instance, Item item) { return instance.itematic$isOf(ItemKeys.ENCHANTED_GOLDEN_APPLE); } - - @Redirect( - method = "readCustomDataFromNbt", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" - ) - ) - private boolean isOfForSaddleUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.SADDLE); - } - - @Mixin(targets = "net/minecraft/entity/passive/AbstractHorseEntity$2") - public static class SaddleStackReferenceExtender { - @Redirect( - method = "set", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" - ) - ) - private boolean isOfForSaddleUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.SADDLE); - } - } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/GoatEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/GoatEntityExtender.java index 45423203..511b6872 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/GoatEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/GoatEntityExtender.java @@ -3,6 +3,7 @@ import net.errorcraft.itematic.item.ItemKeys; import net.errorcraft.itematic.mixin.entity.mob.MobEntityExtender; import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.InstrumentComponent; import net.minecraft.entity.EntityType; import net.minecraft.entity.passive.AnimalEntity; import net.minecraft.entity.passive.GoatEntity; @@ -35,7 +36,7 @@ protected GoatEntityExtender(EntityType entityType, Worl private Function, ? extends ItemStack> getStackForInstrumentUseCreateStack(Function, ? extends ItemStack> mapper) { return instrument -> { ItemStack stack = this.getWorld().itematic$createStack(ItemKeys.GOAT_HORN); - stack.set(DataComponentTypes.INSTRUMENT, instrument); + stack.set(DataComponentTypes.INSTRUMENT, new InstrumentComponent(instrument)); return stack; }; } diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/MerchantEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/MerchantEntityExtender.java index c26b8720..51144f8a 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/MerchantEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/MerchantEntityExtender.java @@ -1,7 +1,6 @@ package net.errorcraft.itematic.mixin.entity.passive; import com.google.common.collect.Lists; -import com.mojang.serialization.DynamicOps; import net.errorcraft.itematic.mixin.entity.mob.MobEntityExtender; import net.errorcraft.itematic.util.context.ItematicContextTypes; import net.errorcraft.itematic.village.trade.Trade; @@ -11,8 +10,6 @@ import net.minecraft.loot.context.LootContext; import net.minecraft.loot.context.LootContextParameters; import net.minecraft.loot.context.LootWorldContext; -import net.minecraft.nbt.NbtElement; -import net.minecraft.registry.RegistryOps; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.registry.entry.RegistryEntryList; import net.minecraft.server.world.ServerWorld; @@ -23,7 +20,6 @@ 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.ModifyArg; import org.spongepowered.asm.mixin.injection.Redirect; import java.util.ArrayList; @@ -49,18 +45,6 @@ private void fillRecipesUseDynamicRegistry(MerchantEntity instance) { this.fillRecipesFromContext(); } - @ModifyArg( - method = "readCustomDataFromNbt", - at = @At( - value = "INVOKE", - target = "Lcom/mojang/serialization/Codec;parse(Lcom/mojang/serialization/DynamicOps;Ljava/lang/Object;)Lcom/mojang/serialization/DataResult;", - remap = false - ) - ) - private DynamicOps parseTradeOfferListUseCodec(DynamicOps ops) { - return RegistryOps.of(ops, this.getWorld().getRegistryManager()); - } - @Unique protected void fillRecipes(LootContext context) {} @@ -83,9 +67,17 @@ protected void fillRecipesFromPool(RegistryEntryList.Named entries, int c int actualCount = Math.min(count, entries.size()); ArrayList> pool = Lists.newArrayList(entries); TradeOfferList recipeList = this.getOffers(); - for (int i = 0; i < actualCount; i++) { - TradeOffer tradeOffer = pool.remove(this.random.nextInt(pool.size())).value().createTradeOffer(context); + int addedTrades = 0; + while (addedTrades < actualCount && !pool.isEmpty()) { + TradeOffer tradeOffer = pool.remove(this.random.nextInt(pool.size())) + .value() + .createTradeOffer(context); + if (tradeOffer == null) { + continue; + } + recipeList.add(tradeOffer); + addedTrades++; } } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/MilkableEntitiesExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/MilkableEntitiesExtender.java index 2e8a156b..88196289 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/MilkableEntitiesExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/MilkableEntitiesExtender.java @@ -2,8 +2,8 @@ import net.errorcraft.itematic.item.ItemKeys; import net.minecraft.entity.EntityType; +import net.minecraft.entity.passive.AbstractCowEntity; import net.minecraft.entity.passive.AnimalEntity; -import net.minecraft.entity.passive.CowEntity; import net.minecraft.entity.passive.GoatEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -14,7 +14,10 @@ import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Slice; -@Mixin({ CowEntity.class, GoatEntity.class }) +@Mixin({ + AbstractCowEntity.class, + GoatEntity.class +}) public abstract class MilkableEntitiesExtender extends AnimalEntity { protected MilkableEntitiesExtender(EntityType entityType, World world) { super(entityType, world); diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/MooshroomEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/MooshroomEntityExtender.java index b8393a64..f724f65c 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/MooshroomEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/MooshroomEntityExtender.java @@ -11,7 +11,6 @@ import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.tag.TagKey; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; import org.objectweb.asm.Opcodes; @@ -88,17 +87,6 @@ private boolean isOfForShearsUseRegistryKeyCheck(ItemStack instance, Item item) return instance.itematic$isOf(ItemKeys.SHEARS); } - @Redirect( - method = "interactMob", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isIn(Lnet/minecraft/registry/tag/TagKey;)Z" - ) - ) - private boolean isInForSmallFlowersUseItemComponentCheck(ItemStack instance, TagKey tag) { - return instance.itematic$hasBehavior(ItemComponentTypes.SUSPICIOUS_EFFECT_INGREDIENT); - } - @Redirect( method = "getStewEffectFrom", at = @At( diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/PigEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/PigEntityExtender.java index 3e3990d7..191dbebf 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/PigEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/PigEntityExtender.java @@ -4,7 +4,6 @@ import net.errorcraft.itematic.item.ItematicItemTags; import net.errorcraft.itematic.mixin.entity.mob.MobEntityExtender; import net.minecraft.entity.EntityType; -import net.minecraft.entity.ItemEntity; import net.minecraft.entity.ai.goal.Goal; import net.minecraft.entity.ai.goal.GoalSelector; import net.minecraft.entity.passive.AnimalEntity; @@ -15,7 +14,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.tag.TagKey; -import net.minecraft.server.world.ServerWorld; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; @@ -67,28 +65,6 @@ private ItemStack newItemStackForGoldenSwordUseCreateStack(ItemConvertible item) return this.getWorld().itematic$createStack(ItemKeys.GOLDEN_SWORD); } - @Redirect( - method = "interactMob", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" - ) - ) - private boolean isOfForSaddleUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.SADDLE); - } - - @Redirect( - method = "dropInventory", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/entity/passive/PigEntity;dropItem(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/entity/ItemEntity;" - ) - ) - private ItemEntity dropItemForSaddleUseRegistryKey(PigEntity instance, ServerWorld world, ItemConvertible itemConvertible) { - return this.itematic$dropItem(world, ItemKeys.SADDLE); - } - @Redirect( method = "getControllingPassenger", at = @At( diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/SheepEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/SheepEntityExtender.java index 68cbd003..6b22d180 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/SheepEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/SheepEntityExtender.java @@ -1,37 +1,21 @@ package net.errorcraft.itematic.mixin.entity.passive; import net.errorcraft.itematic.item.ItemKeys; -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.component.components.DyeItemComponent; import net.errorcraft.itematic.mixin.entity.mob.MobEntityExtender; import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.passive.SheepEntity; -import net.minecraft.item.DyeItem; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.recipe.input.CraftingRecipeInput; import net.minecraft.registry.RegistryKey; -import net.minecraft.util.DyeColor; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; 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; - -import java.util.List; -import java.util.Optional; -import java.util.function.Function; -import java.util.function.Predicate; @Mixin(SheepEntity.class) public abstract class SheepEntityExtender extends MobEntityExtender { - @Shadow - public abstract DyeColor getColor(); - protected SheepEntityExtender(EntityType entityType, World world) { super(entityType, world); } @@ -47,71 +31,6 @@ private boolean isOfForShearsUseRegistryKeyCheck(ItemStack instance, Item item) return instance.itematic$isOf(ItemKeys.SHEARS); } - @Redirect( - method = "getChildColor", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/entity/passive/SheepEntity;createChildColorRecipeInput(Lnet/minecraft/util/DyeColor;Lnet/minecraft/util/DyeColor;)Lnet/minecraft/recipe/input/CraftingRecipeInput;" - ) - ) - private CraftingRecipeInput createChildColorRecipeInput(DyeColor firstColor, DyeColor secondColor) { - return CraftingRecipeInput.create( - 2, - 1, - List.of( - this.getWorld().itematic$createStack(firstColor.itematic$itemKey()), - this.getWorld().itematic$createStack(secondColor.itematic$itemKey()) - ) - ); - } - - @Redirect( - method = "getChildColor", - at = @At( - value = "INVOKE", - target = "Ljava/util/Optional;filter(Ljava/util/function/Predicate;)Ljava/util/Optional;" - ) - ) - private Optional instanceOfDyeItemUseItemComponent(Optional instance, Predicate predicate) { - return instance.flatMap(item -> item.itematic$getBehavior(ItemComponentTypes.DYE)); - } - - @Redirect( - method = "getChildColor", - at = @At( - value = "INVOKE", - target = "Ljava/util/Optional;map(Ljava/util/function/Function;)Ljava/util/Optional;", - ordinal = 0 - ), - slice = @Slice( - from = @At( - value = "INVOKE", - target = "Ljava/util/Optional;filter(Ljava/util/function/Predicate;)Ljava/util/Optional;" - ) - ) - ) - private Optional castToDyeItemDoNothing(Optional instance, Function mapper) { - return instance; - } - - @ModifyArg( - method = "getChildColor", - at = @At( - value = "INVOKE", - target = "Ljava/util/Optional;map(Ljava/util/function/Function;)Ljava/util/Optional;", - ordinal = 1 - ), - slice = @Slice( - from = @At( - value = "INVOKE", - target = "Ljava/util/Optional;filter(Ljava/util/function/Predicate;)Ljava/util/Optional;" - ) - ) - ) - private Function getColorUseItemComponent(Function mapper) { - return DyeItemComponent::color; - } - @Override protected @Nullable RegistryKey pickBlockKey() { return ItemKeys.SHEEP_SPAWN_EGG; diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/StriderEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/StriderEntityExtender.java index e78b02b0..ddf57137 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/StriderEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/StriderEntityExtender.java @@ -4,7 +4,6 @@ import net.errorcraft.itematic.item.ItemKeys; import net.errorcraft.itematic.mixin.entity.mob.MobEntityExtender; import net.minecraft.entity.EntityType; -import net.minecraft.entity.ItemEntity; import net.minecraft.entity.passive.AnimalEntity; import net.minecraft.entity.passive.StriderEntity; import net.minecraft.entity.player.PlayerEntity; @@ -12,7 +11,6 @@ import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; import net.minecraft.registry.RegistryKey; -import net.minecraft.server.world.ServerWorld; import net.minecraft.world.ServerWorldAccess; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; @@ -26,28 +24,6 @@ protected StriderEntityExtender(EntityType entityType, W super(entityType, world); } - @Redirect( - method = "interactMob", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" - ) - ) - private boolean isOfForSaddleUseRegistryKey(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.SADDLE); - } - - @Redirect( - method = "dropInventory", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/entity/passive/StriderEntity;dropItem(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/entity/ItemEntity;" - ) - ) - private ItemEntity dropItemForSaddleUseRegistryKey(StriderEntity instance, ServerWorld world, ItemConvertible itemConvertible) { - return this.itematic$dropItem(world, ItemKeys.SADDLE); - } - @Redirect( method = "getControllingPassenger", at = @At( diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/VillagerEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/VillagerEntityExtender.java index 018a4082..b7fda21b 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/VillagerEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/VillagerEntityExtender.java @@ -46,7 +46,7 @@ protected VillagerEntityExtender(EntityType entityType, ) ) private boolean containsForGatherableItemsUseItemTagCheck(ImmutableSet instance, Object o, @Local(argsOnly = true) ItemStack stack) { - TagKey tag = this.getVillagerData().getProfession().itematic$gatherableItemsTag(); + TagKey tag = this.getVillagerData().profession().value().itematic$gatherableItems(); if (tag == null) { return false; } diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/WanderingTraderEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/WanderingTraderEntityExtender.java index 526904bb..f5e769ec 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/passive/WanderingTraderEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/passive/WanderingTraderEntityExtender.java @@ -22,6 +22,7 @@ import net.minecraft.util.Util; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; +import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -32,8 +33,9 @@ public abstract class WanderingTraderEntityExtender extends MerchantEntityExtender { @Unique private static final Object2IntMap> TRADE_TO_AMOUNT = Util.make(new Object2IntArrayMap<>(), trades -> { + trades.put(TradeTags.WANDERING_TRADER_BUYING, 2); + trades.put(TradeTags.WANDERING_TRADER_SPECIAL, 2); trades.put(TradeTags.WANDERING_TRADER_REGULAR, 5); - trades.put(TradeTags.WANDERING_TRADER_SPECIAL, 1); }); public WanderingTraderEntityExtender(EntityType entityType, World world) { @@ -61,7 +63,8 @@ private ItemStack newItemStackForPotionUseCreateStack(Item item, RegistryEntry

entityType, World world) { super(entityType, world); } @@ -58,28 +59,6 @@ private boolean isEquippedForTurtleHelmetUseRegistryKeyCheck(PlayerEntity instan return this.isEquipped(ItemKeys.TURTLE_HELMET); } - @Redirect( - method = "damageShield", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" - ) - ) - private boolean isOfForShieldUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.SHIELD); - } - - @Redirect( - method = "damageShield", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/stat/StatType;getOrCreateStat(Ljava/lang/Object;)Lnet/minecraft/stat/Stat;" - ) - ) - private Stat getOrCreateStatForActiveItemUseRegistryEntry(StatType instance, T key) { - return instance.itematic$getOrCreateStat(this.activeItemStack.getRegistryEntry()); - } - @Redirect( method = "attack", at = @At( @@ -116,7 +95,7 @@ private void neverSetEmptyStack(PlayerEntity instance, Hand hand, ItemStack stac ) ) private double multiplyByAttackSpeedMultiplier(double original) { - return this.inventory.getMainHandStack().itematic$attackSpeedMultiplier() * original; + return this.getMainHandStack().itematic$attackSpeedMultiplier() * original; } @Redirect( @@ -130,6 +109,11 @@ private boolean isOfUseItemComponentCheck(ItemStack instance, Item item) { return instance.itematic$hasBehavior(ItemComponentTypes.ZOOM); } + @Override + public boolean itematic$hasStackInInventory(ItemStack stack) { + return this.getInventory().contains(stack); + } + @Override public ItemStack itematic$getAmmunition(ItemStack stack) { ItemListDataComponent heldAmmunition = stack.getOrDefault(ItematicDataComponentTypes.SHOOTER_HELD_AMMUNITION, ItemListDataComponent.DEFAULT); diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/FireworkRocketEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/FireworkRocketEntityExtender.java index fe38a04e..e98f74b8 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/FireworkRocketEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/FireworkRocketEntityExtender.java @@ -12,8 +12,6 @@ import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.Redirect; -import java.util.function.Supplier; - @Mixin(FireworkRocketEntity.class) public abstract class FireworkRocketEntityExtender extends ProjectileEntity { public FireworkRocketEntityExtender(EntityType entityType, World world) { @@ -31,9 +29,11 @@ private Item getHandPosOffsetUseRegistryEntry(Item item) { return this.getWorld().itematic$getItem(ItemKeys.FIREWORK_ROCKET).value(); } - @Redirect( - method = { "initDataTracker", "readCustomDataFromNbt" }, + method = { + "initDataTracker", + "readCustomDataFromNbt" + }, at = @At( value = "INVOKE", target = "Lnet/minecraft/entity/projectile/FireworkRocketEntity;getDefaultStack()Lnet/minecraft/item/ItemStack;" @@ -42,15 +42,4 @@ private Item getHandPosOffsetUseRegistryEntry(Item item) { private ItemStack newItemStackForFireworkRocketUseCreateStack() { return this.getWorld().itematic$createStack(ItemKeys.FIREWORK_ROCKET); } - - @ModifyArg( - method = "readCustomDataFromNbt", - at = @At( - value = "INVOKE", - target = "Ljava/util/Optional;orElseGet(Ljava/util/function/Supplier;)Ljava/lang/Object;" - ) - ) - private Supplier newItemStackSupplierForFireworkRocketUseCreateStack(Supplier supplier) { - return () -> this.getWorld().itematic$createStack(ItemKeys.FIREWORK_ROCKET); - } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/thrown/EggEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/thrown/EggEntityExtender.java index e874ce67..e5acd137 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/thrown/EggEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/thrown/EggEntityExtender.java @@ -1,20 +1,51 @@ package net.errorcraft.itematic.mixin.entity.projectile.thrown; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import net.errorcraft.itematic.item.ItemKeys; +import net.minecraft.component.ComponentsAccess; +import net.minecraft.component.DataComponentTypes; import net.minecraft.entity.EntityType; +import net.minecraft.entity.passive.ChickenVariant; import net.minecraft.entity.projectile.thrown.EggEntity; import net.minecraft.entity.projectile.thrown.ThrownItemEntity; import net.minecraft.item.Item; import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.entry.LazyRegistryEntryReference; import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; @Mixin(EggEntity.class) public abstract class EggEntityExtender extends ThrownItemEntityExtender { + @Unique + private LazyRegistryEntryReference chickenVariant; + public EggEntityExtender(EntityType entityType, World world) { super(entityType, world); } + @Override + protected void copyComponentsFrom(ComponentsAccess from) { + super.copyComponentsFrom(from); + this.chickenVariant = from.get(DataComponentTypes.CHICKEN_VARIANT); + } + + @ModifyExpressionValue( + method = "onCollision", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/item/ItemStack;get(Lnet/minecraft/component/ComponentType;)Ljava/lang/Object;" + ) + ) + private Object getChickenVariantPossiblyUseDefault(Object original) { + if (original != null) { + return original; + } + + return this.chickenVariant; + } + @Override protected RegistryKey getDefaultItemKey() { return ItemKeys.EGG; diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/thrown/LingeringPotionEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/thrown/LingeringPotionEntityExtender.java new file mode 100644 index 00000000..23b4a2cf --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/thrown/LingeringPotionEntityExtender.java @@ -0,0 +1,22 @@ +package net.errorcraft.itematic.mixin.entity.projectile.thrown; + +import net.errorcraft.itematic.item.ItemKeys; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.projectile.thrown.LingeringPotionEntity; +import net.minecraft.entity.projectile.thrown.ThrownEntity; +import net.minecraft.item.Item; +import net.minecraft.registry.RegistryKey; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(LingeringPotionEntity.class) +public abstract class LingeringPotionEntityExtender extends ThrownItemEntityExtender { + protected LingeringPotionEntityExtender(EntityType entityType, World world) { + super(entityType, world); + } + + @Override + protected RegistryKey getDefaultItemKey() { + return ItemKeys.LINGERING_POTION; + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/thrown/PotionEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/thrown/PotionEntityExtender.java deleted file mode 100644 index 8aef6fb3..00000000 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/thrown/PotionEntityExtender.java +++ /dev/null @@ -1,36 +0,0 @@ -package net.errorcraft.itematic.mixin.entity.projectile.thrown; - -import net.errorcraft.itematic.item.ItemKeys; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.projectile.thrown.PotionEntity; -import net.minecraft.entity.projectile.thrown.ThrownItemEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.registry.RegistryKey; -import net.minecraft.world.World; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(PotionEntity.class) -public abstract class PotionEntityExtender extends ThrownItemEntityExtender { - public PotionEntityExtender(EntityType entityType, World world) { - super(entityType, world); - } - - @Redirect( - method = "isLingering", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" - ) - ) - private boolean isOfForLingeringPotionUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.LINGERING_POTION); - } - - @Override - protected RegistryKey getDefaultItemKey() { - return ItemKeys.SPLASH_POTION; - } -} diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/thrown/SnowballEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/thrown/SnowballEntityExtender.java index 472fda45..be417e59 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/thrown/SnowballEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/thrown/SnowballEntityExtender.java @@ -5,12 +5,9 @@ import net.minecraft.entity.projectile.thrown.SnowballEntity; import net.minecraft.entity.projectile.thrown.ThrownItemEntity; import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; import net.minecraft.registry.RegistryKey; import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(SnowballEntity.class) public abstract class SnowballEntityExtender extends ThrownItemEntityExtender { @@ -18,17 +15,6 @@ public SnowballEntityExtender(EntityType entityType, super(entityType, world); } - @Redirect( - method = "getParticleParameters", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" - ) - ) - private boolean isOfForDefaultItemUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(this.getDefaultItemKey()); - } - @Override protected RegistryKey getDefaultItemKey() { return ItemKeys.SNOWBALL; diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/thrown/SplashPotionEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/thrown/SplashPotionEntityExtender.java new file mode 100644 index 00000000..f3eb18ad --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/projectile/thrown/SplashPotionEntityExtender.java @@ -0,0 +1,22 @@ +package net.errorcraft.itematic.mixin.entity.projectile.thrown; + +import net.errorcraft.itematic.item.ItemKeys; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.projectile.thrown.SplashPotionEntity; +import net.minecraft.entity.projectile.thrown.ThrownEntity; +import net.minecraft.item.Item; +import net.minecraft.registry.RegistryKey; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(SplashPotionEntity.class) +public abstract class SplashPotionEntityExtender extends ThrownItemEntityExtender { + protected SplashPotionEntityExtender(EntityType entityType, World world) { + super(entityType, world); + } + + @Override + protected RegistryKey getDefaultItemKey() { + return ItemKeys.SPLASH_POTION; + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/item/AnimalArmorItemExtender.java b/src/main/java/net/errorcraft/itematic/mixin/item/AnimalArmorItemExtender.java deleted file mode 100644 index 9fe6b8a8..00000000 --- a/src/main/java/net/errorcraft/itematic/mixin/item/AnimalArmorItemExtender.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.errorcraft.itematic.mixin.item; - -import net.errorcraft.itematic.access.item.AnimalArmorItemTypeAccess; -import net.minecraft.entity.EntityType; -import net.minecraft.item.AnimalArmorItem; -import net.minecraft.registry.Registries; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.registry.entry.RegistryEntryList; -import net.minecraft.sound.SoundEvent; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -public class AnimalArmorItemExtender { - @Mixin(AnimalArmorItem.Type.class) - public static class TypeExtender implements AnimalArmorItemTypeAccess { - @Shadow - @Final - SoundEvent breakSound; - - @Shadow - @Final - RegistryEntryList> allowedEntities; - - @Override - public RegistryEntry itematic$breakSound() { - return Registries.SOUND_EVENT.getEntry(this.breakSound); - } - - @Override - public RegistryEntryList> itematic$allowedEntities() { - return this.allowedEntities; - } - } -} diff --git a/src/main/java/net/errorcraft/itematic/mixin/item/BoneMealItemExtender.java b/src/main/java/net/errorcraft/itematic/mixin/item/BoneMealItemExtender.java new file mode 100644 index 00000000..d153a22c --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/item/BoneMealItemExtender.java @@ -0,0 +1,22 @@ +package net.errorcraft.itematic.mixin.item; + +import net.minecraft.item.BoneMealItem; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(BoneMealItem.class) +public class BoneMealItemExtender { + @Redirect( + method = { + "useOnFertilizable", + "useOnGround" + }, + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/item/ItemStack;decrement(I)V" + ) + ) + private static void doNotDecrementItemStack(ItemStack instance, int amount) {} +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/item/DebugStickItemAccessor.java b/src/main/java/net/errorcraft/itematic/mixin/item/DebugStickItemAccessor.java index 09934c6e..5555bf0e 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/item/DebugStickItemAccessor.java +++ b/src/main/java/net/errorcraft/itematic/mixin/item/DebugStickItemAccessor.java @@ -12,5 +12,5 @@ @Mixin(DebugStickItem.class) public interface DebugStickItemAccessor { @Invoker("use") - boolean callUse(PlayerEntity player, BlockState state, WorldAccess world, BlockPos pos, boolean update, ItemStack stack); + boolean itematic$use(PlayerEntity player, BlockState state, WorldAccess world, BlockPos pos, boolean update, ItemStack stack); } diff --git a/src/main/java/net/errorcraft/itematic/mixin/item/FilledMapItemAccessor.java b/src/main/java/net/errorcraft/itematic/mixin/item/FilledMapItemAccessor.java index 21919f0c..3ff31434 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/item/FilledMapItemAccessor.java +++ b/src/main/java/net/errorcraft/itematic/mixin/item/FilledMapItemAccessor.java @@ -3,6 +3,7 @@ import net.minecraft.component.type.MapIdComponent; import net.minecraft.item.FilledMapItem; import net.minecraft.registry.RegistryKey; +import net.minecraft.server.world.ServerWorld; import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; @@ -10,7 +11,7 @@ @Mixin(FilledMapItem.class) public interface FilledMapItemAccessor { @Invoker("allocateMapId") - static MapIdComponent allocateMapId(World world, int x, int z, int scale, boolean showIcons, boolean unlimitedTracking, RegistryKey dimension) { + static MapIdComponent allocateMapId(ServerWorld world, int x, int z, int scale, boolean showIcons, boolean unlimitedTracking, RegistryKey dimension) { throw new AssertionError(); } } 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 be509d68..fb0aed1d 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/item/ItemExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/item/ItemExtender.java @@ -5,7 +5,6 @@ import net.errorcraft.itematic.access.item.ItemAccess; import net.errorcraft.itematic.component.ItematicDataComponentTypes; import net.errorcraft.itematic.component.type.UseDurationDataComponent; -import net.errorcraft.itematic.inventory.StackReferenceUtil; import net.errorcraft.itematic.item.ItemDisplay; import net.errorcraft.itematic.item.ItemKeys; import net.errorcraft.itematic.item.ItemResult; @@ -15,12 +14,13 @@ import net.errorcraft.itematic.item.component.ItemComponentType; import net.errorcraft.itematic.item.component.ItemComponentTypes; import net.errorcraft.itematic.item.component.components.BlockItemComponent; -import net.errorcraft.itematic.item.component.components.DamageableItemComponent; +import net.errorcraft.itematic.item.data.InventoryTickListener; import net.errorcraft.itematic.item.event.ItemEvent; import net.errorcraft.itematic.item.event.ItemEventMap; import net.errorcraft.itematic.item.event.ItemEvents; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; import net.fabricmc.fabric.api.item.v1.EnchantingContext; import net.fabricmc.fabric.api.item.v1.FabricItem; import net.minecraft.block.BlockState; @@ -44,14 +44,13 @@ import net.minecraft.item.consume.UseAction; import net.minecraft.item.tooltip.TooltipData; import net.minecraft.item.tooltip.TooltipType; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.registry.DefaultedRegistry; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.registry.entry.RegistryFixedCodec; import net.minecraft.screen.slot.Slot; import net.minecraft.server.world.ServerWorld; -import net.minecraft.sound.SoundEvent; -import net.minecraft.sound.SoundEvents; import net.minecraft.text.Text; import net.minecraft.util.*; import net.minecraft.util.math.BlockPos; @@ -64,8 +63,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import java.util.List; import java.util.Optional; +import java.util.function.Consumer; @Mixin(Item.class) public abstract class ItemExtender implements ItemAccess, FabricItem { @@ -148,16 +147,20 @@ private void checkStackableItemComponent(CallbackInfoReturnable info) { @Overwrite public ActionResult use(World world, PlayerEntity user, Hand hand) { ItemStack stack = user.getStackInHand(hand); - StackReference stackReference = StackReferenceUtil.of(stack); + ItemStackExchanger stackExchanger = ItemStackExchanger.forEntity(user, stack); ItemResult result = ItemResult.PASS; for (ItemComponent component : this.itemComponents) { - ItemResult newResult = component.use(world, user, hand, stack, stackReference::set); + ItemResult newResult = component.use(world, user, hand, stack, stackExchanger); result = result.max(newResult); } if (world instanceof ServerWorld serverWorld) { - ActionContext context = ActionContext.builder(serverWorld, stack, stackReference::set, hand) - .entityPosition(ActionContextParameter.THIS, user) + ActionContext context = ActionContext.builder(serverWorld) + .stackExchanger(stackExchanger) + .add(LootContextParameters.THIS_ENTITY, user) + .add(LootContextParameters.ORIGIN, user.getPos()) + .add(LootContextParameters.TOOL, stack) + .add(ItematicContextParameters.HAND, hand) .build(); if (this.itematic$invokeEvent(ItemEvents.USE, context)) { result = result.max(ItemResult.CONSUME); @@ -166,7 +169,7 @@ public ActionResult use(World world, PlayerEntity user, Hand hand) { ActionResult trueResult = result.toActionResult(); if (trueResult instanceof ActionResult.Success success) { - return success.withNewHandStack(stackReference.get()); + return success.withNewHandStack(stackExchanger.result()); } return trueResult; @@ -179,28 +182,32 @@ public ActionResult use(World world, PlayerEntity user, Hand hand) { @Overwrite public ActionResult useOnBlock(ItemUsageContext context) { ItemStack stack = context.getStack(); - StackReference stackReference = StackReferenceUtil.of(stack); + ItemStackExchanger stackExchanger = context.itematic$stackExchanger(); ItemResult result = ItemResult.PASS; for (ItemComponent component : this.itemComponents) { - ItemResult newResult = component.useOnBlock(context, stackReference::set); + ItemResult newResult = component.useOnBlock(context, stackExchanger); result = result.max(newResult); } if (context.getWorld() instanceof ServerWorld serverWorld) { - ActionContext actionContext = ActionContext.builder(serverWorld, stack, stackReference::set, context.getHand()) - .entityPosition(ActionContextParameter.THIS, context.getPlayer()) - .position(ActionContextParameter.TARGET, context.getBlockPos()) - .side(context.getSide()) + ActionContext actionContext = ActionContext.builder(serverWorld) + .stackExchanger(stackExchanger) + .addOptional(LootContextParameters.THIS_ENTITY, context.getPlayer()) + .addOptional(LootContextParameters.ORIGIN, context.getPlayer(), Entity::getPos) + .add(ItematicContextParameters.INTERACTED_POSITION, context.getBlockPos().toCenterPos()) + .add(LootContextParameters.TOOL, stack) + .add(ItematicContextParameters.HAND, context.getHand()) + .add(ItematicContextParameters.SIDE, context.getSide()) .build(); if (this.itematic$invokeEvent(ItemEvents.USE_ON_BLOCK, actionContext)) { result = result.max(ItemResult.CONSUME); } } - tryUpdateItemStack(context.getPlayer(), context.getHand(), stack, stackReference); + tryUpdateItemStack(context.getPlayer(), context.getHand(), stack, stackExchanger); ActionResult trueResult = result.toActionResult(); if (trueResult instanceof ActionResult.Success success) { - trueResult = success.withNewHandStack(stackReference.get()); + trueResult = success.withNewHandStack(stackExchanger.result()); } return trueResult; @@ -212,27 +219,32 @@ public ActionResult useOnBlock(ItemUsageContext context) { */ @Overwrite public ActionResult useOnEntity(ItemStack stack, PlayerEntity user, LivingEntity entity, Hand hand) { - StackReference stackReference = StackReferenceUtil.of(stack); + ItemStackExchanger stackExchanger = ItemStackExchanger.forEntity(user, stack); ItemResult result = ItemResult.PASS; for (ItemComponent component : this.itemComponents) { - ItemResult newResult = component.useOnEntity(user, entity, hand, stack, stackReference::set); + ItemResult newResult = component.useOnEntity(user, entity, hand, stack, stackExchanger); result = result.max(newResult); } if (user.getWorld() instanceof ServerWorld serverWorld) { - ActionContext context = ActionContext.builder(serverWorld, stack, stackReference::set, hand) - .entityPosition(ActionContextParameter.THIS, user) - .entityPosition(ActionContextParameter.TARGET, entity) + ActionContext context = ActionContext.builder(serverWorld) + .stackExchanger(stackExchanger) + .add(LootContextParameters.THIS_ENTITY, user) + .add(LootContextParameters.ORIGIN, user.getPos()) + .add(ItematicContextParameters.TARGET_ENTITY, entity) + .add(ItematicContextParameters.INTERACTED_POSITION, entity.getPos()) + .add(LootContextParameters.TOOL, stack) + .add(ItematicContextParameters.HAND, hand) .build(); if (this.itematic$invokeEvent(ItemEvents.USE_ON_ENTITY, context)) { result = result.max(ItemResult.CONSUME); } } - tryUpdateItemStack(user, hand, stack, stackReference); + tryUpdateItemStack(user, hand, stack, stackExchanger); ActionResult trueResult = result.toActionResult(); if (trueResult instanceof ActionResult.Success success) { - trueResult = success.withNewHandStack(stackReference.get()); + trueResult = success.withNewHandStack(stackExchanger.result()); } return trueResult; @@ -243,23 +255,26 @@ public ActionResult useOnEntity(ItemStack stack, PlayerEntity user, LivingEntity * @reason Uses the ItemComponent implementation for data-driven items. */ @Overwrite - public boolean postHit(ItemStack stack, LivingEntity target, LivingEntity attacker) { - boolean result = false; - StackReference stackReference = StackReferenceUtil.of(stack); + public void postHit(ItemStack stack, LivingEntity target, LivingEntity attacker) { + ItemStackExchanger stackExchanger = ItemStackExchanger.forEntity(attacker, stack); for (ItemComponent component : this.itemComponents) { - result |= component.postHit(stack, target, attacker, stackReference::set); + component.postHit(stack, target, attacker, stackExchanger); } if (attacker.getWorld() instanceof ServerWorld serverWorld) { - ActionContext context = ActionContext.builder(serverWorld, stack, stackReference::set, EquipmentSlot.MAINHAND) - .entityPosition(ActionContextParameter.THIS, attacker) - .entityPosition(ActionContextParameter.TARGET, target) + ActionContext context = ActionContext.builder(serverWorld) + .stackExchanger(stackExchanger) + .add(LootContextParameters.THIS_ENTITY, attacker) + .add(LootContextParameters.ORIGIN, attacker.getPos()) + .add(ItematicContextParameters.TARGET_ENTITY, target) + .add(ItematicContextParameters.INTERACTED_POSITION, target.getPos()) + .add(LootContextParameters.TOOL, stack) + .add(ItematicContextParameters.EQUIPMENT_SLOT, EquipmentSlot.MAINHAND) .build(); this.itematic$invokeEvent(ItemEvents.HIT_ENTITY, context); } - tryUpdateItemStack(attacker, Hand.MAIN_HAND, stack, stackReference); - return result; + tryUpdateItemStack(attacker, Hand.MAIN_HAND, stack, stackExchanger); } /** @@ -269,20 +284,24 @@ public boolean postHit(ItemStack stack, LivingEntity target, LivingEntity attack @Overwrite public boolean postMine(ItemStack stack, World world, BlockState state, BlockPos pos, LivingEntity miner) { boolean result = false; - StackReference stackReference = StackReferenceUtil.of(stack); + ItemStackExchanger stackExchanger = ItemStackExchanger.forEntity(miner, stack); for (ItemComponent component : this.itemComponents) { - result |= component.postMine(stack, world, state, pos, miner, stackReference::set); + result |= component.postMine(stack, world, state, pos, miner, stackExchanger); } if (world instanceof ServerWorld serverWorld) { - ActionContext context = ActionContext.builder(serverWorld, stack, stackReference::set, EquipmentSlot.MAINHAND) - .entityPosition(ActionContextParameter.THIS, miner) - .position(ActionContextParameter.TARGET, pos.toCenterPos()) + ActionContext context = ActionContext.builder(serverWorld) + .stackExchanger(stackExchanger) + .add(LootContextParameters.THIS_ENTITY, miner) + .add(LootContextParameters.ORIGIN, miner.getPos()) + .add(ItematicContextParameters.INTERACTED_POSITION, pos.toCenterPos()) + .add(LootContextParameters.TOOL, stack) + .add(ItematicContextParameters.EQUIPMENT_SLOT, EquipmentSlot.MAINHAND) .build(); this.itematic$invokeEvent(ItemEvents.BROKE_BLOCK, context); } - tryUpdateItemStack(miner, Hand.MAIN_HAND, stack, stackReference); + tryUpdateItemStack(miner, Hand.MAIN_HAND, stack, stackExchanger); return result; } @@ -317,19 +336,23 @@ private void onItemEntityDestroyedUseItemComponent(ItemEntity entity, CallbackIn public boolean onStoppedUsing(ItemStack stack, World world, LivingEntity user, int remainingUseTicks) { boolean result = false; int usedTicks = user.itematic$itemUsedTicks(); - StackReference stackReference = StackReferenceUtil.of(stack); + ItemStackExchanger stackExchanger = ItemStackExchanger.forEntity(user, stack); for (ItemComponent component : this.itemComponents) { - result |= component.stopUsing(stack, world, user, usedTicks, remainingUseTicks, stackReference::set); + result |= component.stopUsing(stack, world, user, usedTicks, remainingUseTicks, stackExchanger); } if (world instanceof ServerWorld serverWorld) { - ActionContext context = ActionContext.builder(serverWorld, stack, stackReference::set, user.getActiveHand()) - .entityPosition(ActionContextParameter.THIS, user) + ActionContext context = ActionContext.builder(serverWorld) + .stackExchanger(stackExchanger) + .add(LootContextParameters.THIS_ENTITY, user) + .add(LootContextParameters.ORIGIN, user.getPos()) + .add(LootContextParameters.TOOL, stack) + .add(ItematicContextParameters.HAND, user.getActiveHand()) .build(); this.itematic$invokeEvent(ItemEvents.STOPPED_USING, context); } - tryUpdateItemStack(user, Hand.MAIN_HAND, stack, stackReference); + tryUpdateItemStack(user, Hand.MAIN_HAND, stack, stackExchanger); return result; } @@ -340,32 +363,34 @@ public boolean onStoppedUsing(ItemStack stack, World world, LivingEntity user, i ) public void finishUsingUseItemComponent(ItemStack stack, World world, LivingEntity user, CallbackInfoReturnable info) { int usedTicks = user.itematic$itemUsedTicks(); - StackReference stackReference = StackReferenceUtil.of(stack); + ItemStackExchanger stackExchanger = ItemStackExchanger.forEntity(user, stack); for (ItemComponent component : this.itemComponents) { - component.finishUsing(world, user, stack, usedTicks, stackReference::set); + component.finishUsing(world, user, stack, usedTicks, stackExchanger); } if (world instanceof ServerWorld serverWorld) { - ActionContext context = ActionContext.builder(serverWorld, stack, stackReference::set, user.getActiveHand()) - .entityPosition(ActionContextParameter.THIS, user) + ActionContext context = ActionContext.builder(serverWorld) + .stackExchanger(stackExchanger) + .add(LootContextParameters.THIS_ENTITY, user) + .add(LootContextParameters.ORIGIN, user.getPos()) + .add(LootContextParameters.TOOL, stack) + .add(ItematicContextParameters.HAND, user.getActiveHand()) .build(); this.itematic$invokeEvent(ItemEvents.FINISHED_USING, context); } this.itematic$getBehavior(ItemComponentTypes.CONSUMABLE) - .ifPresent(c -> c.consume(user, stack, stackReference::set, world, user.getActiveHand())); - info.setReturnValue(stackReference.get()); + .ifPresent(c -> c.consume(user, stack, stackExchanger, world, user.getActiveHand())); + info.setReturnValue(stackExchanger.result()); } - /** - * @author ErrorCraft - * @reason Uses the ItemComponent implementation for data-driven items. - */ - @Overwrite - public void inventoryTick(ItemStack stack, World world, Entity entity, int slot, boolean selected) { - for (ItemComponent component : this.itemComponents) { - component.inventoryTick(stack, world, entity, slot, selected); - } + @Inject( + method = "inventoryTick", + at = @At("HEAD") + ) + public void callInventoryTickListeners(ItemStack stack, ServerWorld world, Entity entity, EquipmentSlot slot, CallbackInfo info) { + stack.streamAll(InventoryTickListener.class) + .forEach(inventoryTickListener -> inventoryTickListener.itematic$onInventoryTick(world, stack, entity, slot)); } /** @@ -388,9 +413,12 @@ public boolean onStackClicked(ItemStack stack, Slot slot, ClickType clickType, P @Overwrite public boolean onClicked(ItemStack stack, ItemStack otherStack, Slot slot, ClickType clickType, PlayerEntity player, StackReference cursorStackReference) { boolean result = false; + ItemStackExchanger stackExchanger = ItemStackExchanger.forEntity(player, otherStack); for (ItemComponent component : this.itemComponents) { - result |= component.clickedOnWithStack(stack, otherStack, slot, clickType, player, cursorStackReference::set); + result |= component.clickedOnWithStack(stack, otherStack, slot, clickType, player, stackExchanger); } + + cursorStackReference.set(stackExchanger.result()); return result; } @@ -404,28 +432,15 @@ public void onCraft(ItemStack stack, World world, CallbackInfo info) { } } - /** - * @author ErrorCraft - * @reason Uses the ItemComponent implementation for data-driven items. - */ - @Overwrite - public void appendTooltip(ItemStack stack, Item.TooltipContext context, List tooltip, TooltipType type) { - this.display.tooltip() - .ifPresent(tooltip::addAll); - for (ItemComponent component : this.itemComponents) { - component.appendTooltip(stack, context, tooltip, type); - } - } - @Inject( method = "canMine", at = @At("HEAD"), cancellable = true ) - private void useDebugStickItemComponent(BlockState state, World world, BlockPos pos, PlayerEntity miner, CallbackInfoReturnable info) { + private void useDebugStickItemComponent(ItemStack stack, BlockState state, World world, BlockPos pos, LivingEntity user, CallbackInfoReturnable info) { this.itematic$getBehavior(ItemComponentTypes.DEBUG_STICK) - .ifPresent(c -> { - c.use(miner, state, world, pos); + .ifPresent(debugStick -> { + debugStick.use(user, state, world, pos, stack); info.setReturnValue(false); }); } @@ -452,17 +467,6 @@ private boolean isCorrectForDropsPassItemStack(ToolComponent instance, BlockStat return instance.itematic$isCorrectForDrops(stack, state); } - @Inject( - method = "hasGlint", - at = @At("HEAD"), - cancellable = true - ) - public void checkPointableItemComponent(ItemStack stack, CallbackInfoReturnable info) { - if (this.itematic$hasBehavior(ItemComponentTypes.POINTABLE) && stack.contains(DataComponentTypes.LODESTONE_TRACKER)) { - info.setReturnValue(true); - } - } - /** * @author ErrorCraft * @reason Uses the ItemComponent implementation for data-driven items. @@ -474,18 +478,6 @@ public boolean canBeNested() { .orElse(true); } - /** - * @author ErrorCraft - * @reason Uses the ItemComponent implementation for data-driven items. - */ - @Overwrite - public SoundEvent getBreakSound() { - return this.itematic$getBehavior(ItemComponentTypes.DAMAGEABLE) - .flatMap(DamageableItemComponent::breakSound) - .map(RegistryEntry::value) - .orElse(SoundEvents.ENTITY_ITEM_BREAK); - } - @Inject( method = "getUseAction", at = @At("HEAD"), @@ -534,10 +526,8 @@ public final String getTranslationKey() { cancellable = true ) public void getName(ItemStack stack, CallbackInfoReturnable info) { - this.itematic$getBehavior(ItemComponentTypes.POINTABLE) - .flatMap(c -> c.lodestoneTranslationKey(stack)) - .or(() -> this.itematic$getBehavior(ItemComponentTypes.POTION_HOLDER) - .map(c -> c.translationKey(stack, this.display.translationKey()))) + this.itematic$getBehavior(ItemComponentTypes.POTION_HOLDER) + .map(c -> c.translationKey(stack, this.display.translationKey())) .or(() -> this.itematic$getBehavior(ItemComponentTypes.BANNER_PATTERN_HOLDER) .flatMap(c -> c.translationKey(stack, this.display.translationKey()))) .map(Text::translatable) @@ -645,6 +635,14 @@ private void checkTextHolderItemComponent(ItemStack stack, CallbackInfoReturnabl return this.events.hasListener(event); } + @Override + public void itematic$addTooltip(ItemStack stack, Item.TooltipContext context, Consumer builder, TooltipType type) { + this.display.tooltip().ifPresent(tooltip -> tooltip.forEach(builder)); + for (ItemComponent component : this.itemComponents) { + component.appendTooltip(stack, context, builder, type); + } + } + @Override public boolean itematic$mayStartUsing(World world, PlayerEntity user, Hand hand, ItemStack stack) { return this.itematic$getBehavior(ItemComponentTypes.FOOD) @@ -658,12 +656,12 @@ public boolean canBeEnchantedWith(ItemStack stack, RegistryEntry en } @Unique - private static void tryUpdateItemStack(LivingEntity target, Hand hand, ItemStack stack, StackReference stackReference) { + private static void tryUpdateItemStack(LivingEntity target, Hand hand, ItemStack stack, ItemStackExchanger stackExchanger) { if (target == null) { return; } - ItemStack newStack = stackReference.get(); + ItemStack newStack = stackExchanger.result(); if (stack == newStack) { return; } 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 c803b2d4..b298d4a6 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/item/ItemStackExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/item/ItemStackExtender.java @@ -2,14 +2,12 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.ModifyReturnValue; -import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import net.errorcraft.itematic.access.item.ItemStackAccess; import net.errorcraft.itematic.component.ItematicDataComponentTypes; import net.errorcraft.itematic.item.ItemKeys; import net.errorcraft.itematic.item.ItemUtil; -import net.errorcraft.itematic.item.ItematicItemTags; import net.errorcraft.itematic.item.component.ItemComponent; import net.errorcraft.itematic.item.component.ItemComponentType; import net.errorcraft.itematic.item.component.ItemComponentTypes; @@ -18,17 +16,16 @@ import net.errorcraft.itematic.item.event.ItemEvents; import net.errorcraft.itematic.item.shooter.method.ShooterMethodTypes; import net.errorcraft.itematic.util.Util; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; import net.fabricmc.fabric.api.item.v1.EnchantingContext; import net.fabricmc.fabric.api.item.v1.FabricItemStack; -import net.minecraft.block.BlockState; -import net.minecraft.component.ComponentChanges; -import net.minecraft.component.ComponentHolder; -import net.minecraft.component.ComponentMap; -import net.minecraft.component.MergedComponentMap; +import net.minecraft.component.*; +import net.minecraft.component.type.TooltipDisplayComponent; +import net.minecraft.component.type.WeaponComponent; import net.minecraft.enchantment.Enchantment; import net.minecraft.entity.Entity; +import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.StackReference; @@ -36,6 +33,7 @@ import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; import net.minecraft.item.tooltip.TooltipType; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.registry.DefaultedRegistry; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.entry.RegistryEntry; @@ -48,7 +46,6 @@ import net.minecraft.stat.StatType; import net.minecraft.text.Text; import net.minecraft.util.*; -import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import org.jetbrains.annotations.NotNull; @@ -64,7 +61,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.HashSet; -import java.util.List; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; @@ -92,6 +88,9 @@ public abstract class ItemStackExtender implements ComponentHolder, ItemStackAcc @Shadow public abstract boolean isEmpty(); + @Shadow + public abstract ItemStack split(int amount); + @Shadow public abstract void damage(int amount, ServerWorld world, @Nullable ServerPlayerEntity player, Consumer breakCallback); @@ -107,6 +106,9 @@ public abstract class ItemStackExtender implements ComponentHolder, ItemStackAcc @Shadow public abstract int getMaxCount(); + @Shadow + public abstract ItemStack copyWithCount(int count); + @Shadow public abstract int getCount(); @@ -235,12 +237,23 @@ public void checkEmptyStackActionResult(CallbackInfoReturnable inf at = @At("HEAD"), cancellable = true ) - public void checkEmptyStackBoolean(CallbackInfoReturnable info) { + public void checkEmptyStackBooleanFalse(CallbackInfoReturnable info) { if (this.isEmpty()) { info.setReturnValue(false); } } + @Inject( + method = "canMine", + at = @At("HEAD"), + cancellable = true + ) + public void checkEmptyStackBooleanTrue(CallbackInfoReturnable info) { + if (this.isEmpty()) { + info.setReturnValue(true); + } + } + @Inject( method = { "usageTick", @@ -290,7 +303,7 @@ private Item getItemGetItemFieldUseRegistryEntryToPreventNullPointerException(It } @Redirect( - method = "copy", + method = "copy()Lnet/minecraft/item/ItemStack;", at = @At( value = "NEW", target = "(Lnet/minecraft/item/ItemConvertible;ILnet/minecraft/component/MergedComponentMap;)Lnet/minecraft/item/ItemStack;" @@ -503,19 +516,21 @@ private void checkEmptyStack(CallbackInfoReturnable info) { } } - @WrapWithCondition( - method = "getTooltip", + @Inject( + method = "appendTooltip", at = @At( value = "INVOKE", - target = "Lnet/minecraft/item/Item;appendTooltip(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/Item$TooltipContext;Ljava/util/List;Lnet/minecraft/item/tooltip/TooltipType;)V" + target = "Lnet/minecraft/item/Item;appendTooltip(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/Item$TooltipContext;Lnet/minecraft/component/type/TooltipDisplayComponent;Ljava/util/function/Consumer;Lnet/minecraft/item/tooltip/TooltipType;)V" ) ) - private boolean appendTooltipCheckRegistryEntry(Item instance, ItemStack stack, Item.TooltipContext context, List tooltip, TooltipType type) { - return this.entry != null; + private void addTooltipFromItem(Item.TooltipContext context, TooltipDisplayComponent displayComponent, PlayerEntity player, TooltipType type, Consumer textConsumer, CallbackInfo info) { + if (this.entry != null) { + this.entry.value().itematic$addTooltip((ItemStack) (Object) this, context, textConsumer, type); + } } @Redirect( - method = "getTooltip", + method = "appendTooltip", at = @At( value = "INVOKE", target = "Lnet/minecraft/registry/DefaultedRegistry;getId(Ljava/lang/Object;)Lnet/minecraft/util/Identifier;" @@ -548,15 +563,15 @@ private void onClickedUseRegistryEntryNullCheck(ItemStack stack, Slot slot, Clic } } - @Inject( - method = "postMine", - at = @At("HEAD"), - cancellable = true + @Redirect( + method = "postDamageEntity", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/item/ItemStack;get(Lnet/minecraft/component/ComponentType;)Ljava/lang/Object;" + ) ) - private void postMineUseRegistryEntryNullCheck(World world, BlockState state, BlockPos pos, PlayerEntity miner, CallbackInfo info) { - if (this.isEmpty()) { - info.cancel(); - } + private Object getWeaponDataComponentReturnNull(ItemStack instance, ComponentType type) { + return null; } @ModifyReturnValue( @@ -565,7 +580,7 @@ private void postMineUseRegistryEntryNullCheck(World world, BlockState state, Bl ) private int limitDamageApplied(int original) { return this.itematic$getBehavior(ItemComponentTypes.DAMAGEABLE) - .map(c -> Math.min(c.maximumDamage((ItemStack)(Object) this) - this.getDamage(), original)) + .map(c -> Math.min(c.maximumDamage((ItemStack) (Object) this) - this.getDamage(), original)) .orElse(original); } @@ -638,7 +653,7 @@ private ActionResult.Success doNotModifyResultingItemStackIfNotUseable(ActionRes ) private void checkForUseableBehavior(LivingEntity user, ItemStack stack, CallbackInfoReturnable info) { if (!this.itematic$hasBehavior(ItemComponentTypes.USEABLE)) { - info.setReturnValue((ItemStack)(Object) this); + info.setReturnValue((ItemStack) (Object) this); } } @@ -665,7 +680,7 @@ private static void checkEmptyStack(ItemStack stack, CallbackInfoReturnable enchantment, EnchantingContext context) { // Use the original implementation again - return enchantment.value().isAcceptableItem((ItemStack)(Object) this); + return enchantment.value().isAcceptableItem((ItemStack) (Object) this); } @Override @@ -698,6 +713,15 @@ public boolean canBeEnchantedWith(RegistryEntry enchantment, Enchan return actualAmount; } + @Override + public ItemStack itematic$copyOrSplit(@Nullable LivingEntity holder, int amount) { + if (holder != null && holder.isInCreativeMode()) { + return this.copyWithCount(amount); + } + + return this.split(amount); + } + @Override public ItemStack itematic$copyWithItem(RegistryEntry item) { return this.itematic$copyComponentsToNewStack(item, this.count); @@ -724,13 +748,14 @@ public boolean canBeEnchantedWith(RegistryEntry enchantment, Enchan @Override public void itematic$damage(int amount, ActionContext context) { - if (context.player(ActionContextParameter.THIS).map(PlayerEntity::isCreative).orElse(false)) { - return; - } - this.context = context; - Entity entity = context.entity(ActionContextParameter.THIS).orElse(null); - this.damage(amount, context.world(), entity instanceof ServerPlayerEntity player ? player : null, item -> this.onItemBroken(item, entity, context)); + Entity entity = context.get(LootContextParameters.THIS_ENTITY); + this.damage( + amount, + context.world(), + entity instanceof ServerPlayerEntity player ? player : null, + item -> this.onItemBroken(item, entity, context) + ); this.context = null; } @@ -750,7 +775,7 @@ public boolean canBeEnchantedWith(RegistryEntry enchantment, Enchan @Override public boolean itematic$invokeEvent(ItemEvent event, ActionContext context) { - if (this.entry == null) { + if (this.isEmpty()) { return false; } @@ -773,19 +798,6 @@ public boolean canBeEnchantedWith(RegistryEntry enchantment, Enchan return this.entry.value().itematic$hasEventListener(event); } - @Override - public boolean itematic$canMine(BlockState state, World world, BlockPos pos, PlayerEntity miner) { - if (this.entry == null) { - return true; - } - - if (miner.isCreative() && this.isIn(ItematicItemTags.PREVENTS_MINING_IN_CREATIVE)) { - return false; - } - - return this.entry.value().canMine(state, world, pos, miner); - } - @Override public boolean itematic$mayStartUsing(World world, PlayerEntity user, Hand hand, ItemStack stack) { if (this.entry == null) { @@ -809,7 +821,7 @@ private void setFields(RegistryEntry entry) { this.entry = entry; if (entry.hasKeyAndValue()) { this.components = new MergedComponentMap(entry.value().getComponents()); - entry.value().postProcessComponents((ItemStack)(Object) this); + entry.value().postProcessComponents((ItemStack) (Object) this); } else { this.components = new MergedComponentMap(ComponentMap.EMPTY); } @@ -820,20 +832,19 @@ private void setFields(RegistryEntry entry, ComponentChanges changes) { this.entry = entry; if (entry.hasKeyAndValue()) { this.components = MergedComponentMap.create(entry.value().getComponents(), changes); - entry.value().postProcessComponents((ItemStack)(Object) this); + entry.value().postProcessComponents((ItemStack) (Object) this); } else { - this.components = new MergedComponentMap(ComponentMap.EMPTY); + this.components = MergedComponentMap.create(ComponentMap.EMPTY, changes); } } @Unique private void onItemBroken(Item item, Entity entity, ActionContext context) { - if (entity instanceof LivingEntity livingEntity) { - context.slot().ifPresent(slot -> livingEntity.sendEquipmentBreakStatus(item, slot)); + EquipmentSlot slot = context.get(ItematicContextParameters.EQUIPMENT_SLOT); + if (slot != null && entity instanceof LivingEntity livingEntity) { + livingEntity.sendEquipmentBreakStatus(item, slot); } - this.decrement(1); this.itematic$invokeEvent(ItemEvents.BREAK_ITEM, context); - this.setDamage(0); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/item/ItemUsageContextExtender.java b/src/main/java/net/errorcraft/itematic/mixin/item/ItemUsageContextExtender.java new file mode 100644 index 00000000..d3a4e938 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/item/ItemUsageContextExtender.java @@ -0,0 +1,32 @@ +package net.errorcraft.itematic.mixin.item; + +import net.errorcraft.itematic.access.item.ItemUsageContextAccess; +import net.errorcraft.itematic.world.action.context.ItemStackExchanger; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUsageContext; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(ItemUsageContext.class) +public class ItemUsageContextExtender implements ItemUsageContextAccess { + @Shadow + @Final + @Nullable + private PlayerEntity player; + + @Shadow + @Final + private ItemStack stack; + + @Override + public ItemStackExchanger itematic$stackExchanger() { + if (this.player == null) { + return ItemStackExchanger.EMPTY; + } + + return ItemStackExchanger.forEntity(this.player, this.stack); + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/item/ItemUsageExtender.java b/src/main/java/net/errorcraft/itematic/mixin/item/ItemUsageExtender.java deleted file mode 100644 index 168898ce..00000000 --- a/src/main/java/net/errorcraft/itematic/mixin/item/ItemUsageExtender.java +++ /dev/null @@ -1,23 +0,0 @@ -package net.errorcraft.itematic.mixin.item; - -import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; -import net.errorcraft.itematic.item.ItemUsageUtil; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemUsage; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(ItemUsage.class) -public class ItemUsageExtender { - @WrapWithCondition( - method = "exchangeStack(Lnet/minecraft/item/ItemStack;Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/item/ItemStack;Z)Lnet/minecraft/item/ItemStack;", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;decrementUnlessCreative(ILnet/minecraft/entity/LivingEntity;)V" - ) - ) - private static boolean checkDecrementStackCount(ItemStack instance, int amount, LivingEntity entity) { - return ItemUsageUtil.decrementCount(); - } -} diff --git a/src/main/java/net/errorcraft/itematic/mixin/item/SmithingTemplateItemAccessor.java b/src/main/java/net/errorcraft/itematic/mixin/item/SmithingTemplateItemAccessor.java index c1e8d0d7..487420a9 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/item/SmithingTemplateItemAccessor.java +++ b/src/main/java/net/errorcraft/itematic/mixin/item/SmithingTemplateItemAccessor.java @@ -2,7 +2,6 @@ import net.minecraft.item.SmithingTemplateItem; import net.minecraft.text.Text; -import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; @@ -12,78 +11,68 @@ @Mixin(SmithingTemplateItem.class) public interface SmithingTemplateItemAccessor { - @Accessor("TITLE_FORMATTING") - static Formatting getTitleFormatting() { - throw new AssertionError(); - } - - @Accessor("DESCRIPTION_FORMATTING") - static Formatting getDescriptionFormatting() { - throw new AssertionError(); - } - @Accessor("SMITHING_TEMPLATE_TEXT") - static Text getSmithingTemplateText() { + static Text smithingTemplateTitle() { throw new AssertionError(); } @Accessor("APPLIES_TO_TEXT") - static Text getAppliesToText() { + static Text appliesToTitle() { throw new AssertionError(); } @Accessor("ARMOR_TRIM_APPLIES_TO_TEXT") - static Text getTrimPatternAppliesToText() { + static Text trimPatternAppliesToLabel() { throw new AssertionError(); } @Accessor("INGREDIENTS_TEXT") - static Text getIngredientsText() { + static Text ingredientsTitle() { throw new AssertionError(); } @Accessor("ARMOR_TRIM_INGREDIENTS_TEXT") - static Text getTrimPatternIngredientsText() { + static Text trimPatternIngredients() { throw new AssertionError(); } @Accessor("ARMOR_TRIM_BASE_SLOT_DESCRIPTION_TEXT") - static Text getTrimPatternBaseSlotDescriptionText() { + static Text trimPatternBaseSlotDescription() { throw new AssertionError(); } @Accessor("ARMOR_TRIM_ADDITIONS_SLOT_DESCRIPTION_TEXT") - static Text getTrimPatternAdditionsSlotDescriptionText() { + static Text trimPatternAdditionsSlotDescription() { throw new AssertionError(); } @Accessor("NETHERITE_UPGRADE_BASE_SLOT_DESCRIPTION_TEXT") - static Text getItemUpgradeBaseSlotDescriptionText() { + static Text itemUpgradeBaseSlotDescription() { throw new AssertionError(); } @Accessor("NETHERITE_UPGRADE_ADDITIONS_SLOT_DESCRIPTION_TEXT") - static Text getItemUpgradeAdditionsSlotDescriptionText() { + static Text itemUpgradeAdditionsSlotDescription() { throw new AssertionError(); } @Invoker("getArmorTrimEmptyBaseSlotTextures") - static List getTrimPatternEmptyBaseSlotTextures() { + static List trimPatternEmptyBaseSlotTextures() { throw new AssertionError(); } @Invoker("getArmorTrimEmptyAdditionsSlotTextures") - static List getTrimPatternEmptyAdditionsSlotTextures() { + static List trimPatternEmptyAdditionsSlotTextures() { throw new AssertionError(); } @Invoker("getNetheriteUpgradeEmptyBaseSlotTextures") - static List getItemUpgradeEmptyBaseSlotTextures() { + static List itemUpgradeEmptyBaseSlotTextures() { throw new AssertionError(); } @Invoker("getNetheriteUpgradeEmptyAdditionsSlotTextures") - static List getItemUpgradeEmptyAdditionsSlotTextures() { + static List itemUpgradeEmptyAdditionsSlotTextures() { throw new AssertionError(); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/item/SpawnEggItemAccessor.java b/src/main/java/net/errorcraft/itematic/mixin/item/SpawnEggItemAccessor.java deleted file mode 100644 index 148f129e..00000000 --- a/src/main/java/net/errorcraft/itematic/mixin/item/SpawnEggItemAccessor.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.errorcraft.itematic.mixin.item; - -import com.mojang.serialization.MapCodec; -import net.minecraft.entity.EntityType; -import net.minecraft.item.SpawnEggItem; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(SpawnEggItem.class) -public interface SpawnEggItemAccessor { - @Accessor("ENTITY_TYPE_MAP_CODEC") - static MapCodec> entityTypeMapCodec() { - throw new AssertionError(); - } -} diff --git a/src/main/java/net/errorcraft/itematic/mixin/loot/condition/LocationCheckLootConditionExtender.java b/src/main/java/net/errorcraft/itematic/mixin/loot/condition/LocationCheckLootConditionExtender.java new file mode 100644 index 00000000..58eed9ca --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/loot/condition/LocationCheckLootConditionExtender.java @@ -0,0 +1,64 @@ +package net.errorcraft.itematic.mixin.loot.condition; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.MapCodec; +import net.errorcraft.itematic.access.loot.condition.LocationCheckLootConditionAccess; +import net.errorcraft.itematic.loot.condition.LocationCheckLootConditionExtraFields; +import net.minecraft.loot.condition.LocationCheckLootCondition; +import net.minecraft.util.context.ContextParameter; +import net.minecraft.util.math.Vec3d; +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; + +@Mixin(LocationCheckLootCondition.class) +public class LocationCheckLootConditionExtender implements LocationCheckLootConditionAccess { + @Unique + private LocationCheckLootConditionExtraFields extraFields = LocationCheckLootConditionExtraFields.DEFAULT; + + @ModifyExpressionValue( + method = "", + at = @At( + value = "INVOKE", + target = "Lcom/mojang/serialization/codecs/RecordCodecBuilder;mapCodec(Ljava/util/function/Function;)Lcom/mojang/serialization/MapCodec;", + ordinal = 1, + remap = false + ) + ) + private static MapCodec mapCodecAddExtraFields(MapCodec original) { + return original.dependent( + LocationCheckLootConditionExtraFields.CODEC, + locationCheck -> Pair.of( + locationCheck.itematic$extraFields(), + LocationCheckLootConditionExtraFields.CODEC + ), + (locationCheck, extraFields) -> { + locationCheck.itematic$setExtraFields(extraFields); + return locationCheck; + } + ); + } + + @ModifyArg( + method = "test(Lnet/minecraft/loot/context/LootContext;)Z", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/loot/context/LootContext;get(Lnet/minecraft/util/context/ContextParameter;)Ljava/lang/Object;" + ) + ) + private ContextParameter usePositionTarget(ContextParameter parameter) { + return this.extraFields.position().parameter(); + } + + @Override + public LocationCheckLootConditionExtraFields itematic$extraFields() { + return this.extraFields; + } + + @Override + public void itematic$setExtraFields(LocationCheckLootConditionExtraFields extraFields) { + this.extraFields = extraFields; + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/loot/function/ExplorationMapLootFunctionExtender.java b/src/main/java/net/errorcraft/itematic/mixin/loot/function/ExplorationMapLootFunctionExtender.java index a41cd670..1b4f44b7 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/loot/function/ExplorationMapLootFunctionExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/loot/function/ExplorationMapLootFunctionExtender.java @@ -7,7 +7,7 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.loot.function.ExplorationMapLootFunction; -import net.minecraft.world.World; +import net.minecraft.server.world.ServerWorld; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @@ -33,10 +33,10 @@ private boolean isOfForMapUseItemComponentCheck(ItemStack instance, Item item, @ method = "process", at = @At( value = "INVOKE", - target = "Lnet/minecraft/item/FilledMapItem;createMap(Lnet/minecraft/world/World;IIBZZ)Lnet/minecraft/item/ItemStack;" + target = "Lnet/minecraft/item/FilledMapItem;createMap(Lnet/minecraft/server/world/ServerWorld;IIBZZ)Lnet/minecraft/item/ItemStack;" ) ) - private ItemStack createMapUseItemComponent(World world, int x, int z, byte scale, boolean showIcons, boolean unlimitedTracking, @Share("mappableItemComponent") LocalRef mappableItemComponent) { + private ItemStack createMapUseItemComponent(ServerWorld world, int x, int z, byte scale, boolean showIcons, boolean unlimitedTracking, @Share("mappableItemComponent") LocalRef mappableItemComponent) { return mappableItemComponent.get().createStack(world, x, z, scale, showIcons, unlimitedTracking); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/network/state/PlayStateFactoriesExtender.java b/src/main/java/net/errorcraft/itematic/mixin/network/state/PlayStateFactoriesExtender.java index 14f74efc..be48acfd 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/network/state/PlayStateFactoriesExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/network/state/PlayStateFactoriesExtender.java @@ -2,10 +2,11 @@ import net.errorcraft.itematic.network.packet.ItematicPlayPackets; import net.errorcraft.itematic.network.packet.s2c.play.TwirlS2CPacket; -import net.minecraft.network.NetworkStateBuilder; import net.minecraft.network.RegistryByteBuf; import net.minecraft.network.listener.ClientPlayPacketListener; +import net.minecraft.network.state.NetworkStateBuilder; import net.minecraft.network.state.PlayStateFactories; +import net.minecraft.util.Unit; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -17,7 +18,7 @@ public class PlayStateFactoriesExtender { method = "method_55958", at = @At("TAIL") ) - private static void registerCustomS2CPackets(NetworkStateBuilder builder, CallbackInfo info) { + private static void registerCustomS2CPackets(NetworkStateBuilder builder, CallbackInfo info) { builder.add(ItematicPlayPackets.TWIRL, TwirlS2CPacket.CODEC); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/recipe/BookCloningRecipeExtender.java b/src/main/java/net/errorcraft/itematic/mixin/recipe/BookCloningRecipeExtender.java deleted file mode 100644 index ef2829c5..00000000 --- a/src/main/java/net/errorcraft/itematic/mixin/recipe/BookCloningRecipeExtender.java +++ /dev/null @@ -1,62 +0,0 @@ -package net.errorcraft.itematic.mixin.recipe; - -import com.llamalad7.mixinextras.sugar.Local; -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.item.WrittenBookItem; -import net.minecraft.recipe.BookCloningRecipe; -import org.objectweb.asm.Opcodes; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.*; - -@Mixin(BookCloningRecipe.class) -public class BookCloningRecipeExtender { - @Redirect( - method = { - "matches(Lnet/minecraft/recipe/input/CraftingRecipeInput;Lnet/minecraft/world/World;)Z", - "craft(Lnet/minecraft/recipe/input/CraftingRecipeInput;Lnet/minecraft/registry/RegistryWrapper$WrapperLookup;)Lnet/minecraft/item/ItemStack;" - }, - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z", - ordinal = 0 - ) - ) - private boolean isOfForWrittenBookUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.WRITTEN_BOOK); - } - - @Redirect( - method = { - "matches(Lnet/minecraft/recipe/input/CraftingRecipeInput;Lnet/minecraft/world/World;)Z", - "craft(Lnet/minecraft/recipe/input/CraftingRecipeInput;Lnet/minecraft/registry/RegistryWrapper$WrapperLookup;)Lnet/minecraft/item/ItemStack;" - }, - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z", - ordinal = 0 - ), - slice = @Slice( - from = @At( - value = "FIELD", - target = "Lnet/minecraft/item/Items;WRITABLE_BOOK:Lnet/minecraft/item/Item;", - opcode = Opcodes.GETSTATIC - ) - ) - ) - private boolean isOfForWritableBookUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.WRITABLE_BOOK); - } - - @ModifyConstant( - method = "getRecipeRemainders", - constant = @Constant( - classValue = WrittenBookItem.class - ) - ) - private boolean instanceOfWrittenBookItemUseItemComponentCheck(Object reference, Class clazz, @Local(ordinal = 0) ItemStack inputStack) { - return inputStack.itematic$hasBehavior(ItemComponentTypes.TEXT_HOLDER); - } -} diff --git a/src/main/java/net/errorcraft/itematic/mixin/recipe/CraftingDecoratedPotRecipeExtender.java b/src/main/java/net/errorcraft/itematic/mixin/recipe/CraftingDecoratedPotRecipeExtender.java index f70863f7..4c0fc7e7 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/recipe/CraftingDecoratedPotRecipeExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/recipe/CraftingDecoratedPotRecipeExtender.java @@ -1,10 +1,10 @@ package net.errorcraft.itematic.mixin.recipe; +import net.errorcraft.itematic.block.entity.SherdsUtil; import net.errorcraft.itematic.item.ItemKeys; import net.errorcraft.itematic.item.component.ItemComponentTypes; import net.errorcraft.itematic.mixin.block.entity.SherdsAccessor; import net.minecraft.block.entity.Sherds; -import net.minecraft.component.DataComponentTypes; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.recipe.CraftingDecoratedPotRecipe; @@ -52,7 +52,6 @@ public ItemStack craft(CraftingRecipeInput input, RegistryWrapper.WrapperLookup Optional.of(input.getStackInSlot(5).getRegistryEntry()), Optional.of(input.getStackInSlot(7).getRegistryEntry()) ); - stack.set(DataComponentTypes.POT_DECORATIONS, sherds); - return stack; + return SherdsUtil.addSherdsToStack(stack, sherds); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/recipe/SmithingTransformRecipeExtender.java b/src/main/java/net/errorcraft/itematic/mixin/recipe/SmithingTransformRecipeExtender.java index a5e8138b..9ff0f309 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/recipe/SmithingTransformRecipeExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/recipe/SmithingTransformRecipeExtender.java @@ -3,10 +3,9 @@ import net.errorcraft.itematic.access.recipe.RecipeAccess; import net.errorcraft.itematic.item.ItemKeys; import net.minecraft.item.Item; -import net.minecraft.item.ItemConvertible; -import net.minecraft.item.ItemStack; import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.SmithingTransformRecipe; +import net.minecraft.recipe.TransmuteRecipeResult; import net.minecraft.recipe.display.RecipeDisplay; import net.minecraft.recipe.display.SlotDisplay; import net.minecraft.recipe.display.SmithingRecipeDisplay; @@ -14,8 +13,6 @@ 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.Redirect; import java.util.List; import java.util.Optional; @@ -28,7 +25,7 @@ public class SmithingTransformRecipeExtender implements RecipeAccess { @Shadow @Final - Optional base; + Ingredient base; @Shadow @Final @@ -36,27 +33,16 @@ public class SmithingTransformRecipeExtender implements RecipeAccess { @Shadow @Final - ItemStack result; - - @Redirect( - method = "craft(Lnet/minecraft/recipe/input/SmithingRecipeInput;Lnet/minecraft/registry/RegistryWrapper$WrapperLookup;)Lnet/minecraft/item/ItemStack;", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;copyComponentsToNewStack(Lnet/minecraft/item/ItemConvertible;I)Lnet/minecraft/item/ItemStack;" - ) - ) - private ItemStack copyComponentsToNewStackUseRegistryEntry(ItemStack instance, ItemConvertible item, int count) { - return instance.itematic$copyComponentsToNewStack(this.result.getRegistryEntry(), count); - } + TransmuteRecipeResult result; @Override public List itematic$displays(RegistryEntryLookup items) { return List.of( new SmithingRecipeDisplay( Ingredient.toDisplay(this.template), - Ingredient.toDisplay(this.base), + this.base.toDisplay(), Ingredient.toDisplay(this.addition), - new SlotDisplay.StackSlotDisplay(this.result), + this.result.createSlotDisplay(), new SlotDisplay.ItemSlotDisplay(items.getOrThrow(ItemKeys.SMITHING_TABLE)) ) ); diff --git a/src/main/java/net/errorcraft/itematic/mixin/recipe/SmithingTrimRecipeExtender.java b/src/main/java/net/errorcraft/itematic/mixin/recipe/SmithingTrimRecipeExtender.java index bd421559..9ef9acba 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/recipe/SmithingTrimRecipeExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/recipe/SmithingTrimRecipeExtender.java @@ -3,44 +3,49 @@ import net.errorcraft.itematic.access.recipe.RecipeAccess; import net.errorcraft.itematic.item.ItemKeys; import net.minecraft.item.Item; +import net.minecraft.item.equipment.trim.ArmorTrimPattern; import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.SmithingTrimRecipe; import net.minecraft.recipe.display.RecipeDisplay; import net.minecraft.recipe.display.SlotDisplay; import net.minecraft.recipe.display.SmithingRecipeDisplay; import net.minecraft.registry.RegistryEntryLookup; +import net.minecraft.registry.entry.RegistryEntry; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import java.util.List; -import java.util.Optional; @Mixin(SmithingTrimRecipe.class) public class SmithingTrimRecipeExtender implements RecipeAccess { @Shadow @Final - Optional template; + Ingredient template; @Shadow @Final - Optional base; + Ingredient base; @Shadow @Final - Optional addition; + Ingredient addition; + + @Shadow + @Final + RegistryEntry pattern; @Override public List itematic$displays(RegistryEntryLookup items) { - SlotDisplay base = Ingredient.toDisplay(this.base); - SlotDisplay material = Ingredient.toDisplay(this.addition); - SlotDisplay pattern = Ingredient.toDisplay(this.template); + SlotDisplay base = this.base.toDisplay(); + SlotDisplay material = this.addition.toDisplay(); + SlotDisplay pattern = this.template.toDisplay(); return List.of( new SmithingRecipeDisplay( pattern, base, material, - new SlotDisplay.SmithingTrimSlotDisplay(base, material, pattern), + new SlotDisplay.SmithingTrimSlotDisplay(base, material, this.pattern), new SlotDisplay.ItemSlotDisplay(items.getOrThrow(ItemKeys.SMITHING_TABLE)) ) ); diff --git a/src/main/java/net/errorcraft/itematic/mixin/recipe/TransmuteRecipeExtender.java b/src/main/java/net/errorcraft/itematic/mixin/recipe/TransmuteRecipeExtender.java index b4c19cfe..c3733999 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/recipe/TransmuteRecipeExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/recipe/TransmuteRecipeExtender.java @@ -3,23 +3,20 @@ import net.errorcraft.itematic.access.recipe.RecipeAccess; import net.errorcraft.itematic.item.ItemKeys; import net.minecraft.item.Item; -import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; import net.minecraft.recipe.CraftingRecipe; import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.TransmuteRecipe; +import net.minecraft.recipe.TransmuteRecipeResult; import net.minecraft.recipe.display.RecipeDisplay; import net.minecraft.recipe.display.ShapelessCraftingRecipeDisplay; import net.minecraft.recipe.display.SlotDisplay; import net.minecraft.recipe.input.CraftingRecipeInput; import net.minecraft.registry.RegistryEntryLookup; -import net.minecraft.registry.entry.RegistryEntry; 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.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; import java.util.List; @@ -35,21 +32,7 @@ public abstract class TransmuteRecipeExtender implements CraftingRecipe, RecipeA @Shadow @Final - RegistryEntry result; - - @Shadow - public abstract List getDisplays(); - - @Redirect( - method = "craft(Lnet/minecraft/recipe/input/CraftingRecipeInput;Lnet/minecraft/registry/RegistryWrapper$WrapperLookup;)Lnet/minecraft/item/ItemStack;", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;copyComponentsToNewStack(Lnet/minecraft/item/ItemConvertible;I)Lnet/minecraft/item/ItemStack;" - ) - ) - private ItemStack copyComponentsToNewStackUseRegistryEntry(ItemStack instance, ItemConvertible item, int count) { - return instance.itematic$copyComponentsToNewStack(this.result, count); - } + TransmuteRecipeResult result; @Override public DefaultedList getRecipeRemainders(CraftingRecipeInput input) { @@ -62,7 +45,7 @@ public DefaultedList getRecipeRemainders(CraftingRecipeInput input) { } final int index = i; - if (!foundInput && this.input.test(stack) && !stack.itemMatches(this.result)) { + if (!foundInput && this.input.test(stack) && !stack.itemMatches(this.result.itemEntry())) { foundInput = true; this.input.itematic$remainder() .map(ItemStack::copy) @@ -85,7 +68,7 @@ public DefaultedList getRecipeRemainders(CraftingRecipeInput input) { this.input.toDisplay(), this.material.toDisplay() ), - new SlotDisplay.ItemSlotDisplay(this.result), + this.result.createSlotDisplay(), new SlotDisplay.ItemSlotDisplay(items.getOrThrow(ItemKeys.CRAFTING_TABLE)) ) ); diff --git a/src/main/java/net/errorcraft/itematic/mixin/recipe/TransmuteRecipeResultExtender.java b/src/main/java/net/errorcraft/itematic/mixin/recipe/TransmuteRecipeResultExtender.java new file mode 100644 index 00000000..68a1caed --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/recipe/TransmuteRecipeResultExtender.java @@ -0,0 +1,30 @@ +package net.errorcraft.itematic.mixin.recipe; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemConvertible; +import net.minecraft.item.ItemStack; +import net.minecraft.recipe.TransmuteRecipeResult; +import net.minecraft.registry.entry.RegistryEntry; +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.Redirect; + +@Mixin(TransmuteRecipeResult.class) +public class TransmuteRecipeResultExtender { + @Shadow + @Final + private RegistryEntry itemEntry; + + @Redirect( + method = "apply", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/item/ItemStack;copyComponentsToNewStack(Lnet/minecraft/item/ItemConvertible;I)Lnet/minecraft/item/ItemStack;" + ) + ) + private ItemStack copyComponentsToNewStackUseRegistryEntry(ItemStack instance, ItemConvertible item, int count) { + return instance.itematic$copyComponentsToNewStack(this.itemEntry, count); + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/registry/BuiltinRegistriesExtender.java b/src/main/java/net/errorcraft/itematic/mixin/registry/BuiltinRegistriesExtender.java index 5f45de5f..ee2ddec8 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/registry/BuiltinRegistriesExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/registry/BuiltinRegistriesExtender.java @@ -3,7 +3,6 @@ import net.errorcraft.itematic.item.ItemUtil; import net.errorcraft.itematic.item.dispense.behavior.DispenseBehaviors; import net.errorcraft.itematic.item.group.entry.provider.ItemGroupEntryProviders; -import net.errorcraft.itematic.item.smithing.template.SmithingTemplates; import net.errorcraft.itematic.registry.ItematicRegistryKeys; import net.errorcraft.itematic.village.trade.Trades; import net.errorcraft.itematic.world.action.Actions; @@ -32,7 +31,6 @@ private static void initialiseCustomRegistries(CallbackInfo info) { .addRegistry(ItematicRegistryKeys.ITEM_GROUP_ENTRY_PROVIDER, ItemGroupEntryProviders::bootstrap) .addRegistry(ItematicRegistryKeys.TRADE, Trades::bootstrap) .addRegistry(ItematicRegistryKeys.ACTION, Actions::bootstrap) - .addRegistry(ItematicRegistryKeys.SMITHING_TEMPLATE, SmithingTemplates::bootstrap) .addRegistry(ItematicRegistryKeys.DISPENSE_BEHAVIOR, DispenseBehaviors::bootstrap); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/registry/RegistryLoaderExtender.java b/src/main/java/net/errorcraft/itematic/mixin/registry/RegistryLoaderExtender.java index 16adc0ee..d9a39374 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/registry/RegistryLoaderExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/registry/RegistryLoaderExtender.java @@ -7,7 +7,6 @@ import net.errorcraft.itematic.item.ItemUtil; import net.errorcraft.itematic.item.dispense.behavior.DispenseBehavior; import net.errorcraft.itematic.item.group.entry.provider.ItemGroupEntryProvider; -import net.errorcraft.itematic.item.smithing.template.SmithingTemplate; import net.errorcraft.itematic.registry.ActionValidator; import net.errorcraft.itematic.registry.ItematicRegistryKeys; import net.errorcraft.itematic.village.trade.Trade; @@ -43,7 +42,6 @@ private static List> addCustomEntries(List> addCustomNetworkEntries(List customCriteria() { + throw new AssertionError(); + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/scoreboard/ScoreboardCriterionExtender.java b/src/main/java/net/errorcraft/itematic/mixin/scoreboard/ScoreboardCriterionExtender.java index abeb42e5..a5ea1bf8 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/scoreboard/ScoreboardCriterionExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/scoreboard/ScoreboardCriterionExtender.java @@ -1,24 +1,19 @@ package net.errorcraft.itematic.mixin.scoreboard; -import com.llamalad7.mixinextras.sugar.Local; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.codecs.PrimitiveCodec; import net.errorcraft.itematic.access.scoreboard.ScoreboardCriterionAccess; import net.errorcraft.itematic.scoreboard.ScoreboardCriterionUtil; -import net.minecraft.registry.Registry; -import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.entry.RegistryEntry; +import net.errorcraft.itematic.serialization.RegistryMapperCodec; import net.minecraft.scoreboard.ScoreboardCriterion; -import net.minecraft.stat.Stat; -import net.minecraft.stat.StatType; -import net.minecraft.util.Identifier; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mutable; 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 java.util.Optional; import java.util.function.Function; @Mixin(ScoreboardCriterion.class) @@ -29,28 +24,19 @@ public class ScoreboardCriterionExtender implements ScoreboardCriterionAccess { private String name; @Redirect( - method = "getOrCreateStatCriterion(Lnet/minecraft/stat/StatType;Lnet/minecraft/util/Identifier;)Ljava/util/Optional;", + method = "", at = @At( value = "INVOKE", - target = "Lnet/minecraft/registry/Registry;getOptionalValue(Lnet/minecraft/util/Identifier;)Ljava/util/Optional;" + target = "Lcom/mojang/serialization/codecs/PrimitiveCodec;comapFlatMap(Ljava/util/function/Function;Ljava/util/function/Function;)Lcom/mojang/serialization/Codec;", + remap = false ) ) - private static Optional> getOrEmptyUseDynamicRegistry(Registry instance, Identifier id) { - RegistryKey> key = instance.getKey(); - return ScoreboardCriterionUtil.lookup() - .getOrThrow(key) - .getOptional(RegistryKey.of(key, id)); - } - - @ModifyArg( - method = "getOrCreateStatCriterion(Lnet/minecraft/stat/StatType;Lnet/minecraft/util/Identifier;)Ljava/util/Optional;", - at = @At( - value = "INVOKE", - target = "Ljava/util/Optional;map(Ljava/util/function/Function;)Ljava/util/Optional;" - ) - ) - private static Function, ? extends Stat> mapToStatUseRegistryEntry(Function mapper, @Local(argsOnly = true) StatType statType) { - return statType::itematic$getOrCreateStat; + private static Codec useDynamicRegistry(PrimitiveCodec instance, Function> to, Function from) { + return RegistryMapperCodec.of( + instance, + ScoreboardCriterionUtil::byName, + ScoreboardCriterion::getName + ); } @Override diff --git a/src/main/java/net/errorcraft/itematic/mixin/scoreboard/ScoreboardStateExtender.java b/src/main/java/net/errorcraft/itematic/mixin/scoreboard/ScoreboardStateExtender.java deleted file mode 100644 index 7c1f5b99..00000000 --- a/src/main/java/net/errorcraft/itematic/mixin/scoreboard/ScoreboardStateExtender.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.errorcraft.itematic.mixin.scoreboard; - -import net.errorcraft.itematic.scoreboard.ScoreboardCriterionUtil; -import net.minecraft.nbt.NbtList; -import net.minecraft.registry.RegistryWrapper; -import net.minecraft.scoreboard.ScoreboardState; -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.CallbackInfo; - -@Mixin(ScoreboardState.class) -public class ScoreboardStateExtender { - @Inject( - method = "readObjectivesNbt", - at = @At("HEAD") - ) - private void setLookup(NbtList nbt, RegistryWrapper.WrapperLookup registries, CallbackInfo info) { - ScoreboardCriterionUtil.setLookup(registries); - } - - @Inject( - method = "readObjectivesNbt", - at = @At("TAIL") - ) - private void resetLookup(NbtList nbt, RegistryWrapper.WrapperLookup registries, CallbackInfo info) { - ScoreboardCriterionUtil.setLookup(null); - } -} diff --git a/src/main/java/net/errorcraft/itematic/mixin/screen/HorseScreenHandlerExtender.java b/src/main/java/net/errorcraft/itematic/mixin/screen/HorseScreenHandlerExtender.java deleted file mode 100644 index f6f5f562..00000000 --- a/src/main/java/net/errorcraft/itematic/mixin/screen/HorseScreenHandlerExtender.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.errorcraft.itematic.mixin.screen; - -import net.errorcraft.itematic.item.ItemKeys; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -public class HorseScreenHandlerExtender { - @Mixin(targets = "net/minecraft/screen/HorseScreenHandler$1") - public static class SaddleSlotExtender { - @Redirect( - method = "canInsert", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" - ) - ) - private boolean isOfForSaddleUseRegistryKeyCheck(ItemStack instance, Item item) { - return instance.itematic$isOf(ItemKeys.SADDLE); - } - } -} diff --git a/src/main/java/net/errorcraft/itematic/mixin/screen/LoomScreenHandlerExtender.java b/src/main/java/net/errorcraft/itematic/mixin/screen/LoomScreenHandlerExtender.java index 629894ae..1f71e941 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/screen/LoomScreenHandlerExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/screen/LoomScreenHandlerExtender.java @@ -1,68 +1,37 @@ package net.errorcraft.itematic.mixin.screen; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.sugar.Local; import com.llamalad7.mixinextras.sugar.Share; 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.BannerPatternItemComponent; import net.errorcraft.itematic.item.component.components.DyeItemComponent; -import net.minecraft.block.entity.BannerPattern; -import net.minecraft.item.*; -import net.minecraft.registry.tag.TagKey; +import net.minecraft.item.BannerItem; +import net.minecraft.item.DyeItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import net.minecraft.screen.LoomScreenHandler; import net.minecraft.util.DyeColor; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.*; +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.Redirect; import java.util.Optional; @Mixin(LoomScreenHandler.class) public class LoomScreenHandlerExtender { - @ModifyConstant( - method = "getPatternsFor", - constant = @Constant( - classValue = BannerPatternItem.class, - ordinal = 0 - ) - ) - private boolean instanceOfBannerPatternItemUseItemComponent(Object reference, Class clazz, ItemStack stack, @Share("bannerPatternItemComponent") LocalRef bannerPatternItemComponent) { - Optional optionalComponent = stack.itematic$getBehavior(ItemComponentTypes.BANNER_PATTERN); - optionalComponent.ifPresent(bannerPatternItemComponent::set); - return optionalComponent.isPresent(); - } - - @ModifyVariable( - method = "getPatternsFor", - at = @At("LOAD"), - ordinal = 0 - ) - private Item castToBannerPatternItemUseNull(Item instance) { - return null; - } - - @Redirect( - method = "getPatternsFor", + @ModifyExpressionValue( + method = "quickMove", at = @At( value = "INVOKE", - target = "Lnet/minecraft/item/BannerPatternItem;getPattern()Lnet/minecraft/registry/tag/TagKey;" - ) - ) - private TagKey getPatternUseItemComponent(BannerPatternItem instance, @Share("bannerPatternItemComponent") LocalRef bannerPatternItemComponent) { - return bannerPatternItemComponent.get().patterns(); - } - - @ModifyConstant( - method = "quickMove", - constant = @Constant( - classValue = BannerItem.class, - ordinal = 0 + target = "Lnet/minecraft/item/ItemStack;contains(Lnet/minecraft/component/ComponentType;)Z" ) ) - private boolean instanceOfBannerItemUseItemComponent(Object reference, Class clazz, @Local(ordinal = 1) ItemStack slotStack) { - return slotStack.itematic$getBehavior(ItemComponentTypes.BANNER_PATTERN_HOLDER) - .map(BannerPatternHolderItemComponent::modifiable) - .orElse(false); + private boolean containsProvidersBannerPatternsDataComponentAlsoCheckItemBehaviorComponent(boolean original, @Local(ordinal = 1) ItemStack slotStack) { + return original && slotStack.itematic$hasBehavior(ItemComponentTypes.BANNER_PATTERN_HOLDER); } @ModifyConstant( @@ -72,19 +41,10 @@ private boolean instanceOfBannerItemUseItemComponent(Object reference, Class clazz, @Local(ordinal = 1) ItemStack slotStack) { - return slotStack.itematic$hasBehavior(ItemComponentTypes.DYE); - } - - @ModifyConstant( - method = "quickMove", - constant = @Constant( - classValue = BannerPatternItem.class, - ordinal = 0 - ) - ) - private boolean instanceOfBannerPatternItemUseItemComponentCheck(Object reference, Class clazz, @Local(ordinal = 1) ItemStack slotStack) { - return slotStack.itematic$hasBehavior(ItemComponentTypes.BANNER_PATTERN); + private boolean instanceOfDyeItemUseItemComponentCheck(Object reference, Class clazz, @Local(ordinal = 1) ItemStack slotStack, @Share("dye") LocalRef dye) { + Optional optionalDye = slotStack.itematic$getBehavior(ItemComponentTypes.DYE); + optionalDye.ifPresent(dye::set); + return optionalDye.isPresent(); } @Redirect( @@ -105,10 +65,8 @@ private Item getItemUseNull(ItemStack instance) { target = "Lnet/minecraft/item/DyeItem;getColor()Lnet/minecraft/util/DyeColor;" ) ) - private DyeColor getColorUseItemComponent(DyeItem instance, @Local(ordinal = 1) ItemStack dyeStack) { - return dyeStack.itematic$getBehavior(ItemComponentTypes.DYE) - .map(DyeItemComponent::color) - .orElse(DyeColor.WHITE); + private DyeColor getColorUseItemComponent(DyeItem instance, @Share("dye") LocalRef dye) { + return dye.get().color(); } @Mixin(targets = "net/minecraft/screen/LoomScreenHandler$3") @@ -143,15 +101,15 @@ private boolean instanceOfDyeItemUseItemComponentCheck(Object reference, Class clazz, ItemStack stack) { - return stack.itematic$hasBehavior(ItemComponentTypes.BANNER_PATTERN); + private boolean containsProvidersBannerPatternsDataComponentAlsoCheckItemBehaviorComponent(boolean original, ItemStack stack) { + return original && stack.itematic$hasBehavior(ItemComponentTypes.BANNER_PATTERN_HOLDER); } } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/server/ServerPlayerInteractionManagerExtender.java b/src/main/java/net/errorcraft/itematic/mixin/server/ServerPlayerInteractionManagerExtender.java deleted file mode 100644 index 97a9f034..00000000 --- a/src/main/java/net/errorcraft/itematic/mixin/server/ServerPlayerInteractionManagerExtender.java +++ /dev/null @@ -1,32 +0,0 @@ -package net.errorcraft.itematic.mixin.server; - -import net.minecraft.block.BlockState; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.network.ServerPlayerInteractionManager; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -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.Redirect; - -@Mixin(ServerPlayerInteractionManager.class) -public class ServerPlayerInteractionManagerExtender { - @Shadow - @Final - protected ServerPlayerEntity player; - - @Redirect( - method = "tryBreakBlock", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/Item;canMine(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/player/PlayerEntity;)Z" - ) - ) - private boolean tryBreakBlockCanMineUseItemStackVersion(Item instance, BlockState state, World world, BlockPos pos, PlayerEntity miner) { - return this.player.getMainHandStack().itematic$canMine(state, world, pos, miner); - } -} diff --git a/src/main/java/net/errorcraft/itematic/mixin/stat/ServerStatHandlerExtender.java b/src/main/java/net/errorcraft/itematic/mixin/stat/ServerStatHandlerExtender.java index 5b1cc960..947d71bb 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/stat/ServerStatHandlerExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/stat/ServerStatHandlerExtender.java @@ -1,13 +1,16 @@ package net.errorcraft.itematic.mixin.stat; import com.llamalad7.mixinextras.sugar.Local; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DynamicOps; +import net.minecraft.registry.Registry; import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryFixedCodec; import net.minecraft.server.MinecraftServer; import net.minecraft.stat.ServerStatHandler; import net.minecraft.stat.Stat; import net.minecraft.stat.StatHandler; import net.minecraft.stat.StatType; -import net.minecraft.util.Identifier; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -15,7 +18,6 @@ import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.Redirect; -import java.util.Optional; import java.util.function.Function; @Mixin(ServerStatHandler.class) @@ -24,40 +26,64 @@ public class ServerStatHandlerExtender extends StatHandler { @Final private MinecraftServer server; + @Redirect( + method = "createCodec", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/registry/Registry;getCodec()Lcom/mojang/serialization/Codec;" + ) + ) + private static Codec> getCodecUseRegistryEntry(Registry instance) { + return RegistryFixedCodec.of(instance.getKey()); + } + @ModifyArg( - method = "createStat", + method = "createCodec", at = @At( value = "INVOKE", - target = "Ljava/util/Optional;flatMap(Ljava/util/function/Function;)Ljava/util/Optional;" + target = "Lcom/mojang/serialization/Codec;flatComapMap(Ljava/util/function/Function;Ljava/util/function/Function;)Lcom/mojang/serialization/Codec;", + remap = false + ), + index = 0 + ) + private static Function, Stat> flatComapMapToUseRegistryEntry(Function> to, @Local(argsOnly = true) StatType statType) { + return statType::itematic$getOrCreateStat; + } + + @ModifyArg( + method = "method_67581", + at = @At( + value = "INVOKE", + target = "Lcom/mojang/serialization/DataResult;success(Ljava/lang/Object;)Lcom/mojang/serialization/DataResult;", + remap = false ) ) - private Function>> flatMapToEntryUseDynamicRegistry(Function> mapper, @Local(argsOnly = true) StatType type) { - return id -> this.server.getRegistryManager() - .getOrThrow(type.getRegistry().getKey()) - .getEntry(id); + @SuppressWarnings("unchecked") + private static T getValueUseRegistryEntry(T result, @Local(argsOnly = true) Stat stat) { + return (T) stat.itematic$entry(); } @ModifyArg( - method = "createStat", + method = "parse", at = @At( value = "INVOKE", - target = "Ljava/util/Optional;map(Ljava/util/function/Function;)Ljava/util/Optional;" + target = "Lcom/mojang/serialization/Dynamic;(Lcom/mojang/serialization/DynamicOps;Ljava/lang/Object;)V", + remap = false ) ) - private Function, Stat> mapToStatUseRegistryEntry(Function mapper, @Local(argsOnly = true) StatType type) { - return type::itematic$getOrCreateStat; + private DynamicOps useRegistryOps(DynamicOps ops) { + return this.server.getRegistryManager().getOps(ops); } - @Redirect( + @ModifyArg( method = "asString", at = @At( value = "INVOKE", - target = "Lnet/minecraft/stat/ServerStatHandler;getStatId(Lnet/minecraft/stat/Stat;)Lnet/minecraft/util/Identifier;" + target = "Lcom/mojang/serialization/Codec;encodeStart(Lcom/mojang/serialization/DynamicOps;Ljava/lang/Object;)Lcom/mojang/serialization/DataResult;", + remap = false ) ) - private Identifier getStatIdUseDynamicRegistry(Stat stat) { - return this.server.getRegistryManager() - .getOrThrow(stat.getType().getRegistry().getKey()) - .getId(stat.getValue()); + private DynamicOps encodeStartUseRegistryOps(DynamicOps ops) { + return this.server.getRegistryManager().getOps(ops); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/stat/StatExtender.java b/src/main/java/net/errorcraft/itematic/mixin/stat/StatExtender.java index 487ae2db..68da78da 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/stat/StatExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/stat/StatExtender.java @@ -10,6 +10,9 @@ import org.spongepowered.asm.mixin.Mixin; 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.callback.CallbackInfoReturnable; @Mixin(Stat.class) public class StatExtender implements StatAccess { @@ -20,6 +23,17 @@ public class StatExtender implements StatAccess { @Unique private RegistryEntry entry; + @Inject( + method = "getName(Lnet/minecraft/stat/StatType;Ljava/lang/Object;)Ljava/lang/String;", + at = @At("HEAD"), + cancellable = true + ) + private static void checkNull(StatType type, T value, CallbackInfoReturnable info) { + if (value == null) { + info.setReturnValue(""); + } + } + @Override public RegistryEntry itematic$entry() { return this.entry; diff --git a/src/main/java/net/errorcraft/itematic/mixin/stat/StatTypeExtender.java b/src/main/java/net/errorcraft/itematic/mixin/stat/StatTypeExtender.java index 7cce47c2..58de0b94 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/stat/StatTypeExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/stat/StatTypeExtender.java @@ -142,7 +142,7 @@ private V computeIfAbsentUseRegistryEntry(Map instance, K k, Functi @SuppressWarnings("unchecked") public Stat itematic$getOrCreateStat(RegistryEntry entry, StatFormatter formatter) { return this.entryStats.computeIfAbsent(entry, value -> { - Stat stat = StatAccessor.create((StatType)(Object) this, value.value(), formatter); + Stat stat = StatAccessor.create((StatType)(Object) this, value.hasKeyAndValue() ? value.value() : null, formatter); stat.itematic$setEntry(value); return stat; }); diff --git a/src/main/java/net/errorcraft/itematic/mixin/util/DyeColorExtender.java b/src/main/java/net/errorcraft/itematic/mixin/util/DyeColorExtender.java index a8a7ef58..725a2876 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/util/DyeColorExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/util/DyeColorExtender.java @@ -2,15 +2,30 @@ import net.errorcraft.itematic.access.util.DyeColorAccess; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.item.component.ItemComponentTypes; +import net.errorcraft.itematic.item.component.components.DyeItemComponent; +import net.minecraft.item.DyeItem; import net.minecraft.item.Item; +import net.minecraft.recipe.input.CraftingRecipeInput; import net.minecraft.registry.RegistryKey; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.DyeColor; 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.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.Slice; + +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Predicate; @Mixin(DyeColor.class) +@SuppressWarnings("DataFlowIssue") public class DyeColorExtender implements DyeColorAccess { @Shadow @Final @@ -98,6 +113,71 @@ public class DyeColorExtender implements DyeColorAccess { ((DyeColorExtender)(Object) BLACK).itemKey = ItemKeys.BLACK_DYE; } + @Redirect( + method = "mixColors", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/util/DyeColor;createColorMixingRecipeInput(Lnet/minecraft/util/DyeColor;Lnet/minecraft/util/DyeColor;)Lnet/minecraft/recipe/input/CraftingRecipeInput;" + ) + ) + private static CraftingRecipeInput newItemStackForRecipeInputUseCreateStack(DyeColor firstColor, DyeColor secondColor, ServerWorld world) { + return CraftingRecipeInput.create( + 2, + 1, + List.of( + world.itematic$createStack(firstColor.itematic$itemKey()), + world.itematic$createStack(secondColor.itematic$itemKey()) + ) + ); + } + + @Redirect( + method = "mixColors", + at = @At( + value = "INVOKE", + target = "Ljava/util/Optional;filter(Ljava/util/function/Predicate;)Ljava/util/Optional;" + ) + ) + private static Optional instanceOfDyeItemUseItemComponent(Optional instance, Predicate predicate) { + return instance.flatMap(item -> item.itematic$getBehavior(ItemComponentTypes.DYE)); + } + + @Redirect( + method = "mixColors", + at = @At( + value = "INVOKE", + target = "Ljava/util/Optional;map(Ljava/util/function/Function;)Ljava/util/Optional;", + ordinal = 0 + ), + slice = @Slice( + from = @At( + value = "INVOKE", + target = "Ljava/util/Optional;filter(Ljava/util/function/Predicate;)Ljava/util/Optional;" + ) + ) + ) + private static Optional castToDyeItemDoNothing(Optional instance, Function mapper) { + return instance; + } + + @ModifyArg( + method = "mixColors", + at = @At( + value = "INVOKE", + target = "Ljava/util/Optional;map(Ljava/util/function/Function;)Ljava/util/Optional;", + ordinal = 1 + ), + slice = @Slice( + from = @At( + value = "INVOKE", + target = "Ljava/util/Optional;filter(Ljava/util/function/Predicate;)Ljava/util/Optional;" + ) + ) + ) + private static Function getColorUseItemComponent(Function mapper) { + return DyeItemComponent::color; + } + @Override public RegistryKey itematic$itemKey() { return this.itemKey; diff --git a/src/main/java/net/errorcraft/itematic/mixin/util/context/ContextParameterMapAccessor.java b/src/main/java/net/errorcraft/itematic/mixin/util/context/ContextParameterMapAccessor.java new file mode 100644 index 00000000..844eb1e8 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/util/context/ContextParameterMapAccessor.java @@ -0,0 +1,20 @@ +package net.errorcraft.itematic.mixin.util.context; + +import net.minecraft.util.context.ContextParameter; +import net.minecraft.util.context.ContextParameterMap; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; + +import java.util.Map; + +@Mixin(ContextParameterMap.class) +public interface ContextParameterMapAccessor { + @Invoker("") + static ContextParameterMap create(Map, ?> map) { + throw new AssertionError(); + } + + @Accessor("map") + Map, Object> itematic$parameters(); +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/util/context/ContextParameterMapExtender.java b/src/main/java/net/errorcraft/itematic/mixin/util/context/ContextParameterMapExtender.java new file mode 100644 index 00000000..b8e16308 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/util/context/ContextParameterMapExtender.java @@ -0,0 +1,29 @@ +package net.errorcraft.itematic.mixin.util.context; + +import net.errorcraft.itematic.access.util.context.ContextParameterMapBuilderAccess; +import net.minecraft.util.context.ContextParameter; +import net.minecraft.util.context.ContextParameterMap; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.Map; + +public class ContextParameterMapExtender { + @Mixin(ContextParameterMap.Builder.class) + public static class BuilderExtender implements ContextParameterMapBuilderAccess { + @Shadow + @Final + private Map, Object> map; + + @Override + public void itematic$copy(ContextParameterMap other) { + this.map.putAll(((ContextParameterMapAccessor) other).itematic$parameters()); + } + + @Override + public ContextParameterMap itematic$build() { + return ContextParameterMapAccessor.create(this.map); + } + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/util/dynamic/CodecsAccessor.java b/src/main/java/net/errorcraft/itematic/mixin/util/dynamic/CodecsAccessor.java deleted file mode 100644 index 37309385..00000000 --- a/src/main/java/net/errorcraft/itematic/mixin/util/dynamic/CodecsAccessor.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.errorcraft.itematic.mixin.util.dynamic; - -import com.mojang.serialization.Codec; -import net.minecraft.util.dynamic.Codecs; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -import java.util.function.Function; - -@Mixin(Codecs.class) -public interface CodecsAccessor { - @Invoker("rangedFloat") - static Codec rangedFloat(float min, float max, Function messageFactory) { - throw new AssertionError(); - } -} diff --git a/src/main/java/net/errorcraft/itematic/mixin/village/TradeOffersAccessor.java b/src/main/java/net/errorcraft/itematic/mixin/village/TradeOffersAccessor.java index ec61f187..29c982e5 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/village/TradeOffersAccessor.java +++ b/src/main/java/net/errorcraft/itematic/mixin/village/TradeOffersAccessor.java @@ -21,47 +21,47 @@ static int rareMaxUses() { throw new AssertionError(); } - @Accessor("NOVICE_SELL_XP") + @Accessor("NOVICE_SELL_EXPERIENCE") static int noviceSellTradeExperience() { throw new AssertionError(); } - @Accessor("NOVICE_BUY_XP") + @Accessor("NOVICE_BUY_EXPERIENCE") static int noviceBuyTradeExperience() { throw new AssertionError(); } - @Accessor("APPRENTICE_SELL_XP") + @Accessor("APPRENTICE_SELL_EXPERIENCE") static int apprenticeSellTradeExperience() { throw new AssertionError(); } - @Accessor("APPRENTICE_BUY_XP") + @Accessor("APPRENTICE_BUY_EXPERIENCE") static int apprenticeBuyTradeExperience() { throw new AssertionError(); } - @Accessor("JOURNEYMAN_SELL_XP") + @Accessor("JOURNEYMAN_SELL_EXPERIENCE") static int journeymanSellTradeExperience() { throw new AssertionError(); } - @Accessor("JOURNEYMAN_BUY_XP") + @Accessor("JOURNEYMAN_BUY_EXPERIENCE") static int journeymanBuyTradeExperience() { throw new AssertionError(); } - @Accessor("EXPERT_SELL_XP") + @Accessor("EXPERT_SELL_EXPERIENCE") static int expertSellTradeExperience() { throw new AssertionError(); } - @Accessor("EXPERT_BUY_XP") + @Accessor("EXPERT_BUY_EXPERIENCE") static int expertBuyTradeExperience() { throw new AssertionError(); } - @Accessor("MASTER_TRADE_XP") + @Accessor("MASTER_TRADE_EXPERIENCE") static int masterTradeExperience() { throw new AssertionError(); } diff --git a/src/main/java/net/errorcraft/itematic/mixin/village/VillagerDataExtender.java b/src/main/java/net/errorcraft/itematic/mixin/village/VillagerDataExtender.java index cc936855..19477cbb 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/village/VillagerDataExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/village/VillagerDataExtender.java @@ -3,6 +3,7 @@ import net.errorcraft.itematic.access.village.VillagerDataAccess; import net.errorcraft.itematic.registry.ItematicRegistryKeys; import net.errorcraft.itematic.village.trade.Trade; +import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.registry.tag.TagKey; import net.minecraft.util.Identifier; import net.minecraft.util.math.MathHelper; @@ -18,7 +19,7 @@ public class VillagerDataExtender implements VillagerDataAccess { @Shadow @Final - private VillagerProfession profession; + private RegistryEntry profession; @Shadow @Final @@ -34,11 +35,11 @@ public class VillagerDataExtender implements VillagerDataAccess { }; public @Nullable TagKey itematic$tradeTag() { - if (this.profession.workSound() == null) { + if (this.profession.value().workSound() == null) { return null; } - Identifier tag = Identifier.ofVanilla(this.profession.id() + "_" + this.levelName()); + Identifier tag = this.profession.getKey().orElseThrow().getValue().withPath(path -> path + "_" + this.levelName()); return TagKey.of(ItematicRegistryKeys.TRADE, tag); } diff --git a/src/main/java/net/errorcraft/itematic/mixin/village/VillagerProfessionExtender.java b/src/main/java/net/errorcraft/itematic/mixin/village/VillagerProfessionExtender.java index 6eea7a95..0e03d36c 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/village/VillagerProfessionExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/village/VillagerProfessionExtender.java @@ -1,38 +1,40 @@ package net.errorcraft.itematic.mixin.village; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import net.errorcraft.itematic.access.village.VillagerProfessionAccess; import net.errorcraft.itematic.item.ItematicItemTags; import net.minecraft.item.Item; import net.minecraft.registry.tag.TagKey; import net.minecraft.village.VillagerProfession; 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.Unique; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(VillagerProfession.class) public class VillagerProfessionExtender implements VillagerProfessionAccess { - @Shadow - @Final - public static VillagerProfession FARMER; - @Unique - private TagKey gatherableItemsTag; + private TagKey gatherableItems; - @Inject( - method = "", - at = @At("TAIL") + @ModifyExpressionValue( + method = "registerAndGetDefault", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/village/VillagerProfession;register(Lnet/minecraft/registry/Registry;Lnet/minecraft/registry/RegistryKey;Lnet/minecraft/registry/RegistryKey;Lcom/google/common/collect/ImmutableSet;Lcom/google/common/collect/ImmutableSet;Lnet/minecraft/sound/SoundEvent;)Lnet/minecraft/village/VillagerProfession;" + ) ) - private static void staticSetGatherableItemsTag(CallbackInfo info) { - ((VillagerProfessionExtender)(Object) FARMER).gatherableItemsTag = ItematicItemTags.FARMER_VILLAGER_GATHERABLE_ITEMS; + private static VillagerProfession setGatherableItemsTag(VillagerProfession original) { + original.itematic$setGatherableItems(ItematicItemTags.FARMER_VILLAGER_GATHERABLE_ITEMS); + return original; + } + + @Override + public @Nullable TagKey itematic$gatherableItems() { + return this.gatherableItems; } @Override - public @Nullable TagKey itematic$gatherableItemsTag() { - return this.gatherableItemsTag; + public void itematic$setGatherableItems(TagKey gatherableItems) { + this.gatherableItems = gatherableItems; } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/village/raid/RaidExtender.java b/src/main/java/net/errorcraft/itematic/mixin/village/raid/RaidExtender.java index ac2908d5..c9dc0bfa 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/village/raid/RaidExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/village/raid/RaidExtender.java @@ -6,9 +6,7 @@ import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; import net.minecraft.village.raid.Raid; -import net.minecraft.world.World; 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.Inject; import org.spongepowered.asm.mixin.injection.Redirect; @@ -17,9 +15,6 @@ @Mixin(Raid.class) public abstract class RaidExtender { - @Shadow - public abstract World getWorld(); - @Redirect( method = "createOminousBanner", at = @At( @@ -53,6 +48,6 @@ private static void checkEmptyStack(CallbackInfoReturnable info, @Loc ) ) private void createOminousBannerSetDataDrivenItemStack(int wave, RaiderEntity entity, CallbackInfo info) { - RaidUtil.createOminousBanner(this.getWorld()); + RaidUtil.createOminousBanner(entity.getWorld()); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/world/WorldExtender.java b/src/main/java/net/errorcraft/itematic/mixin/world/WorldExtender.java index a42db218..018cb5b8 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/world/WorldExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/world/WorldExtender.java @@ -3,6 +3,7 @@ import net.errorcraft.itematic.access.world.WorldAccess; import net.errorcraft.itematic.access.world.WorldViewAccess; import net.errorcraft.itematic.item.ItemAccess; +import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.registry.DynamicRegistryManager; @@ -25,7 +26,7 @@ @Mixin(World.class) public abstract class WorldExtender implements WorldViewAccess, WorldAccess { @Shadow - public abstract void playSound(@Nullable PlayerEntity except, double x, double y, double z, SoundEvent sound, SoundCategory category, float volume, float pitch); + public abstract void playSound(@Nullable Entity source, double x, double y, double z, SoundEvent sound, SoundCategory category, float volume, float pitch); @Unique private ItemAccess itemAccess; @@ -49,7 +50,7 @@ private void constructorSetItemAccess(MutableWorldProperties properties, Registr } @Override - public void itematic$playSound(@Nullable PlayerEntity except, Vec3d pos, SoundEvent sound, SoundCategory category, float volume, float pitch) { - this.playSound(except, pos.getX(), pos.getY(), pos.getZ(), sound, category, volume, pitch); + public void itematic$playSound(@Nullable PlayerEntity source, Vec3d pos, SoundEvent sound, SoundCategory category, float volume, float pitch) { + this.playSound(source, pos.getX(), pos.getY(), pos.getZ(), sound, category, volume, pitch); } } diff --git a/src/main/java/net/errorcraft/itematic/mm/ItematicEarlyRiser.java b/src/main/java/net/errorcraft/itematic/mm/ItematicEarlyRiser.java index 46aa5027..2985b9f7 100644 --- a/src/main/java/net/errorcraft/itematic/mm/ItematicEarlyRiser.java +++ b/src/main/java/net/errorcraft/itematic/mm/ItematicEarlyRiser.java @@ -1,6 +1,7 @@ package net.errorcraft.itematic.mm; import com.chocohead.mm.api.ClassTinkerers; +import net.errorcraft.itematic.util.context.ItematicContextParameters; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.MappingResolver; @@ -12,5 +13,10 @@ public void run() { ClassTinkerers.enumBuilder(recipeBookType) .addEnum("ITEMATIC$BREWING") .build(); + String lootContextEntityTarget = remapper.mapClassName("intermediary", "net.minecraft.class_47$class_50"); + String contextParameter = 'L' + remapper.mapClassName("intermediary", "net.minecraft.class_169") + ';'; + ClassTinkerers.enumBuilder(lootContextEntityTarget, String.class, contextParameter) + .addEnum("ITEMATIC$TARGET_ENTITY", "target_entity", ItematicContextParameters.TARGET_ENTITY) + .build(); } } diff --git a/src/main/java/net/errorcraft/itematic/network/packet/s2c/play/TwirlS2CPacket.java b/src/main/java/net/errorcraft/itematic/network/packet/s2c/play/TwirlS2CPacket.java index 519adbfc..272bd5be 100644 --- a/src/main/java/net/errorcraft/itematic/network/packet/s2c/play/TwirlS2CPacket.java +++ b/src/main/java/net/errorcraft/itematic/network/packet/s2c/play/TwirlS2CPacket.java @@ -15,7 +15,7 @@ public record TwirlS2CPacket(float spinAttackStrength) implements Packet> getPacketId() { + public PacketType> getPacketType() { return ItematicPlayPackets.TWIRL; } diff --git a/src/main/java/net/errorcraft/itematic/predicate/entity/ItematicEntitySubPredicateTypes.java b/src/main/java/net/errorcraft/itematic/predicate/entity/ItematicEntitySubPredicateTypes.java new file mode 100644 index 00000000..2da7e163 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/predicate/entity/ItematicEntitySubPredicateTypes.java @@ -0,0 +1,18 @@ +package net.errorcraft.itematic.predicate.entity; + +import com.mojang.serialization.MapCodec; +import net.minecraft.predicate.entity.EntitySubPredicate; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; + +public class ItematicEntitySubPredicateTypes { + public static final MapCodec VILLAGER = register("villager", VillagerEntitySubPredicate.CODEC); + + private ItematicEntitySubPredicateTypes() {} + + public static void init() {} + + private static MapCodec register(String id, MapCodec codec) { + return Registry.register(Registries.ENTITY_SUB_PREDICATE_TYPE, id, codec); + } +} diff --git a/src/main/java/net/errorcraft/itematic/predicate/entity/VillagerEntitySubPredicate.java b/src/main/java/net/errorcraft/itematic/predicate/entity/VillagerEntitySubPredicate.java new file mode 100644 index 00000000..c5e260b0 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/predicate/entity/VillagerEntitySubPredicate.java @@ -0,0 +1,38 @@ +package net.errorcraft.itematic.predicate.entity; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.entity.Entity; +import net.minecraft.predicate.entity.EntitySubPredicate; +import net.minecraft.registry.RegistryCodecs; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.Vec3d; +import net.minecraft.village.VillagerDataContainer; +import net.minecraft.village.VillagerType; +import org.jetbrains.annotations.Nullable; + +public record VillagerEntitySubPredicate(RegistryEntryList variant) implements EntitySubPredicate { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + RegistryCodecs.entryList(RegistryKeys.VILLAGER_TYPE).fieldOf("variant").forGetter(VillagerEntitySubPredicate::variant) + ).apply(instance, VillagerEntitySubPredicate::new)); + + public static VillagerEntitySubPredicate of(RegistryEntryList variant) { + return new VillagerEntitySubPredicate(variant); + } + + @Override + public MapCodec getCodec() { + return CODEC; + } + + @Override + public boolean test(Entity entity, ServerWorld world, @Nullable Vec3d pos) { + if (entity instanceof VillagerDataContainer villagerDataContainer) { + return this.variant.contains(villagerDataContainer.getVillagerData().type()); + } + + return false; + } +} diff --git a/src/main/java/net/errorcraft/itematic/predicate/item/ItemPredicateUtil.java b/src/main/java/net/errorcraft/itematic/predicate/item/ItemPredicateUtil.java index af08407e..a030b460 100644 --- a/src/main/java/net/errorcraft/itematic/predicate/item/ItemPredicateUtil.java +++ b/src/main/java/net/errorcraft/itematic/predicate/item/ItemPredicateUtil.java @@ -6,30 +6,27 @@ import net.minecraft.network.RegistryByteBuf; import net.minecraft.network.codec.PacketCodec; import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.predicate.ComponentPredicate; import net.minecraft.predicate.NumberRange; +import net.minecraft.predicate.component.ComponentsPredicate; import net.minecraft.predicate.item.ItemPredicate; -import net.minecraft.predicate.item.ItemSubPredicate; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntryList; -import java.util.Map; import java.util.Optional; public class ItemPredicateUtil { public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( PacketCodecs.optional(PacketCodecs.registryEntryList(RegistryKeys.ITEM)), ItemPredicate::items, NumberRangeUtil.INTEGER_RANGE_PACKET_CODEC, ItemPredicate::count, - ComponentPredicate.PACKET_CODEC, ItemPredicate::components, - PacketCodecs.registryCodec(ItemSubPredicate.PREDICATES_MAP_CODEC), ItemPredicate::subPredicates, + ComponentsPredicate.PACKET_CODEC, ItemPredicate::components, ItemPredicateExtraFields.PACKET_CODEC, itemPredicate -> ((ItemPredicateAccess)(Object) itemPredicate).itematic$extraFields(), ItemPredicateUtil::create ); private ItemPredicateUtil() {} - private static ItemPredicate create(Optional> items, NumberRange.IntRange count, ComponentPredicate components, Map, ItemSubPredicate> subPredicates, ItemPredicateExtraFields extraFields) { - ItemPredicate predicate = new ItemPredicate(items, count, components, subPredicates); + private static ItemPredicate create(Optional> items, NumberRange.IntRange count, ComponentsPredicate components, ItemPredicateExtraFields extraFields) { + ItemPredicate predicate = new ItemPredicate(items, count, components); ((ItemPredicateAccess)(Object) predicate).itematic$setExtraFields(extraFields); return predicate; } diff --git a/src/main/java/net/errorcraft/itematic/registry/ItematicRegistries.java b/src/main/java/net/errorcraft/itematic/registry/ItematicRegistries.java index 9408b77f..5e9d8dcc 100644 --- a/src/main/java/net/errorcraft/itematic/registry/ItematicRegistries.java +++ b/src/main/java/net/errorcraft/itematic/registry/ItematicRegistries.java @@ -1,23 +1,17 @@ package net.errorcraft.itematic.registry; -import net.errorcraft.itematic.item.color.ItemColorType; -import net.errorcraft.itematic.item.color.ItemColorTypes; import net.errorcraft.itematic.item.component.ItemComponentType; import net.errorcraft.itematic.item.component.ItemComponentTypes; import net.errorcraft.itematic.item.event.ItemEvent; import net.errorcraft.itematic.item.event.ItemEvents; import net.errorcraft.itematic.item.holder.rule.ItemHolderRuleType; import net.errorcraft.itematic.item.holder.rule.ItemHolderRuleTypes; -import net.errorcraft.itematic.item.model.override.ModelOverride; -import net.errorcraft.itematic.item.model.override.ModelOverrides; import net.errorcraft.itematic.item.placement.block.picker.BlockPickerType; import net.errorcraft.itematic.item.placement.block.picker.BlockPickerTypes; -import net.errorcraft.itematic.item.pointer.Pointer; -import net.errorcraft.itematic.item.pointer.Pointers; import net.errorcraft.itematic.item.shooter.method.ShooterMethodType; import net.errorcraft.itematic.item.shooter.method.ShooterMethodTypes; -import net.errorcraft.itematic.item.smithing.template.SmithingTemplateType; -import net.errorcraft.itematic.item.smithing.template.SmithingTemplateTypes; +import net.errorcraft.itematic.item.smithing.template.SmithingTemplate; +import net.errorcraft.itematic.item.smithing.template.SmithingTemplates; import net.errorcraft.itematic.item.use.provider.IntegerProviderType; import net.errorcraft.itematic.item.use.provider.IntegerProviderTypes; import net.errorcraft.itematic.mixin.registry.RegistriesAccessor; @@ -31,13 +25,10 @@ public class ItematicRegistries { public static final Registry> ITEM_COMPONENT_TYPE = RegistriesAccessor.create(ItematicRegistryKeys.ITEM_COMPONENT_TYPE, r -> ItemComponentTypes.USEABLE); - public static final Registry> ITEM_COLOR_TYPE = RegistriesAccessor.create(ItematicRegistryKeys.ITEM_COLOR_TYPE, r -> ItemColorTypes.DYEABLE); public static final Registry ITEM_EVENT = RegistriesAccessor.create(ItematicRegistryKeys.ITEM_EVENT, r -> ItemEvents.USE); public static final Registry> ACTION_TYPE = RegistriesAccessor.create(ItematicRegistryKeys.ACTION_TYPE, r -> ActionTypes.MODIFY_ITEM); - public static final Registry MODEL_OVERRIDE = RegistriesAccessor.create(ItematicRegistryKeys.MODEL_OVERRIDE, r -> ModelOverrides.LEFT_HANDED); - public static final Registry POINTER = RegistriesAccessor.create(ItematicRegistryKeys.POINTER, r -> Pointers.SPAWN_LOCATION); public static final Registry> SEQUENCE_HANDLER_TYPE = RegistriesAccessor.create(ItematicRegistryKeys.SEQUENCE_HANDLER_TYPE, r -> SequenceHandlerTypes.UNCHECKED); - public static final Registry> SMITHING_TEMPLATE_TYPE = RegistriesAccessor.create(ItematicRegistryKeys.SMITHING_TEMPLATE_TYPE, r -> SmithingTemplateTypes.TRIM_PATTERN); + public static final Registry SMITHING_TEMPLATE = RegistriesAccessor.create(ItematicRegistryKeys.SMITHING_TEMPLATE, r -> SmithingTemplates.TRIM_PATTERN); public static final Registry> BLOCK_PICKER_TYPE = RegistriesAccessor.create(ItematicRegistryKeys.BLOCK_PICKER_TYPE, r -> BlockPickerTypes.SIMPLE); public static final Registry> TRADE_MODIFIER_TYPE = RegistriesAccessor.create(ItematicRegistryKeys.TRADE_MODIFIER_TYPE, r -> TradeModifierTypes.ENCHANT_WITH_LEVELS); public static final Registry> INTEGER_PROVIDER_TYPE = RegistriesAccessor.create(ItematicRegistryKeys.INTEGER_PROVIDER_TYPE, r -> IntegerProviderTypes.CONSTANT); diff --git a/src/main/java/net/errorcraft/itematic/registry/ItematicRegistryKeys.java b/src/main/java/net/errorcraft/itematic/registry/ItematicRegistryKeys.java index 7d4d9686..5bff8b39 100644 --- a/src/main/java/net/errorcraft/itematic/registry/ItematicRegistryKeys.java +++ b/src/main/java/net/errorcraft/itematic/registry/ItematicRegistryKeys.java @@ -1,17 +1,13 @@ package net.errorcraft.itematic.registry; -import net.errorcraft.itematic.item.color.ItemColorType; import net.errorcraft.itematic.item.component.ItemComponentType; import net.errorcraft.itematic.item.dispense.behavior.DispenseBehavior; import net.errorcraft.itematic.item.event.ItemEvent; import net.errorcraft.itematic.item.group.entry.provider.ItemGroupEntryProvider; import net.errorcraft.itematic.item.holder.rule.ItemHolderRuleType; -import net.errorcraft.itematic.item.model.override.ModelOverride; import net.errorcraft.itematic.item.placement.block.picker.BlockPickerType; -import net.errorcraft.itematic.item.pointer.Pointer; import net.errorcraft.itematic.item.shooter.method.ShooterMethodType; import net.errorcraft.itematic.item.smithing.template.SmithingTemplate; -import net.errorcraft.itematic.item.smithing.template.SmithingTemplateType; import net.errorcraft.itematic.item.use.provider.IntegerProviderType; import net.errorcraft.itematic.village.trade.Trade; import net.errorcraft.itematic.village.trade.modifier.TradeModifierType; @@ -24,17 +20,13 @@ public class ItematicRegistryKeys { public static final RegistryKey>> ITEM_COMPONENT_TYPE = RegistryKey.ofRegistry(Identifier.ofVanilla("item_component_type")); - public static final RegistryKey>> ITEM_COLOR_TYPE = RegistryKey.ofRegistry(Identifier.ofVanilla("item_color_type")); public static final RegistryKey> DISPENSE_BEHAVIOR = RegistryKey.ofRegistry(Identifier.ofVanilla("dispense_behavior")); public static final RegistryKey> ITEM_EVENT = RegistryKey.ofRegistry(Identifier.ofVanilla("item_event")); public static final RegistryKey>> ACTION_TYPE = RegistryKey.ofRegistry(Identifier.ofVanilla("action_type")); public static final RegistryKey> ITEM_GROUP_ENTRY_PROVIDER = RegistryKey.ofRegistry(Identifier.ofVanilla("item_group_entry_provider")); - public static final RegistryKey> MODEL_OVERRIDE = RegistryKey.ofRegistry(Identifier.ofVanilla("model_override")); - public static final RegistryKey> POINTER = RegistryKey.ofRegistry(Identifier.ofVanilla("pointer")); public static final RegistryKey> TRADE = RegistryKey.ofRegistry(Identifier.ofVanilla("trade")); public static final RegistryKey> ACTION = RegistryKey.ofRegistry(Identifier.ofVanilla("action")); public static final RegistryKey>> SEQUENCE_HANDLER_TYPE = RegistryKey.ofRegistry(Identifier.ofVanilla("sequence_handler_type")); - public static final RegistryKey>> SMITHING_TEMPLATE_TYPE = RegistryKey.ofRegistry(Identifier.ofVanilla("smithing_template_type")); public static final RegistryKey> SMITHING_TEMPLATE = RegistryKey.ofRegistry(Identifier.ofVanilla("smithing_template")); public static final RegistryKey>> BLOCK_PICKER_TYPE = RegistryKey.ofRegistry(Identifier.ofVanilla("block_picker_type")); public static final RegistryKey>> TRADE_MODIFIER_TYPE = RegistryKey.ofRegistry(Identifier.ofVanilla("trade_modifier_type")); diff --git a/src/main/java/net/errorcraft/itematic/registry/RecursionValidator.java b/src/main/java/net/errorcraft/itematic/registry/RecursionValidator.java index 93b2b4e1..4fc23f76 100644 --- a/src/main/java/net/errorcraft/itematic/registry/RecursionValidator.java +++ b/src/main/java/net/errorcraft/itematic/registry/RecursionValidator.java @@ -23,6 +23,12 @@ public void add(RegistryEntry.Reference entry) { } } + public void remove(RegistryEntry.Reference entry) { + if (!this.foundEntries.remove(entry)) { + throw new IllegalStateException("Action " + entry.registryKey().getValue() + " is not present in sequence: " + this.sequence(entry)); + } + } + private String sequence(RegistryEntry.Reference towardsEntry) { return Stream.concat(this.foundEntries.stream(), Stream.of(towardsEntry)) .map(RegistryEntry.Reference::registryKey) diff --git a/src/main/java/net/errorcraft/itematic/scoreboard/ScoreboardCriterionUtil.java b/src/main/java/net/errorcraft/itematic/scoreboard/ScoreboardCriterionUtil.java index 3d95a423..c44b7e6b 100644 --- a/src/main/java/net/errorcraft/itematic/scoreboard/ScoreboardCriterionUtil.java +++ b/src/main/java/net/errorcraft/itematic/scoreboard/ScoreboardCriterionUtil.java @@ -1,17 +1,45 @@ package net.errorcraft.itematic.scoreboard; -import net.minecraft.registry.RegistryWrapper; +import net.errorcraft.itematic.mixin.scoreboard.ScoreboardCriterionAccessor; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryOps; +import net.minecraft.scoreboard.ScoreboardCriterion; +import net.minecraft.stat.StatType; +import net.minecraft.util.Identifier; + +import java.util.Map; +import java.util.Optional; public class ScoreboardCriterionUtil { - private static RegistryWrapper.WrapperLookup lookup; + private static final Map CUSTOM_CRITERIA = ScoreboardCriterionAccessor.customCriteria(); private ScoreboardCriterionUtil() {} - public static RegistryWrapper.WrapperLookup lookup() { - return lookup; + public static Optional byName(String name, RegistryOps ops) { + ScoreboardCriterion customCriterion = CUSTOM_CRITERIA.get(name); + if (customCriterion != null) { + return Optional.of(customCriterion); + } + + int separatorIndex = name.indexOf(':'); + if (separatorIndex == -1) { + return Optional.empty(); + } + + return Registries.STAT_TYPE.getOptionalValue(Identifier.splitOn(name.substring(0, separatorIndex), '.')) + .flatMap(statType -> getStat( + statType, + Identifier.splitOn(name.substring(separatorIndex + 1), '.'), + ops + )); } - public static void setLookup(RegistryWrapper.WrapperLookup lookup) { - ScoreboardCriterionUtil.lookup = lookup; + private static Optional getStat(StatType statType, Identifier id, RegistryOps ops) { + RegistryKey> registryKey = statType.getRegistry().getKey(); + return ops.getEntryLookup(registryKey) + .flatMap(lookup -> lookup.getOptional(RegistryKey.of(registryKey, id))) + .map(statType::itematic$getOrCreateStat); } } diff --git a/src/main/java/net/errorcraft/itematic/screen/BrewingStandMenuDelegate.java b/src/main/java/net/errorcraft/itematic/screen/BrewingStandMenuDelegate.java index 4f22c9f1..8c492742 100644 --- a/src/main/java/net/errorcraft/itematic/screen/BrewingStandMenuDelegate.java +++ b/src/main/java/net/errorcraft/itematic/screen/BrewingStandMenuDelegate.java @@ -16,6 +16,7 @@ import net.minecraft.screen.*; import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.SlotActionType; +import net.minecraft.screen.sync.ItemStackHash; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.collection.DefaultedList; @@ -133,18 +134,18 @@ public void updateToClient() { } @Override - public void setPreviousTrackedSlot(int slot, ItemStack stack) { - this.delegate.setPreviousTrackedSlot(slot, stack); + public void setReceivedStack(int slot, ItemStack stack) { + this.delegate.setReceivedStack(slot, stack); } @Override - public void setPreviousTrackedSlotMutable(int slot, ItemStack stack) { - this.delegate.setPreviousTrackedSlotMutable(slot, stack); + public void setReceivedHash(int slot, ItemStackHash hash) { + this.delegate.setReceivedHash(slot, hash); } @Override - public void setPreviousCursorStack(ItemStack stack) { - this.delegate.setPreviousCursorStack(stack); + public void setReceivedCursorHash(ItemStackHash cursorStackHash) { + this.delegate.setReceivedCursorHash(cursorStackHash); } @Override diff --git a/src/main/java/net/errorcraft/itematic/serialization/ItematicCodecs.java b/src/main/java/net/errorcraft/itematic/serialization/ItematicCodecs.java index c8edb56a..2ac6c123 100644 --- a/src/main/java/net/errorcraft/itematic/serialization/ItematicCodecs.java +++ b/src/main/java/net/errorcraft/itematic/serialization/ItematicCodecs.java @@ -3,7 +3,6 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; 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; @@ -44,7 +43,14 @@ public static Codec positiveFloat(float maxInclusive) { if (maxInclusive <= 0.0f) { throw new IllegalArgumentException("maxInclusive must be positive, got " + maxInclusive + " instead"); } - return CodecsAccessor.rangedFloat(0.0f, maxInclusive, value -> "Value must be positive and at most " + maxInclusive + ": " + value); + + return Codecs.POSITIVE_FLOAT.validate(value -> { + if (value <= maxInclusive) { + return DataResult.success(value); + } + + return DataResult.error(() -> "Value must be at most " + maxInclusive + ": " + value); + }); } public static Codec positiveFraction(int maxInclusive) { diff --git a/src/main/java/net/errorcraft/itematic/serialization/RegistryMapperCodec.java b/src/main/java/net/errorcraft/itematic/serialization/RegistryMapperCodec.java new file mode 100644 index 00000000..d8c57263 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/serialization/RegistryMapperCodec.java @@ -0,0 +1,46 @@ +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.RegistryOps; + +import java.util.Optional; +import java.util.function.BiFunction; +import java.util.function.Function; + +public class RegistryMapperCodec implements Codec { + private final Codec fromCodec; + private final BiFunction, Optional> to; + private final Function from; + + private RegistryMapperCodec(Codec fromCodec, BiFunction, Optional> to, Function from) { + this.fromCodec = fromCodec; + this.to = to; + this.from = from; + } + + public static RegistryMapperCodec of(Codec fromCodec, BiFunction, Optional> to, Function from) { + return new RegistryMapperCodec<>(fromCodec, to, from); + } + + @Override + public DataResult> decode(DynamicOps ops, T input) { + if (!(ops instanceof RegistryOps registryOps)) { + return DataResult.error(() -> "Registries are inaccessible"); + } + + return this.fromCodec.decode(ops, input) + .map(Pair::getFirst) + .map(joined -> this.to.apply(joined, registryOps)) + .flatMap(result -> result.map(DataResult::success) + .orElseGet(() -> DataResult.error(() -> "Invalid name: " + input))) + .map(result -> Pair.of(result, input)); + } + + @Override + public DataResult encode(A input, DynamicOps ops, T prefix) { + return this.fromCodec.encode(this.from.apply(input), ops, prefix); + } +} diff --git a/src/main/java/net/errorcraft/itematic/sound/SoundEventKeys.java b/src/main/java/net/errorcraft/itematic/sound/SoundEventKeys.java index 7a9ec32f..4d5fa397 100644 --- a/src/main/java/net/errorcraft/itematic/sound/SoundEventKeys.java +++ b/src/main/java/net/errorcraft/itematic/sound/SoundEventKeys.java @@ -27,7 +27,8 @@ public class SoundEventKeys { public static final RegistryKey GENERIC_SPLASH = of("entity.generic.splash"); public static final RegistryKey HOE_TILL = of("item.hoe.till"); public static final RegistryKey HONEY_BOTTLE_DRINK = of("item.honey_bottle.drink"); - public static final RegistryKey LLAMA_SWAG = of("entity.llama.swag"); + public static final RegistryKey HORSE_ARMOR = of("entity.horse.armor"); + public static final RegistryKey LODESTONE_COMPASS_LOCK = of("item.lodestone_compass.lock"); public static final RegistryKey MUSIC_DISC_5 = of("music_disc.5"); public static final RegistryKey MUSIC_DISC_11 = of("music_disc.11"); public static final RegistryKey MUSIC_DISC_13 = of("music_disc.13"); @@ -48,10 +49,13 @@ public class SoundEventKeys { public static final RegistryKey MUSIC_DISC_WAIT = of("music_disc.wait"); public static final RegistryKey MUSIC_DISC_WARD = of("music_disc.ward"); public static final RegistryKey OMINOUS_BOTTLE_DISPOSE = of("item.ominous_bottle.dispose"); + public static final RegistryKey SHIELD_BLOCK = of("item.shield.block"); + public static final RegistryKey SHIELD_BREAK = of("item.shield.break"); public static final RegistryKey SHOVEL_FLATTEN = of("item.shovel.flatten"); public static final RegistryKey SPYGLASS_USE = of("item.spyglass.use"); public static final RegistryKey SPYGLASS_STOP_USING = of("item.spyglass.stop_using"); public static final RegistryKey TNT_PRIMED = of("entity.tnt.primed"); + public static final RegistryKey WOLF_ARMOR_BREAK = of("item.wolf_armor.break"); private SoundEventKeys() {} diff --git a/src/main/java/net/errorcraft/itematic/util/IdentifierUtil.java b/src/main/java/net/errorcraft/itematic/util/IdentifierUtil.java deleted file mode 100644 index 6e196d97..00000000 --- a/src/main/java/net/errorcraft/itematic/util/IdentifierUtil.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.errorcraft.itematic.util; - -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.Identifier; -import net.minecraft.util.Util; - -public class IdentifierUtil { - public static String createTranslationKey(RegistryKey key, String prefix, String suffix) { - return createTranslationKey(key.getValue(), prefix, suffix); - } - - public static String createTranslationKey(Identifier id, String prefix, String suffix) { - return Util.createTranslationKey(prefix, id) + "." + suffix; - } -} diff --git a/src/main/java/net/errorcraft/itematic/util/PositionUtil.java b/src/main/java/net/errorcraft/itematic/util/PositionUtil.java deleted file mode 100644 index e6ac52cc..00000000 --- a/src/main/java/net/errorcraft/itematic/util/PositionUtil.java +++ /dev/null @@ -1,12 +0,0 @@ -package net.errorcraft.itematic.util; - -import net.minecraft.util.math.Position; -import net.minecraft.util.math.Vec3d; - -public class PositionUtil { - private PositionUtil() {} - - public static Vec3d vec3d(Position position) { - return new Vec3d(position.getX(), position.getY(), position.getZ()); - } -} diff --git a/src/main/java/net/errorcraft/itematic/util/Util.java b/src/main/java/net/errorcraft/itematic/util/Util.java index d5ef3c51..9bcd6d01 100644 --- a/src/main/java/net/errorcraft/itematic/util/Util.java +++ b/src/main/java/net/errorcraft/itematic/util/Util.java @@ -1,7 +1,6 @@ package net.errorcraft.itematic.util; -import net.minecraft.util.math.MathHelper; -import org.apache.commons.lang3.math.Fraction; +import net.minecraft.util.Identifier; import java.util.Arrays; import java.util.Objects; @@ -10,13 +9,13 @@ public class Util { private Util() {} + public static String descriptionKey(String prefix, Identifier id, String suffix) { + return net.minecraft.util.Util.createTranslationKey(prefix, id) + "." + suffix; + } + public static String stackTraceMessage(String message) { return Arrays.stream(Thread.currentThread().getStackTrace()) .map(Objects::toString) .collect(Collectors.joining("\n\t", message + "\nStack trace:\n\t", "")); } - - public static int multiplyFraction(Fraction fraction, int multiplier) { - return MathHelper.ceil(fraction.multiplyBy(Fraction.getFraction(multiplier, 1)).doubleValue()); - } } diff --git a/src/main/java/net/errorcraft/itematic/util/context/ItematicContextParameters.java b/src/main/java/net/errorcraft/itematic/util/context/ItematicContextParameters.java index 18cae769..995d335c 100644 --- a/src/main/java/net/errorcraft/itematic/util/context/ItematicContextParameters.java +++ b/src/main/java/net/errorcraft/itematic/util/context/ItematicContextParameters.java @@ -1,10 +1,18 @@ package net.errorcraft.itematic.util.context; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.util.Hand; import net.minecraft.util.context.ContextParameter; import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; public class ItematicContextParameters { public static final ContextParameter SIDE = ContextParameter.of("side"); + public static final ContextParameter INTERACTED_POSITION = ContextParameter.of("interacted_position"); + public static final ContextParameter EQUIPMENT_SLOT = ContextParameter.of("equipment_slot"); + public static final ContextParameter HAND = ContextParameter.of("hand"); + public static final ContextParameter TARGET_ENTITY = ContextParameter.of("target_entity"); private ItematicContextParameters() {} diff --git a/src/main/java/net/errorcraft/itematic/util/context/ItematicContextTypes.java b/src/main/java/net/errorcraft/itematic/util/context/ItematicContextTypes.java index 95728fba..90ee4272 100644 --- a/src/main/java/net/errorcraft/itematic/util/context/ItematicContextTypes.java +++ b/src/main/java/net/errorcraft/itematic/util/context/ItematicContextTypes.java @@ -5,12 +5,6 @@ import net.minecraft.util.context.ContextType; public class ItematicContextTypes { - public static final ContextType ACTION = LootContextTypesAccessor.register("action", builder -> - builder.allow(LootContextParameters.THIS_ENTITY) - .require(LootContextParameters.ORIGIN) - .allow(LootContextParameters.TOOL) - .allow(ItematicContextParameters.SIDE) - ); public static final ContextType TRADE = LootContextTypesAccessor.register("trade", builder -> builder.require(LootContextParameters.THIS_ENTITY) .require(LootContextParameters.ORIGIN) diff --git a/src/main/java/net/errorcraft/itematic/village/trade/Trade.java b/src/main/java/net/errorcraft/itematic/village/trade/Trade.java index 17029b3d..b9047d4b 100644 --- a/src/main/java/net/errorcraft/itematic/village/trade/Trade.java +++ b/src/main/java/net/errorcraft/itematic/village/trade/Trade.java @@ -9,10 +9,11 @@ import net.errorcraft.itematic.village.trade.modifier.TradeModifier; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.loot.condition.LootCondition; import net.minecraft.loot.context.LootContext; import net.minecraft.loot.function.LootFunction; import net.minecraft.loot.function.LootFunctionTypes; -import net.minecraft.predicate.ComponentPredicate; +import net.minecraft.predicate.component.ComponentMapPredicate; import net.minecraft.registry.RegistryEntryLookup; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntry; @@ -25,24 +26,34 @@ import java.util.List; import java.util.Optional; -public record Trade(List wants, Entry gives, int maxUses, int tradeExperience, float priceMultiplier, Optional> tradeModifier) { +public record Trade(List wants, Entry gives, int maxUses, int tradeExperience, float priceMultiplier, Optional> tradeModifier, Optional merchantPredicate) { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( Entry.CODEC.listOf(1, Trade.MAX_WANTED_ENTRIES).fieldOf("wants").forGetter(Trade::wants), Entry.CODEC.fieldOf("gives").forGetter(Trade::gives), Codecs.POSITIVE_INT.fieldOf("max_uses").forGetter(Trade::maxUses), Codec.INT.optionalFieldOf("trade_experience", 1).forGetter(Trade::tradeExperience), Codec.FLOAT.optionalFieldOf("price_multiplier", 0.0f).forGetter(Trade::priceMultiplier), - TradeModifier.CODEC.optionalFieldOf("trade_modifier").forGetter(Trade::tradeModifier) + TradeModifier.CODEC.optionalFieldOf("trade_modifier").forGetter(Trade::tradeModifier), + LootCondition.CODEC.optionalFieldOf("merchant_predicate").forGetter(Trade::merchantPredicate) ).apply(instance, Trade::new)); public static final Codec WANTED_INDEX_CODEC = ItematicCodecs.index(Trade.MAX_WANTED_ENTRIES); private static final int MAX_WANTED_ENTRIES = 2; public TradeOffer createTradeOffer(LootContext context) { + if (!this.test(context)) { + return null; + } + Input wants = this.createWantedStacks(context); TradedItem gives = this.createGivenStack(wants, context); return new TradeOffer(wants.getTradedItem(0).orElseThrow(), wants.getTradedItem(1), gives.itemStack(), this.maxUses, this.tradeExperience, this.priceMultiplier); } + private boolean test(LootContext context) { + return this.merchantPredicate.map(merchantPredicate -> merchantPredicate.test(context)) + .orElse(true); + } + private Input createWantedStacks(LootContext context) { List stacks = this.wants.stream().map(entry -> entry.createStack(context)).toList(); return new Input(stacks); @@ -51,7 +62,7 @@ private Input createWantedStacks(LootContext context) { private TradedItem createGivenStack(Input wants, LootContext context) { ItemStack gives = this.gives.createStack(context); return this.tradeModifier.flatMap(tradeModifier -> tradeModifier.apply(wants, gives, context)) - .orElseGet(() -> new TradedItem(gives.getRegistryEntry(), gives.getCount(), ComponentPredicate.of(gives.getComponents()))); + .orElseGet(() -> new TradedItem(gives.getRegistryEntry(), gives.getCount(), ComponentMapPredicate.of(gives.getComponents()))); } public static Builder builder(Entry gives) { @@ -63,14 +74,23 @@ public static Trade of(Entry firstBuy, Entry sell, int maxUses, int tradeExperie } public static Trade of(Entry firstBuy, Entry sell, int maxUses, int tradeExperience, float priceMultiplier) { - return of(List.of(firstBuy), sell, maxUses, tradeExperience, priceMultiplier, null); + return of(List.of(firstBuy), sell, maxUses, tradeExperience, priceMultiplier, null, null); } - public static Trade of(List wants, Entry gives, int maxUses, int tradeExperience, float priceMultiplier, TradeModifier tradeModifier) { + public static Trade of(List wants, Entry gives, int maxUses, int tradeExperience, float priceMultiplier, TradeModifier tradeModifier, LootCondition merchantPredicate) { if (wants.size() > MAX_WANTED_ENTRIES) { throw new IllegalArgumentException("Wanted entries must not be more than " + MAX_WANTED_ENTRIES); } - return new Trade(wants, gives, maxUses, tradeExperience, priceMultiplier, Optional.ofNullable(tradeModifier)); + + return new Trade( + wants, + gives, + maxUses, + tradeExperience, + priceMultiplier, + Optional.ofNullable(tradeModifier), + Optional.ofNullable(merchantPredicate) + ); } public static class Builder { @@ -80,19 +100,29 @@ public static class Builder { private int tradeExperience; private float priceMultiplier = TradeOffersAccessor.lowPriceMultiplier(); private TradeModifier tradeModifier; + private LootCondition merchantPredicate; public Builder(Entry gives) { this.gives = gives; } public Trade build() { - return Trade.of(this.wants, this.gives, this.maxUses, this.tradeExperience, this.priceMultiplier, this.tradeModifier); + return Trade.of( + this.wants, + this.gives, + this.maxUses, + this.tradeExperience, + this.priceMultiplier, + this.tradeModifier, + this.merchantPredicate + ); } public Builder wants(Entry entry) { if (this.wants.size() >= MAX_WANTED_ENTRIES) { throw new IllegalArgumentException("Tried to add more than " + MAX_WANTED_ENTRIES + " wanted entries"); } + this.wants.add(entry); return this; } @@ -116,6 +146,11 @@ public Builder priceMultiplier(float priceMultiplier) { this.priceMultiplier = priceMultiplier; return this; } + + public Builder merchantPredicate(LootCondition.Builder merchantPredicate) { + this.merchantPredicate = merchantPredicate.build(); + return this; + } } public static class Input { @@ -129,8 +164,9 @@ public Optional getTradedItem(int index) { if (index < 0 || index >= this.stacks.size()) { return Optional.empty(); } + ItemStack stack = this.stacks.get(index); - return Optional.of(new TradedItem(stack.getRegistryEntry(), stack.getCount(), ComponentPredicate.of(stack.getComponents()))); + return Optional.of(new TradedItem(stack.getRegistryEntry(), stack.getCount(), ComponentMapPredicate.of(stack.getComponents()))); } public ItemStack getStack(int index) { diff --git a/src/main/java/net/errorcraft/itematic/village/trade/TradeTags.java b/src/main/java/net/errorcraft/itematic/village/trade/TradeTags.java index a445a295..38cf2d5a 100644 --- a/src/main/java/net/errorcraft/itematic/village/trade/TradeTags.java +++ b/src/main/java/net/errorcraft/itematic/village/trade/TradeTags.java @@ -70,10 +70,9 @@ public class TradeTags { public static final TagKey MASON_JOURNEYMAN = of("mason_journeyman"); public static final TagKey MASON_EXPERT = of("mason_expert"); public static final TagKey MASON_MASTER = of("mason_master"); - public static final TagKey WANDERING_TRADER_REGULAR = of("wandering_trader_regular"); + public static final TagKey WANDERING_TRADER_BUYING = of("wandering_trader_buying"); public static final TagKey WANDERING_TRADER_SPECIAL = of("wandering_trader_special"); - - + public static final TagKey WANDERING_TRADER_REGULAR = of("wandering_trader_regular"); private TradeTags() {} diff --git a/src/main/java/net/errorcraft/itematic/village/trade/Trades.java b/src/main/java/net/errorcraft/itematic/village/trade/Trades.java index a4433d63..2dbb6aa8 100644 --- a/src/main/java/net/errorcraft/itematic/village/trade/Trades.java +++ b/src/main/java/net/errorcraft/itematic/village/trade/Trades.java @@ -5,7 +5,9 @@ import net.errorcraft.itematic.loot.function.DyeItemModifier; import net.errorcraft.itematic.loot.function.SetRandomPotionItemModifier; import net.errorcraft.itematic.mixin.village.TradeOffersAccessor; +import net.errorcraft.itematic.potion.PotionKeys; import net.errorcraft.itematic.potion.PotionTags; +import net.errorcraft.itematic.predicate.entity.VillagerEntitySubPredicate; import net.errorcraft.itematic.registry.ItematicRegistryKeys; import net.errorcraft.itematic.village.trade.modifier.modifiers.EnchantWithLevelsTradeModifier; import net.errorcraft.itematic.village.trade.modifier.modifiers.ItemFromTypeTradeModifier; @@ -15,16 +17,13 @@ import net.minecraft.item.Item; import net.minecraft.item.map.MapDecorationType; import net.minecraft.item.map.MapDecorationTypes; -import net.minecraft.loot.function.AndLootFunction; -import net.minecraft.loot.function.ExplorationMapLootFunction; -import net.minecraft.loot.function.SetNameLootFunction; -import net.minecraft.loot.function.SetStewEffectLootFunction; +import net.minecraft.loot.condition.EntityPropertiesLootCondition; +import net.minecraft.loot.context.LootContext; +import net.minecraft.loot.function.*; import net.minecraft.loot.provider.number.ConstantLootNumberProvider; import net.minecraft.potion.Potion; -import net.minecraft.registry.Registerable; -import net.minecraft.registry.RegistryEntryLookup; -import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.RegistryKeys; +import net.minecraft.predicate.entity.EntityPredicate; +import net.minecraft.registry.*; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.registry.entry.RegistryEntryList; import net.minecraft.registry.tag.EnchantmentTags; @@ -80,22 +79,22 @@ public class Trades { public static final RegistryKey BUY_BLACK_DYE = of("buy_black_dye"); public static final RegistryKey BUY_LIGHT_BLUE_DYE = of("buy_light_blue_dye"); public static final RegistryKey BUY_LIME_DYE = of("buy_lime_dye"); - public static final RegistryKey SELL_WHITE_WOOL = of("sell_white_wool"); - public static final RegistryKey SELL_ORANGE_WOOL = of("sell_orange_wool"); - public static final RegistryKey SELL_MAGENTA_WOOL = of("sell_magenta_wool"); - public static final RegistryKey SELL_LIGHT_BLUE_WOOL = of("sell_light_blue_wool"); - public static final RegistryKey SELL_YELLOW_WOOL = of("sell_yellow_wool"); - public static final RegistryKey SELL_LIME_WOOL = of("sell_lime_wool"); - public static final RegistryKey SELL_PINK_WOOL = of("sell_pink_wool"); - public static final RegistryKey SELL_GRAY_WOOL = of("sell_gray_wool"); - public static final RegistryKey SELL_LIGHT_GRAY_WOOL = of("sell_light_gray_wool"); - public static final RegistryKey SELL_CYAN_WOOL = of("sell_cyan_wool"); - public static final RegistryKey SELL_PURPLE_WOOL = of("sell_purple_wool"); - public static final RegistryKey SELL_BLUE_WOOL = of("sell_blue_wool"); - public static final RegistryKey SELL_BROWN_WOOL = of("sell_brown_wool"); - public static final RegistryKey SELL_GREEN_WOOL = of("sell_green_wool"); - public static final RegistryKey SELL_RED_WOOL = of("sell_red_wool"); - public static final RegistryKey SELL_BLACK_WOOL = of("sell_black_wool"); + public static final RegistryKey SELL_WHITE_WOOL_SHEPHERD = of("sell_white_wool_shepherd"); + public static final RegistryKey SELL_ORANGE_WOOL_SHEPHERD = of("sell_orange_wool_shepherd"); + public static final RegistryKey SELL_MAGENTA_WOOL_SHEPHERD = of("sell_magenta_wool_shepherd"); + public static final RegistryKey SELL_LIGHT_BLUE_WOOL_SHEPHERD = of("sell_light_blue_wool_shepherd"); + public static final RegistryKey SELL_YELLOW_WOOL_SHEPHERD = of("sell_yellow_wool_shepherd"); + public static final RegistryKey SELL_LIME_WOOL_SHEPHERD = of("sell_lime_wool_shepherd"); + public static final RegistryKey SELL_PINK_WOOL_SHEPHERD = of("sell_pink_wool_shepherd"); + public static final RegistryKey SELL_GRAY_WOOL_SHEPHERD = of("sell_gray_wool_shepherd"); + public static final RegistryKey SELL_LIGHT_GRAY_WOOL_SHEPHERD = of("sell_light_gray_wool_shepherd"); + public static final RegistryKey SELL_CYAN_WOOL_SHEPHERD = of("sell_cyan_wool_shepherd"); + public static final RegistryKey SELL_PURPLE_WOOL_SHEPHERD = of("sell_purple_wool_shepherd"); + public static final RegistryKey SELL_BLUE_WOOL_SHEPHERD = of("sell_blue_wool_shepherd"); + public static final RegistryKey SELL_BROWN_WOOL_SHEPHERD = of("sell_brown_wool_shepherd"); + public static final RegistryKey SELL_GREEN_WOOL_SHEPHERD = of("sell_green_wool_shepherd"); + public static final RegistryKey SELL_RED_WOOL_SHEPHERD = of("sell_red_wool_shepherd"); + public static final RegistryKey SELL_BLACK_WOOL_SHEPHERD = of("sell_black_wool_shepherd"); public static final RegistryKey SELL_WHITE_CARPET = of("sell_white_carpet"); public static final RegistryKey SELL_ORANGE_CARPET = of("sell_orange_carpet"); public static final RegistryKey SELL_MAGENTA_CARPET = of("sell_magenta_carpet"); @@ -168,7 +167,7 @@ public class Trades { public static final RegistryKey BUY_TRIPWIRE_HOOK = of("buy_tripwire_hook"); public static final RegistryKey SELL_ENCHANTED_CROSSBOW = of("sell_enchanted_crossbow"); public static final RegistryKey SELL_TIPPED_ARROW = of("sell_tipped_arrow"); - public static final RegistryKey BUY_PAPER = of("buy_paper"); + public static final RegistryKey BUY_PAPER_LIBRARIAN = of("buy_paper_librarian"); public static final RegistryKey SELL_ENCHANTED_BOOK_NOVICE = of("sell_enchanted_book_novice"); public static final RegistryKey SELL_BOOKSHELF = of("sell_bookshelf"); public static final RegistryKey BUY_BOOK = of("buy_book"); @@ -182,13 +181,37 @@ public class Trades { public static final RegistryKey SELL_CLOCK = of("sell_clock"); public static final RegistryKey SELL_COMPASS = of("sell_compass"); public static final RegistryKey SELL_NAME_TAG = of("sell_name_tag"); + public static final RegistryKey BUY_PAPER_CARTOGRAPHER = of("buy_paper_cartographer"); public static final RegistryKey SELL_MAP = of("sell_map"); public static final RegistryKey BUY_GLASS_PANE = of("buy_glass_pane"); - public static final RegistryKey SELL_MONUMENT_MAP = of("sell_monument_map"); + public static final RegistryKey SELL_TAIGA_VILLAGE_MAP = of("sell_taiga_village_map"); + public static final RegistryKey SELL_SWAMP_HUT_MAP = of("sell_swamp_hut_map"); + public static final RegistryKey SELL_SNOWY_VILLAGE_MAP = of("sell_snowy_village_map"); + public static final RegistryKey SELL_SAVANNA_VILLAGE_MAP = of("sell_savanna_village_map"); + public static final RegistryKey SELL_PLAINS_VILLAGE_MAP = of("sell_plains_village_map"); + public static final RegistryKey SELL_JUNGLE_TEMPLE_MAP = of("sell_jungle_temple_map"); + public static final RegistryKey SELL_DESERT_VILLAGE_MAP = of("sell_desert_village_map"); public static final RegistryKey BUY_COMPASS = of("buy_compass"); - public static final RegistryKey SELL_MANSION_MAP = of("sell_mansion_map"); + public static final RegistryKey SELL_MONUMENT_MAP = of("sell_monument_map"); + public static final RegistryKey SELL_TRIAL_CHAMBER_MAP = of("sell_trial_chamber_map"); public static final RegistryKey SELL_ITEM_FRAME = of("sell_item_frame"); + public static final RegistryKey SELL_BLUE_BANNER_CARTOGRAPHER = of("sell_blue_banner_cartographer"); + public static final RegistryKey SELL_WHITE_BANNER_CARTOGRAPHER = of("sell_white_banner_cartographer"); + public static final RegistryKey SELL_RED_BANNER_CARTOGRAPHER = of("sell_red_banner_cartographer"); + public static final RegistryKey SELL_GREEN_BANNER_CARTOGRAPHER = of("sell_green_banner_cartographer"); + public static final RegistryKey SELL_LIME_BANNER_CARTOGRAPHER = of("sell_lime_banner_cartographer"); + public static final RegistryKey SELL_PURPLE_BANNER_CARTOGRAPHER = of("sell_purple_banner_cartographer"); + public static final RegistryKey SELL_CYAN_BANNER_CARTOGRAPHER = of("sell_cyan_banner_cartographer"); + public static final RegistryKey SELL_YELLOW_BANNER_CARTOGRAPHER = of("sell_yellow_banner_cartographer"); + public static final RegistryKey SELL_ORANGE_BANNER_CARTOGRAPHER = of("sell_orange_banner_cartographer"); + public static final RegistryKey SELL_BROWN_BANNER_CARTOGRAPHER = of("sell_brown_banner_cartographer"); + public static final RegistryKey SELL_MAGENTA_BANNER_CARTOGRAPHER = of("sell_magenta_banner_cartographer"); + public static final RegistryKey SELL_LIGHT_BLUE_BANNER_CARTOGRAPHER = of("sell_light_blue_banner_cartographer"); + public static final RegistryKey SELL_PINK_BANNER_CARTOGRAPHER = of("sell_pink_banner_cartographer"); + public static final RegistryKey SELL_GRAY_BANNER_CARTOGRAPHER = of("sell_gray_banner_cartographer"); + public static final RegistryKey SELL_BLACK_BANNER_CARTOGRAPHER = of("sell_black_banner_cartographer"); public static final RegistryKey SELL_GLOBE_BANNER_PATTERN = of("sell_globe_banner_pattern"); + public static final RegistryKey SELL_MANSION_MAP = of("sell_mansion_map"); public static final RegistryKey BUY_ROTTEN_FLESH = of("buy_rotten_flesh"); public static final RegistryKey SELL_REDSTONE = of("sell_redstone"); public static final RegistryKey BUY_GOLD_INGOT = of("buy_gold_ingot"); @@ -300,6 +323,29 @@ public class Trades { public static final RegistryKey SELL_BROWN_GLAZED_TERRACOTTA = of("sell_brown_glazed_terracotta"); public static final RegistryKey SELL_QUARTZ_PILLAR = of("sell_quartz_pillar"); public static final RegistryKey SELL_QUARTZ_BLOCK = of("sell_quartz_block"); + public static final RegistryKey BUY_WATER_BOTTLE = of("buy_water_bottle"); + public static final RegistryKey BUY_WATER_BUCKET = of("buy_water_bucket"); + public static final RegistryKey BUY_MILK_BUCKET = of("buy_milk_bucket"); + public static final RegistryKey BUY_FERMENTED_SPIDER_EYE = of("buy_fermented_spider_eye"); + public static final RegistryKey BUY_BAKED_POTATO = of("buy_baked_potato"); + public static final RegistryKey BUY_HAY_BLOCK = of("buy_hay_block"); + public static final RegistryKey SELL_PACKED_ICE = of("sell_packed_ice"); + public static final RegistryKey SELL_BLUE_ICE = of("sell_blue_ice"); + public static final RegistryKey SELL_GUNPOWDER = of("sell_gunpowder"); + public static final RegistryKey SELL_PODZOL = of("sell_podzol"); + public static final RegistryKey SELL_ACACIA_LOG = of("sell_acacia_log"); + public static final RegistryKey SELL_BIRCH_LOG = of("sell_birch_log"); + public static final RegistryKey SELL_DARK_OAK_LOG = of("sell_dark_oak_log"); + public static final RegistryKey SELL_JUNGLE_LOG = of("sell_jungle_log"); + public static final RegistryKey SELL_OAK_LOG = of("sell_oak_log"); + public static final RegistryKey SELL_SPRUCE_LOG = of("sell_spruce_log"); + public static final RegistryKey SELL_CHERRY_LOG = of("sell_cherry_log"); + public static final RegistryKey SELL_MANGROVE_LOG = of("sell_mangrove_log"); + public static final RegistryKey SELL_PALE_OAK_LOG = of("sell_pale_oak_log"); + public static final RegistryKey SELL_ENCHANTED_IRON_PICKAXE_WANDERING_TRADER = of("sell_enchanted_iron_pickaxe_wandering_trader"); + public static final RegistryKey SELL_LONG_INVISIBILITY_POTION = of("sell_long_invisibility_potion"); + public static final RegistryKey SELL_TROPICAL_FISH_BUCKET = of("sell_tropical_fish_bucket"); + public static final RegistryKey SELL_PUFFERFISH_BUCKET = of("sell_pufferfish_bucket"); public static final RegistryKey SELL_SEA_PICKLE = of("sell_sea_pickle"); public static final RegistryKey SELL_SLIME_BALL = of("sell_slime_ball"); public static final RegistryKey SELL_GLOWSTONE_WANDERING_TRADER = of("sell_glowstone_wandering_trader"); @@ -321,6 +367,7 @@ public class Trades { public static final RegistryKey SELL_OXEYE_DAISY = of("sell_oxeye_daisy"); public static final RegistryKey SELL_CORNFLOWER = of("sell_cornflower"); public static final RegistryKey SELL_LILY_OF_THE_VALLEY = of("sell_lily_of_the_valley"); + public static final RegistryKey SELL_OPEN_EYEBLOSSOM = of("sell_open_eyeblossom"); public static final RegistryKey SELL_WHEAT_SEEDS = of("sell_wheat_seeds"); public static final RegistryKey SELL_BEETROOT_SEEDS = of("sell_beetroot_seeds"); public static final RegistryKey SELL_PUMPKIN_SEEDS = of("sell_pumpkin_seeds"); @@ -332,6 +379,7 @@ public class Trades { public static final RegistryKey SELL_OAK_SAPLING = of("sell_oak_sapling"); public static final RegistryKey SELL_SPRUCE_SAPLING = of("sell_spruce_sapling"); public static final RegistryKey SELL_CHERRY_SAPLING = of("sell_cherry_sapling"); + public static final RegistryKey SELL_PALE_OAK_SAPLING = of("sell_pale_oak_sapling"); public static final RegistryKey SELL_MANGROVE_PROPAGULE = of("sell_mangrove_propagule"); public static final RegistryKey SELL_RED_DYE = of("sell_red_dye"); public static final RegistryKey SELL_WHITE_DYE = of("sell_white_dye"); @@ -355,6 +403,7 @@ public class Trades { public static final RegistryKey SELL_HORN_CORAL_BLOCK = of("sell_horn_coral_block"); public static final RegistryKey SELL_TUBE_CORAL_BLOCK = of("sell_tube_coral_block"); public static final RegistryKey SELL_VINE = of("sell_vine"); + public static final RegistryKey SELL_PALE_HANGING_MOSS = of("sell_pale_hanging_moss"); public static final RegistryKey SELL_BROWN_MUSHROOM = of("sell_brown_mushroom"); public static final RegistryKey SELL_RED_MUSHROOM = of("sell_red_mushroom"); public static final RegistryKey SELL_LILY_PAD = of("sell_lily_pad"); @@ -364,12 +413,10 @@ public class Trades { public static final RegistryKey SELL_POINTED_DRIPSTONE = of("sell_pointed_dripstone"); public static final RegistryKey SELL_ROOTED_DIRT = of("sell_rooted_dirt"); public static final RegistryKey SELL_MOSS_BLOCK = of("sell_moss_block"); - public static final RegistryKey SELL_TROPICAL_FISH_BUCKET = of("sell_tropical_fish_bucket"); - public static final RegistryKey SELL_PUFFERFISH_BUCKET = of("sell_pufferfish_bucket"); - public static final RegistryKey SELL_PACKED_ICE = of("sell_packed_ice"); - public static final RegistryKey SELL_BLUE_ICE = of("sell_blue_ice"); - public static final RegistryKey SELL_GUNPOWDER = of("sell_gunpowder"); - public static final RegistryKey SELL_PODZOL = of("sell_podzol"); + public static final RegistryKey SELL_PALE_MOSS_BLOCK = of("sell_pale_moss_block"); + public static final RegistryKey SELL_WILDFLOWERS = of("sell_wildflowers"); + public static final RegistryKey SELL_TALL_DRY_GRASS = of("sell_tall_dry_grass"); + public static final RegistryKey SELL_FIREFLY_BUSH = of("sell_firefly_bush"); private Trades() {} @@ -378,6 +425,7 @@ public static void bootstrap(Registerable registerable) { RegistryEntryLookup enchantments = registerable.getRegistryLookup(RegistryKeys.ENCHANTMENT); RegistryEntryLookup statusEffects = registerable.getRegistryLookup(RegistryKeys.STATUS_EFFECT); RegistryEntryLookup potions = registerable.getRegistryLookup(RegistryKeys.POTION); + RegistryEntryLookup villagerTypes = registerable.getRegistryLookup(RegistryKeys.VILLAGER_TYPE); registerable.register(BUY_WHEAT, buy(items, items.getOrThrow(ItemKeys.WHEAT), 20, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.noviceBuyTradeExperience())); registerable.register(BUY_POTATO, buy(items, items.getOrThrow(ItemKeys.POTATO), 26, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.noviceBuyTradeExperience())); @@ -410,13 +458,13 @@ public static void bootstrap(Registerable registerable) { registerable.register(BUY_TROPICAL_FISH, buy(items, items.getOrThrow(ItemKeys.TROPICAL_FISH), 6, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertBuyTradeExperience())); registerable.register(BUY_PUFFERFISH, buy(items, items.getOrThrow(ItemKeys.PUFFERFISH), 4, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.masterTradeExperience())); registerable.register(BUY_BOAT, buyFromType(items, items.getOrThrow(ItemKeys.OAK_BOAT), Map.of( - VillagerType.PLAINS, items.getOrThrow(ItemKeys.OAK_BOAT), - VillagerType.TAIGA, items.getOrThrow(ItemKeys.SPRUCE_BOAT), - VillagerType.SNOW, items.getOrThrow(ItemKeys.SPRUCE_BOAT), - VillagerType.DESERT, items.getOrThrow(ItemKeys.JUNGLE_BOAT), - VillagerType.JUNGLE, items.getOrThrow(ItemKeys.JUNGLE_BOAT), - VillagerType.SAVANNA, items.getOrThrow(ItemKeys.ACACIA_BOAT), - VillagerType.SWAMP, items.getOrThrow(ItemKeys.DARK_OAK_BOAT) + villagerTypes.getOrThrow(VillagerType.PLAINS), items.getOrThrow(ItemKeys.OAK_BOAT), + villagerTypes.getOrThrow(VillagerType.TAIGA), items.getOrThrow(ItemKeys.SPRUCE_BOAT), + villagerTypes.getOrThrow(VillagerType.SNOW), items.getOrThrow(ItemKeys.SPRUCE_BOAT), + villagerTypes.getOrThrow(VillagerType.DESERT), items.getOrThrow(ItemKeys.JUNGLE_BOAT), + villagerTypes.getOrThrow(VillagerType.JUNGLE), items.getOrThrow(ItemKeys.JUNGLE_BOAT), + villagerTypes.getOrThrow(VillagerType.SAVANNA), items.getOrThrow(ItemKeys.ACACIA_BOAT), + villagerTypes.getOrThrow(VillagerType.SWAMP), items.getOrThrow(ItemKeys.DARK_OAK_BOAT) ))); registerable.register(BUY_WHITE_WOOL, buy(items, items.getOrThrow(ItemKeys.WHITE_WOOL), 18, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.noviceBuyTradeExperience())); registerable.register(BUY_BROWN_WOOL, buy(items, items.getOrThrow(ItemKeys.BROWN_WOOL), 18, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.noviceBuyTradeExperience())); @@ -428,22 +476,22 @@ public static void bootstrap(Registerable registerable) { registerable.register(BUY_BLACK_DYE, buy(items, items.getOrThrow(ItemKeys.BLACK_DYE), 12, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeBuyTradeExperience())); registerable.register(BUY_LIGHT_BLUE_DYE, buy(items, items.getOrThrow(ItemKeys.LIGHT_BLUE_DYE), 12, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeBuyTradeExperience())); registerable.register(BUY_LIME_DYE, buy(items, items.getOrThrow(ItemKeys.LIME_DYE), 12, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeBuyTradeExperience())); - registerable.register(SELL_WHITE_WOOL, sell(items, items.getOrThrow(ItemKeys.WHITE_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); - registerable.register(SELL_ORANGE_WOOL, sell(items, items.getOrThrow(ItemKeys.ORANGE_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); - registerable.register(SELL_MAGENTA_WOOL, sell(items, items.getOrThrow(ItemKeys.MAGENTA_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); - registerable.register(SELL_LIGHT_BLUE_WOOL, sell(items, items.getOrThrow(ItemKeys.LIGHT_BLUE_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); - registerable.register(SELL_YELLOW_WOOL, sell(items, items.getOrThrow(ItemKeys.YELLOW_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); - registerable.register(SELL_LIME_WOOL, sell(items, items.getOrThrow(ItemKeys.LIME_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); - registerable.register(SELL_PINK_WOOL, sell(items, items.getOrThrow(ItemKeys.PINK_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); - registerable.register(SELL_GRAY_WOOL, sell(items, items.getOrThrow(ItemKeys.GRAY_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); - registerable.register(SELL_LIGHT_GRAY_WOOL, sell(items, items.getOrThrow(ItemKeys.LIGHT_GRAY_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); - registerable.register(SELL_CYAN_WOOL, sell(items, items.getOrThrow(ItemKeys.CYAN_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); - registerable.register(SELL_PURPLE_WOOL, sell(items, items.getOrThrow(ItemKeys.PURPLE_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); - registerable.register(SELL_BLUE_WOOL, sell(items, items.getOrThrow(ItemKeys.BLUE_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); - registerable.register(SELL_BROWN_WOOL, sell(items, items.getOrThrow(ItemKeys.BROWN_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); - registerable.register(SELL_GREEN_WOOL, sell(items, items.getOrThrow(ItemKeys.GREEN_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); - registerable.register(SELL_RED_WOOL, sell(items, items.getOrThrow(ItemKeys.RED_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); - registerable.register(SELL_BLACK_WOOL, sell(items, items.getOrThrow(ItemKeys.BLACK_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); + registerable.register(SELL_WHITE_WOOL_SHEPHERD, sell(items, items.getOrThrow(ItemKeys.WHITE_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); + registerable.register(SELL_ORANGE_WOOL_SHEPHERD, sell(items, items.getOrThrow(ItemKeys.ORANGE_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); + registerable.register(SELL_MAGENTA_WOOL_SHEPHERD, sell(items, items.getOrThrow(ItemKeys.MAGENTA_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); + registerable.register(SELL_LIGHT_BLUE_WOOL_SHEPHERD, sell(items, items.getOrThrow(ItemKeys.LIGHT_BLUE_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); + registerable.register(SELL_YELLOW_WOOL_SHEPHERD, sell(items, items.getOrThrow(ItemKeys.YELLOW_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); + registerable.register(SELL_LIME_WOOL_SHEPHERD, sell(items, items.getOrThrow(ItemKeys.LIME_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); + registerable.register(SELL_PINK_WOOL_SHEPHERD, sell(items, items.getOrThrow(ItemKeys.PINK_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); + registerable.register(SELL_GRAY_WOOL_SHEPHERD, sell(items, items.getOrThrow(ItemKeys.GRAY_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); + registerable.register(SELL_LIGHT_GRAY_WOOL_SHEPHERD, sell(items, items.getOrThrow(ItemKeys.LIGHT_GRAY_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); + registerable.register(SELL_CYAN_WOOL_SHEPHERD, sell(items, items.getOrThrow(ItemKeys.CYAN_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); + registerable.register(SELL_PURPLE_WOOL_SHEPHERD, sell(items, items.getOrThrow(ItemKeys.PURPLE_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); + registerable.register(SELL_BLUE_WOOL_SHEPHERD, sell(items, items.getOrThrow(ItemKeys.BLUE_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); + registerable.register(SELL_BROWN_WOOL_SHEPHERD, sell(items, items.getOrThrow(ItemKeys.BROWN_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); + registerable.register(SELL_GREEN_WOOL_SHEPHERD, sell(items, items.getOrThrow(ItemKeys.GREEN_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); + registerable.register(SELL_RED_WOOL_SHEPHERD, sell(items, items.getOrThrow(ItemKeys.RED_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); + registerable.register(SELL_BLACK_WOOL_SHEPHERD, sell(items, items.getOrThrow(ItemKeys.BLACK_WOOL), 1, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); registerable.register(SELL_WHITE_CARPET, sell(items, items.getOrThrow(ItemKeys.WHITE_CARPET), 4, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); registerable.register(SELL_ORANGE_CARPET, sell(items, items.getOrThrow(ItemKeys.ORANGE_CARPET), 4, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); registerable.register(SELL_MAGENTA_CARPET, sell(items, items.getOrThrow(ItemKeys.MAGENTA_CARPET), 4, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), 1)); @@ -516,7 +564,7 @@ public static void bootstrap(Registerable registerable) { registerable.register(BUY_TRIPWIRE_HOOK, buy(items, items.getOrThrow(ItemKeys.TRIPWIRE_HOOK), 8, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.masterTradeExperience())); registerable.register(SELL_ENCHANTED_CROSSBOW, sellEnchantedItem(items, items.getOrThrow(ItemKeys.CROSSBOW), 15, 3)); registerable.register(SELL_TIPPED_ARROW, sellWithPotion(items, potions.getOrThrow(PotionTags.TRADEABLE), items.getOrThrow(ItemKeys.ARROW), items.getOrThrow(ItemKeys.TIPPED_ARROW), TradeOffersAccessor.masterTradeExperience())); - registerable.register(BUY_PAPER, buy(items, items.getOrThrow(ItemKeys.PAPER), 24, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.noviceBuyTradeExperience())); + registerable.register(BUY_PAPER_LIBRARIAN, buy(items, items.getOrThrow(ItemKeys.PAPER), 24, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.noviceBuyTradeExperience())); registerable.register(SELL_ENCHANTED_BOOK_NOVICE, sellEnchantedBook(items, TradeOffersAccessor.noviceSellTradeExperience(), enchantments.getOrThrow(EnchantmentTags.TRADEABLE))); registerable.register(SELL_BOOKSHELF, sell(items, items.getOrThrow(ItemKeys.BOOKSHELF), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.noviceSellTradeExperience(), 9)); registerable.register(BUY_BOOK, buy(items, items.getOrThrow(ItemKeys.BOOK), 4, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.apprenticeBuyTradeExperience())); @@ -530,13 +578,37 @@ public static void bootstrap(Registerable registerable) { registerable.register(SELL_CLOCK, sell(items, items.getOrThrow(ItemKeys.CLOCK), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertSellTradeExperience(), 5)); registerable.register(SELL_COMPASS, sell(items, items.getOrThrow(ItemKeys.COMPASS), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertSellTradeExperience(), 4)); registerable.register(SELL_NAME_TAG, sell(items, items.getOrThrow(ItemKeys.NAME_TAG), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.masterTradeExperience(), 20)); + registerable.register(BUY_PAPER_CARTOGRAPHER, buy(items, items.getOrThrow(ItemKeys.PAPER), 24, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.noviceBuyTradeExperience())); registerable.register(SELL_MAP, sell(items, items.getOrThrow(ItemKeys.MAP), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.noviceSellTradeExperience(), 7)); registerable.register(BUY_GLASS_PANE, buy(items, items.getOrThrow(ItemKeys.GLASS_PANE), 11, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.apprenticeBuyTradeExperience())); - registerable.register(SELL_MONUMENT_MAP, sellMap(items, 13, StructureTags.ON_OCEAN_EXPLORER_MAPS, "filled_map.monument", MapDecorationTypes.MONUMENT, TradeOffersAccessor.apprenticeSellTradeExperience())); + registerable.register(SELL_TAIGA_VILLAGE_MAP, sellMap(items, 8, StructureTags.ON_TAIGA_VILLAGE_MAPS, "filled_map.village_taiga", MapDecorationTypes.VILLAGE_TAIGA, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), VillagerType.SWAMP, VillagerType.SNOW, VillagerType.PLAINS)); + registerable.register(SELL_SWAMP_HUT_MAP, sellMap(items, 8, StructureTags.ON_SWAMP_EXPLORER_MAPS, "filled_map.explorer_swamp", MapDecorationTypes.SWAMP_HUT, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), VillagerType.TAIGA, VillagerType.SNOW, VillagerType.JUNGLE)); + registerable.register(SELL_SNOWY_VILLAGE_MAP, sellMap(items, 8, StructureTags.ON_SNOWY_VILLAGE_MAPS, "filled_map.village_snowy", MapDecorationTypes.VILLAGE_SNOWY, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), VillagerType.TAIGA, VillagerType.SWAMP)); + registerable.register(SELL_SAVANNA_VILLAGE_MAP, sellMap(items, 8, StructureTags.ON_SAVANNA_VILLAGE_MAPS, "filled_map.village_savanna", MapDecorationTypes.VILLAGE_SAVANNA, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), VillagerType.PLAINS, VillagerType.JUNGLE, VillagerType.DESERT)); + registerable.register(SELL_PLAINS_VILLAGE_MAP, sellMap(items, 8, StructureTags.ON_PLAINS_VILLAGE_MAPS, "filled_map.village_plains", MapDecorationTypes.VILLAGE_PLAINS, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), VillagerType.TAIGA, VillagerType.SNOW, VillagerType.SAVANNA, VillagerType.DESERT)); + registerable.register(SELL_JUNGLE_TEMPLE_MAP, sellMap(items, 8, StructureTags.ON_JUNGLE_EXPLORER_MAPS, "filled_map.explorer_jungle", MapDecorationTypes.JUNGLE_TEMPLE, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), VillagerType.SWAMP, VillagerType.SAVANNA, VillagerType.DESERT)); + registerable.register(SELL_DESERT_VILLAGE_MAP, sellMap(items, 8, StructureTags.ON_DESERT_VILLAGE_MAPS, "filled_map.village_desert", MapDecorationTypes.VILLAGE_DESERT, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.apprenticeSellTradeExperience(), VillagerType.SAVANNA, VillagerType.JUNGLE)); registerable.register(BUY_COMPASS, buy(items, items.getOrThrow(ItemKeys.COMPASS), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.journeymanBuyTradeExperience())); - registerable.register(SELL_MANSION_MAP, sellMap(items, 14, StructureTags.ON_WOODLAND_EXPLORER_MAPS, "filled_map.mansion", MapDecorationTypes.MANSION, TradeOffersAccessor.journeymanSellTradeExperience())); + registerable.register(SELL_MONUMENT_MAP, sellMap(items, 13, StructureTags.ON_OCEAN_EXPLORER_MAPS, "filled_map.monument", MapDecorationTypes.MONUMENT, TradeOffersAccessor.journeymanSellTradeExperience())); + registerable.register(SELL_TRIAL_CHAMBER_MAP, sellMap(items, 12, StructureTags.ON_TRIAL_CHAMBERS_MAPS, "filled_map.trial_chambers", MapDecorationTypes.TRIAL_CHAMBERS, TradeOffersAccessor.journeymanSellTradeExperience())); registerable.register(SELL_ITEM_FRAME, sell(items, items.getOrThrow(ItemKeys.ITEM_FRAME), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertSellTradeExperience(), 7)); + registerable.register(SELL_BLUE_BANNER_CARTOGRAPHER, sell(items, items.getOrThrow(ItemKeys.BLUE_BANNER), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertSellTradeExperience(), 2, VillagerType.SNOW, VillagerType.TAIGA)); + registerable.register(SELL_WHITE_BANNER_CARTOGRAPHER, sell(items, items.getOrThrow(ItemKeys.WHITE_BANNER), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertSellTradeExperience(), 2, VillagerType.SNOW, VillagerType.PLAINS)); + registerable.register(SELL_RED_BANNER_CARTOGRAPHER, sell(items, items.getOrThrow(ItemKeys.RED_BANNER), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertSellTradeExperience(), 2, VillagerType.SNOW, VillagerType.SAVANNA)); + registerable.register(SELL_GREEN_BANNER_CARTOGRAPHER, sell(items, items.getOrThrow(ItemKeys.GREEN_BANNER), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertSellTradeExperience(), 2, VillagerType.DESERT, VillagerType.SAVANNA, VillagerType.JUNGLE)); + registerable.register(SELL_LIME_BANNER_CARTOGRAPHER, sell(items, items.getOrThrow(ItemKeys.LIME_BANNER), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertSellTradeExperience(), 2, VillagerType.DESERT, VillagerType.TAIGA)); + registerable.register(SELL_PURPLE_BANNER_CARTOGRAPHER, sell(items, items.getOrThrow(ItemKeys.PURPLE_BANNER), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertSellTradeExperience(), 2, VillagerType.TAIGA, VillagerType.SWAMP)); + registerable.register(SELL_CYAN_BANNER_CARTOGRAPHER, sell(items, items.getOrThrow(ItemKeys.CYAN_BANNER), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertSellTradeExperience(), 2, VillagerType.DESERT, VillagerType.SNOW)); + registerable.register(SELL_YELLOW_BANNER_CARTOGRAPHER, sell(items, items.getOrThrow(ItemKeys.YELLOW_BANNER), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertSellTradeExperience(), 2, VillagerType.PLAINS, VillagerType.JUNGLE)); + registerable.register(SELL_ORANGE_BANNER_CARTOGRAPHER, sell(items, items.getOrThrow(ItemKeys.ORANGE_BANNER), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertSellTradeExperience(), 2, VillagerType.SAVANNA, VillagerType.DESERT)); + registerable.register(SELL_BROWN_BANNER_CARTOGRAPHER, sell(items, items.getOrThrow(ItemKeys.BROWN_BANNER), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertSellTradeExperience(), 2, VillagerType.PLAINS, VillagerType.JUNGLE)); + registerable.register(SELL_MAGENTA_BANNER_CARTOGRAPHER, sell(items, items.getOrThrow(ItemKeys.MAGENTA_BANNER), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertSellTradeExperience(), 2, VillagerType.SAVANNA)); + registerable.register(SELL_LIGHT_BLUE_BANNER_CARTOGRAPHER, sell(items, items.getOrThrow(ItemKeys.LIGHT_BLUE_BANNER), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertSellTradeExperience(), 2, VillagerType.SNOW, VillagerType.SWAMP)); + registerable.register(SELL_PINK_BANNER_CARTOGRAPHER, sell(items, items.getOrThrow(ItemKeys.PINK_BANNER), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertSellTradeExperience(), 2, VillagerType.TAIGA, VillagerType.PLAINS)); + registerable.register(SELL_GRAY_BANNER_CARTOGRAPHER, sell(items, items.getOrThrow(ItemKeys.GRAY_BANNER), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertSellTradeExperience(), 2, VillagerType.DESERT)); + registerable.register(SELL_BLACK_BANNER_CARTOGRAPHER, sell(items, items.getOrThrow(ItemKeys.BLACK_BANNER), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.expertSellTradeExperience(), 2, VillagerType.SWAMP)); registerable.register(SELL_GLOBE_BANNER_PATTERN, sell(items, items.getOrThrow(ItemKeys.GLOBE_BANNER_PATTERN), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.masterTradeExperience(), 8)); + registerable.register(SELL_MANSION_MAP, sellMap(items, 14, StructureTags.ON_WOODLAND_EXPLORER_MAPS, "filled_map.mansion", MapDecorationTypes.MANSION, TradeOffersAccessor.journeymanSellTradeExperience())); registerable.register(BUY_ROTTEN_FLESH, buy(items, items.getOrThrow(ItemKeys.ROTTEN_FLESH), 32, TradeOffersAccessor.commonMaxUses(), TradeOffersAccessor.noviceBuyTradeExperience())); registerable.register(SELL_REDSTONE, sell(items, items.getOrThrow(ItemKeys.REDSTONE), 2, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.noviceSellTradeExperience(), 1)); registerable.register(BUY_GOLD_INGOT, buy(items, items.getOrThrow(ItemKeys.GOLD_INGOT), 3, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.apprenticeBuyTradeExperience())); @@ -669,6 +741,7 @@ public static void bootstrap(Registerable registerable) { registerable.register(SELL_OXEYE_DAISY, sell(items, items.getOrThrow(ItemKeys.OXEYE_DAISY), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.noviceSellTradeExperience(), 1)); registerable.register(SELL_CORNFLOWER, sell(items, items.getOrThrow(ItemKeys.CORNFLOWER), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.noviceSellTradeExperience(), 1)); registerable.register(SELL_LILY_OF_THE_VALLEY, sell(items, items.getOrThrow(ItemKeys.LILY_OF_THE_VALLEY), 1, 7, TradeOffersAccessor.noviceSellTradeExperience(), 1)); + registerable.register(SELL_OPEN_EYEBLOSSOM, sell(items, items.getOrThrow(ItemKeys.OPEN_EYEBLOSSOM), 1, 7, TradeOffersAccessor.noviceSellTradeExperience(), 1)); registerable.register(SELL_WHEAT_SEEDS, sell(items, items.getOrThrow(ItemKeys.WHEAT_SEEDS), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.noviceSellTradeExperience(), 1)); registerable.register(SELL_BEETROOT_SEEDS, sell(items, items.getOrThrow(ItemKeys.BEETROOT_SEEDS), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.noviceSellTradeExperience(), 1)); registerable.register(SELL_PUMPKIN_SEEDS, sell(items, items.getOrThrow(ItemKeys.PUMPKIN_SEEDS), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.noviceSellTradeExperience(), 1)); @@ -680,6 +753,7 @@ public static void bootstrap(Registerable registerable) { registerable.register(SELL_OAK_SAPLING, sell(items, items.getOrThrow(ItemKeys.OAK_SAPLING), 1, 8, TradeOffersAccessor.noviceSellTradeExperience(), 5)); registerable.register(SELL_SPRUCE_SAPLING, sell(items, items.getOrThrow(ItemKeys.SPRUCE_SAPLING), 1, 8, TradeOffersAccessor.noviceSellTradeExperience(), 5)); registerable.register(SELL_CHERRY_SAPLING, sell(items, items.getOrThrow(ItemKeys.CHERRY_SAPLING), 1, 8, TradeOffersAccessor.noviceSellTradeExperience(), 5)); + registerable.register(SELL_PALE_OAK_SAPLING, sell(items, items.getOrThrow(ItemKeys.PALE_OAK_SAPLING), 1, 8, TradeOffersAccessor.noviceSellTradeExperience(), 5)); registerable.register(SELL_MANGROVE_PROPAGULE, sell(items, items.getOrThrow(ItemKeys.MANGROVE_PROPAGULE), 1, 8, TradeOffersAccessor.noviceSellTradeExperience(), 5)); registerable.register(SELL_RED_DYE, sell(items, items.getOrThrow(ItemKeys.RED_DYE), 3, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.noviceSellTradeExperience(), 1)); registerable.register(SELL_WHITE_DYE, sell(items, items.getOrThrow(ItemKeys.WHITE_DYE), 3, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.noviceSellTradeExperience(), 1)); @@ -703,6 +777,7 @@ public static void bootstrap(Registerable registerable) { registerable.register(SELL_HORN_CORAL_BLOCK, sell(items, items.getOrThrow(ItemKeys.HORN_CORAL_BLOCK), 1, 8, TradeOffersAccessor.noviceSellTradeExperience(), 3)); registerable.register(SELL_TUBE_CORAL_BLOCK, sell(items, items.getOrThrow(ItemKeys.TUBE_CORAL_BLOCK), 1, 8, TradeOffersAccessor.noviceSellTradeExperience(), 3)); registerable.register(SELL_VINE, sell(items, items.getOrThrow(ItemKeys.VINE), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.noviceSellTradeExperience(), 1)); + registerable.register(SELL_PALE_HANGING_MOSS, sell(items, items.getOrThrow(ItemKeys.PALE_HANGING_MOSS), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.noviceSellTradeExperience(), 1)); registerable.register(SELL_BROWN_MUSHROOM, sell(items, items.getOrThrow(ItemKeys.BROWN_MUSHROOM), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.noviceSellTradeExperience(), 1)); registerable.register(SELL_RED_MUSHROOM, sell(items, items.getOrThrow(ItemKeys.RED_MUSHROOM), 1, TradeOffersAccessor.defaultMaxUses(), TradeOffersAccessor.noviceSellTradeExperience(), 1)); registerable.register(SELL_LILY_PAD, sell(items, items.getOrThrow(ItemKeys.LILY_PAD), 2, 5, TradeOffersAccessor.noviceSellTradeExperience(), 1)); @@ -712,12 +787,33 @@ public static void bootstrap(Registerable registerable) { registerable.register(SELL_POINTED_DRIPSTONE, sell(items, items.getOrThrow(ItemKeys.POINTED_DRIPSTONE), 2, 5, TradeOffersAccessor.noviceSellTradeExperience(), 1)); registerable.register(SELL_ROOTED_DIRT, sell(items, items.getOrThrow(ItemKeys.ROOTED_DIRT), 2, 5, TradeOffersAccessor.noviceSellTradeExperience(), 1)); registerable.register(SELL_MOSS_BLOCK, sell(items, items.getOrThrow(ItemKeys.MOSS_BLOCK), 2, 5, TradeOffersAccessor.noviceSellTradeExperience(), 1)); + registerable.register(SELL_PALE_MOSS_BLOCK, sell(items, items.getOrThrow(ItemKeys.PALE_MOSS_BLOCK), 2, 5, TradeOffersAccessor.noviceSellTradeExperience(), 1)); + registerable.register(SELL_WILDFLOWERS, sell(items, items.getOrThrow(ItemKeys.WILDFLOWERS), 1, 5, TradeOffersAccessor.noviceSellTradeExperience(), 1)); + registerable.register(SELL_TALL_DRY_GRASS, sell(items, items.getOrThrow(ItemKeys.TALL_DRY_GRASS), 1, 5, TradeOffersAccessor.noviceSellTradeExperience(), 1)); + registerable.register(SELL_FIREFLY_BUSH, sell(items, items.getOrThrow(ItemKeys.FIREFLY_BUSH), 1, 5, TradeOffersAccessor.noviceSellTradeExperience(), 1)); registerable.register(SELL_TROPICAL_FISH_BUCKET, sell(items, items.getOrThrow(ItemKeys.TROPICAL_FISH_BUCKET), 1, 4, 1, 5)); registerable.register(SELL_PUFFERFISH_BUCKET, sell(items, items.getOrThrow(ItemKeys.PUFFERFISH_BUCKET), 1, 4, 1, 5)); + registerable.register(BUY_WATER_BOTTLE, buyWithPotion(items, potions.getOrThrow(PotionKeys.WATER), items.getOrThrow(ItemKeys.POTION))); + registerable.register(BUY_WATER_BUCKET, buy(items, items.getOrThrow(ItemKeys.WATER_BUCKET), 1, 2, 2, 1)); + registerable.register(BUY_MILK_BUCKET, buy(items, items.getOrThrow(ItemKeys.MILK_BUCKET), 1, 2, 2, 1)); + registerable.register(BUY_FERMENTED_SPIDER_EYE, buy(items, items.getOrThrow(ItemKeys.FERMENTED_SPIDER_EYE), 1, 3, 2, 1)); + registerable.register(BUY_BAKED_POTATO, buy(items, items.getOrThrow(ItemKeys.BAKED_POTATO), 4, 1, 2, 1)); + registerable.register(BUY_HAY_BLOCK, buy(items, items.getOrThrow(ItemKeys.HAY_BLOCK), 1, 1, 2, 1)); registerable.register(SELL_PACKED_ICE, sell(items, items.getOrThrow(ItemKeys.PACKED_ICE), 1, 6, 1, 3)); registerable.register(SELL_BLUE_ICE, sell(items, items.getOrThrow(ItemKeys.BLUE_ICE), 1, 6, 1, 6)); registerable.register(SELL_GUNPOWDER, sell(items, items.getOrThrow(ItemKeys.GUNPOWDER), 1, 8, 1, 1)); registerable.register(SELL_PODZOL, sell(items, items.getOrThrow(ItemKeys.PODZOL), 3, 6, 1, 3)); + registerable.register(SELL_ACACIA_LOG, sell(items, items.getOrThrow(ItemKeys.ACACIA_LOG), 8, 4, 1, 1)); + registerable.register(SELL_BIRCH_LOG, sell(items, items.getOrThrow(ItemKeys.BIRCH_LOG), 8, 4, 1, 1)); + registerable.register(SELL_CHERRY_LOG, sell(items, items.getOrThrow(ItemKeys.CHERRY_LOG), 8, 4, 1, 1)); + registerable.register(SELL_MANGROVE_LOG, sell(items, items.getOrThrow(ItemKeys.MANGROVE_LOG), 8, 4, 1, 1)); + registerable.register(SELL_DARK_OAK_LOG, sell(items, items.getOrThrow(ItemKeys.DARK_OAK_LOG), 8, 4, 1, 1)); + registerable.register(SELL_JUNGLE_LOG, sell(items, items.getOrThrow(ItemKeys.JUNGLE_LOG), 8, 4, 1, 1)); + registerable.register(SELL_OAK_LOG, sell(items, items.getOrThrow(ItemKeys.OAK_LOG), 8, 4, 1, 1)); + registerable.register(SELL_SPRUCE_LOG, sell(items, items.getOrThrow(ItemKeys.SPRUCE_LOG), 8, 4, 1, 1)); + registerable.register(SELL_PALE_OAK_LOG, sell(items, items.getOrThrow(ItemKeys.PALE_OAK_LOG), 8, 4, 1, 1)); + registerable.register(SELL_ENCHANTED_IRON_PICKAXE_WANDERING_TRADER, sellEnchantedItem(items, items.getOrThrow(ItemKeys.IRON_PICKAXE), 1, 3, TradeOffersAccessor.highPriceMultiplier(), 1)); + registerable.register(SELL_LONG_INVISIBILITY_POTION, sellWithPotion(items, potions.getOrThrow(PotionKeys.LONG_INVISIBILITY), items.getOrThrow(ItemKeys.POTION), 1)); } private static Trade buy(RegistryEntryLookup items, RegistryEntry item, int count, int maxUses, int tradeExperience) { @@ -728,7 +824,15 @@ private static Trade buy(RegistryEntryLookup items, RegistryEntry it .build(); } - private static Trade buyFromType(RegistryEntryLookup items, RegistryEntry item, Map> types) { + private static Trade buy(RegistryEntryLookup items, RegistryEntry item, int count, int givenAmount, int maxUses, int tradeExperience) { + return Trade.builder(Trade.Entry.ofEmerald(items, givenAmount)) + .wants(Trade.Entry.of(item, count)) + .maxUses(maxUses) + .tradeExperience(tradeExperience) + .build(); + } + + private static Trade buyFromType(RegistryEntryLookup items, RegistryEntry item, Map, RegistryEntry> types) { return Trade.builder(Trade.Entry.ofEmerald(items)) .wants(Trade.Entry.of(item)) .tradeExperience(TradeOffersAccessor.masterTradeExperience()) @@ -736,6 +840,14 @@ private static Trade buyFromType(RegistryEntryLookup items, RegistryEntry< .build(); } + private static Trade buyWithPotion(RegistryEntryLookup items, RegistryEntry potion, RegistryEntry item) { + return Trade.builder(Trade.Entry.ofEmerald(items)) + .wants(Trade.Entry.of(item, 1, SetPotionLootFunction.builder(potion).build())) + .maxUses(2) + .tradeExperience(1) + .build(); + } + private static Trade sell(RegistryEntryLookup items, RegistryEntry item, int count, int maxUses, int tradeExperience, int price) { return Trade.builder(Trade.Entry.of(item, count)) .wants(Trade.Entry.ofEmerald(items, price)) @@ -744,6 +856,24 @@ private static Trade sell(RegistryEntryLookup items, RegistryEntry i .build(); } + @SafeVarargs + private static Trade sell(RegistryEntryLookup items, RegistryEntry item, int count, int maxUses, int tradeExperience, int price, RegistryKey... types) { + return Trade.builder(Trade.Entry.of(item, count)) + .wants(Trade.Entry.ofEmerald(items, price)) + .maxUses(maxUses) + .tradeExperience(tradeExperience) + .merchantPredicate( + EntityPropertiesLootCondition.builder( + LootContext.EntityTarget.THIS, + EntityPredicate.Builder.create() + .typeSpecific(VillagerEntitySubPredicate.of( + RegistryEntryList.of(Registries.VILLAGER_TYPE::getOrThrow, types) + )) + ) + ) + .build(); + } + private static Trade sell(RegistryEntryLookup items, RegistryEntry item, int count, RegistryEntry processedItem, int processedCount, int maxUses, int tradeExperience, float priceMultiplier) { return Trade.builder(Trade.Entry.of(processedItem, processedCount)) .wants(Trade.Entry.ofEmerald(items)) @@ -769,9 +899,13 @@ private static Trade sellEnchantedItem(RegistryEntryLookup items, Registry } private static Trade sellEnchantedItem(RegistryEntryLookup items, RegistryEntry item, int tradeExperience, int basePrice, float priceMultiplier) { + return sellEnchantedItem(items, item, tradeExperience, basePrice, priceMultiplier, 3); + } + + private static Trade sellEnchantedItem(RegistryEntryLookup items, RegistryEntry item, int tradeExperience, int basePrice, float priceMultiplier, int maxUses) { return Trade.builder(Trade.Entry.of(item)) .wants(Trade.Entry.ofEmerald(items, basePrice)) - .maxUses(3) + .maxUses(maxUses) .tradeExperience(tradeExperience) .tradeModifier(EnchantWithLevelsTradeModifier.of(0, 5, 19)) .priceMultiplier(priceMultiplier) @@ -786,6 +920,14 @@ private static Trade sellWithPotion(RegistryEntryLookup items, RegistryEnt .build(); } + private static Trade sellWithPotion(RegistryEntryLookup items, RegistryEntry potion, RegistryEntry resultItem, int tradeExperience) { + return Trade.builder(Trade.Entry.of(resultItem, 1, SetPotionLootFunction.builder(potion).build())) + .wants(Trade.Entry.ofEmerald(items, 5)) + .tradeExperience(tradeExperience) + .maxUses(1) + .build(); + } + private static Trade sellDyedItem(RegistryEntryLookup items, RegistryEntry item, int price) { return sellDyedItem(items, item, price, 1); } @@ -813,6 +955,33 @@ private static Trade sellMap(RegistryEntryLookup items, int price, TagKey< .build(); } + @SafeVarargs + private static Trade sellMap(RegistryEntryLookup items, int price, TagKey structure, String name, RegistryEntry decoration, int maxUses, int experience, RegistryKey... types) { + AndLootFunction itemModifier = AndLootFunction.create(List.of( + ExplorationMapLootFunction.builder() + .withDestination(structure) + .withDecoration(decoration) + .searchRadius(100) + .build(), + SetNameLootFunction.builder(Text.translatable(name), SetNameLootFunction.Target.ITEM_NAME) + .build() + )); + return Trade.builder(Trade.Entry.of(items.getOrThrow(ItemKeys.MAP), 1, itemModifier)) + .wants(Trade.Entry.ofEmerald(items, price)) + .maxUses(maxUses) + .tradeExperience(experience) + .merchantPredicate( + EntityPropertiesLootCondition.builder( + LootContext.EntityTarget.THIS, + EntityPredicate.Builder.create() + .typeSpecific(VillagerEntitySubPredicate.of( + RegistryEntryList.of(Registries.VILLAGER_TYPE::getOrThrow, types) + )) + ) + ) + .build(); + } + private static Trade sellEnchantedBook(RegistryEntryLookup items, int tradeExperience, RegistryEntryList enchantments) { return Trade.builder(Trade.Entry.of(items.getOrThrow(ItemKeys.BOOK))) .wants(Trade.Entry.ofEmerald(items, 2)) diff --git a/src/main/java/net/errorcraft/itematic/village/trade/modifier/modifiers/EnchantWithLevelsTradeModifier.java b/src/main/java/net/errorcraft/itematic/village/trade/modifier/modifiers/EnchantWithLevelsTradeModifier.java index b20f8622..a1b1b777 100644 --- a/src/main/java/net/errorcraft/itematic/village/trade/modifier/modifiers/EnchantWithLevelsTradeModifier.java +++ b/src/main/java/net/errorcraft/itematic/village/trade/modifier/modifiers/EnchantWithLevelsTradeModifier.java @@ -12,7 +12,7 @@ import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.item.ItemStack; import net.minecraft.loot.context.LootContext; -import net.minecraft.predicate.ComponentPredicate; +import net.minecraft.predicate.component.ComponentMapPredicate; import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntryList; @@ -47,6 +47,6 @@ public Optional apply(Trade.Input wants, ItemStack gives, LootContex .getOptional(EnchantmentTags.ON_TRADED_EQUIPMENT); ItemStack givesActual = EnchantmentHelper.enchant(random, gives, level, registryManager, enchantments); wants.getStack(this.index).itematic$tryIncrement(level); - return Optional.of(new TradedItem(givesActual.getRegistryEntry(), givesActual.getCount(), ComponentPredicate.of(givesActual.getComponents()))); + return Optional.of(new TradedItem(givesActual.getRegistryEntry(), givesActual.getCount(), ComponentMapPredicate.of(givesActual.getComponents()))); } } diff --git a/src/main/java/net/errorcraft/itematic/village/trade/modifier/modifiers/ItemFromTypeTradeModifier.java b/src/main/java/net/errorcraft/itematic/village/trade/modifier/modifiers/ItemFromTypeTradeModifier.java index df0faf6b..d283654b 100644 --- a/src/main/java/net/errorcraft/itematic/village/trade/modifier/modifiers/ItemFromTypeTradeModifier.java +++ b/src/main/java/net/errorcraft/itematic/village/trade/modifier/modifiers/ItemFromTypeTradeModifier.java @@ -11,7 +11,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.loot.context.LootContext; import net.minecraft.loot.context.LootContextParameters; -import net.minecraft.predicate.ComponentPredicate; +import net.minecraft.predicate.component.ComponentMapPredicate; import net.minecraft.registry.Registries; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntry; @@ -23,12 +23,12 @@ import java.util.Map; import java.util.Optional; -public record ItemFromTypeTradeModifier(Map> types) implements TradeModifier { +public record ItemFromTypeTradeModifier(Map, RegistryEntry> types) implements TradeModifier { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - Codec.simpleMap(Registries.VILLAGER_TYPE.getCodec(), RegistryFixedCodec.of(RegistryKeys.ITEM), Registries.VILLAGER_TYPE).fieldOf("types").forGetter(ItemFromTypeTradeModifier::types) + Codec.simpleMap(Registries.VILLAGER_TYPE.getEntryCodec(), RegistryFixedCodec.of(RegistryKeys.ITEM), Registries.VILLAGER_TYPE).fieldOf("types").forGetter(ItemFromTypeTradeModifier::types) ).apply(instance, ItemFromTypeTradeModifier::new)); - public static ItemFromTypeTradeModifier of(Map> types) { + public static ItemFromTypeTradeModifier of(Map, RegistryEntry> types) { return new ItemFromTypeTradeModifier(types); } @@ -42,11 +42,13 @@ public Optional apply(Trade.Input wants, ItemStack gives, LootContex if (!(context.get(LootContextParameters.THIS_ENTITY) instanceof VillagerDataContainer container)) { return Optional.empty(); } - VillagerType type = container.getVillagerData().getType(); + + RegistryEntry type = container.getVillagerData().type(); if (!this.types.containsKey(type)) { return Optional.empty(); } + ItemStack givesActual = gives.itematic$copyWithItem(this.types.get(type)); - return Optional.of(new TradedItem(givesActual.getRegistryEntry(), givesActual.getCount(), ComponentPredicate.of(givesActual.getComponents()))); + return Optional.of(new TradedItem(givesActual.getRegistryEntry(), givesActual.getCount(), ComponentMapPredicate.of(givesActual.getComponents()))); } } diff --git a/src/main/java/net/errorcraft/itematic/village/trade/modifier/modifiers/SingleEnchantmentTradeModifier.java b/src/main/java/net/errorcraft/itematic/village/trade/modifier/modifiers/SingleEnchantmentTradeModifier.java index 60d5abfb..c55fe090 100644 --- a/src/main/java/net/errorcraft/itematic/village/trade/modifier/modifiers/SingleEnchantmentTradeModifier.java +++ b/src/main/java/net/errorcraft/itematic/village/trade/modifier/modifiers/SingleEnchantmentTradeModifier.java @@ -11,7 +11,7 @@ import net.minecraft.enchantment.Enchantment; import net.minecraft.item.ItemStack; import net.minecraft.loot.context.LootContext; -import net.minecraft.predicate.ComponentPredicate; +import net.minecraft.predicate.component.ComponentMapPredicate; import net.minecraft.registry.RegistryCodecs; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntry; @@ -47,7 +47,7 @@ public Optional apply(Trade.Input wants, ItemStack gives, LootContex Random random = context.getRandom(); this.enchantments.getRandom(random) .ifPresent(entry -> this.apply(wants.getStack(this.index), gives, random, entry)); - return Optional.of(new TradedItem(gives.getRegistryEntry(), gives.getCount(), ComponentPredicate.of(gives.getComponents()))); + return Optional.of(new TradedItem(gives.getRegistryEntry(), gives.getCount(), ComponentMapPredicate.of(gives.getComponents()))); } private void apply(ItemStack wants, ItemStack gives, Random random, RegistryEntry enchantment) { diff --git a/src/main/java/net/errorcraft/itematic/world/action/Action.java b/src/main/java/net/errorcraft/itematic/world/action/Action.java index f816fe91..cf2fac9e 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/Action.java +++ b/src/main/java/net/errorcraft/itematic/world/action/Action.java @@ -5,14 +5,16 @@ import net.errorcraft.itematic.registry.ItematicRegistries; import net.errorcraft.itematic.world.action.actions.SequenceAction; import net.errorcraft.itematic.world.action.context.ActionContext; +import net.errorcraft.itematic.world.action.sequence.handler.SequenceHandler; import net.errorcraft.itematic.world.action.sequence.handler.handlers.UncheckedSequenceHandler; public interface Action> { Codec> ELEMENT_CODEC = ItematicRegistries.ACTION_TYPE.getCodec().dispatch("type", Action::type, ActionType::codec); Codec> CODEC = Codec.lazyInitialized(() -> Codec.either(ELEMENT_CODEC, UncheckedSequenceHandler.CODEC).xmap(either -> either.map(action -> action, SequenceAction::new), action -> { - if (action instanceof SequenceAction sequenceAction && sequenceAction.handler() instanceof UncheckedSequenceHandler uncheckedSequenceHandler) { + if (action instanceof SequenceAction(SequenceHandler handler) && handler instanceof UncheckedSequenceHandler uncheckedSequenceHandler) { return Either.right(uncheckedSequenceHandler); } + return Either.left(action); })); diff --git a/src/main/java/net/errorcraft/itematic/world/action/ActionEntry.java b/src/main/java/net/errorcraft/itematic/world/action/ActionEntry.java index 23c22a56..7f87a97b 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/ActionEntry.java +++ b/src/main/java/net/errorcraft/itematic/world/action/ActionEntry.java @@ -6,6 +6,8 @@ import net.errorcraft.itematic.world.action.actions.SequenceAction; import net.errorcraft.itematic.world.action.context.ActionContext; import net.errorcraft.itematic.world.action.sequence.handler.SequenceHandler; +import net.minecraft.loot.condition.LootCondition; +import net.minecraft.loot.context.LootContext; import net.minecraft.registry.RegistryCodecs; import net.minecraft.registry.entry.RegistryElementCodec; import net.minecraft.registry.entry.RegistryEntry; @@ -13,26 +15,14 @@ import java.util.Optional; -public record ActionEntry(Action action, Optional requirements) { +public record ActionEntry(Action action, Optional requirements) { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( Action.CODEC.fieldOf("action").forGetter(ActionEntry::action), - ActionRequirements.CODEC.optionalFieldOf("requirements").forGetter(ActionEntry::requirements) + LootCondition.CODEC.optionalFieldOf("requirements").forGetter(ActionEntry::requirements) ).apply(instance, ActionEntry::new)); public static final Codec> REGISTRY_CODEC = RegistryElementCodec.of(ItematicRegistryKeys.ACTION, CODEC); public static final Codec> REGISTRY_ENTRY_LIST_CODEC = RegistryCodecs.entryList(ItematicRegistryKeys.ACTION, CODEC, true); - public Optional execute(ActionContext context) { - if (!this.test(context)) { - return Optional.empty(); - } - return Optional.of(this.action.execute(context)); - } - - private boolean test(ActionContext context) { - return this.requirements.map(requirements -> requirements.test(context)) - .orElse(true); - } - public static ActionEntry of(Action action) { return new ActionEntry(action, Optional.empty()); } @@ -41,11 +31,30 @@ public static ActionEntry of(SequenceHandler.Builder builder) { return new ActionEntry(SequenceAction.of(builder), Optional.empty()); } - public static ActionEntry of(ActionRequirements requirements, Action action) { - return new ActionEntry(action, Optional.of(requirements)); + public static ActionEntry of(LootCondition.Builder requirements, Action action) { + return new ActionEntry(action, Optional.of(requirements.build())); + } + + public static ActionEntry of(LootCondition.Builder requirements, SequenceHandler.Builder builder) { + return new ActionEntry(SequenceAction.of(builder), Optional.of(requirements.build())); } - public static ActionEntry of(ActionRequirements requirements, SequenceHandler.Builder builder) { - return new ActionEntry(SequenceAction.of(builder), Optional.of(requirements)); + public Optional execute(ActionContext context) { + if (!this.test(context)) { + return Optional.empty(); + } + + return Optional.of(this.action.execute(context)); + } + + private boolean test(ActionContext context) { + if (this.requirements.isEmpty()) { + return true; + } + + LootCondition requirements = this.requirements.get(); + LootContext lootContext = context.lootContext(); + lootContext.markActive(LootContext.predicate(requirements)); + return requirements.test(lootContext); } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/ActionRequirements.java b/src/main/java/net/errorcraft/itematic/world/action/ActionRequirements.java deleted file mode 100644 index 2458e382..00000000 --- a/src/main/java/net/errorcraft/itematic/world/action/ActionRequirements.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.errorcraft.itematic.world.action; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameters; -import net.minecraft.loot.condition.LootCondition; -import net.minecraft.loot.context.LootContext; - -public record ActionRequirements(ActionContextParameters context, LootCondition conditions) { - public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - ActionContextParameters.CODEC.fieldOf("context").forGetter(ActionRequirements::context), - LootCondition.CODEC.fieldOf("conditions").forGetter(ActionRequirements::conditions) - ).apply(instance, ActionRequirements::new)); - - public boolean test(ActionContext context) { - LootContext lootContext = context.createLootContext(this.context); - lootContext.markActive(LootContext.predicate(this.conditions)); - return this.conditions.test(lootContext); - } - - public static ActionRequirements of(ActionContextParameters context, LootCondition conditions) { - return new ActionRequirements(context, conditions); - } -} 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 ebca8365..f5155ff9 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/ActionTypeKeys.java +++ b/src/main/java/net/errorcraft/itematic/world/action/ActionTypeKeys.java @@ -20,7 +20,6 @@ public class ActionTypeKeys { public static final RegistryKey> MODIFY_SIGN = of("modify_sign"); public static final RegistryKey> WAX_BLOCK = of("wax_block"); public static final RegistryKey> DECREMENT_ITEM = of("decrement_item"); - public static final RegistryKey> SET_ITEM_POINTER_LOCATION = of("set_item_pointer_location"); public static final RegistryKey> LIGHT_END_PORTAL = of("light_end_portal"); public static final RegistryKey> PLAY_SOUND = of("play_sound"); public static final RegistryKey> DISPLAY_PARTICLE = of("display_particle"); @@ -28,7 +27,6 @@ public class ActionTypeKeys { public static final RegistryKey> DROP_ITEM_FROM_BLOCK = of("drop_item_from_block"); public static final RegistryKey> ATTACH_LEASHED_ENTITIES_ON_BLOCK = of("attach_leashed_entities_on_block"); public static final RegistryKey> SET_ENTITY_NAME_FROM_ITEM = of("set_entity_name_from_item"); - public static final RegistryKey> OPEN_BOOK_FROM_ITEM = of("open_book_from_item"); public static final RegistryKey> PLACE_BLOCK_FROM_ITEM = of("place_block_from_item"); public static final RegistryKey> MARK_BANNER_ON_ITEM = of("mark_banner_on_item"); public static final RegistryKey> TWIRL_PLAYER = of("twirl_player"); @@ -40,7 +38,6 @@ public class ActionTypeKeys { public static final RegistryKey> INVOKE_GAME_EVENT = of("invoke_game_event"); public static final RegistryKey> INVOKE_ITEM_EVENT = of("invoke_item_event"); public static final RegistryKey> PLACE_CARVED_PUMPKIN = of("place_carved_pumpkin"); - public static final RegistryKey> SADDLE_ENTITY_AT_POSITION = of("saddle_entity_at_position"); public static final RegistryKey> SHEAR_AT_POSITION = of("shear_at_position"); public static final RegistryKey> SHOOT_PROJECTILE_FROM_ITEM = of("shoot_projectile_from_item"); public static final RegistryKey> SPAWN_ENTITY = of("spawn_entity"); 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 8dfc4db3..e75b82bc 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/ActionTypes.java +++ b/src/main/java/net/errorcraft/itematic/world/action/ActionTypes.java @@ -21,7 +21,6 @@ public class ActionTypes { public static final ActionType MODIFY_SIGN = register(ActionTypeKeys.MODIFY_SIGN, new ActionType<>(ModifySignAction.CODEC)); public static final ActionType WAX_BLOCK = register(ActionTypeKeys.WAX_BLOCK, new ActionType<>(WaxBlockAction.CODEC)); public static final ActionType DECREMENT_ITEM = register(ActionTypeKeys.DECREMENT_ITEM, new ActionType<>(DecrementItemAction.CODEC)); - public static final ActionType SET_ITEM_POINTER_LOCATION = register(ActionTypeKeys.SET_ITEM_POINTER_LOCATION, new ActionType<>(SetItemPointerLocationAction.CODEC)); public static final ActionType LIGHT_END_PORTAL = register(ActionTypeKeys.LIGHT_END_PORTAL, new ActionType<>(LightEndPortalAction.CODEC)); public static final ActionType PLAY_SOUND = register(ActionTypeKeys.PLAY_SOUND, new ActionType<>(PlaySoundAction.CODEC)); public static final ActionType DISPLAY_PARTICLE = register(ActionTypeKeys.DISPLAY_PARTICLE, new ActionType<>(DisplayParticleAction.CODEC)); @@ -29,7 +28,6 @@ public class ActionTypes { public static final ActionType DROP_ITEM_FROM_BLOCK = register(ActionTypeKeys.DROP_ITEM_FROM_BLOCK, new ActionType<>(DropItemFromBlockAction.CODEC)); public static final ActionType ATTACH_LEASHED_ENTITIES_ON_BLOCK = register(ActionTypeKeys.ATTACH_LEASHED_ENTITIES_ON_BLOCK, new ActionType<>(AttachLeashedEntitiesOnBlockAction.CODEC)); public static final ActionType SET_ENTITY_NAME_FROM_ITEM = register(ActionTypeKeys.SET_ENTITY_NAME_FROM_ITEM, new ActionType<>(SetEntityNameFromItemAction.CODEC)); - public static final ActionType OPEN_BOOK_FROM_ITEM = register(ActionTypeKeys.OPEN_BOOK_FROM_ITEM, new ActionType<>(OpenBookFromItemAction.CODEC)); public static final ActionType PLACE_BLOCK_FROM_ITEM = register(ActionTypeKeys.PLACE_BLOCK_FROM_ITEM, new ActionType<>(PlaceBlockFromItemAction.CODEC)); public static final ActionType MARK_BANNER_ON_ITEM = register(ActionTypeKeys.MARK_BANNER_ON_ITEM, new ActionType<>(MarkBannerOnItemAction.CODEC)); public static final ActionType TWIRL_PLAYER = register(ActionTypeKeys.TWIRL_PLAYER, new ActionType<>(TwirlPlayerAction.CODEC)); @@ -41,7 +39,6 @@ public class ActionTypes { public static final ActionType INVOKE_GAME_EVENT = register(ActionTypeKeys.INVOKE_GAME_EVENT, new ActionType<>(InvokeGameEventAction.CODEC)); public static final ActionType INVOKE_ITEM_EVENT = register(ActionTypeKeys.INVOKE_ITEM_EVENT, new ActionType<>(InvokeItemEventAction.CODEC)); public static final ActionType PLACE_CARVED_PUMPKIN = register(ActionTypeKeys.PLACE_CARVED_PUMPKIN, new ActionType<>(PlaceCarvedPumpkinAction.CODEC)); - public static final ActionType SADDLE_ENTITY_AT_POSITION = register(ActionTypeKeys.SADDLE_ENTITY_AT_POSITION, new ActionType<>(SaddleEntityAtPositionAction.CODEC)); public static final ActionType SHEAR_AT_POSITION = register(ActionTypeKeys.SHEAR_AT_POSITION, new ActionType<>(ShearAtPositionAction.CODEC)); public static final ActionType SHOOT_PROJECTILE_FROM_ITEM = register(ActionTypeKeys.SHOOT_PROJECTILE_FROM_ITEM, new ActionType<>(ShootProjectileFromItemAction.CODEC)); public static final ActionType SPAWN_ENTITY = register(ActionTypeKeys.SPAWN_ENTITY, new ActionType<>(SpawnEntityAction.CODEC)); diff --git a/src/main/java/net/errorcraft/itematic/world/action/Actions.java b/src/main/java/net/errorcraft/itematic/world/action/Actions.java index 90680401..cd8a538b 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/Actions.java +++ b/src/main/java/net/errorcraft/itematic/world/action/Actions.java @@ -3,13 +3,13 @@ import net.errorcraft.itematic.block.BlockKeys; import net.errorcraft.itematic.block.ItematicBlockTags; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.loot.condition.LocationCheckLootConditionUtil; import net.errorcraft.itematic.loot.predicate.SideCheckPredicate; import net.errorcraft.itematic.registry.ItematicRegistryKeys; import net.errorcraft.itematic.sound.SoundEventKeys; import net.errorcraft.itematic.util.Vec3dProvider; import net.errorcraft.itematic.world.action.actions.*; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameters; +import net.errorcraft.itematic.world.action.context.PositionTarget; import net.errorcraft.itematic.world.action.sequence.handler.handlers.FirstToPassRequirementsSequenceHandler; import net.errorcraft.itematic.world.action.sequence.handler.handlers.PassingSequenceHandler; import net.errorcraft.itematic.world.action.sequence.handler.handlers.UncheckedSequenceHandler; @@ -17,8 +17,8 @@ import net.minecraft.item.Item; import net.minecraft.loot.condition.AllOfLootCondition; import net.minecraft.loot.condition.InvertedLootCondition; -import net.minecraft.loot.condition.LocationCheckLootCondition; import net.minecraft.loot.condition.LootCondition; +import net.minecraft.loot.context.LootContext; import net.minecraft.particle.ParticleTypes; import net.minecraft.particle.SimpleParticleType; import net.minecraft.predicate.BlockPredicate; @@ -60,72 +60,70 @@ public static void bootstrap(Registerable registerable) { registerable.register(USE_HOE_ON_BLOCK, ActionEntry.of( PassingSequenceHandler.builder() - .add(FirstToPassRequirementsSequenceHandler.tag(actions.getOrThrow(ActionTags.USE_HOE_ON_BLOCK))) + .add(FirstToPassRequirementsSequenceHandler.of(actions.getOrThrow(ActionTags.USE_HOE_ON_BLOCK))) .add(DamageItemAction.of(1)) - .add(SwingHandAction.INSTANCE) - .add(PlaySoundAction.of(ActionContextParameter.TARGET, soundEvents.getOrThrow(SoundEventKeys.HOE_TILL), SoundCategory.BLOCKS)) + .add(SwingHandAction.of(LootContext.EntityTarget.THIS)) + .add(PlaySoundAction.of(PositionTarget.INTERACTED_POSITION, soundEvents.getOrThrow(SoundEventKeys.HOE_TILL), SoundCategory.BLOCKS)) )); registerable.register(TILL_DIRT, ActionEntry.of( - setBlockRequirements(blocks, builder -> builder.tag(blocks, ItematicBlockTags.TILLABLE_INTO_FARMLAND), true), - SetBlockStateAction.of(ActionContextParameter.TARGET, blocks.getOrThrow(BlockKeys.FARMLAND)) + setBlockConditions(blocks, builder -> builder.tag(blocks, ItematicBlockTags.TILLABLE_INTO_FARMLAND)), + SetBlockStateAction.of(PositionTarget.INTERACTED_POSITION, blocks.getOrThrow(BlockKeys.FARMLAND)) )); registerable.register(TILL_COARSE_DIRT, ActionEntry.of( - setBlockRequirements(blocks, builder -> builder.blocks(blocks, blocks.getOrThrow(BlockKeys.COARSE_DIRT).value()), true), - SetBlockStateAction.of(ActionContextParameter.TARGET, blocks.getOrThrow(BlockKeys.DIRT)) + setBlockConditions(blocks, builder -> builder.blocks(blocks, blocks.getOrThrow(BlockKeys.COARSE_DIRT).value())), + SetBlockStateAction.of(PositionTarget.INTERACTED_POSITION, blocks.getOrThrow(BlockKeys.DIRT)) )); registerable.register(TILL_ROOTED_DIRT, ActionEntry.of( - setBlockRequirements(blocks, builder -> builder.blocks(blocks, blocks.getOrThrow(BlockKeys.ROOTED_DIRT).value()), false), + LocationCheckLootConditionUtil.builder( + PositionTarget.INTERACTED_POSITION, + LocationPredicate.Builder.create() + .block(BlockPredicate.Builder.create() + .blocks(blocks, blocks.getOrThrow(BlockKeys.ROOTED_DIRT).value())) + ), PassingSequenceHandler.builder() - .add(SetBlockStateAction.of(ActionContextParameter.TARGET, blocks.getOrThrow(BlockKeys.DIRT))) - .add(DropItemFromBlockAction.of(ActionContextParameter.TARGET, items.getOrThrow(ItemKeys.HANGING_ROOTS))) + .add(SetBlockStateAction.of(PositionTarget.INTERACTED_POSITION, blocks.getOrThrow(BlockKeys.DIRT))) + .add(DropItemFromBlockAction.of(PositionTarget.INTERACTED_POSITION, items.getOrThrow(ItemKeys.HANGING_ROOTS))) )); registerable.register(USE_SHOVEL_ON_BLOCK, ActionEntry.of( - ActionRequirements.of( - ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.TARGET), - InvertedLootCondition.builder( - SideCheckPredicate.builder(Direction.DOWN) - ).build() + InvertedLootCondition.builder( + SideCheckPredicate.builder(Direction.DOWN) ), PassingSequenceHandler.builder() - .add(FirstToPassRequirementsSequenceHandler.tag(actions.getOrThrow(ActionTags.USE_SHOVEL_ON_BLOCK))) + .add(FirstToPassRequirementsSequenceHandler.of(actions.getOrThrow(ActionTags.USE_SHOVEL_ON_BLOCK))) .add(DamageItemAction.of(1)) - .add(SwingHandAction.INSTANCE) + .add(SwingHandAction.of(LootContext.EntityTarget.THIS)) )); registerable.register(FLATTEN_GROUND, ActionEntry.of( - setBlockRequirements(blocks, builder -> builder.tag(blocks, ItematicBlockTags.FLATTENABLE_INTO_DIRT_PATH), true), + setBlockConditions(blocks, builder -> builder.tag(blocks, ItematicBlockTags.FLATTENABLE_INTO_DIRT_PATH)), PassingSequenceHandler.builder() - .add(SetBlockStateAction.of(ActionContextParameter.TARGET, blocks.getOrThrow(BlockKeys.DIRT_PATH))) - .add(PlaySoundAction.of(ActionContextParameter.TARGET, soundEvents.getOrThrow(SoundEventKeys.SHOVEL_FLATTEN), SoundCategory.BLOCKS)) + .add(SetBlockStateAction.of(PositionTarget.INTERACTED_POSITION, blocks.getOrThrow(BlockKeys.DIRT_PATH))) + .add(PlaySoundAction.of(PositionTarget.INTERACTED_POSITION, soundEvents.getOrThrow(SoundEventKeys.SHOVEL_FLATTEN), SoundCategory.BLOCKS)) )); registerable.register(EXTINGUISH_CAMPFIRE, ActionEntry.of( - ActionRequirements.of( - ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.TARGET), - LocationCheckLootCondition.builder( - LocationPredicate.Builder.create() - .block(BlockPredicate.Builder.create() - .tag(blocks, BlockTags.CAMPFIRES) - .state(StatePredicate.Builder.create() - .exactMatch(Properties.LIT, true)))) - .build() + LocationCheckLootConditionUtil.builder( + PositionTarget.INTERACTED_POSITION, + LocationPredicate.Builder.create() + .block(BlockPredicate.Builder.create() + .tag(blocks, BlockTags.CAMPFIRES) + .state(StatePredicate.Builder.create() + .exactMatch(Properties.LIT, true))) ), PassingSequenceHandler.builder() - .add(ModifyBlockStateAction.builder(ActionContextParameter.TARGET) + .add(ModifyBlockStateAction.builder(PositionTarget.INTERACTED_POSITION) .property(Properties.LIT, false) .build()) - .add(PlaySoundAction.builder(ActionContextParameter.TARGET, soundEvents.getOrThrow(SoundEventKeys.FIRE_EXTINGUISH), SoundCategory.BLOCKS) + .add(PlaySoundAction.builder(PositionTarget.INTERACTED_POSITION, soundEvents.getOrThrow(SoundEventKeys.FIRE_EXTINGUISH), SoundCategory.BLOCKS) .volume(0.5f) .pitch(1.8f, 3.4f) .build()) .add(FirstToPassRequirementsSequenceHandler.builder() .add( - ActionRequirements.of( - ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.TARGET), - LocationCheckLootCondition.builder( - LocationPredicate.Builder.create() - .block(BlockPredicate.Builder.create() - .state(StatePredicate.Builder.create() - .exactMatch(Properties.SIGNAL_FIRE, true)))) - .build() + LocationCheckLootConditionUtil.builder( + PositionTarget.INTERACTED_POSITION, + LocationPredicate.Builder.create() + .block(BlockPredicate.Builder.create() + .state(StatePredicate.Builder.create() + .exactMatch(Properties.SIGNAL_FIRE, true))) ), campfireParticles(true) ) @@ -136,116 +134,105 @@ public static void bootstrap(Registerable registerable) { PassingSequenceHandler.builder() .add(FirstToPassRequirementsSequenceHandler.builder() .add( - ActionRequirements.of( - ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.TARGET), - AllOfLootCondition.builder( - LocationCheckLootCondition.builder( + AllOfLootCondition.builder( + LocationCheckLootConditionUtil.builder( + PositionTarget.INTERACTED_POSITION, + LocationPredicate.Builder.create() + .block(BlockPredicate.Builder.create() + .state(StatePredicate.Builder.create() + .exactMatch(Properties.LIT, false)))), + InvertedLootCondition.builder( + LocationCheckLootConditionUtil.builder( + PositionTarget.INTERACTED_POSITION, LocationPredicate.Builder.create() .block(BlockPredicate.Builder.create() .state(StatePredicate.Builder.create() - .exactMatch(Properties.LIT, false)))), - InvertedLootCondition.builder( - LocationCheckLootCondition.builder( - LocationPredicate.Builder.create() - .block(BlockPredicate.Builder.create() - .state(StatePredicate.Builder.create() - .exactMatch(Properties.WATERLOGGED, true)))))) - .build() + .exactMatch(Properties.WATERLOGGED, true))))) ), - ModifyBlockStateAction.builder(ActionContextParameter.TARGET) + ModifyBlockStateAction.builder(PositionTarget.INTERACTED_POSITION) .property(Properties.LIT, true) .build() ) .add( - ActionRequirements.of( - ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.TARGET), - LocationCheckLootCondition.builder( - LocationPredicate.Builder.create() - .block(BlockPredicate.Builder.create() - .blocks(blocks, blocks.getOrThrow(BlockKeys.TNT).value()))) - .build() + LocationCheckLootConditionUtil.builder( + PositionTarget.INTERACTED_POSITION, + LocationPredicate.Builder.create() + .block(BlockPredicate.Builder.create() + .blocks(blocks, blocks.getOrThrow(BlockKeys.TNT).value())) ), - PrimeTntAction.of(ActionContextParameter.TARGET) + PassingSequenceHandler.builder() + .add(PrimeTntAction.of(PositionTarget.INTERACTED_POSITION)) + .add(PlaySoundAction.of(PositionTarget.INTERACTED_POSITION, soundEvents.getOrThrow(SoundEventKeys.TNT_PRIMED), SoundCategory.BLOCKS)) ) - .add(PlaceBlockAction.of(blocks.getOrThrow(BlockKeys.FIRE), ActionContextParameter.TARGET, false))) - .addOptional(SwingHandAction.INSTANCE) + .add(PlaceBlockAction.of(blocks.getOrThrow(BlockKeys.FIRE), PositionTarget.INTERACTED_POSITION))) + .addOptional(SwingHandAction.of(LootContext.EntityTarget.THIS)) )); } public static ActionEntry waxSign(RegistryEntryLookup blocks, boolean wax) { - return modifySign(blocks, ModifySignAction.wax(ActionContextParameter.TARGET, wax)); + return modifySign(blocks, ModifySignAction.wax(PositionTarget.INTERACTED_POSITION, wax)); } public static ActionEntry glowSign(RegistryEntryLookup blocks, boolean glow) { - return modifySign(blocks, ModifySignAction.glow(ActionContextParameter.TARGET, glow)); + return modifySign(blocks, ModifySignAction.glow(PositionTarget.INTERACTED_POSITION, glow)); } public static ActionEntry potBlock(RegistryEntryLookup blocks, RegistryKey pottedBlock) { return ActionEntry.of( - ActionRequirements.of( - ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.TARGET), - LocationCheckLootCondition.builder( - LocationPredicate.Builder.create() - .block(BlockPredicate.Builder.create() - .blocks(blocks, blocks.getOrThrow(BlockKeys.FLOWER_POT).value()))) - .build() + LocationCheckLootConditionUtil.builder( + PositionTarget.INTERACTED_POSITION, + LocationPredicate.Builder.create() + .block(BlockPredicate.Builder.create() + .blocks(blocks, blocks.getOrThrow(BlockKeys.FLOWER_POT).value())) ), PassingSequenceHandler.builder() - .add(SetBlockStateAction.of(ActionContextParameter.TARGET, blocks.getOrThrow(pottedBlock))) - .add(InvokeGameEventAction.of(GameEvent.BLOCK_CHANGE, ActionContextParameter.TARGET, ActionContextParameter.THIS)) - .add(IncrementStatAction.of(ActionContextParameter.THIS, Stats.CUSTOM.getOrCreateStat(Stats.POT_FLOWER))) + .add(SetBlockStateAction.of(PositionTarget.INTERACTED_POSITION, blocks.getOrThrow(pottedBlock))) + .add(InvokeGameEventAction.of(GameEvent.BLOCK_CHANGE, PositionTarget.INTERACTED_POSITION, LootContext.EntityTarget.THIS)) + .add(IncrementStatAction.of(LootContext.EntityTarget.THIS, Stats.CUSTOM.getOrCreateStat(Stats.POT_FLOWER))) .add(DecrementItemAction.of(1)) - .add(SwingHandAction.INSTANCE) + .add(SwingHandAction.of(LootContext.EntityTarget.THIS)) ); } private static ActionEntry modifySign(RegistryEntryLookup blocks, ModifySignAction action) { return ActionEntry.of( - ActionRequirements.of( - ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.TARGET), - LocationCheckLootCondition.builder( - LocationPredicate.Builder.create() - .block(BlockPredicate.Builder.create() - .tag(blocks, BlockTags.SIGNS))) - .build() + LocationCheckLootConditionUtil.builder( + PositionTarget.INTERACTED_POSITION, + LocationPredicate.Builder.create() + .block(BlockPredicate.Builder.create() + .tag(blocks, BlockTags.SIGNS)) ), PassingSequenceHandler.builder() .add(action) .add(DecrementItemAction.of(1)) - .add(SwingHandAction.INSTANCE) + .add(SwingHandAction.of(LootContext.EntityTarget.THIS)) ); } - private static ActionRequirements setBlockRequirements(RegistryEntryLookup blocks, UnaryOperator blockPredicateBuilder, boolean checkEmptySpace) { - return ActionRequirements.of( - ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.TARGET), - setBlockConditions(blocks, blockPredicateBuilder.apply(BlockPredicate.Builder.create()), checkEmptySpace).build() - ); - } - - private static LootCondition.Builder setBlockConditions(RegistryEntryLookup blocks, BlockPredicate.Builder blockPredicate, boolean checkEmptySpace) { - LootCondition.Builder locationCheckPredicate = LocationCheckLootCondition.builder( - LocationPredicate.Builder.create() - .block(blockPredicate)); - if (!checkEmptySpace) { - return locationCheckPredicate; - } + private static LootCondition.Builder setBlockConditions(RegistryEntryLookup blocks, UnaryOperator blockPredicateBuilder) { return AllOfLootCondition.builder( - locationCheckPredicate, + LocationCheckLootConditionUtil.builder( + PositionTarget.INTERACTED_POSITION, + LocationPredicate.Builder.create() + .block(blockPredicateBuilder.apply(BlockPredicate.Builder.create())) + ), InvertedLootCondition.builder( SideCheckPredicate.builder(Direction.DOWN) ), - LocationCheckLootCondition.builder( + LocationCheckLootConditionUtil.builder( + PositionTarget.INTERACTED_POSITION, LocationPredicate.Builder.create() .block(BlockPredicate.Builder.create() .tag(blocks, BlockTags.AIR)), - new BlockPos(0, 1, 0))); + new BlockPos(0, 1, 0) + ) + ); } private static UncheckedSequenceHandler.Builder campfireParticles(boolean signal) { SimpleParticleType type = signal ? ParticleTypes.CAMPFIRE_SIGNAL_SMOKE : ParticleTypes.CAMPFIRE_COSY_SMOKE; return UncheckedSequenceHandler.builder() - .add(DisplayParticleAction.builder(ActionContextParameter.TARGET, type) + .add(DisplayParticleAction.builder(PositionTarget.INTERACTED_POSITION, type) .count(20) .offset(Vec3dProvider.of( -1.0d / 3.0d, 1.0d / 3.0d, @@ -255,7 +242,7 @@ private static UncheckedSequenceHandler.Builder campfireParticles(boolean signal .delta(Vec3dProvider.of(0.0d, 0.07d, 0.0d)) .force() .build()) - .add(DisplayParticleAction.builder(ActionContextParameter.TARGET, type) + .add(DisplayParticleAction.builder(PositionTarget.INTERACTED_POSITION, type) .count(20) .offset(Vec3dProvider.of( -0.25d, 0.25d, 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 index 13cc6e10..b7684380 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/AddStatusEffectsAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/AddStatusEffectsAction.java @@ -6,20 +6,20 @@ 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 net.minecraft.loot.context.LootContext; import java.util.List; -public record AddStatusEffectsAction(List effects, ActionContextParameter entity) implements Action { +public record AddStatusEffectsAction(List effects, LootContext.EntityTarget 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) + LootContext.EntityTarget.CODEC.fieldOf("entity").forGetter(AddStatusEffectsAction::entity) ).apply(instance, AddStatusEffectsAction::new)); public static AddStatusEffectsAction of(StatusEffectInstance... effects) { - return new AddStatusEffectsAction(List.of(effects), ActionContextParameter.THIS); + return new AddStatusEffectsAction(List.of(effects), LootContext.EntityTarget.THIS); } @Override @@ -29,9 +29,11 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - return context.livingEntity(this.entity) - .map(this::addStatusEffects) - .orElse(false); + if (context.get(this.entity.getParameter()) instanceof LivingEntity target) { + return this.addStatusEffects(target); + } + + return false; } private boolean addStatusEffects(LivingEntity target) { diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/ApplySuspiciousStewEffectsFromItemAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/ApplySuspiciousStewEffectsFromItemAction.java index 15ffed86..a66dc265 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/ApplySuspiciousStewEffectsFromItemAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/ApplySuspiciousStewEffectsFromItemAction.java @@ -2,20 +2,25 @@ import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.errorcraft.itematic.item.ItemStackUtil; 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.component.DataComponentTypes; import net.minecraft.component.type.SuspiciousStewEffectsComponent; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContext; +import net.minecraft.loot.context.LootContextParameters; -public record ApplySuspiciousStewEffectsFromItemAction(ActionContextParameter entity) implements Action { +public record ApplySuspiciousStewEffectsFromItemAction(LootContext.EntityTarget entity) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("entity").forGetter(ApplySuspiciousStewEffectsFromItemAction::entity) + LootContext.EntityTarget.CODEC.fieldOf("entity").forGetter(ApplySuspiciousStewEffectsFromItemAction::entity) ).apply(instance, ApplySuspiciousStewEffectsFromItemAction::new)); - public static ApplySuspiciousStewEffectsFromItemAction of(ActionContextParameter entity) { + public static ApplySuspiciousStewEffectsFromItemAction of(LootContext.EntityTarget entity) { return new ApplySuspiciousStewEffectsFromItemAction(entity); } @@ -26,18 +31,25 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - return context.livingEntity(this.entity) - .map(entity -> { - SuspiciousStewEffectsComponent suspiciousStewEffects = context.stack().get(DataComponentTypes.SUSPICIOUS_STEW_EFFECTS); - if (suspiciousStewEffects == null) { - return false; - } - - for (SuspiciousStewEffectsComponent.StewEffect effect : suspiciousStewEffects.effects()) { - entity.addStatusEffect(effect.createStatusEffectInstance()); - } - return true; - }) - .orElse(false); + ItemStack stack = context.get(LootContextParameters.TOOL); + if (ItemStackUtil.isNullOrEmpty(stack)) { + return false; + } + + SuspiciousStewEffectsComponent suspiciousStewEffects = stack.get(DataComponentTypes.SUSPICIOUS_STEW_EFFECTS); + if (suspiciousStewEffects == null) { + return false; + } + + Entity entity = context.get(this.entity.getParameter()); + if (!(entity instanceof LivingEntity livingEntity)) { + return false; + } + + for (SuspiciousStewEffectsComponent.StewEffect effect : suspiciousStewEffects.effects()) { + livingEntity.addStatusEffect(effect.createStatusEffectInstance()); + } + + return true; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/AttachLeashedEntitiesOnBlockAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/AttachLeashedEntitiesOnBlockAction.java index aab2dda3..511fff23 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/AttachLeashedEntitiesOnBlockAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/AttachLeashedEntitiesOnBlockAction.java @@ -1,19 +1,27 @@ 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.errorcraft.itematic.world.action.context.PositionTarget; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.LeadItem; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.registry.tag.BlockTags; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; -public record AttachLeashedEntitiesOnBlockAction() implements Action { - public static final AttachLeashedEntitiesOnBlockAction INSTANCE = new AttachLeashedEntitiesOnBlockAction(); - public static final MapCodec CODEC = MapCodec.unit(INSTANCE); +public record AttachLeashedEntitiesOnBlockAction(PositionTarget position) implements Action { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + PositionTarget.CODEC.fieldOf("position").forGetter(AttachLeashedEntitiesOnBlockAction::position) + ).apply(instance, AttachLeashedEntitiesOnBlockAction::new)); + + public static AttachLeashedEntitiesOnBlockAction of(PositionTarget position) { + return new AttachLeashedEntitiesOnBlockAction(position); + } @Override public ActionType type() { @@ -22,13 +30,16 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - BlockPos pos = context.blockPos(ActionContextParameter.TARGET); + BlockPos pos = context.getBlockPos(this.position.parameter()); ServerWorld world = context.world(); if (!world.getBlockState(pos).isIn(BlockTags.FENCES)) { return false; } - context.player(ActionContextParameter.THIS) - .ifPresent(player -> LeadItem.attachHeldMobsToBlock(player, world, pos)); - return true; + + if (context.get(LootContextParameters.THIS_ENTITY) instanceof PlayerEntity player) { + return LeadItem.attachHeldMobsToBlock(player, world, pos).isAccepted(); + } + + return false; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/BrushArmadilloAtPositionAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/BrushArmadilloAtPositionAction.java index f5dbb7c7..755d5334 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/BrushArmadilloAtPositionAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/BrushArmadilloAtPositionAction.java @@ -6,21 +6,20 @@ 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.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.entity.passive.ArmadilloEntity; import net.minecraft.predicate.entity.EntityPredicates; -import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; import java.util.List; -public record BrushArmadilloAtPositionAction(ActionContextParameter position) implements Action { +public record BrushArmadilloAtPositionAction(PositionTarget position) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(BrushArmadilloAtPositionAction::position) + PositionTarget.CODEC.fieldOf("position").forGetter(BrushArmadilloAtPositionAction::position) ).apply(instance, BrushArmadilloAtPositionAction::new)); - public static BrushArmadilloAtPositionAction of(ActionContextParameter position) { + public static BrushArmadilloAtPositionAction of(PositionTarget position) { return new BrushArmadilloAtPositionAction(position); } @@ -31,17 +30,26 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - ServerWorld world = context.world(); - BlockPos pos = context.blockPos(this.position); - List armadillos = world.getEntitiesByClass(ArmadilloEntity.class, new Box(pos), EntityPredicates.EXCEPT_SPECTATOR); + BlockPos pos = context.getBlockPos(this.position.parameter()); + if (pos == null) { + return false; + } + + List armadillos = context.world().getEntitiesByClass( + ArmadilloEntity.class, + new Box(pos), + EntityPredicates.EXCEPT_SPECTATOR + ); if (armadillos.isEmpty()) { return false; } + for (ArmadilloEntity armadillo : armadillos) { if (armadillo.brushScute()) { return true; } } + return false; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/ChargeRespawnAnchorAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/ChargeRespawnAnchorAction.java index 852ac99f..70f99f0a 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/ChargeRespawnAnchorAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/ChargeRespawnAnchorAction.java @@ -6,19 +6,20 @@ 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.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.RespawnAnchorBlock; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; -public record ChargeRespawnAnchorAction(ActionContextParameter position) implements Action { +public record ChargeRespawnAnchorAction(PositionTarget position) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(ChargeRespawnAnchorAction::position) + PositionTarget.CODEC.fieldOf("position").forGetter(ChargeRespawnAnchorAction::position) ).apply(instance, ChargeRespawnAnchorAction::new)); - public static ChargeRespawnAnchorAction of(ActionContextParameter position) { + public static ChargeRespawnAnchorAction of(PositionTarget position) { return new ChargeRespawnAnchorAction(position); } @@ -30,15 +31,21 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { ServerWorld world = context.world(); - BlockPos pos = context.blockPos(this.position); + BlockPos pos = context.getBlockPos(this.position.parameter()); + if (pos == null) { + return false; + } + BlockState state = world.getBlockState(pos); if (!state.isOf(Blocks.RESPAWN_ANCHOR)) { return false; } + if (state.get(RespawnAnchorBlock.CHARGES) == RespawnAnchorBlock.MAX_CHARGES) { return false; } - RespawnAnchorBlock.charge(context.entity(ActionContextParameter.THIS).orElse(null), world, pos, state); + + RespawnAnchorBlock.charge(context.get(LootContextParameters.THIS_ENTITY), world, pos, state); return true; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/ClearStatusEffectsAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/ClearStatusEffectsAction.java index ff1f7645..754e1bd6 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/ClearStatusEffectsAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/ClearStatusEffectsAction.java @@ -6,18 +6,16 @@ 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.Entity; import net.minecraft.entity.LivingEntity; +import net.minecraft.loot.context.LootContext; -import java.util.Optional; - -public record ClearStatusEffectsAction(ActionContextParameter entity) implements Action { +public record ClearStatusEffectsAction(LootContext.EntityTarget entity) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("entity").forGetter(ClearStatusEffectsAction::entity) + LootContext.EntityTarget.CODEC.fieldOf("entity").forGetter(ClearStatusEffectsAction::entity) ).apply(instance, ClearStatusEffectsAction::new)); - public static ClearStatusEffectsAction of(ActionContextParameter entity) { + public static ClearStatusEffectsAction of(LootContext.EntityTarget entity) { return new ClearStatusEffectsAction(entity); } @@ -28,14 +26,11 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - Optional optionalEntity = context.entity(this.entity); - if (optionalEntity.isEmpty()) { - return false; - } - if (optionalEntity.get() instanceof LivingEntity target) { - target.clearStatusEffects(); - return true; + Entity entity = context.get(this.entity.getParameter()); + if (entity instanceof LivingEntity target) { + return target.clearStatusEffects(); } + return false; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/DamageItemAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/DamageItemAction.java index 420c3134..cb8b062f 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/DamageItemAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/DamageItemAction.java @@ -1,25 +1,23 @@ package net.errorcraft.itematic.world.action.actions; -import com.mojang.serialization.Codec; 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.player.PlayerEntity; +import net.minecraft.entity.LivingEntity; import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.util.dynamic.Codecs; -public record DamageItemAction(int amount, boolean ignoreGameMode) implements Action { +public record DamageItemAction(int amount) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - Codecs.POSITIVE_INT.fieldOf("amount").forGetter(DamageItemAction::amount), - Codec.BOOL.optionalFieldOf("ignore_game_mode", false).forGetter(DamageItemAction::ignoreGameMode) + Codecs.POSITIVE_INT.fieldOf("amount").forGetter(DamageItemAction::amount) ).apply(instance, DamageItemAction::new)); public static DamageItemAction of(int amount) { - return new DamageItemAction(amount, false); + return new DamageItemAction(amount); } @Override @@ -29,22 +27,25 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - ItemStack stack = context.stack(); - if (stack.isEmpty()) { + ItemStack stack = context.get(LootContextParameters.TOOL); + if (stack == null || stack.isEmpty()) { return false; } + if (!stack.isDamageable()) { return false; } - if (!this.preventDamage(context)) { - stack.itematic$damage(this.amount, context); + + if (preventDamage(context)) { + return false; } + + stack.itematic$damage(this.amount, context); return true; } - private boolean preventDamage(ActionContext context) { - return context.entity(ActionContextParameter.THIS).orElse(null) instanceof PlayerEntity player - && player.isCreative() - && !this.ignoreGameMode; + private static boolean preventDamage(ActionContext context) { + return context.get(LootContextParameters.THIS_ENTITY) instanceof LivingEntity entity + && entity.isInCreativeMode(); } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/DecrementItemAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/DecrementItemAction.java index 7a1a7d48..3dc39cea 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/DecrementItemAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/DecrementItemAction.java @@ -7,8 +7,10 @@ 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.Entity; +import net.minecraft.entity.LivingEntity; import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.util.dynamic.Codecs; public record DecrementItemAction(int amount, boolean ignoreGameMode) implements Action { @@ -28,15 +30,21 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - ItemStack stack = context.stack(); - if (stack.isEmpty()) { + ItemStack stack = context.get(LootContextParameters.TOOL); + if (stack == null || stack.isEmpty()) { return false; } + if (this.ignoreGameMode) { stack.decrement(this.amount); } else { - stack.decrementUnlessCreative(this.amount, context.livingEntity(ActionContextParameter.THIS).orElse(null)); + Entity entity = context.get(LootContextParameters.THIS_ENTITY); + stack.decrementUnlessCreative( + this.amount, + entity instanceof LivingEntity livingEntity ? livingEntity : null + ); } + return true; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/DisplayParticleAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/DisplayParticleAction.java index c305720e..7308f539 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/DisplayParticleAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/DisplayParticleAction.java @@ -9,17 +9,17 @@ 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.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.particle.ParticleEffect; import net.minecraft.particle.ParticleTypes; -import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.dynamic.Codecs; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.random.Random; -public record DisplayParticleAction(ActionContextParameter position, ParticleEffect particle, int count, Vec3dProvider offset, Vec3dProvider delta, double speed, boolean force) implements Action { +public record DisplayParticleAction(PositionTarget position, ParticleEffect particle, int count, Vec3dProvider offset, Vec3dProvider delta, double speed, boolean force) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(DisplayParticleAction::position), + PositionTarget.CODEC.fieldOf("position").forGetter(DisplayParticleAction::position), ParticleTypes.TYPE_CODEC.fieldOf("particle").forGetter(DisplayParticleAction::particle), Codecs.NON_NEGATIVE_INT.fieldOf("count").forGetter(DisplayParticleAction::count), Vec3dProvider.CODEC.optionalFieldOf("offset", Vec3dProvider.ZERO).forGetter(DisplayParticleAction::offset), @@ -28,7 +28,7 @@ public record DisplayParticleAction(ActionContextParameter position, ParticleEff Codec.BOOL.optionalFieldOf("force", false).forGetter(DisplayParticleAction::force) ).apply(instance, DisplayParticleAction::new)); - public static Builder builder(ActionContextParameter position, ParticleEffect particle) { + public static Builder builder(PositionTarget position, ParticleEffect particle) { return new Builder(position, particle); } @@ -40,23 +40,40 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { ServerWorld world = context.world(); - Vec3d pos = context.position(this.position).add(this.offset.get(world.getRandom())); - return this.spawnParticles(world, pos); + Random random = world.getRandom(); + Vec3d pos = this.position(context, random); + if (pos == null) { + return false; + } + + Vec3d delta = this.delta.get(random); + int amountOfPlayersShown = world.spawnParticles( + this.particle, + this.force, + false, + pos.getX(), + pos.getY(), + pos.getZ(), + this.count, + delta.getX(), + delta.getY(), + delta.getZ(), + this.speed + ); + return amountOfPlayersShown > 0; } - private boolean spawnParticles(ServerWorld world, Vec3d pos) { - Vec3d delta = this.delta.get(world.getRandom()); - int count = 0; - for (ServerPlayerEntity player : world.getPlayers()) { - if (world.spawnParticles(player, this.particle, this.force, pos.getX(), pos.getY(), pos.getZ(), this.count, delta.getX(), delta.getY(), delta.getZ(), this.speed)) { - count++; - } + private Vec3d position(ActionContext context, Random random) { + Vec3d pos = context.get(this.position.parameter()); + if (pos == null) { + return null; } - return count > 0; + + return pos.add(this.offset.get(random)); } public static class Builder { - private final ActionContextParameter position; + private final PositionTarget position; private final ParticleEffect particle; private int count = 0; private Vec3dProvider offset = Vec3dProvider.ZERO; @@ -64,7 +81,7 @@ public static class Builder { private double speed = 0.0d; private boolean force = false; - private Builder(ActionContextParameter position, ParticleEffect particle) { + private Builder(PositionTarget position, ParticleEffect particle) { this.position = position; this.particle = particle; } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/DropItemFromBlockAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/DropItemFromBlockAction.java index 7c0967ca..cca1d0ee 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/DropItemFromBlockAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/DropItemFromBlockAction.java @@ -2,26 +2,27 @@ import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.errorcraft.itematic.util.context.ItematicContextParameters; 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.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.block.Block; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.registry.entry.RegistryFixedCodec; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; -public record DropItemFromBlockAction(ActionContextParameter position, RegistryEntry item) implements Action { +public record DropItemFromBlockAction(PositionTarget position, ItemStack item) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(DropItemFromBlockAction::position), - RegistryFixedCodec.of(RegistryKeys.ITEM).fieldOf("item").forGetter(DropItemFromBlockAction::item) + PositionTarget.CODEC.fieldOf("position").forGetter(DropItemFromBlockAction::position), + ItemStack.CODEC.fieldOf("item").forGetter(DropItemFromBlockAction::item) ).apply(instance, DropItemFromBlockAction::new)); - public static DropItemFromBlockAction of(ActionContextParameter position, RegistryEntry item) { - return new DropItemFromBlockAction(position, item); + public static DropItemFromBlockAction of(PositionTarget position, RegistryEntry item) { + return new DropItemFromBlockAction(position, new ItemStack(item)); } @Override @@ -31,7 +32,17 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - Block.dropStack(context.world(), context.blockPos(this.position), context.side(), new ItemStack(this.item)); + BlockPos pos = context.getBlockPos(this.position.parameter()); + if (pos == null) { + return false; + } + + Direction side = context.get(ItematicContextParameters.SIDE); + if (side == null) { + return false; + } + + Block.dropStack(context.world(), pos, side, this.item.copy()); return true; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/EquipEntityAtPositionAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/EquipEntityAtPositionAction.java index a52cdd78..f1b57f9e 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/EquipEntityAtPositionAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/EquipEntityAtPositionAction.java @@ -2,25 +2,28 @@ import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.errorcraft.itematic.item.ItemStackUtil; 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.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.mob.MobEntity; import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; import java.util.List; -public record EquipEntityAtPositionAction(ActionContextParameter position) implements Action { +public record EquipEntityAtPositionAction(PositionTarget position) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(EquipEntityAtPositionAction::position) + PositionTarget.CODEC.fieldOf("position").forGetter(EquipEntityAtPositionAction::position) ).apply(instance, EquipEntityAtPositionAction::new)); - public static EquipEntityAtPositionAction of(ActionContextParameter position) { + public static EquipEntityAtPositionAction of(PositionTarget position) { return new EquipEntityAtPositionAction(position); } @@ -31,25 +34,35 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - ItemStack equipment = context.stack(); + ItemStack equipment = context.get(LootContextParameters.TOOL); + if (ItemStackUtil.isNullOrEmpty(equipment)) { + return false; + } + + BlockPos pos = context.getBlockPos(this.position.parameter()); + if (pos == null) { + return false; + } + List entities = context.world().getEntitiesByClass( LivingEntity.class, - new Box(context.blockPos(this.position)), + new Box(pos), entity -> entity.canEquipFromDispenser(equipment) ); if (entities.isEmpty()) { return false; } - LivingEntity target = entities.getFirst(); - EquipmentSlot equipmentSlot = target.getPreferredEquipmentSlot(equipment); - ItemStack equippedStack = equipment.copyWithCount(1); - target.equipStack(equipmentSlot, equippedStack); - if (target instanceof MobEntity mobEntity) { - mobEntity.setEquipmentDropChance(equipmentSlot, 2.0f); - mobEntity.setPersistent(); - } - + equip(entities.getFirst(), equipment.copyWithCount(1)); return true; } + + private static void equip(LivingEntity target, ItemStack equipment) { + EquipmentSlot slot = target.getPreferredEquipmentSlot(equipment); + target.equipStack(slot, equipment); + if (target instanceof MobEntity mobTarget) { + mobTarget.setEquipmentDropChance(slot, 2.0f); + mobTarget.setPersistent(); + } + } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/EquipHorseWithChestAtPositionAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/EquipHorseWithChestAtPositionAction.java index 38b2dceb..63f494be 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/EquipHorseWithChestAtPositionAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/EquipHorseWithChestAtPositionAction.java @@ -2,24 +2,27 @@ import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.errorcraft.itematic.item.ItemStackUtil; 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.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.entity.passive.AbstractDonkeyEntity; import net.minecraft.entity.passive.AbstractHorseEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; import java.util.List; -public record EquipHorseWithChestAtPositionAction(ActionContextParameter position) implements Action { +public record EquipHorseWithChestAtPositionAction(PositionTarget position) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(EquipHorseWithChestAtPositionAction::position) + PositionTarget.CODEC.fieldOf("position").forGetter(EquipHorseWithChestAtPositionAction::position) ).apply(instance, EquipHorseWithChestAtPositionAction::new)); - public static EquipHorseWithChestAtPositionAction of(ActionContextParameter position) { + public static EquipHorseWithChestAtPositionAction of(PositionTarget position) { return new EquipHorseWithChestAtPositionAction(position); } @@ -30,13 +33,27 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - BlockPos pos = context.blockPos(this.position); - List donkeys = context.world().getEntitiesByClass(AbstractDonkeyEntity.class, new Box(pos), donkey -> donkey.isAlive() && !donkey.hasChest()); + ItemStack stack = context.get(LootContextParameters.TOOL); + if (ItemStackUtil.isNullOrEmpty(stack)) { + return false; + } + + BlockPos pos = context.getBlockPos(this.position.parameter()); + if (pos == null) { + return false; + } + + List donkeys = context.world().getEntitiesByClass( + AbstractDonkeyEntity.class, + new Box(pos), + donkey -> donkey.isAlive() && !donkey.hasChest() + ); for (AbstractDonkeyEntity donkey : donkeys) { - if (donkey.isTame() && donkey.getStackReference(AbstractHorseEntity.field_30414).set(context.stack())) { + if (donkey.isTame() && donkey.getStackReference(AbstractHorseEntity.field_30414).set(stack.copy())) { return true; } } + return false; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/ExchangeItemAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/ExchangeItemAction.java index f396adb9..5c30d674 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/ExchangeItemAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/ExchangeItemAction.java @@ -3,37 +3,31 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.item.ItemUsageUtil; 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.block.dispenser.ItemDispenserBehavior; import net.minecraft.component.ComponentChanges; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.registry.entry.RegistryFixedCodec; -public record ExchangeItemAction(RegistryEntry item, ComponentChanges components, boolean decrementCount) implements Action { +public record ExchangeItemAction(ItemStack item, boolean decrementCount) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - RegistryFixedCodec.of(RegistryKeys.ITEM).fieldOf("item").forGetter(ExchangeItemAction::item), - ComponentChanges.CODEC.optionalFieldOf("components", ComponentChanges.EMPTY).forGetter(ExchangeItemAction::components), + ItemStack.CODEC.fieldOf("item").forGetter(ExchangeItemAction::item), Codec.BOOL.optionalFieldOf("decrement_count", true).forGetter(ExchangeItemAction::decrementCount) ).apply(instance, ExchangeItemAction::new)); public static ExchangeItemAction of(RegistryEntry item) { - return new ExchangeItemAction(item, ComponentChanges.EMPTY, true); + return new ExchangeItemAction(new ItemStack(item), true); } public static ExchangeItemAction ofNoDecrement(RegistryEntry item) { - return new ExchangeItemAction(item, ComponentChanges.EMPTY, false); + return new ExchangeItemAction(new ItemStack(item), false); } public static ExchangeItemAction of(RegistryEntry item, ComponentChanges components) { - return new ExchangeItemAction(item, components, true); + return new ExchangeItemAction(new ItemStack(item, 1, components), true); } @Override @@ -43,24 +37,11 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - ItemStack resultStack = this.exchange(new ItemStack(this.item, 1, this.components), context); - context.setResultStack(resultStack); - return true; - } + if (this.decrementCount) { + context.resultStack().decrement(1); + } - public ItemStack exchange(ItemStack resultStack, ActionContext context) { - return context.player(ActionContextParameter.THIS) - .map(player -> ItemUsageUtil.exchangeStack(context.stack(), player, resultStack, true, this.decrementCount)) - .orElseGet(() -> { - ItemStack stack = context.stack(); - if (this.decrementCount) { - stack.decrement(1); - } - if (stack.isEmpty()) { - return resultStack; - } - ItemDispenserBehavior.spawnItem(context.world(), resultStack, 6, context.side(), context.position(ActionContextParameter.TARGET)); - return stack; - }); + context.exchangeStack(this.item.copy()); + return true; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/FertilizeAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/FertilizeAction.java index e96ecc8a..1152143b 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/FertilizeAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/FertilizeAction.java @@ -1,21 +1,28 @@ package net.errorcraft.itematic.world.action.actions; import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.errorcraft.itematic.util.context.ItematicContextParameters; 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.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.item.BoneMealItem; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.WorldEvents; -import net.minecraft.world.event.GameEvent; -public record FertilizeAction() implements Action { - public static final FertilizeAction INSTANCE = new FertilizeAction(); - public static final MapCodec CODEC = MapCodec.unit(INSTANCE); +public record FertilizeAction(PositionTarget position) implements Action { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + PositionTarget.CODEC.fieldOf("position").forGetter(FertilizeAction::position) + ).apply(instance, FertilizeAction::new)); + + public static FertilizeAction of(PositionTarget position) { + return new FertilizeAction(position); + } @Override public ActionType type() { @@ -24,20 +31,33 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { + Vec3d pos = context.get(this.position.parameter()); + if (pos == null) { + return false; + } + + BlockPos blockPos = BlockPos.ofFloored(pos); ServerWorld world = context.world(); - BlockPos pos = context.blockPos(ActionContextParameter.TARGET); - if (BoneMealItem.useOnFertilizable(context.stack(), world, pos)) { - context.player(ActionContextParameter.THIS).ifPresent(player -> player.emitGameEvent(GameEvent.ITEM_INTERACT_FINISH)); - world.syncWorldEvent(WorldEvents.BONE_MEAL_USED, pos, 15); + if (BoneMealItem.useOnFertilizable(null, world, blockPos)) { + fertilized(world, blockPos); return true; } - Direction side = context.side(); - BlockPos offsetPos = pos.offset(side); - if (world.getBlockState(pos).isSideSolidFullSquare(world, pos, side) && BoneMealItem.useOnGround(context.stack(), world, offsetPos, side)) { - context.player(ActionContextParameter.THIS).ifPresent(player -> player.emitGameEvent(GameEvent.ITEM_INTERACT_FINISH)); - world.syncWorldEvent(WorldEvents.BONE_MEAL_USED, offsetPos, 15); + + Direction side = context.get(ItematicContextParameters.SIDE); + if (side == null) { + return false; + } + + BlockPos offsetBlockPos = blockPos.offset(side); + if (world.getBlockState(blockPos).isSideSolidFullSquare(world, blockPos, side) && BoneMealItem.useOnGround(null, world, offsetBlockPos, side)) { + fertilized(world, offsetBlockPos); return true; } + return false; } + + private static void fertilized(ServerWorld world, BlockPos pos) { + world.syncWorldEvent(WorldEvents.BONE_MEAL_USED, pos, 15); + } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/IncrementStatAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/IncrementStatAction.java index 25ca6592..d22fdcb5 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/IncrementStatAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/IncrementStatAction.java @@ -7,16 +7,17 @@ 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.player.PlayerEntity; +import net.minecraft.loot.context.LootContext; import net.minecraft.stat.Stat; -public record IncrementStatAction(ActionContextParameter entity, Stat stat) implements Action { +public record IncrementStatAction(LootContext.EntityTarget entity, Stat stat) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("entity").forGetter(IncrementStatAction::entity), + LootContext.EntityTarget.CODEC.fieldOf("entity").forGetter(IncrementStatAction::entity), StatUtil.CODEC.fieldOf("stat").forGetter(IncrementStatAction::stat) ).apply(instance, IncrementStatAction::new)); - public static IncrementStatAction of(ActionContextParameter entity, Stat stat) { + public static IncrementStatAction of(LootContext.EntityTarget entity, Stat stat) { return new IncrementStatAction(entity, stat); } @@ -27,11 +28,11 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - return context.player(this.entity) - .map(player -> { - player.incrementStat(this.stat); - return true; - }) - .orElse(false); + if (context.get(this.entity.getParameter()) instanceof PlayerEntity player) { + player.incrementStat(this.stat); + return true; + } + + return false; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/InvokeGameEventAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/InvokeGameEventAction.java index 6ed5c206..42014887 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/InvokeGameEventAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/InvokeGameEventAction.java @@ -6,8 +6,9 @@ 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.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.entity.Entity; +import net.minecraft.loot.context.LootContext; import net.minecraft.registry.Registries; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.util.math.Vec3d; @@ -15,14 +16,14 @@ import java.util.Optional; -public record InvokeGameEventAction(RegistryEntry event, ActionContextParameter position, Optional entity) implements Action { +public record InvokeGameEventAction(RegistryEntry event, PositionTarget position, Optional entity) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( Registries.GAME_EVENT.getEntryCodec().fieldOf("event").forGetter(InvokeGameEventAction::event), - ActionContextParameter.CODEC.fieldOf("position").forGetter(InvokeGameEventAction::position), - ActionContextParameter.CODEC.optionalFieldOf("entity").forGetter(InvokeGameEventAction::entity) + PositionTarget.CODEC.fieldOf("position").forGetter(InvokeGameEventAction::position), + LootContext.EntityTarget.CODEC.optionalFieldOf("entity").forGetter(InvokeGameEventAction::entity) ).apply(instance, InvokeGameEventAction::new)); - public static InvokeGameEventAction of(RegistryEntry event, ActionContextParameter position, ActionContextParameter entity) { + public static InvokeGameEventAction of(RegistryEntry event, PositionTarget position, LootContext.EntityTarget entity) { return new InvokeGameEventAction(event, position, Optional.of(entity)); } @@ -33,8 +34,14 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - Entity entity = this.entity.flatMap(context::entity).orElse(null); - Vec3d pos = context.position(this.position); + Vec3d pos = context.get(this.position.parameter()); + if (pos == null) { + return false; + } + + Entity entity = this.entity.map(LootContext.EntityTarget::getParameter) + .map(context::get) + .orElse(null); context.world().emitGameEvent(entity, this.event, pos); return true; } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/InvokeItemEventAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/InvokeItemEventAction.java index 511965c1..926b105f 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/InvokeItemEventAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/InvokeItemEventAction.java @@ -8,6 +8,8 @@ import net.errorcraft.itematic.world.action.ActionType; import net.errorcraft.itematic.world.action.ActionTypes; import net.errorcraft.itematic.world.action.context.ActionContext; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; public record InvokeItemEventAction(ItemEvent event) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( @@ -25,6 +27,7 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - return context.stack().itematic$invokeEvent(this.event, context); + return context.getOrDefault(LootContextParameters.TOOL, ItemStack.EMPTY) + .itematic$invokeEvent(this.event, context); } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/LightEndPortalAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/LightEndPortalAction.java index 04b653ba..72a08805 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/LightEndPortalAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/LightEndPortalAction.java @@ -6,7 +6,7 @@ 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.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.block.Block; import net.minecraft.block.Blocks; import net.minecraft.block.EndPortalFrameBlock; @@ -15,13 +15,13 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.WorldEvents; -public record LightEndPortalAction(ActionContextParameter position) implements Action { +public record LightEndPortalAction(PositionTarget position) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(LightEndPortalAction::position) + PositionTarget.CODEC.fieldOf("position").forGetter(LightEndPortalAction::position) ).apply(instance, LightEndPortalAction::new)); private static final int PORTAL_SIZE = 3; - public static LightEndPortalAction of(ActionContextParameter position) { + public static LightEndPortalAction of(PositionTarget position) { return new LightEndPortalAction(position); } @@ -33,7 +33,7 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { ServerWorld world = context.world(); - BlockPos pos = context.blockPos(this.position); + BlockPos pos = context.getBlockPos(this.position.parameter()); BlockPattern.Result result = EndPortalFrameBlock.getCompletedFramePattern() .searchAround(world, pos); if (result == null) { diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/MarkBannerOnItemAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/MarkBannerOnItemAction.java index b314399a..6f989aca 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/MarkBannerOnItemAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/MarkBannerOnItemAction.java @@ -2,23 +2,26 @@ import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.errorcraft.itematic.item.ItemStackUtil; 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.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.item.FilledMapItem; +import net.minecraft.item.ItemStack; import net.minecraft.item.map.MapState; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.registry.tag.BlockTags; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; -public record MarkBannerOnItemAction(ActionContextParameter position) implements Action { +public record MarkBannerOnItemAction(PositionTarget position) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(MarkBannerOnItemAction::position) + PositionTarget.CODEC.fieldOf("position").forGetter(MarkBannerOnItemAction::position) ).apply(instance, MarkBannerOnItemAction::new)); - public static MarkBannerOnItemAction of(ActionContextParameter position) { + public static MarkBannerOnItemAction of(PositionTarget position) { return new MarkBannerOnItemAction(position); } @@ -29,12 +32,22 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { + BlockPos pos = context.getBlockPos(this.position.parameter()); + if (pos == null) { + return false; + } + ServerWorld world = context.world(); - BlockPos pos = context.blockPos(this.position); if (!world.getBlockState(pos).isIn(BlockTags.BANNERS)) { return false; } - MapState state = FilledMapItem.getMapState(context.stack(), world); + + ItemStack stack = context.get(LootContextParameters.TOOL); + if (ItemStackUtil.isNullOrEmpty(stack)) { + return false; + } + + MapState state = FilledMapItem.getMapState(stack, world); return state == null || state.addBanner(world, pos); } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/ModifyBlockStateAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/ModifyBlockStateAction.java index 7ec2bc78..964e0cbf 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/ModifyBlockStateAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/ModifyBlockStateAction.java @@ -3,30 +3,29 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.block.BlockStateUtil; 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.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.component.type.BlockStateComponent; import net.minecraft.server.world.ServerWorld; -import net.minecraft.state.StateManager; import net.minecraft.state.property.Property; import net.minecraft.util.math.BlockPos; import java.util.HashMap; import java.util.Map; -public record ModifyBlockStateAction(ActionContextParameter position, Map properties, boolean pushEntitiesUpwards) implements Action { +public record ModifyBlockStateAction(PositionTarget position, BlockStateComponent properties, boolean pushEntitiesUpwards) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(ModifyBlockStateAction::position), - Codec.unboundedMap(Codec.STRING, Codec.STRING).fieldOf("properties").forGetter(ModifyBlockStateAction::properties), + PositionTarget.CODEC.fieldOf("position").forGetter(ModifyBlockStateAction::position), + BlockStateComponent.CODEC.fieldOf("properties").forGetter(ModifyBlockStateAction::properties), Codec.BOOL.optionalFieldOf("push_entities_upwards", false).forGetter(ModifyBlockStateAction::pushEntitiesUpwards) ).apply(instance, ModifyBlockStateAction::new)); - public static Builder builder(ActionContextParameter position) { + public static Builder builder(PositionTarget position) { return new Builder(position); } @@ -38,38 +37,40 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { ServerWorld world = context.world(); - BlockPos pos = context.blockPos(this.position); - BlockState state = world.getBlockState(pos); - BlockState newState = state; - StateManager stateManager = state.getBlock().getStateManager(); - for (String key : this.properties.keySet()) { - Property property = stateManager.getProperty(key); - if (property == null) { - continue; - } - newState = BlockStateUtil.with(newState, property, this.properties.get(key)); + BlockPos pos = context.getBlockPos(this.position.parameter()); + if (pos == null) { + return false; } - if (state == newState) { + + BlockState currentState = world.getBlockState(pos); + BlockState newState = this.properties.applyToState(currentState); + if (newState == currentState) { return false; } + if (this.pushEntitiesUpwards) { - Block.pushEntitiesUpBeforeBlockChange(state, newState, world, pos); + Block.pushEntitiesUpBeforeBlockChange(currentState, newState, world, pos); } + world.setBlockState(pos, newState); return true; } public static final class Builder { - private final ActionContextParameter position; + private final PositionTarget position; private final Map properties = new HashMap<>(); private boolean pushEntitiesUpwards = false; - private Builder(ActionContextParameter position) { + private Builder(PositionTarget position) { this.position = position; } public ModifyBlockStateAction build() { - return new ModifyBlockStateAction(this.position, this.properties, this.pushEntitiesUpwards); + return new ModifyBlockStateAction( + this.position, + new BlockStateComponent(this.properties), + this.pushEntitiesUpwards + ); } public > Builder property(Property property, T value) { diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/ModifyItemAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/ModifyItemAction.java index 03c75b76..ee2cacc5 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/ModifyItemAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/ModifyItemAction.java @@ -2,22 +2,39 @@ import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.errorcraft.itematic.item.ItemStackUtil; 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.ActionContextParameters; +import net.errorcraft.itematic.world.action.context.ItemStackTarget; import net.minecraft.item.ItemStack; import net.minecraft.loot.context.LootContext; +import net.minecraft.loot.function.AndLootFunction; import net.minecraft.loot.function.LootFunction; import net.minecraft.loot.function.LootFunctionTypes; -public record ModifyItemAction(LootFunction itemModifier, ActionContextParameters context) implements Action { +import java.util.stream.Stream; + +public record ModifyItemAction(ItemStackTarget stack, LootFunction itemModifier) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - LootFunctionTypes.CODEC.fieldOf("item_modifier").forGetter(ModifyItemAction::itemModifier), - ActionContextParameters.CODEC.fieldOf("context").forGetter(ModifyItemAction::context) + ItemStackTarget.CODEC.optionalFieldOf("stack", ItemStackTarget.TOOL).forGetter(ModifyItemAction::stack), + LootFunctionTypes.CODEC.fieldOf("item_modifier").forGetter(ModifyItemAction::itemModifier) ).apply(instance, ModifyItemAction::new)); + public static ModifyItemAction of(ItemStackTarget stack, LootFunction.Builder itemModifier) { + return new ModifyItemAction(stack, itemModifier.build()); + } + + public static ModifyItemAction of(ItemStackTarget stack, LootFunction.Builder... itemModifiers) { + AndLootFunction itemModifier = AndLootFunction.create( + Stream.of(itemModifiers) + .map(LootFunction.Builder::build) + .toList() + ); + return new ModifyItemAction(stack, itemModifier); + } + @Override public ActionType type() { return ActionTypes.MODIFY_ITEM; @@ -25,13 +42,18 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - if (context.stack().isEmpty()) { + ItemStack stack = context.get(this.stack.parameter()); + if (ItemStackUtil.isNullOrEmpty(stack)) { return false; } - LootContext lootContext = context.createLootContext(this.context); + + LootContext lootContext = context.lootContext(); lootContext.markActive(LootContext.itemModifier(this.itemModifier)); - ItemStack resultStack = this.itemModifier.apply(context.stack(), lootContext); - context.setResultStack(resultStack); + ItemStack resultStack = this.itemModifier.apply(stack, lootContext); + if (resultStack != stack) { + context.exchangeStack(resultStack); + } + return true; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/ModifySignAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/ModifySignAction.java index 56b1b631..3dc900d6 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/ModifySignAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/ModifySignAction.java @@ -7,31 +7,33 @@ 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.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.block.entity.SignBlockEntity; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.util.DyeColor; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import java.util.Optional; -public record ModifySignAction(ActionContextParameter position, Optional color, Optional glow, Optional wax) implements Action { +public record ModifySignAction(PositionTarget position, Optional color, Optional glow, Optional wax) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(ModifySignAction::position), + PositionTarget.CODEC.fieldOf("position").forGetter(ModifySignAction::position), DyeColor.CODEC.optionalFieldOf("color").forGetter(ModifySignAction::color), Codec.BOOL.optionalFieldOf("glow").forGetter(ModifySignAction::glow), Codec.BOOL.optionalFieldOf("wax").forGetter(ModifySignAction::wax) ).apply(instance, ModifySignAction::new)); - public static ModifySignAction dye(ActionContextParameter position, DyeColor color) { + public static ModifySignAction dye(PositionTarget position, DyeColor color) { return new ModifySignAction(position, Optional.of(color), Optional.empty(), Optional.empty()); } - public static ModifySignAction glow(ActionContextParameter position, boolean glow) { + public static ModifySignAction glow(PositionTarget position, boolean glow) { return new ModifySignAction(position, Optional.empty(), Optional.of(glow), Optional.empty()); } - public static ModifySignAction wax(ActionContextParameter position, boolean wax) { + public static ModifySignAction wax(PositionTarget position, boolean wax) { return new ModifySignAction(position, Optional.empty(), Optional.empty(), Optional.of(wax)); } @@ -42,19 +44,28 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - BlockPos pos = context.blockPos(this.position); - if (!(context.world().getBlockEntity(pos) instanceof SignBlockEntity blockEntity)) { + Vec3d pos = context.get(this.position.parameter()); + if (pos == null) { return false; } - return context.player(ActionContextParameter.THIS) - .map(player -> this.modify(blockEntity, player)) - .orElse(false); + + BlockPos blockPos = BlockPos.ofFloored(pos); + if (!(context.world().getBlockEntity(blockPos) instanceof SignBlockEntity blockEntity)) { + return false; + } + + if (context.get(LootContextParameters.THIS_ENTITY) instanceof PlayerEntity player) { + return this.modify(blockEntity, player); + } + + return false; } private boolean modify(SignBlockEntity blockEntity, PlayerEntity player) { if (blockEntity.isWaxed()) { return false; } + boolean front = blockEntity.isPlayerFacingFront(player); boolean result = false; result |= this.glow.map(glow -> blockEntity.changeText(text -> text.withGlowing(glow), front)) diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/OpenBookFromItemAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/OpenBookFromItemAction.java deleted file mode 100644 index 7ff19a07..00000000 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/OpenBookFromItemAction.java +++ /dev/null @@ -1,32 +0,0 @@ -package net.errorcraft.itematic.world.action.actions; - -import com.mojang.serialization.MapCodec; -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.item.ItemStack; -import net.minecraft.stat.Stats; - -public record OpenBookFromItemAction() implements Action { - public static final OpenBookFromItemAction INSTANCE = new OpenBookFromItemAction(); - public static final MapCodec CODEC = MapCodec.unit(INSTANCE); - - @Override - public ActionType type() { - return ActionTypes.OPEN_BOOK_FROM_ITEM; - } - - @Override - public boolean execute(ActionContext context) { - return context.player(ActionContextParameter.THIS) - .map(player -> { - ItemStack stack = context.stack(); - player.useBook(stack, context.hand()); - player.incrementStat(Stats.USED.itematic$getOrCreateStat(stack.getRegistryEntry())); - return true; - }) - .orElse(false); - } -} diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/PlaceBlockAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/PlaceBlockAction.java index 15db3db9..708b681f 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/PlaceBlockAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/PlaceBlockAction.java @@ -10,23 +10,19 @@ 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.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.block.Block; import net.minecraft.registry.entry.RegistryEntry; -public record PlaceBlockAction(BlockPicker block, ActionContextParameter position, boolean decrementCount) implements Action { +public record PlaceBlockAction(BlockPicker block, PositionTarget position, boolean decrementCount) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( BlockPicker.CODEC.fieldOf("block").forGetter(PlaceBlockAction::block), - ActionContextParameter.CODEC.fieldOf("position").forGetter(PlaceBlockAction::position), + PositionTarget.CODEC.fieldOf("position").forGetter(PlaceBlockAction::position), Codec.BOOL.optionalFieldOf("decrement_count", true).forGetter(PlaceBlockAction::decrementCount) ).apply(instance, PlaceBlockAction::new)); - public static PlaceBlockAction of(RegistryEntry block, ActionContextParameter position, boolean decrementCount) { - return of(new SimpleBlockPicker(block), position, decrementCount); - } - - public static PlaceBlockAction of(BlockPicker block, ActionContextParameter position, boolean decrementCount) { - return new PlaceBlockAction(block, position, decrementCount); + public static PlaceBlockAction of(RegistryEntry block, PositionTarget position) { + return new PlaceBlockAction(new SimpleBlockPicker(block), position, false); } @Override @@ -36,7 +32,11 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - BlockPlacer placer = BlockPlacer.of(context, this.position, this.block, false, this.decrementCount); + BlockPlacer placer = BlockPlacer.action(context, this.position, this.block, this.decrementCount); + if (placer == null) { + return false; + } + return placer.place().succeeds(); } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/PlaceBlockFromItemAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/PlaceBlockFromItemAction.java index d7f38f88..2eef0990 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/PlaceBlockFromItemAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/PlaceBlockFromItemAction.java @@ -4,19 +4,23 @@ import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.item.component.ItemComponentTypes; +import net.errorcraft.itematic.item.component.components.BlockItemComponent; +import net.errorcraft.itematic.item.placement.BlockPlacer; 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.errorcraft.itematic.world.action.context.PositionTarget; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; -public record PlaceBlockFromItemAction(ActionContextParameter position, boolean decrementCount) implements Action { +public record PlaceBlockFromItemAction(PositionTarget position, boolean decrementCount) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(PlaceBlockFromItemAction::position), + PositionTarget.CODEC.fieldOf("position").forGetter(PlaceBlockFromItemAction::position), Codec.BOOL.optionalFieldOf("decrement_count", true).forGetter(PlaceBlockFromItemAction::decrementCount) ).apply(instance, PlaceBlockFromItemAction::new)); - public static PlaceBlockFromItemAction of(ActionContextParameter position, boolean decrementCount) { + public static PlaceBlockFromItemAction of(PositionTarget position, boolean decrementCount) { return new PlaceBlockFromItemAction(position, decrementCount); } @@ -27,10 +31,18 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - return context.stack().itematic$getBehavior(ItemComponentTypes.BLOCK) - .map(component -> { - PlaceBlockAction action = PlaceBlockAction.of(component.block(), this.position, this.decrementCount); - return action.execute(context); - }).orElse(false); + BlockItemComponent block = context.getOrDefault(LootContextParameters.TOOL, ItemStack.EMPTY) + .itematic$getBehavior(ItemComponentTypes.BLOCK) + .orElse(null); + if (block == null) { + return false; + } + + BlockPlacer placer = BlockPlacer.action(context, this.position, block.block(), this.decrementCount); + if (placer == null) { + return false; + } + + return placer.place().succeeds(); } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/PlaceCarvedPumpkinAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/PlaceCarvedPumpkinAction.java index c938b687..640ad91e 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/PlaceCarvedPumpkinAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/PlaceCarvedPumpkinAction.java @@ -6,20 +6,21 @@ 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.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.block.Block; import net.minecraft.block.Blocks; import net.minecraft.block.CarvedPumpkinBlock; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.world.event.GameEvent; -public record PlaceCarvedPumpkinAction(ActionContextParameter position) implements Action { +public record PlaceCarvedPumpkinAction(PositionTarget position) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(PlaceCarvedPumpkinAction::position) + PositionTarget.CODEC.fieldOf("position").forGetter(PlaceCarvedPumpkinAction::position) ).apply(instance, PlaceCarvedPumpkinAction::new)); - public static PlaceCarvedPumpkinAction of(ActionContextParameter position) { + public static PlaceCarvedPumpkinAction of(PositionTarget position) { return new PlaceCarvedPumpkinAction(position); } @@ -30,16 +31,22 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { + BlockPos pos = context.getBlockPos(this.position.parameter()); + if (pos == null) { + return false; + } + ServerWorld world = context.world(); - BlockPos pos = context.blockPos(this.position); if (!world.isAir(pos)) { return false; } + if (!((CarvedPumpkinBlock) Blocks.CARVED_PUMPKIN).canDispense(world, pos)) { return false; } + world.setBlockState(pos, Blocks.CARVED_PUMPKIN.getDefaultState(), Block.NOTIFY_ALL); - world.emitGameEvent(context.entity(ActionContextParameter.THIS).orElse(null), GameEvent.BLOCK_PLACE, pos); + world.emitGameEvent(context.get(LootContextParameters.THIS_ENTITY), GameEvent.BLOCK_PLACE, pos); return true; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/PlaySoundAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/PlaySoundAction.java index 9f5de0c3..eab58d0e 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/PlaySoundAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/PlaySoundAction.java @@ -8,8 +8,9 @@ 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.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.entity.Entity; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.server.world.ServerWorld; import net.minecraft.sound.SoundCategory; @@ -20,9 +21,9 @@ import java.util.Optional; -public record PlaySoundAction(ActionContextParameter position, RegistryEntry sound, Optional category, Range.FloatRange volume, Range.FloatRange pitch, boolean fromEntity) implements Action { +public record PlaySoundAction(PositionTarget position, RegistryEntry sound, Optional category, Range.FloatRange volume, Range.FloatRange pitch, boolean fromEntity) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(PlaySoundAction::position), + PositionTarget.CODEC.fieldOf("position").forGetter(PlaySoundAction::position), SoundEvent.ENTRY_CODEC.fieldOf("sound").forGetter(PlaySoundAction::sound), StringIdentifiable.createCodec(SoundCategory::values).optionalFieldOf("category").forGetter(PlaySoundAction::category), Range.FLOAT_CODEC.fieldOf("volume").forGetter(PlaySoundAction::volume), @@ -30,20 +31,30 @@ public record PlaySoundAction(ActionContextParameter position, RegistryEntry sound, SoundCategory category) { + public static Builder builder(PositionTarget position, RegistryEntry sound, SoundCategory category) { return new Builder(position, sound, category); } - public static PlaySoundAction of(ActionContextParameter position, RegistryEntry sound) { - return new PlaySoundAction(position, sound, Optional.empty(), Range.FloatRange.of(1.0f), Range.FloatRange.of(1.0f), false); + public static PlaySoundAction of(PositionTarget position, RegistryEntry sound) { + return new PlaySoundAction( + position, + sound, + Optional.empty(), + Range.FloatRange.of(1.0f), + Range.FloatRange.of(1.0f), + false + ); } - public static PlaySoundAction of(ActionContextParameter position, RegistryEntry sound, SoundCategory category) { - return new PlaySoundAction(position, sound, Optional.of(category), Range.FloatRange.of(1.0f), Range.FloatRange.of(1.0f), false); - } - - public static PlaySoundAction of(ActionContextParameter position, RegistryEntry sound, SoundCategory category, float volume, float pitch) { - return new PlaySoundAction(position, sound, Optional.of(category), Range.FloatRange.of(volume), Range.FloatRange.of(pitch), false); + public static PlaySoundAction of(PositionTarget position, RegistryEntry sound, SoundCategory category) { + return new PlaySoundAction( + position, + sound, + Optional.of(category), + Range.FloatRange.of(1.0f), + Range.FloatRange.of(1.0f), + false + ); } @Override @@ -53,7 +64,8 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - SoundCategory category = this.category(context.entity(ActionContextParameter.THIS).orElse(null)); + Entity entity = context.get(LootContextParameters.THIS_ENTITY); + SoundCategory category = this.category(entity); if (category == null) { return false; } @@ -63,15 +75,17 @@ public boolean execute(ActionContext context) { float volume = this.volume.get(random); float pitch = this.pitch.get(random); long seed = random.nextLong(); - context.entity(ActionContextParameter.THIS) - .filter(entity -> this.fromEntity) - .ifPresentOrElse( - entity -> world.playSoundFromEntity(null, entity, this.sound, category, volume, pitch, seed), - () -> { - Vec3d pos = context.position(this.position); - world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), this.sound, category, volume, pitch, seed); - } - ); + if (this.fromEntity && entity != null) { + world.playSoundFromEntity(null, entity, this.sound, category, volume, pitch, seed); + return true; + } + + Vec3d pos = context.get(this.position.parameter()); + if (pos == null) { + return false; + } + + world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), this.sound, category, volume, pitch, seed); return true; } @@ -86,13 +100,13 @@ private SoundCategory category(Entity entity) { } public static class Builder { - private final ActionContextParameter position; + private final PositionTarget position; private final RegistryEntry sound; private final SoundCategory category; private Range.FloatRange volume = Range.FloatRange.of(1.0f); private Range.FloatRange pitch = Range.FloatRange.of(1.0f); - private Builder(ActionContextParameter position, RegistryEntry sound, SoundCategory category) { + private Builder(PositionTarget position, RegistryEntry sound, SoundCategory category) { this.position = position; this.sound = sound; this.category = category; diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/PrimeTntAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/PrimeTntAction.java index 2179a9d5..2e828d5c 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/PrimeTntAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/PrimeTntAction.java @@ -2,21 +2,25 @@ import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.errorcraft.itematic.mixin.block.TntBlockAccessor; 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.block.TntBlock; +import net.errorcraft.itematic.world.action.context.PositionTarget; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.server.world.ServerWorld; +import net.minecraft.text.Text; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.GameRules; -public record PrimeTntAction(ActionContextParameter position) implements Action { +public record PrimeTntAction(PositionTarget position) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(PrimeTntAction::position) + PositionTarget.CODEC.fieldOf("position").forGetter(PrimeTntAction::position) ).apply(instance, PrimeTntAction::new)); - public static PrimeTntAction of(ActionContextParameter position) { + public static PrimeTntAction of(PositionTarget position) { return new PrimeTntAction(position); } @@ -27,13 +31,22 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - BlockPos pos = context.blockPos(this.position); + BlockPos pos = context.get(this.position.parameter(), BlockPos::ofFloored); + if (pos == null) { + return false; + } + ServerWorld world = context.world(); - if (world.getBlockState(pos).getBlock() instanceof TntBlock) { - TntBlock.primeTnt(world, pos); + PlayerEntity player = context.get(LootContextParameters.THIS_ENTITY, PlayerEntity.class); + if (TntBlockAccessor.primeTnt(world, pos, player)) { world.removeBlock(pos, false); return true; } + + if (player != null && !world.getGameRules().getBoolean(GameRules.TNT_EXPLODES)) { + player.sendMessage(Text.translatable("block.minecraft.tnt.disabled"), true); + } + return false; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/RemoveStatusEffectsAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/RemoveStatusEffectsAction.java index d7431c95..b5b9a19b 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/RemoveStatusEffectsAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/RemoveStatusEffectsAction.java @@ -6,22 +6,22 @@ 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.StatusEffect; +import net.minecraft.loot.context.LootContext; import net.minecraft.registry.RegistryCodecs; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.registry.entry.RegistryEntryList; -public record RemoveStatusEffectsAction(RegistryEntryList effects, ActionContextParameter entity) implements Action { +public record RemoveStatusEffectsAction(RegistryEntryList effects, LootContext.EntityTarget entity) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( RegistryCodecs.entryList(RegistryKeys.STATUS_EFFECT).fieldOf("effects").forGetter(RemoveStatusEffectsAction::effects), - ActionContextParameter.CODEC.fieldOf("entity").forGetter(RemoveStatusEffectsAction::entity) + LootContext.EntityTarget.CODEC.fieldOf("entity").forGetter(RemoveStatusEffectsAction::entity) ).apply(instance, RemoveStatusEffectsAction::new)); @SafeVarargs - public static RemoveStatusEffectsAction of(ActionContextParameter entity, RegistryEntry... effects) { + public static RemoveStatusEffectsAction of(LootContext.EntityTarget entity, RegistryEntry... effects) { return new RemoveStatusEffectsAction(RegistryEntryList.of(effects), entity); } @@ -32,9 +32,11 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - return context.livingEntity(this.entity) - .map(this::removeStatusEffects) - .orElse(false); + if (context.get(this.entity.getParameter()) instanceof LivingEntity target) { + return this.removeStatusEffects(target); + } + + return false; } private boolean removeStatusEffects(LivingEntity target) { @@ -42,6 +44,7 @@ private boolean removeStatusEffects(LivingEntity target) { for (RegistryEntry effect : this.effects) { removedStatusEffects |= target.removeStatusEffect(effect); } + return removedStatusEffects; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/RunFunctionAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/RunFunctionAction.java index 71ee3538..27c5c5d6 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/RunFunctionAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/RunFunctionAction.java @@ -6,8 +6,9 @@ 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.ActionContextParameters; +import net.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.command.ReturnValueConsumer; +import net.minecraft.loot.context.LootContext; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.function.CommandFunction; import net.minecraft.server.function.CommandFunctionManager; @@ -16,10 +17,11 @@ import java.util.Optional; -public record RunFunctionAction(Identifier function, ActionContextParameters context) implements Action { +public record RunFunctionAction(Identifier function, Optional entity, Optional position) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( Identifier.CODEC.fieldOf("function").forGetter(RunFunctionAction::function), - ActionContextParameters.CODEC.fieldOf("context").forGetter(RunFunctionAction::context) + LootContext.EntityTarget.CODEC.optionalFieldOf("entity").forGetter(RunFunctionAction::entity), + PositionTarget.CODEC.optionalFieldOf("position").forGetter(RunFunctionAction::position) ).apply(instance, RunFunctionAction::new)); @Override @@ -34,8 +36,9 @@ public boolean execute(ActionContext context) { if (function.isEmpty()) { return false; } + MutableBoolean success = new MutableBoolean(); - ServerCommandSource source = context.createCommandSource(this.context, functionManager) + ServerCommandSource source = context.commandSource(functionManager, this.entity, this.position) .mergeReturnValueConsumers((successful, returnValue) -> success.setValue(successful), ReturnValueConsumer::chain); functionManager.execute(function.get(), source); return success.booleanValue(); diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/SaddleEntityAtPositionAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/SaddleEntityAtPositionAction.java deleted file mode 100644 index 60394312..00000000 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/SaddleEntityAtPositionAction.java +++ /dev/null @@ -1,52 +0,0 @@ -package net.errorcraft.itematic.world.action.actions; - -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.item.component.ItemComponentTypes; -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.Saddleable; -import net.minecraft.item.ItemStack; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.sound.SoundCategory; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Box; - -import java.util.List; - -public record SaddleEntityAtPositionAction(ActionContextParameter position) implements Action { - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(SaddleEntityAtPositionAction::position) - ).apply(instance, SaddleEntityAtPositionAction::new)); - - public static SaddleEntityAtPositionAction of(ActionContextParameter position) { - return new SaddleEntityAtPositionAction(position); - } - - @Override - public ActionType type() { - return ActionTypes.SADDLE_ENTITY_AT_POSITION; - } - - @Override - public boolean execute(ActionContext context) { - ItemStack stack = context.stack(); - return stack.itematic$getBehavior(ItemComponentTypes.SADDLE) - .map(c -> { - BlockPos position = context.blockPos(this.position); - ServerWorld world = context.world(); - List targets = world.getEntitiesByClass(LivingEntity.class, new Box(position), entity -> entity instanceof Saddleable); - for (LivingEntity target : targets) { - if (c.trySaddle(target, world, stack, SoundCategory.BLOCKS)) { - return true; - } - } - return false; - }) - .orElse(false); - } -} diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/SequenceAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/SequenceAction.java index b12af64f..0a0316b6 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/SequenceAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/SequenceAction.java @@ -41,9 +41,12 @@ private static void validateEntry(RecursionValidator validator, RegistryEntry referenceEntry)) { return; } + validator.add(referenceEntry); if (referenceEntry.value().action() instanceof SequenceAction action) { action.validate(validator); } + + validator.remove(referenceEntry); } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/SetBlockStateAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/SetBlockStateAction.java index c76685cb..857ae858 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/SetBlockStateAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/SetBlockStateAction.java @@ -6,7 +6,7 @@ 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.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.registry.entry.RegistryEntry; @@ -14,20 +14,16 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.event.GameEvent; -public record SetBlockStateAction(ActionContextParameter position, BlockState state) implements Action { +public record SetBlockStateAction(PositionTarget position, BlockState state) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(SetBlockStateAction::position), + PositionTarget.CODEC.fieldOf("position").forGetter(SetBlockStateAction::position), BlockState.CODEC.fieldOf("state").forGetter(SetBlockStateAction::state) ).apply(instance, SetBlockStateAction::new)); - public static SetBlockStateAction of(ActionContextParameter position, RegistryEntry entry) { + public static SetBlockStateAction of(PositionTarget position, RegistryEntry entry) { return new SetBlockStateAction(position, entry.value().getDefaultState()); } - public static SetBlockStateAction of(ActionContextParameter position, BlockState state) { - return new SetBlockStateAction(position, state); - } - @Override public ActionType type() { return ActionTypes.SET_BLOCK_STATE; @@ -36,10 +32,15 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { ServerWorld world = context.world(); - BlockPos pos = context.blockPos(this.position); + BlockPos pos = context.getBlockPos(this.position.parameter()); + if (pos == null) { + return false; + } + if (!world.setBlockState(pos, this.state, Block.NOTIFY_ALL_AND_REDRAW)) { return false; } + world.emitGameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Emitter.of(this.state)); return true; } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/SetEntityNameFromItemAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/SetEntityNameFromItemAction.java index 6b0408e2..d48da4bc 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/SetEntityNameFromItemAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/SetEntityNameFromItemAction.java @@ -6,19 +6,21 @@ 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.component.DataComponentTypes; import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.mob.MobEntity; -import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContext; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.text.Text; -public record SetEntityNameFromItemAction(ActionContextParameter entity) implements Action { +public record SetEntityNameFromItemAction(LootContext.EntityTarget entity) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("entity").forGetter(SetEntityNameFromItemAction::entity) + LootContext.EntityTarget.CODEC.fieldOf("entity").forGetter(SetEntityNameFromItemAction::entity) ).apply(instance, SetEntityNameFromItemAction::new)); - public static SetEntityNameFromItemAction of(ActionContextParameter entity) { + public static SetEntityNameFromItemAction of(LootContext.EntityTarget entity) { return new SetEntityNameFromItemAction(entity); } @@ -29,20 +31,34 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - Text customName = context.stack().get(DataComponentTypes.CUSTOM_NAME); + ItemStack stack = context.get(LootContextParameters.TOOL); + if (stack == null || stack.isEmpty()) { + return false; + } + + Text customName = stack.get(DataComponentTypes.CUSTOM_NAME); if (customName == null) { return false; } - Entity entity = context.entity(this.entity).orElse(null); - if (entity == null || entity instanceof PlayerEntity) { + + Entity entity = context.get(this.entity.getParameter()); + if (entity instanceof LivingEntity livingEntity) { + return trySetName(livingEntity, customName); + } + + return false; + } + + private static boolean trySetName(LivingEntity target, Text name) { + if (!target.getType().isSaveable() || !target.isAlive()) { return false; } - if (entity.isAlive()) { - entity.setCustomName(customName); - if (entity instanceof MobEntity mobEntity) { - mobEntity.setPersistent(); - } + + target.setCustomName(name); + if (target instanceof MobEntity mobTarget) { + mobTarget.setPersistent(); } + return true; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/SetItemPointerLocationAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/SetItemPointerLocationAction.java deleted file mode 100644 index 2795b294..00000000 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/SetItemPointerLocationAction.java +++ /dev/null @@ -1,57 +0,0 @@ -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.component.DataComponentTypes; -import net.minecraft.component.type.LodestoneTrackerComponent; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemUsage; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.sound.SoundCategory; -import net.minecraft.sound.SoundEvents; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.GlobalPos; -import org.jetbrains.annotations.Nullable; - -import java.util.Optional; - -public record SetItemPointerLocationAction(ActionContextParameter position) implements Action { - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(SetItemPointerLocationAction::position) - ).apply(instance, SetItemPointerLocationAction::new)); - - public static SetItemPointerLocationAction of(ActionContextParameter position) { - return new SetItemPointerLocationAction(position); - } - - @Override - public ActionType type() { - return ActionTypes.SET_ITEM_POINTER_LOCATION; - } - - @Override - public boolean execute(ActionContext context) { - BlockPos pos = context.blockPos(this.position); - ServerWorld world = context.world(); - world.playSound(null, pos, SoundEvents.ITEM_LODESTONE_COMPASS_LOCK, SoundCategory.PLAYERS, 1.0f, 1.0f); - ItemStack stack = context.stack(); - ItemStack resultStack = stack.split(1); - resultStack.set(DataComponentTypes.LODESTONE_TRACKER, new LodestoneTrackerComponent(Optional.of(GlobalPos.create(world.getRegistryKey(), pos)), true)); - PlayerEntity player = context.player(ActionContextParameter.THIS).orElse(null); - context.setResultStack(getResultStack(player, stack, resultStack)); - return true; - } - - private static ItemStack getResultStack(@Nullable PlayerEntity player, ItemStack currentStack, ItemStack newStack) { - if (player == null) { - return newStack; - } - return ItemUsage.exchangeStack(currentStack, player, newStack); - } -} diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/ShearAtPositionAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/ShearAtPositionAction.java index 14d948a0..1ed4a316 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/ShearAtPositionAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/ShearAtPositionAction.java @@ -7,16 +7,18 @@ 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.errorcraft.itematic.world.action.context.PositionTarget; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; -public record ShearAtPositionAction(ActionContextParameter position) implements Action { +public record ShearAtPositionAction(PositionTarget position) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(ShearAtPositionAction::position) + PositionTarget.CODEC.fieldOf("position").forGetter(ShearAtPositionAction::position) ).apply(instance, ShearAtPositionAction::new)); - public static ShearAtPositionAction of(ActionContextParameter position) { + public static ShearAtPositionAction of(PositionTarget position) { return new ShearAtPositionAction(position); } @@ -27,8 +29,13 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { + BlockPos pos = context.getBlockPos(this.position.parameter()); + if (pos == null) { + return false; + } + ServerWorld world = context.world(); - BlockPos pos = context.blockPos(this.position); - return ShearsDispenserBehaviorAccessor.tryShearBlock(world, pos) || ShearsDispenserBehaviorAccessor.tryShearEntity(world, pos, context.stack()); + return ShearsDispenserBehaviorAccessor.tryShearBlock(world, pos) + || ShearsDispenserBehaviorAccessor.tryShearEntity(world, pos, context.getOrDefault(LootContextParameters.TOOL, ItemStack.EMPTY)); } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/ShootProjectileFromItemAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/ShootProjectileFromItemAction.java index 94d8f910..1400b0c8 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/ShootProjectileFromItemAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/ShootProjectileFromItemAction.java @@ -8,16 +8,18 @@ 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.errorcraft.itematic.world.action.context.PositionTarget; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; -public record ShootProjectileFromItemAction(ActionContextParameter position, float power, float uncertainty) implements Action { +public record ShootProjectileFromItemAction(PositionTarget position, float power, float uncertainty) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(ShootProjectileFromItemAction::position), + PositionTarget.CODEC.fieldOf("position").forGetter(ShootProjectileFromItemAction::position), Codec.FLOAT.fieldOf("power").forGetter(ShootProjectileFromItemAction::power), Codec.FLOAT.fieldOf("uncertainty").forGetter(ShootProjectileFromItemAction::uncertainty) ).apply(instance, ShootProjectileFromItemAction::new)); - public static ShootProjectileFromItemAction of(ActionContextParameter position, float power, float uncertainty) { + public static ShootProjectileFromItemAction of(PositionTarget position, float power, float uncertainty) { return new ShootProjectileFromItemAction(position, power, uncertainty); } @@ -28,7 +30,7 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - return context.stack() + return context.getOrDefault(LootContextParameters.TOOL, ItemStack.EMPTY) .itematic$getBehavior(ItemComponentTypes.PROJECTILE) .map(c -> c.createEntity(context, this.position, 0.0f, this.power, this.uncertainty)) .map(entity -> { diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/SpawnEntityAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/SpawnEntityAction.java index 44b9ae43..ad5f7779 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/SpawnEntityAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/SpawnEntityAction.java @@ -2,21 +2,25 @@ import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.entity.initializer.EntityInitializer; import net.errorcraft.itematic.item.placement.EntityPlacer; 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.errorcraft.itematic.world.action.context.PositionTarget; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.SpawnReason; +import net.minecraft.registry.Registries; +import net.minecraft.registry.entry.RegistryEntry; -public record SpawnEntityAction(ActionContextParameter position, EntityInitializer entity) implements Action { +public record SpawnEntityAction(PositionTarget position, RegistryEntry> entity) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(SpawnEntityAction::position), - EntityInitializer.CODEC.fieldOf("entity").forGetter(SpawnEntityAction::entity) + PositionTarget.CODEC.fieldOf("position").forGetter(SpawnEntityAction::position), + Registries.ENTITY_TYPE.getEntryCodec().fieldOf("entity").forGetter(SpawnEntityAction::entity) ).apply(instance, SpawnEntityAction::new)); - public static SpawnEntityAction of(ActionContextParameter position, EntityInitializer entity) { + public static SpawnEntityAction of(PositionTarget position, RegistryEntry> entity) { return new SpawnEntityAction(position, entity); } @@ -27,8 +31,15 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - return EntityPlacer.action(context, this.position, this.entity) - .place() - .succeeds(); + Entity entity = EntityPlacer.of( + this.entity.value(), + context, + false, + SpawnReason.COMMAND, + null, + false, + this.position + ).place(); + return entity != null; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/SpawnEntityFromItemAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/SpawnEntityFromItemAction.java index 1ab228b3..5f0f97b0 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/SpawnEntityFromItemAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/SpawnEntityFromItemAction.java @@ -3,19 +3,20 @@ import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.placement.EntityPlacer; 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.errorcraft.itematic.world.action.context.PositionTarget; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; -public record SpawnEntityFromItemAction(ActionContextParameter position) implements Action { +public record SpawnEntityFromItemAction(PositionTarget position) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(SpawnEntityFromItemAction::position) + PositionTarget.CODEC.fieldOf("position").forGetter(SpawnEntityFromItemAction::position) ).apply(instance, SpawnEntityFromItemAction::new)); - public static SpawnEntityFromItemAction of(ActionContextParameter position) { + public static SpawnEntityFromItemAction of(PositionTarget position) { return new SpawnEntityFromItemAction(position); } @@ -26,11 +27,9 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - return context.stack() + return context.getOrDefault(LootContextParameters.TOOL, ItemStack.EMPTY) .itematic$getBehavior(ItemComponentTypes.ENTITY) - .map(itemComponent -> EntityPlacer.action(context, this.position, itemComponent) - .place() - .succeeds()) - .orElse(false); + .map(entity -> entity.place(context)) + .isPresent(); } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/SwingHandAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/SwingHandAction.java index f1c64922..2827d4d5 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/SwingHandAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/SwingHandAction.java @@ -1,17 +1,25 @@ package net.errorcraft.itematic.world.action.actions; import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.errorcraft.itematic.util.context.ItematicContextParameters; 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.Entity; import net.minecraft.entity.LivingEntity; +import net.minecraft.loot.context.LootContext; import net.minecraft.util.Hand; -public record SwingHandAction() implements Action { - public static final SwingHandAction INSTANCE = new SwingHandAction(); - public static final MapCodec CODEC = MapCodec.unit(INSTANCE); +public record SwingHandAction(LootContext.EntityTarget entity) implements Action { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + LootContext.EntityTarget.CODEC.fieldOf("entity").forGetter(SwingHandAction::entity) + ).apply(instance, SwingHandAction::new)); + + public static SwingHandAction of(LootContext.EntityTarget entity) { + return new SwingHandAction(entity); + } @Override public ActionType type() { @@ -20,14 +28,17 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - if (!(context.entity(ActionContextParameter.THIS).orElse(null) instanceof LivingEntity entity)) { + Entity entity = context.get(this.entity.getParameter()); + if (!(entity instanceof LivingEntity target)) { return false; } - Hand hand = context.hand(); + + Hand hand = context.get(ItematicContextParameters.HAND); if (hand == null) { return false; } - entity.swingHand(hand, true); + + target.swingHand(hand, true); return true; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/TakeHoneyAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/TakeHoneyAction.java index 52f345e0..8ec8638d 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/TakeHoneyAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/TakeHoneyAction.java @@ -6,18 +6,20 @@ 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.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.block.BeehiveBlock; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BeehiveBlockEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.util.math.BlockPos; -public record TakeHoneyAction(ActionContextParameter position) implements Action { +public record TakeHoneyAction(PositionTarget position) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(TakeHoneyAction::position) + PositionTarget.CODEC.fieldOf("position").forGetter(TakeHoneyAction::position) ).apply(instance, TakeHoneyAction::new)); - public static TakeHoneyAction of(ActionContextParameter position) { + public static TakeHoneyAction of(PositionTarget position) { return new TakeHoneyAction(position); } @@ -28,18 +30,31 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - BlockPos pos = context.blockPos(this.position); + BlockPos pos = context.getBlockPos(this.position.parameter()); + if (pos == null) { + return false; + } + BlockState state = context.world().getBlockState(pos); if (!state.contains(BeehiveBlock.HONEY_LEVEL)) { return false; } + if (state.get(BeehiveBlock.HONEY_LEVEL) < BeehiveBlock.FULL_HONEY_LEVEL) { return false; } + if (!(state.getBlock() instanceof BeehiveBlock beehiveBlock)) { return false; } - beehiveBlock.takeHoney(context.world(), state, pos, context.player(ActionContextParameter.THIS).orElse(null), BeehiveBlockEntity.BeeState.BEE_RELEASED); + + beehiveBlock.takeHoney( + context.world(), + state, + pos, + context.get(LootContextParameters.THIS_ENTITY) instanceof PlayerEntity player ? player : null, + BeehiveBlockEntity.BeeState.BEE_RELEASED + ); return true; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/TeleportAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/TeleportAction.java index 0969e472..40ccbe3e 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/TeleportAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/TeleportAction.java @@ -6,29 +6,25 @@ 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.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.passive.FoxEntity; +import net.minecraft.loot.context.LootContext; import net.minecraft.server.world.ServerWorld; -import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvents; import net.minecraft.util.dynamic.Codecs; -import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.world.event.GameEvent; -import java.util.Optional; - -public record TeleportAction(int distance, ActionContextParameter entity) implements Action { +public record TeleportAction(int distance, LootContext.EntityTarget entity) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( Codecs.POSITIVE_INT.fieldOf("distance").forGetter(TeleportAction::distance), - ActionContextParameter.CODEC.fieldOf("entity").forGetter(TeleportAction::entity) + LootContext.EntityTarget.CODEC.fieldOf("entity").forGetter(TeleportAction::entity) ).apply(instance, TeleportAction::new)); private static final int MAX_TELEPORT_ATTEMPTS = 16; - public static TeleportAction of(int distance, ActionContextParameter entity) { + public static TeleportAction of(int distance, LootContext.EntityTarget entity) { return new TeleportAction(distance, entity); } @@ -39,13 +35,11 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - Optional entity = context.entity(this.entity); - if (entity.isEmpty()) { - return false; - } - if (entity.get() instanceof LivingEntity target) { + Entity entity = context.get(this.entity.getParameter()); + if (entity instanceof LivingEntity target) { return this.teleport(target, context.world()); } + return false; } @@ -53,30 +47,38 @@ private boolean teleport(LivingEntity target, ServerWorld world) { Vec3d position = target.getPos(); for (int i = 0; i < MAX_TELEPORT_ATTEMPTS; i++) { double newX = position.getX() + (target.getRandom().nextDouble() - 0.5d) * this.distance; - double newY = MathHelper.clamp(position.getY() + target.getRandom().nextInt(this.distance) - (this.distance * 0.5d), world.getBottomY(), world.getBottomY() + world.getLogicalHeight() - 1); + double newY = Math.clamp( + position.getY() + (target.getRandom().nextDouble() - 0.5d) * this.distance, + world.getBottomY(), + world.getBottomY() + world.getLogicalHeight() - 1 + ); double newZ = position.getZ() + (target.getRandom().nextDouble() - 0.5d) * this.distance; if (target.hasVehicle()) { target.stopRiding(); } + if (target.teleport(newX, newY, newZ, true)) { - this.teleported(target, world, position); + teleported(target, world, position); return true; } } + return false; } - private void teleported(LivingEntity target, ServerWorld world, Vec3d position) { + private static void teleported(LivingEntity target, ServerWorld world, Vec3d position) { world.emitGameEvent(GameEvent.TELEPORT, position, GameEvent.Emitter.of(target)); - SoundEvent soundEvent = getSoundEvent(target); - world.itematic$playSound(null, position, soundEvent, SoundCategory.PLAYERS, 1.0f, 1.0f); + SoundEvent soundEvent = soundEvent(target); + world.itematic$playSound(null, position, soundEvent, target.getSoundCategory(), 1.0f, 1.0f); target.playSound(soundEvent, 1.0f, 1.0f); + target.onLanding(); } - private static SoundEvent getSoundEvent(LivingEntity target) { + private static SoundEvent soundEvent(LivingEntity target) { if (target instanceof FoxEntity) { return SoundEvents.ENTITY_FOX_TELEPORT; } + return SoundEvents.ITEM_CHORUS_FRUIT_TELEPORT; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/TwirlPlayerAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/TwirlPlayerAction.java index 714f84aa..365e407b 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/TwirlPlayerAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/TwirlPlayerAction.java @@ -1,18 +1,20 @@ package net.errorcraft.itematic.world.action.actions; import com.mojang.serialization.MapCodec; +import net.errorcraft.itematic.item.ItemStackUtil; import net.errorcraft.itematic.network.packet.s2c.play.TwirlS2CPacket; 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.component.EnchantmentEffectComponentTypes; import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.Entity; import net.minecraft.entity.MovementType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.item.TridentItem; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.sound.SoundCategory; @@ -21,10 +23,12 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -public record TwirlPlayerAction() implements Action { +public class TwirlPlayerAction implements Action { public static final TwirlPlayerAction INSTANCE = new TwirlPlayerAction(); public static final MapCodec CODEC = MapCodec.unit(INSTANCE); + private TwirlPlayerAction() {} + @Override public ActionType type() { return ActionTypes.TWIRL_PLAYER; @@ -32,12 +36,16 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - PlayerEntity player = context.player(ActionContextParameter.THIS).orElse(null); - if (player == null) { + Entity entity = context.get(LootContextParameters.THIS_ENTITY); + if (!(entity instanceof PlayerEntity player)) { + return false; + } + + ItemStack stack = context.get(LootContextParameters.TOOL); + if (ItemStackUtil.isNullOrEmpty(stack)) { return false; } - ItemStack stack = context.stack(); float spinAttackStrength = EnchantmentHelper.getTridentSpinAttackStrength(stack, player); if (spinAttackStrength <= 0.0f) { return false; diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/UseBucketAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/UseBucketAction.java index 97db3c4e..790ee191 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/UseBucketAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/UseBucketAction.java @@ -3,21 +3,28 @@ import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.item.component.ItemComponentTypes; +import net.errorcraft.itematic.item.component.components.BucketItemComponent; +import net.errorcraft.itematic.util.context.ItematicContextParameters; 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.errorcraft.itematic.world.action.context.PositionTarget; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; +import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; -public record UseBucketAction(ActionContextParameter position) implements Action { +public record UseBucketAction(PositionTarget position) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(UseBucketAction::position) + PositionTarget.CODEC.fieldOf("position").forGetter(UseBucketAction::position) ).apply(instance, UseBucketAction::new)); - public static UseBucketAction of(ActionContextParameter position) { + public static UseBucketAction of(PositionTarget position) { return new UseBucketAction(position); } @@ -28,14 +35,32 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - ItemStack stack = context.stack(); + ItemStack stack = context.getOrDefault(LootContextParameters.TOOL, ItemStack.EMPTY); return stack.itematic$getBehavior(ItemComponentTypes.BUCKET) - .map(c -> { - BlockPos pos = context.blockPos(this.position); - BlockHitResult hitResult = new BlockHitResult(pos.toCenterPos(), context.side(), pos, true); - return c.place(context.world(), context.player(ActionContextParameter.THIS).orElse(null), context.hand(), stack, context.resultStackConsumer(), hitResult) - .succeeds(); - }) + .map(bucket -> this.place(bucket, stack, context)) .orElse(false); } + + private boolean place(BucketItemComponent bucket, ItemStack stack, ActionContext context) { + Vec3d pos = context.get(this.position.parameter()); + if (pos == null) { + return false; + } + + Direction side = context.get(ItematicContextParameters.SIDE); + if (side == null) { + return false; + } + + Hand hand = context.getOrDefault(ItematicContextParameters.HAND, Hand.MAIN_HAND); + BlockHitResult hitResult = new BlockHitResult(pos, side, BlockPos.ofFloored(pos), true); + return bucket.place( + context.world(), + context.get(LootContextParameters.THIS_ENTITY) instanceof PlayerEntity player ? player : null, + hand, + stack, + context.stackExchanger(), + hitResult + ).succeeds(); + } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/WaxBlockAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/WaxBlockAction.java index ea65f77c..a433f040 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/WaxBlockAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/WaxBlockAction.java @@ -6,21 +6,22 @@ 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.errorcraft.itematic.world.action.context.PositionTarget; import net.minecraft.block.Block; -import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.Entity; import net.minecraft.item.HoneycombItem; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.world.WorldEvents; import net.minecraft.world.event.GameEvent; -public record WaxBlockAction(ActionContextParameter position) implements Action { +public record WaxBlockAction(PositionTarget position) implements Action { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("position").forGetter(WaxBlockAction::position) + PositionTarget.CODEC.fieldOf("position").forGetter(WaxBlockAction::position) ).apply(instance, WaxBlockAction::new)); - public static WaxBlockAction of(ActionContextParameter position) { + public static WaxBlockAction of(PositionTarget position) { return new WaxBlockAction(position); } @@ -32,13 +33,19 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { ServerWorld world = context.world(); - BlockPos pos = context.blockPos(this.position); - return HoneycombItem.getWaxedState(world.getBlockState(pos)).map(state -> { - PlayerEntity player = context.player(ActionContextParameter.THIS).orElse(null); - world.setBlockState(pos, state, Block.NOTIFY_ALL_AND_REDRAW); - world.emitGameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Emitter.of(player, state)); - world.syncWorldEvent(null, WorldEvents.BLOCK_WAXED, pos, 0); - return true; - }).orElse(false); + BlockPos pos = context.get(this.position.parameter(), BlockPos::ofFloored); + if (pos == null) { + return false; + } + + return HoneycombItem.getWaxedState(world.getBlockState(pos)) + .map(state -> { + Entity entity = context.get(LootContextParameters.THIS_ENTITY); + world.setBlockState(pos, state, Block.NOTIFY_ALL_AND_REDRAW); + world.emitGameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Emitter.of(entity, state)); + world.syncWorldEvent(WorldEvents.BLOCK_WAXED, pos, 0); + return true; + }) + .orElse(false); } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/context/ActionContext.java b/src/main/java/net/errorcraft/itematic/world/action/context/ActionContext.java index 94067e86..ed85b986 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/context/ActionContext.java +++ b/src/main/java/net/errorcraft/itematic/world/action/context/ActionContext.java @@ -1,284 +1,235 @@ package net.errorcraft.itematic.world.action.context; -import net.errorcraft.itematic.item.ItemStackConsumer; -import net.errorcraft.itematic.util.PositionUtil; +import net.errorcraft.itematic.item.placement.block.picker.BlockPicker; import net.errorcraft.itematic.util.context.ItematicContextParameters; -import net.errorcraft.itematic.util.context.ItematicContextTypes; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; -import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameters; -import net.minecraft.block.Block; import net.minecraft.entity.Entity; -import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.AutomaticItemPlacementContext; import net.minecraft.item.ItemPlacementContext; import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemUsageContext; import net.minecraft.loot.context.LootContext; import net.minecraft.loot.context.LootContextParameters; import net.minecraft.loot.context.LootWorldContext; -import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.function.CommandFunctionManager; import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.Hand; +import net.minecraft.util.context.ContextParameter; +import net.minecraft.util.context.ContextParameterMap; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Position; import net.minecraft.util.math.Vec3d; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.util.HashMap; import java.util.Map; import java.util.Optional; +import java.util.function.Function; public class ActionContext { - private final Builder builder; private final ServerWorld world; - protected final Map entities; - protected final Map positions; - protected Direction side = Direction.UP; - protected ItemStack stack = ItemStack.EMPTY; - protected ItemStackConsumer resultStackConsumer; - protected EquipmentSlot slot; - - public ActionContext(ServerWorld world) { - this(world, new HashMap<>(), new HashMap<>()); - } + private final ContextParameterMap parameters; + private final ItemStackExchanger stackExchanger; - private ActionContext(ServerWorld world, Map entities, Map positions) { + private ActionContext(ServerWorld world, ContextParameterMap parameters, ItemStackExchanger stackExchanger) { this.world = world; - this.entities = entities; - this.positions = positions; - this.builder = null; - } - - private ActionContext(Builder builder) { - this.builder = builder; - this.world = builder.world; - this.entities = new HashMap<>(builder.entities); - this.positions = new HashMap<>(builder.positions); - this.side = builder.side; - this.stack = builder.stack; - this.resultStackConsumer = builder.resultStackConsumer; - this.slot = builder.slot; + this.parameters = parameters; + this.stackExchanger = stackExchanger; } public static Builder builder(ServerWorld world) { return new Builder(world); } - public static Builder builder(ServerWorld world, ItemStack stack, ItemStackConsumer resultStackConsumer) { - return builder(world) - .stack(stack) - .resultStackConsumer(resultStackConsumer); + public Builder extend() { + return new Builder(this); } - public static Builder builder(ServerWorld world, ItemStack stack, ItemStackConsumer resultStackConsumer, EquipmentSlot slot) { - return builder(world, stack, resultStackConsumer) - .slot(slot); + public ServerWorld world() { + return this.world; } - public static Builder builder(ServerWorld world, ItemStack stack, ItemStackConsumer resultStackConsumer, Hand hand) { - if (hand == null) { - return builder(world, stack, resultStackConsumer); - } - - return builder(world, stack, resultStackConsumer, LivingEntity.getSlotForHand(hand)); + public ItemStackExchanger stackExchanger() { + return this.stackExchanger; } - public Builder builderForCopy() { - return this.builder; + public boolean has(ContextParameter parameter) { + return this.parameters.contains(parameter); } - public LootContext createLootContext(ActionContextParameters parameters) { - LootWorldContext set = new LootWorldContext.Builder(this.world) - .add(LootContextParameters.THIS_ENTITY, this.entities.get(parameters.entity())) - .add(LootContextParameters.ORIGIN, this.position(parameters.position())) - .add(LootContextParameters.TOOL, this.stack) - .add(ItematicContextParameters.SIDE, this.side) - .build(ItematicContextTypes.ACTION); - return new LootContext.Builder(set).build(Optional.empty()); + @Nullable + public T get(ContextParameter parameter) { + return this.parameters.getNullable(parameter); } - public ServerCommandSource createCommandSource(ActionContextParameters parameters, CommandFunctionManager functionManager) { - return functionManager.getScheduledCommandSource() - .withEntity(this.entities.get(parameters.entity())) - .withPosition(this.positions.get(parameters.position())); - } + @Nullable + public U get(ContextParameter parameter, Class clazz) { + T value = this.get(parameter); + if (clazz.isInstance(value)) { + return clazz.cast(value); + } - public ItemUsageContext createItemUsageContext(ActionContextParameter position) { - return new ItemUsageContext( - this.world, - this.player(ActionContextParameter.THIS).orElse(null), - this.hand(), - this.stack(), - new BlockHitResult( - this.position(position), - this.side(), - this.blockPos(position), - false - ) - ); + return null; } - public ItemPlacementContext createItemPlacementContext(ActionContextParameter position, RegistryEntry block) { - if (this.entity(ActionContextParameter.THIS).isPresent()) { - ItemPlacementContext placementContext = new ItemPlacementContext(this.createItemUsageContext(position)); - return block.value().itematic$placementContext(placementContext); + @Nullable + public U get(ContextParameter parameter, Function<@NotNull T, U> mapper) { + T value = this.get(parameter); + if (value == null) { + return null; } - BlockPos pos = this.blockPos(position); - Direction useSide = this.world.isAir(pos.down()) ? this.side : Direction.UP; - return new AutomaticItemPlacementContext(this.world, pos, this.side, this.stack, useSide); - } - public ServerWorld world() { - return this.world; + return mapper.apply(value); } - public Optional entity(ActionContextParameter parameter) { - return Optional.ofNullable(this.entities.get(parameter)); + public T getOrDefault(ContextParameter parameter, T defaultValue) { + return this.parameters.getOrDefault(parameter, defaultValue); } - public Optional livingEntity(ActionContextParameter parameter) { - return this.entity(parameter).map(entity -> { - if (entity instanceof LivingEntity livingEntity) { - return livingEntity; - } - return null; - }); + @Nullable + public BlockPos getBlockPos(ContextParameter parameter) { + return this.get(parameter, BlockPos::ofFloored); } - public Optional player(ActionContextParameter parameter) { - return this.entity(parameter).map(entity -> { - if (entity instanceof PlayerEntity player) { - return player; - } - return null; - }); + public ItemStack resultStack() { + return this.stackExchanger.result(); } - public Vec3d position(ActionContextParameter parameter) { - Vec3d position = this.positions.get(parameter); - if (position == null) { - return this.world.getSpawnPos().toCenterPos(); - } - return position; + public void exchangeStack(ItemStack stack) { + this.stackExchanger.exchange(stack); } - public BlockPos blockPos(ActionContextParameter parameter) { - return BlockPos.ofFloored(this.position(parameter)); + public LootContext lootContext() { + LootWorldContext context = new LootWorldContext( + this.world, + this.parameters, + Map.of(), + 0.0f + ); + return new LootContext.Builder(context).build(Optional.empty()); } - public Direction side() { - return this.side; + public ServerCommandSource commandSource(CommandFunctionManager functionManager, Optional entity, Optional position) { + ServerCommandSource source = functionManager.getScheduledCommandSource(); + source = entity.map(LootContext.EntityTarget::getParameter) + .map(this::get) + .map(source::withEntity) + .orElse(source); + source = position.map(PositionTarget::parameter) + .map(this::get) + .map(source::withPosition) + .orElse(source); + return source; } - public ItemStack stack() { - return this.stack; - } - public ItemStackConsumer resultStackConsumer() { - return this.resultStackConsumer; - } + @Nullable + public ItemPlacementContext blockPlaceContext(PositionTarget position, BlockPicker block) { + Vec3d pos = this.get(position.parameter()); + if (pos == null) { + return null; + } - public void setResultStack(ItemStack stack) { - if (this.resultStackConsumer == null) { - return; + Direction side = this.get(ItematicContextParameters.SIDE); + if (side == null) { + return null; } - this.resultStackConsumer.set(stack); - } - public Optional slot() { - return Optional.ofNullable(this.slot); + ItemPlacementContext placeContext = this.blockPlaceContext(pos, side); + return block.placementContext(placeContext); } - public Hand hand() { - if (this.slot == null) { - return null; + private ItemPlacementContext blockPlaceContext(Vec3d pos, Direction side) { + BlockPos blockPos = BlockPos.ofFloored(pos); + Entity entity = this.get(LootContextParameters.THIS_ENTITY); + if (entity != null) { + return new ItemPlacementContext( + this.world, + entity instanceof PlayerEntity player ? player : null, + this.get(ItematicContextParameters.HAND), + this.getOrDefault(LootContextParameters.TOOL, ItemStack.EMPTY), + new BlockHitResult( + pos, + side, + blockPos, + false + ) + ); } - return switch (this.slot) { - case MAINHAND -> Hand.MAIN_HAND; - case OFFHAND -> Hand.OFF_HAND; - default -> null; - }; + + Direction useSide = this.world.isAir(blockPos.down()) ? side : Direction.UP; + return new AutomaticItemPlacementContext( + this.world, + blockPos, + side, + this.getOrDefault(LootContextParameters.TOOL, ItemStack.EMPTY), + useSide + ); } public static class Builder { private final ServerWorld world; - private final Map entities = new HashMap<>(); - private final Map positions = new HashMap<>(); - private Direction side = Direction.UP; - private ItemStack stack = ItemStack.EMPTY; - private ItemStackConsumer resultStackConsumer; - private EquipmentSlot slot; + private ItemStackExchanger stackExchanger = ItemStackExchanger.EMPTY; + private final ContextParameterMap.Builder parameters = new ContextParameterMap.Builder(); private Builder(ServerWorld world) { this.world = world; } - public ActionContext build() { - return new ActionContext(this); + private Builder(ActionContext currentContext) { + this.world = currentContext.world; + this.stackExchanger = currentContext.stackExchanger; + this.parameters.itematic$copy(currentContext.parameters); } - public Builder entity(ActionContextParameter parameter, Entity entity) { - this.entities.put(parameter, entity); - return this; + public ActionContext build() { + return new ActionContext( + this.world, + this.parameters.itematic$build(), + this.stackExchanger + ); } - public Builder entityPosition(ActionContextParameter parameter, Entity entity) { - this.entities.put(parameter, entity); - if (entity != null) { - this.positions.put(parameter, entity.getPos()); - } + public Builder stackExchanger(ItemStackExchanger stackExchanger) { + this.stackExchanger = stackExchanger; return this; } - public Builder position(ActionContextParameter parameter, BlockPos position) { - return this.position(parameter, Vec3d.ofBottomCenter(position)); - } + public Builder possibleStackExchanger(@Nullable LivingEntity consumingEntity, ItemStack initialStack) { + if (consumingEntity == null) { + return this; + } - public Builder position(ActionContextParameter parameter, Position position) { - return this.position(parameter, PositionUtil.vec3d(position)); + return this.stackExchanger(consumingEntity, initialStack); } - public Builder position(ActionContextParameter parameter, Vec3d position) { - if (position == null) { - throw new IllegalArgumentException("Position was null"); - } - this.positions.put(parameter, position); + public Builder stackExchanger(LivingEntity consumingEntity, ItemStack initialStack) { + this.stackExchanger = ItemStackExchanger.forEntity(consumingEntity, initialStack); return this; } - public Builder side(Direction side) { - if (side == null) { - throw new IllegalArgumentException("Side was null"); - } - this.side = side; + public Builder stackExchanger(Direction side, Vec3d pos, ItemStack initialStack) { + this.stackExchanger = ItemStackExchanger.forDispenser(this.world, side, pos, initialStack); return this; } - public Builder stack(ItemStack stack) { - if (stack == null) { - throw new IllegalArgumentException("Item stack was null"); - } - this.stack = stack; + public Builder add(ContextParameter parameter, T value) { + this.parameters.add(parameter, value); return this; } - public Builder resultStackConsumer(ItemStackConsumer resultStackConsumer) { - this.resultStackConsumer = resultStackConsumer; + public Builder addOptional(ContextParameter parameter, @Nullable T value) { + this.parameters.addNullable(parameter, value); return this; } - public Builder slot(EquipmentSlot slot) { - this.slot = slot; - return this; - } + public Builder addOptional(ContextParameter parameter, @Nullable U value, Function<@NotNull U, T> mapper) { + if (value == null) { + return this; + } - public Builder hand(Hand hand) { - this.slot = LivingEntity.getSlotForHand(hand); + this.addOptional(parameter, mapper.apply(value)); return this; } } diff --git a/src/main/java/net/errorcraft/itematic/world/action/context/ItemStackExchanger.java b/src/main/java/net/errorcraft/itematic/world/action/context/ItemStackExchanger.java new file mode 100644 index 00000000..2a0e77af --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/world/action/context/ItemStackExchanger.java @@ -0,0 +1,63 @@ +package net.errorcraft.itematic.world.action.context; + +import net.minecraft.block.dispenser.ItemDispenserBehavior; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; + +import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.Predicate; + +public class ItemStackExchanger { + public static final ItemStackExchanger EMPTY = new ItemStackExchanger( + stack -> true, + stack -> {}, + ItemStack.EMPTY + ); + + private final Predicate shouldDrop; + private final Consumer dropper; + private ItemStack currentStack; + + private ItemStackExchanger(Predicate shouldDrop, Consumer dropper, ItemStack initialStack) { + this.shouldDrop = Objects.requireNonNull(shouldDrop); + this.dropper = Objects.requireNonNull(dropper); + this.currentStack = Objects.requireNonNull(initialStack); + } + + public static ItemStackExchanger forEntity(LivingEntity entity, ItemStack initialStack) { + return new ItemStackExchanger( + stack -> !entity.isInCreativeMode() || !entity.itematic$hasStackInInventory(stack), + entity::giveOrDropStack, + initialStack + ); + } + + public static ItemStackExchanger forDispenser(ServerWorld world, Direction side, Vec3d pos, ItemStack initialStack) { + return new ItemStackExchanger( + stack -> true, + stack -> ItemDispenserBehavior.spawnItem(world, stack, 6, side, pos), + initialStack + ); + } + + public ItemStack result() { + return this.currentStack; + } + + public void exchange(ItemStack stack) { + Objects.requireNonNull(stack); + if (stack == this.currentStack) { + return; + } + + if (!this.currentStack.isEmpty() && this.shouldDrop.test(this.currentStack)) { + this.dropper.accept(this.currentStack); + } + + this.currentStack = stack; + } +} diff --git a/src/main/java/net/errorcraft/itematic/world/action/context/ItemStackTarget.java b/src/main/java/net/errorcraft/itematic/world/action/context/ItemStackTarget.java new file mode 100644 index 00000000..692f240d --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/world/action/context/ItemStackTarget.java @@ -0,0 +1,30 @@ +package net.errorcraft.itematic.world.action.context; + +import com.mojang.serialization.Codec; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameters; +import net.minecraft.util.StringIdentifiable; +import net.minecraft.util.context.ContextParameter; + +public enum ItemStackTarget implements StringIdentifiable { + TOOL("tool", LootContextParameters.TOOL); + + public static final Codec CODEC = StringIdentifiable.createCodec(ItemStackTarget::values); + + private final String name; + private final ContextParameter parameter; + + ItemStackTarget(String name, ContextParameter parameter) { + this.name = name; + this.parameter = parameter; + } + + @Override + public String asString() { + return this.name; + } + + public ContextParameter parameter() { + return this.parameter; + } +} diff --git a/src/main/java/net/errorcraft/itematic/world/action/context/ItematicEntityTargets.java b/src/main/java/net/errorcraft/itematic/world/action/context/ItematicEntityTargets.java new file mode 100644 index 00000000..f6536684 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/world/action/context/ItematicEntityTargets.java @@ -0,0 +1,10 @@ +package net.errorcraft.itematic.world.action.context; + +import com.chocohead.mm.api.ClassTinkerers; +import net.minecraft.loot.context.LootContext; + +public class ItematicEntityTargets { + public static final LootContext.EntityTarget TARGET_ENTITY = ClassTinkerers.getEnum(LootContext.EntityTarget.class, "ITEMATIC$TARGET_ENTITY"); + + private ItematicEntityTargets() {} +} diff --git a/src/main/java/net/errorcraft/itematic/world/action/context/PositionTarget.java b/src/main/java/net/errorcraft/itematic/world/action/context/PositionTarget.java new file mode 100644 index 00000000..ac9748a2 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/world/action/context/PositionTarget.java @@ -0,0 +1,32 @@ +package net.errorcraft.itematic.world.action.context; + +import com.mojang.serialization.Codec; +import net.errorcraft.itematic.util.context.ItematicContextParameters; +import net.minecraft.loot.context.LootContextParameters; +import net.minecraft.util.StringIdentifiable; +import net.minecraft.util.context.ContextParameter; +import net.minecraft.util.math.Vec3d; + +public enum PositionTarget implements StringIdentifiable { + ORIGIN("origin", LootContextParameters.ORIGIN), + INTERACTED_POSITION("interacted", ItematicContextParameters.INTERACTED_POSITION); + + public static final Codec CODEC = StringIdentifiable.createCodec(PositionTarget::values); + + private final String name; + private final ContextParameter parameter; + + PositionTarget(String name, ContextParameter parameter) { + this.name = name; + this.parameter = parameter; + } + + @Override + public String asString() { + return this.name; + } + + public ContextParameter parameter() { + return this.parameter; + } +} diff --git a/src/main/java/net/errorcraft/itematic/world/action/context/parameter/ActionContextParameter.java b/src/main/java/net/errorcraft/itematic/world/action/context/parameter/ActionContextParameter.java deleted file mode 100644 index 9b487911..00000000 --- a/src/main/java/net/errorcraft/itematic/world/action/context/parameter/ActionContextParameter.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.errorcraft.itematic.world.action.context.parameter; - -import com.mojang.serialization.Codec; -import net.minecraft.util.StringIdentifiable; - -public enum ActionContextParameter implements StringIdentifiable { - THIS("this"), - TARGET("target"); - - public static final Codec CODEC = StringIdentifiable.createCodec(ActionContextParameter::values); - - private final String name; - - ActionContextParameter(String name) { - this.name = name; - } - - @Override - public String asString() { - return this.name; - } -} diff --git a/src/main/java/net/errorcraft/itematic/world/action/context/parameter/ActionContextParameters.java b/src/main/java/net/errorcraft/itematic/world/action/context/parameter/ActionContextParameters.java deleted file mode 100644 index 677ebf0a..00000000 --- a/src/main/java/net/errorcraft/itematic/world/action/context/parameter/ActionContextParameters.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.errorcraft.itematic.world.action.context.parameter; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; - -public record ActionContextParameters(ActionContextParameter entity, ActionContextParameter position) { - public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - ActionContextParameter.CODEC.fieldOf("entity").forGetter(ActionContextParameters::entity), - ActionContextParameter.CODEC.fieldOf("position").forGetter(ActionContextParameters::position) - ).apply(instance, ActionContextParameters::new)); - - public static ActionContextParameters of(ActionContextParameter entity, ActionContextParameter position) { - return new ActionContextParameters(entity, position); - } -} diff --git a/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/SequenceHandler.java b/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/SequenceHandler.java index e7074ac8..58372550 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/SequenceHandler.java +++ b/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/SequenceHandler.java @@ -4,9 +4,9 @@ import net.errorcraft.itematic.registry.ItematicRegistries; import net.errorcraft.itematic.world.action.Action; import net.errorcraft.itematic.world.action.ActionEntry; -import net.errorcraft.itematic.world.action.ActionRequirements; import net.errorcraft.itematic.world.action.actions.SequenceAction; import net.errorcraft.itematic.world.action.context.ActionContext; +import net.minecraft.loot.condition.LootCondition; import net.minecraft.registry.entry.RegistryEntry; public interface SequenceHandler> { @@ -21,19 +21,19 @@ interface Builder, S extends Builder> { default S add(Builder builder) { return this.add(SequenceAction.of(builder)); } - default S add(ActionRequirements requirements, Builder builder) { + default S add(LootCondition.Builder requirements, Builder builder) { return this.add(requirements, SequenceAction.of(builder)); } default S add(SequenceHandler handler) { return this.add(SequenceAction.of(handler)); } - default S add(ActionRequirements requirements, SequenceHandler handler) { + default S add(LootCondition.Builder requirements, SequenceHandler handler) { return this.add(requirements, SequenceAction.of(handler)); } default S add(Action action) { return this.add(ActionEntry.of(action)); } - default S add(ActionRequirements requirements, Action action) { + default S add(LootCondition.Builder requirements, Action action) { return this.add(ActionEntry.of(requirements, action)); } default S add(ActionEntry entry) { diff --git a/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/FirstToPassRequirementsSequenceHandler.java b/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/FirstToPassRequirementsSequenceHandler.java index 529c3583..086e2170 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/FirstToPassRequirementsSequenceHandler.java +++ b/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/FirstToPassRequirementsSequenceHandler.java @@ -16,6 +16,10 @@ public record FirstToPassRequirementsSequenceHandler(RegistryEntryList entries) implements SequenceHandler { public static final Codec CODEC = ActionEntry.REGISTRY_ENTRY_LIST_CODEC.xmap(FirstToPassRequirementsSequenceHandler::new, FirstToPassRequirementsSequenceHandler::entries); + public static FirstToPassRequirementsSequenceHandler of(RegistryEntryList entries) { + return new FirstToPassRequirementsSequenceHandler(entries); + } + public static Builder builder() { return new Builder(); } @@ -33,6 +37,7 @@ public boolean handle(ActionContext context) { return result.get(); } } + return false; } @@ -41,13 +46,11 @@ public Iterable> iterateEntries() { return this.entries; } - public static FirstToPassRequirementsSequenceHandler tag(RegistryEntryList.Named tag) { - return new FirstToPassRequirementsSequenceHandler(tag); - } - public static class Builder implements SequenceHandler.Builder { private final List> entries = new ArrayList<>(); + private Builder() {} + @Override public FirstToPassRequirementsSequenceHandler build() { return new FirstToPassRequirementsSequenceHandler(RegistryEntryList.of(this.entries)); diff --git a/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/FirstToSucceedSequenceHandler.java b/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/FirstToSucceedSequenceHandler.java index a56ac3d1..cff0838c 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/FirstToSucceedSequenceHandler.java +++ b/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/FirstToSucceedSequenceHandler.java @@ -31,6 +31,7 @@ public boolean handle(ActionContext context) { return true; } } + return false; } diff --git a/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/PassingSequenceHandler.java b/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/PassingSequenceHandler.java index 476891ab..415f897b 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/PassingSequenceHandler.java +++ b/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/PassingSequenceHandler.java @@ -33,6 +33,7 @@ public boolean handle(ActionContext context) { return false; } } + return true; } @@ -77,6 +78,7 @@ private boolean execute(ActionContext context) { if (this.action.value().execute(context).orElse(false)) { return true; } + return this.optional; } diff --git a/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/RandomizeSequenceHandler.java b/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/RandomizeSequenceHandler.java index c661c3f3..88108e73 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/RandomizeSequenceHandler.java +++ b/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/RandomizeSequenceHandler.java @@ -33,6 +33,7 @@ public boolean handle(ActionContext context) { for (RegistryEntry entry : this.randomEntries(context.world().getRandom())) { result |= entry.value().execute(context).orElse(false); } + return result; } diff --git a/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/UncheckedSequenceHandler.java b/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/UncheckedSequenceHandler.java index b66f0c53..10021446 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/UncheckedSequenceHandler.java +++ b/src/main/java/net/errorcraft/itematic/world/action/sequence/handler/handlers/UncheckedSequenceHandler.java @@ -30,6 +30,7 @@ public boolean handle(ActionContext context) { for (RegistryEntry entry : this.entries) { result |= entry.value().execute(context).orElse(false); } + return result; } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 1768dc49..38cc8e64 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -43,12 +43,6 @@ "net/minecraft/class_1297": [ "net/errorcraft/itematic/access/entity/EntityAccess" ], - "net/minecraft/class_1299": [ - "net/errorcraft/itematic/access/entity/EntityTypeAccess" - ], - "net/minecraft/class_1299\u0024class_1300": [ - "net/errorcraft/itematic/access/entity/EntityTypeBuilderAccess" - ], "net/minecraft/class_1308": [ "net/errorcraft/itematic/access/entity/mob/MobEntityAccess" ], @@ -82,9 +76,6 @@ "net/minecraft/class_2073\u0024class_2074": [ "net/errorcraft/itematic/access/predicate/item/ItemPredicateBuilderAccess" ], - "net/minecraft/class_2248": [ - "net/errorcraft/itematic/access/block/BlockAccess" - ], "net/minecraft/class_2302": [ "net/errorcraft/itematic/access/block/CropBlockAccess" ], @@ -103,21 +94,9 @@ "net/minecraft/class_3611": [ "net/errorcraft/itematic/access/fluid/FluidAccess" ], - "net/minecraft/class_3850": [ - "net/errorcraft/itematic/access/village/VillagerDataAccess" - ], - "net/minecraft/class_3852": [ - "net/errorcraft/itematic/access/village/VillagerProfessionAccess" - ], - "net/minecraft/class_4059\u0024class_9076": [ - "net/errorcraft/itematic/access/item/AnimalArmorItemTypeAccess" - ], "net/minecraft/class_4538": [ "net/errorcraft/itematic/access/world/WorldViewAccess" ], - "net/minecraft/class_5289\u0024class_5290": [ - "net/errorcraft/itematic/access/client/gui/screen/GameModeSelectionScreenGameModeSelectionAccess" - ], "net/minecraft/class_6880": [ "net/errorcraft/itematic/access/registry/entry/RegistryEntryAccess" ], diff --git a/src/main/resources/itematic.classtweaker b/src/main/resources/itematic.classtweaker index ae8356d5..d2fd35f6 100644 --- a/src/main/resources/itematic.classtweaker +++ b/src/main/resources/itematic.classtweaker @@ -2,7 +2,7 @@ classTweaker v1 named accessible class net/minecraft/registry/Registries$Initializer accessible class net/minecraft/entity/passive/OcelotEntity$OcelotTemptGoal -accessible class net/minecraft/client/gui/screen/GameModeSelectionScreen$GameModeSelection +accessible class net/minecraft/client/gui/screen/GameModeSwitcherScreen$GameModeSelection 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 @@ -12,3 +12,13 @@ accessible class net/minecraft/client/gui/screen/recipebook/RecipeAlternat 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 +inject-interface net/minecraft/block/AbstractBlock net/errorcraft/itematic/access/block/AbstractBlockAccess +inject-interface net/minecraft/util/context/ContextParameterMap$Builder net/errorcraft/itematic/access/util/context/ContextParameterMapBuilderAccess +inject-interface net/minecraft/loot/condition/LocationCheckLootCondition net/errorcraft/itematic/access/loot/condition/LocationCheckLootConditionAccess +inject-interface net/minecraft/item/ItemUsageContext net/errorcraft/itematic/access/item/ItemUsageContextAccess +inject-interface net/minecraft/entity/EntityType net/errorcraft/itematic/access/entity/EntityTypeAccess +inject-interface net/minecraft/entity/EntityType$Builder net/errorcraft/itematic/access/entity/EntityTypeBuilderAccess +inject-interface net/minecraft/block/entity/BlockEntity net/errorcraft/itematic/access/block/entity/BlockEntityAccess +inject-interface net/minecraft/village/VillagerData net/errorcraft/itematic/access/village/VillagerDataAccess +inject-interface net/minecraft/village/VillagerProfession net/errorcraft/itematic/access/village/VillagerProfessionAccess +inject-interface net/minecraft/client/gui/screen/GameModeSwitcherScreen$GameModeSelection net/errorcraft/itematic/access/client/gui/screen/GameModeSwitcherScreenAccess$GameModeSelectionAccess diff --git a/src/main/resources/itematic.mixins.json b/src/main/resources/itematic.mixins.json index 159df2e1..a342f1e6 100644 --- a/src/main/resources/itematic.mixins.json +++ b/src/main/resources/itematic.mixins.json @@ -18,7 +18,6 @@ "block.BeehiveBlockExtender", "block.BeetrootsBlockExtender", "block.BigDripleafStemBlockExtender", - "block.BlockExtender", "block.BlockItemAccessor", "block.BlocksExtender", "block.BubbleColumnBlockExtender", @@ -39,10 +38,10 @@ "block.FertilizableFlowerBlockExtender", "block.FlowerPotBlockExtender", "block.FluidBlockExtender", - "block.GlowLichenBlockExtender", "block.IgnitableBlockExtender", "block.KelpBlockExtender", "block.LightBlockExtender", + "block.MultifaceBlockExtender", "block.NetherWartBlockExtender", "block.OnUseWithItemStatIncreasingBlocksExtender", "block.PistonHeadBlockExtender", @@ -51,11 +50,12 @@ "block.PumpkinBlockExtender", "block.RespawnAnchorBlockExtender", "block.ScaffoldingBlockExtender", - "block.SculkVeinBlockExtender", + "block.SegmentedExtender", "block.ShulkerBoxBlockExtender", "block.StemBlockExtender", "block.SweetBerryBushBlockExtender", "block.TallSeagrassBlockExtender", + "block.TntBlockAccessor", "block.TntBlockExtender", "block.TorchflowerBlockExtender", "block.TripwireBlockExtender", @@ -69,7 +69,6 @@ "block.dispenser.ShearsDispenserBehaviorAccessor", "block.entity.AbstractFurnaceBlockEntityExtender", "block.entity.BannerBlockEntityExtender", - "block.entity.BlockEntityExtender", "block.entity.BrewingStandBlockEntityExtender", "block.entity.BrewingStandBlockEntityExtender$PropertyDelegateExtender", "block.entity.DecoratedPotBlockEntityExtender", @@ -91,12 +90,16 @@ "component.type.ConsumableComponentExtender", "component.type.DyedColorComponentExtender", "component.type.EquippableComponentExtender", + "component.type.LodestoneTrackerComponentExtender", + "component.type.MapIdComponentExtender", "component.type.ToolComponentExtender", "component.type.ToolComponentExtender$RuleExtender", "datafixer.SchemasExtender", + "enchantment.EnchantmentHelperAccessor", "enchantment.EnchantmentHelperExtender", "entity.BucketableExtender", "entity.CrossbowUserExtender", + "entity.EntityAccessor", "entity.EntityExtender", "entity.EntityTypeExtender", "entity.EntityTypeExtender$BuilderExtender", @@ -134,6 +137,7 @@ "entity.mob.BlazeEntityExtender", "entity.mob.BoggedEntityExtender", "entity.mob.CaveSpiderEntityExtender", + "entity.mob.CreakingEntityExtender", "entity.mob.CreeperEntityExtender", "entity.mob.DrownedEntityExtender", "entity.mob.DrownedEntityExtender$TridentAttackGoalExtender", @@ -177,7 +181,6 @@ "entity.passive.AbstractDonkeyEntityExtender", "entity.passive.AbstractDonkeyEntityExtender$StackReferenceExtender", "entity.passive.AbstractHorseEntityExtender", - "entity.passive.AbstractHorseEntityExtender$SaddleStackReferenceExtender", "entity.passive.AllayEntityExtender", "entity.passive.ArmadilloEntityExtender", "entity.passive.AxolotlEntityExtender", @@ -236,8 +239,9 @@ "entity.projectile.thrown.EggEntityExtender", "entity.projectile.thrown.EnderPearlEntityExtender", "entity.projectile.thrown.ExperienceBottleEntityExtender", - "entity.projectile.thrown.PotionEntityExtender", + "entity.projectile.thrown.LingeringPotionEntityExtender", "entity.projectile.thrown.SnowballEntityExtender", + "entity.projectile.thrown.SplashPotionEntityExtender", "entity.projectile.thrown.ThrownItemEntityExtender", "entity.raid.RaiderEntityExtender", "entity.raid.RaiderEntityExtender$PickUpBannerAsLeaderGoalExtender", @@ -255,7 +259,7 @@ "fluid.LavaFluidExtender", "fluid.WaterFluidExtender", "inventory.SimpleInventoryExtender", - "item.AnimalArmorItemExtender$TypeExtender", + "item.BoneMealItemExtender", "item.BrushItemAccessor", "item.BrushItemExtender", "item.BundleItemAccessor", @@ -278,14 +282,14 @@ "item.ItemGroupsExtender", "item.ItemPlacementContextExtender", "item.ItemStackExtender", - "item.ItemUsageExtender", + "item.ItemUsageContextExtender", "item.KnowledgeBookItemExtender", "item.RangedWeaponItemAccessor", "item.SmithingTemplateItemAccessor", - "item.SpawnEggItemAccessor", "item.tooltip.BundleTooltipDataExtender", "loot.ContainerComponentModifierExtender", "loot.ContainerComponentModifiersExtender$BundleContentsExtender", + "loot.condition.LocationCheckLootConditionExtender", "loot.condition.LootConditionTypesAccessor", "loot.context.LootContextTypesAccessor", "loot.entry.TagEntryExtender", @@ -311,7 +315,6 @@ "recipe.ArmorDyeRecipeExtender", "recipe.BannerDuplicateRecipeExtender", "recipe.BlastingRecipeExtender", - "recipe.BookCloningRecipeExtender", "recipe.CampfireCookingRecipeExtender", "recipe.CraftingDecoratedPotRecipeExtender", "recipe.FireworkRocketRecipeExtender", @@ -336,6 +339,7 @@ "recipe.StonecuttingRecipeExtender", "recipe.TippedArrowRecipeExtender", "recipe.TransmuteRecipeExtender", + "recipe.TransmuteRecipeResultExtender", "recipe.book.RecipeBookOptionsExtender", "recipe.display.SlotDisplayExtender$AnyFuelSlotDisplayExtender", "recipe.display.SlotDisplayExtender$ItemSlotDisplayExtender", @@ -350,8 +354,8 @@ "registry.entry.RegistryEntryExtender$ReferenceExtender", "registry.entry.RegistryEntryListExtender", "registry.entry.RegistryEntryListExtender$ListBackedExtender", + "scoreboard.ScoreboardCriterionAccessor", "scoreboard.ScoreboardCriterionExtender", - "scoreboard.ScoreboardStateExtender", "screen.AbstractFurnaceScreenHandlerExtender", "screen.AnvilScreenHandlerExtender", "screen.BrewingStandScreenHandlerAccessor", @@ -364,7 +368,6 @@ "screen.EnchantmentScreenHandlerExtender$LapisLazuliSlotExtender", "screen.GrindstoneScreenHandlerExtender", "screen.GrindstoneScreenHandlerExtender$EnchantedItemSlotExtender", - "screen.HorseScreenHandlerExtender$SaddleSlotExtender", "screen.LoomScreenHandlerExtender", "screen.LoomScreenHandlerExtender$BannerPatternSlotExtender", "screen.LoomScreenHandlerExtender$BannerSlotExtender", @@ -372,7 +375,6 @@ "screen.ScreenHandlerTypeAccessor", "screen.ScreenHandlerTypeExtender", "screen.slot.FurnaceFuelSlotExtender", - "server.ServerPlayerInteractionManagerExtender", "server.command.ScoreboardCommandExtender", "server.network.ServerPlayNetworkHandlerExtender", "sound.SoundCategoryExtender", @@ -382,7 +384,8 @@ "stat.StatTypeExtender", "structure.EndCityGeneratorExtender$PieceExtender", "util.DyeColorExtender", - "util.dynamic.CodecsAccessor", + "util.context.ContextParameterMapAccessor", + "util.context.ContextParameterMapExtender$BuilderExtender", "village.TradeOfferExtender", "village.TradeOffersAccessor", "village.TradeOffersExtender",