Update to 25w03a ()

* Update to 25w03a

* Bump version
This commit is contained in:
modmuss 2025-01-15 18:34:20 +00:00 committed by GitHub
parent 3f161dddc9
commit c327076adb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
52 changed files with 405 additions and 786 deletions
build.gradle
fabric-api-base/src/testmod/java/net/fabricmc/fabric/test/base
fabric-biome-api-v1/src/main/java/net/fabricmc/fabric
fabric-command-api-v2/src/testmod/java/net/fabricmc/fabric/test/command
fabric-content-registries-v0/src
main/java/net/fabricmc/fabric
testmod/java/net/fabricmc/fabric/test/content/registry
fabric-data-attachment-api-v1/src/testmod/java/net/fabricmc/fabric/test/attachment/gametest
fabric-data-generation-api-v1/src/main/resources
fabric-events-interaction-v0/src/testmod/java/net/fabricmc/fabric/test/event/interaction
fabric-game-rule-api-v1/src/main
java/net/fabricmc/fabric
api/gamerule/v1
impl/gamerule
resources
fabric-item-api-v1/src/testmod/java/net/fabricmc/fabric/test/item
fabric-object-builder-api-v1/src
fabric-recipe-api-v1/src
test/java/net/fabricmc/fabric/test/recipe/ingredient
testmod/java/net/fabricmc/fabric/test/recipe/ingredient
fabric-renderer-api-v1/src
client/java/net/fabricmc/fabric/mixin/renderer/client
testmodClient/java/net/fabricmc/fabric/test/renderer/client
fabric-rendering-v1/src/testmod/java/net/fabricmc/fabric/test/rendering
fabric-resource-conditions-api-v1
build.gradle
src
test/java/net/fabricmc/fabric/test/resource/conditions
testmod/java/net/fabricmc/fabric/test/resource/conditions
fabric-screen-handler-api-v1/src/testmod/java/net/fabricmc/fabric/test/screenhandler/block
fabric-transfer-api-v1/src/testmod/java/net/fabricmc/fabric/test/transfer/gametests
fabric-transitive-access-wideners-v1
gradle.propertiessettings.gradle

View file

@ -631,12 +631,12 @@ subprojects {
testmodImplementation sourceSets.main.output testmodImplementation sourceSets.main.output
// Make all modules depend on the gametest api (and thus res loader) to try and promote its usage. // Make all modules depend on the gametest api (and thus res loader) to try and promote its usage.
if (project.name != "fabric-gametest-api-v1") { // if (project.name != "fabric-gametest-api-v1") {
testmodImplementation project(path: ':fabric-gametest-api-v1', configuration: 'namedElements') // testmodImplementation project(path: ':fabric-gametest-api-v1', configuration: 'namedElements')
testmodClientImplementation project(":fabric-gametest-api-v1").sourceSets.client.output // testmodClientImplementation project(":fabric-gametest-api-v1").sourceSets.client.output
testmodImplementation project(path: ':fabric-resource-loader-v0', configuration: 'namedElements') // testmodImplementation project(path: ':fabric-resource-loader-v0', configuration: 'namedElements')
testmodClientImplementation project(":fabric-resource-loader-v0").sourceSets.client.output // testmodClientImplementation project(":fabric-resource-loader-v0").sourceSets.client.output
} // }
// Make all testmods run with registry-sync-v0 as it is required to register new objects. // Make all testmods run with registry-sync-v0 as it is required to register new objects.
if (project.name != "fabric-registry-sync-v0") { if (project.name != "fabric-registry-sync-v0") {

View file

@ -18,13 +18,10 @@ package net.fabricmc.fabric.test.base;
import org.spongepowered.asm.mixin.MixinEnvironment; import org.spongepowered.asm.mixin.MixinEnvironment;
import net.minecraft.test.GameTest;
import net.minecraft.test.TestContext; import net.minecraft.test.TestContext;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
public class FabricApiBaseGameTest { public class FabricApiBaseGameTest {
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) //@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) TODO 1.21.5 tests
public void auditMixins(TestContext context) { public void auditMixins(TestContext context) {
MixinEnvironment.getCurrentEnvironment().audit(); MixinEnvironment.getCurrentEnvironment().audit();

View file

@ -286,7 +286,7 @@ public interface BiomeModificationContext {
* @see BiomeEffects.Builder#music(MusicSound) * @see BiomeEffects.Builder#music(MusicSound)
*/ */
default void setMusic(@NotNull MusicSound sound) { default void setMusic(@NotNull MusicSound sound) {
setMusic(Pool.method_66214(sound)); setMusic(Pool.of(sound));
} }
/** /**

View file

@ -26,7 +26,7 @@ import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnGroup; import net.minecraft.entity.SpawnGroup;
import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.tag.TagKey; import net.minecraft.registry.tag.TagKey;
import net.minecraft.util.collection.Present; import net.minecraft.util.collection.Weighted;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.SpawnSettings; import net.minecraft.world.biome.SpawnSettings;
import net.minecraft.world.dimension.DimensionOptions; import net.minecraft.world.dimension.DimensionOptions;
@ -148,7 +148,7 @@ public final class BiomeSelectors {
SpawnSettings spawnSettings = context.getBiome().getSpawnSettings(); SpawnSettings spawnSettings = context.getBiome().getSpawnSettings();
for (SpawnGroup spawnGroup : SpawnGroup.values()) { for (SpawnGroup spawnGroup : SpawnGroup.values()) {
for (Present<SpawnSettings.SpawnEntry> spawnEntry : spawnSettings.getSpawnEntries(spawnGroup).getEntries()) { for (Weighted<SpawnSettings.SpawnEntry> spawnEntry : spawnSettings.getSpawnEntries(spawnGroup).getEntries()) {
if (entityTypes.contains(spawnEntry.value().type())) { if (entityTypes.contains(spawnEntry.value().type())) {
return true; return true;
} }

View file

@ -46,7 +46,7 @@ import net.minecraft.sound.BiomeMoodSound;
import net.minecraft.sound.MusicSound; import net.minecraft.sound.MusicSound;
import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvent;
import net.minecraft.util.collection.Pool; import net.minecraft.util.collection.Pool;
import net.minecraft.util.collection.Present; import net.minecraft.util.collection.Weighted;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeEffects; import net.minecraft.world.biome.BiomeEffects;
import net.minecraft.world.biome.BiomeParticleConfig; import net.minecraft.world.biome.BiomeParticleConfig;
@ -341,7 +341,7 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
private class SpawnSettingsContextImpl implements SpawnSettingsContext { private class SpawnSettingsContextImpl implements SpawnSettingsContext {
private final SpawnSettings spawnSettings = biome.getSpawnSettings(); private final SpawnSettings spawnSettings = biome.getSpawnSettings();
private final EnumMap<SpawnGroup, List<Present<SpawnSettings.SpawnEntry>>> fabricSpawners = new EnumMap<>(SpawnGroup.class); private final EnumMap<SpawnGroup, List<Weighted<SpawnSettings.SpawnEntry>>> fabricSpawners = new EnumMap<>(SpawnGroup.class);
SpawnSettingsContextImpl() { SpawnSettingsContextImpl() {
unfreezeSpawners(); unfreezeSpawners();
@ -374,7 +374,7 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
private void freezeSpawners() { private void freezeSpawners() {
Map<SpawnGroup, Pool<SpawnSettings.SpawnEntry>> spawners = new HashMap<>(spawnSettings.spawners); Map<SpawnGroup, Pool<SpawnSettings.SpawnEntry>> spawners = new HashMap<>(spawnSettings.spawners);
for (Map.Entry<SpawnGroup, List<Present<SpawnSettings.SpawnEntry>>> entry : fabricSpawners.entrySet()) { for (Map.Entry<SpawnGroup, List<Weighted<SpawnSettings.SpawnEntry>>> entry : fabricSpawners.entrySet()) {
if (entry.getValue().isEmpty()) { if (entry.getValue().isEmpty()) {
spawners.put(entry.getKey(), Pool.empty()); spawners.put(entry.getKey(), Pool.empty());
} else { } else {
@ -399,7 +399,7 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
Objects.requireNonNull(spawnGroup); Objects.requireNonNull(spawnGroup);
Objects.requireNonNull(spawnEntry); Objects.requireNonNull(spawnEntry);
fabricSpawners.get(spawnGroup).add(new Present<>(spawnEntry, weight)); fabricSpawners.get(spawnGroup).add(new Weighted<>(spawnEntry, weight));
} }
@Override @Override

View file

@ -21,12 +21,9 @@ import java.util.Locale;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.mob.MobEntity;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.test.GameTest;
import net.minecraft.test.TestContext; import net.minecraft.test.TestContext;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
public class EntitySelectorGameTest { public class EntitySelectorGameTest {
private void spawn(TestContext context, float health) { private void spawn(TestContext context, float health) {
MobEntity entity = context.spawnMob(EntityType.CREEPER, BlockPos.ORIGIN); MobEntity entity = context.spawnMob(EntityType.CREEPER, BlockPos.ORIGIN);
@ -34,7 +31,7 @@ public class EntitySelectorGameTest {
entity.setHealth(health); entity.setHealth(health);
} }
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) // @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) TODO 1.21.5 tests
public void testEntitySelector(TestContext context) { public void testEntitySelector(TestContext context) {
BlockPos absolute = context.getAbsolutePos(BlockPos.ORIGIN); BlockPos absolute = context.getAbsolutePos(BlockPos.ORIGIN);

View file

@ -24,8 +24,6 @@ import org.slf4j.LoggerFactory;
import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemConvertible;
import net.minecraft.loot.LootTable; import net.minecraft.loot.LootTable;
import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;
import net.minecraft.village.VillagerProfession; import net.minecraft.village.VillagerProfession;
import net.fabricmc.fabric.impl.content.registry.VillagerInteractionRegistriesImpl; import net.fabricmc.fabric.impl.content.registry.VillagerInteractionRegistriesImpl;
@ -77,26 +75,18 @@ public final class VillagerInteractionRegistries {
} }
} }
/**
* @deprecated Use {@link #registerGiftLootTable(VillagerProfession, RegistryKey)} instead.
*/
@Deprecated
public static void registerGiftLootTable(VillagerProfession profession, Identifier lootTable) {
registerGiftLootTable(profession, RegistryKey.of(RegistryKeys.LOOT_TABLE, lootTable));
}
/** /**
* Registers a hero of the village gifts loot table to a profession. * Registers a hero of the village gifts loot table to a profession.
* @param profession the profession to modify * @param profession the profession to modify
* @param lootTable the loot table to associate with the profession * @param lootTable the loot table to associate with the profession
*/ */
public static void registerGiftLootTable(VillagerProfession profession, RegistryKey<LootTable> lootTable) { public static void registerGiftLootTable(RegistryKey<VillagerProfession> profession, RegistryKey<LootTable> lootTable) {
Objects.requireNonNull(profession, "Profession cannot be null!"); Objects.requireNonNull(profession, "Profession cannot be null!");
Objects.requireNonNull(lootTable, "Loot table identifier cannot be null!"); Objects.requireNonNull(lootTable, "Loot table identifier cannot be null!");
RegistryKey<LootTable> oldValue = GiveGiftsToHeroTaskAccessor.fabric_getGifts().put(profession, lootTable); RegistryKey<LootTable> oldValue = GiveGiftsToHeroTaskAccessor.fabric_getGifts().put(profession, lootTable);
if (oldValue != null) { if (oldValue != null) {
LOGGER.info("Overriding previous gift loot table of {} profession, was: {}, now: {}", profession.id(), oldValue, lootTable); LOGGER.info("Overriding previous gift loot table of {} profession, was: {}, now: {}", profession.getValue(), oldValue, lootTable);
} }
} }
} }

View file

@ -29,7 +29,7 @@ import net.minecraft.village.VillagerProfession;
@Mixin(GiveGiftsToHeroTask.class) @Mixin(GiveGiftsToHeroTask.class)
public interface GiveGiftsToHeroTaskAccessor { public interface GiveGiftsToHeroTaskAccessor {
@Accessor("GIFTS") @Accessor("GIFTS")
static Map<VillagerProfession, RegistryKey<LootTable>> fabric_getGifts() { static Map<RegistryKey<VillagerProfession>, RegistryKey<LootTable>> fabric_getGifts() {
throw new AssertionError("Untransformed @Accessor"); throw new AssertionError("Untransformed @Accessor");
} }
} }

View file

@ -16,32 +16,8 @@
package net.fabricmc.fabric.test.content.registry; package net.fabricmc.fabric.test.content.registry;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.ComposterBlock;
import net.minecraft.block.HopperBlock;
import net.minecraft.block.entity.AbstractFurnaceBlockEntity;
import net.minecraft.block.entity.BrewingStandBlockEntity;
import net.minecraft.block.entity.HopperBlockEntity;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.PotionContentsComponent;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.potion.Potions;
import net.minecraft.test.GameTest;
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;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
public class ContentRegistryGameTest { public class ContentRegistryGameTest {
/* TODO 1.21.5 tests
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testCompostingChanceRegistry(TestContext context) { public void testCompostingChanceRegistry(TestContext context) {
BlockPos pos = new BlockPos(0, 1, 0); BlockPos pos = new BlockPos(0, 1, 0);
@ -244,4 +220,6 @@ public class ContentRegistryGameTest {
context.complete(); context.complete();
}); });
} }
*/
} }

View file

@ -17,21 +17,19 @@
package net.fabricmc.fabric.test.content.registry; package net.fabricmc.fabric.test.content.registry;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.test.GameTest;
import net.minecraft.test.GameTestException;
import net.minecraft.test.TestContext; import net.minecraft.test.TestContext;
import net.minecraft.text.Text;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
import net.fabricmc.fabric.api.registry.FlammableBlockRegistry; import net.fabricmc.fabric.api.registry.FlammableBlockRegistry;
public class FlammableTest { public class FlammableTest {
/** /**
* Regression test for <a href="https://github.com/FabricMC/fabric/issues/2108">FlammableBlockRegistry ignoring tags on first load</a>. * Regression test for <a href="https://github.com/FabricMC/fabric/issues/2108">FlammableBlockRegistry ignoring tags on first load</a>.
*/ */
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) // @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) TODO 1.21.5 tests
public void testFlammableTag(TestContext context) { public void testFlammableTag(TestContext context) {
if (FlammableBlockRegistry.getDefaultInstance().get(Blocks.SAND).getBurnChance() != 4) { if (FlammableBlockRegistry.getDefaultInstance().get(Blocks.SAND).getBurnChance() != 4) {
throw new GameTestException("Expected blocks in the sand tag to be flammable!"); context.method_66943(Text.literal("Expected blocks in the sand tag to be flammable!"));
} }
context.complete(); context.complete();

View file

@ -16,32 +16,15 @@
package net.fabricmc.fabric.test.attachment.gametest; package net.fabricmc.fabric.test.attachment.gametest;
import java.util.List;
import java.util.Objects;
import java.util.function.IntSupplier; import java.util.function.IntSupplier;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnReason;
import net.minecraft.entity.mob.DrownedEntity;
import net.minecraft.entity.mob.ZombieEntity;
import net.minecraft.server.MinecraftServer;
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.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.TeleportTarget;
import net.minecraft.world.World;
import net.fabricmc.fabric.api.attachment.v1.AttachmentRegistry; import net.fabricmc.fabric.api.attachment.v1.AttachmentRegistry;
import net.fabricmc.fabric.api.attachment.v1.AttachmentType; import net.fabricmc.fabric.api.attachment.v1.AttachmentType;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
import net.fabricmc.fabric.test.attachment.AttachmentTestMod; import net.fabricmc.fabric.test.attachment.AttachmentTestMod;
import net.fabricmc.fabric.test.attachment.mixin.ZombieEntityAccessor;
public class AttachmentCopyTests implements FabricGameTest { public class AttachmentCopyTests {
// using a lambda type because serialization shouldn't play a role in this // using a lambda type because serialization shouldn't play a role in this
public static AttachmentType<IntSupplier> DUMMY = AttachmentRegistry.create( public static AttachmentType<IntSupplier> DUMMY = AttachmentRegistry.create(
Identifier.of(AttachmentTestMod.MOD_ID, "dummy") Identifier.of(AttachmentTestMod.MOD_ID, "dummy")
@ -51,6 +34,7 @@ public class AttachmentCopyTests implements FabricGameTest {
AttachmentRegistry.Builder::copyOnDeath AttachmentRegistry.Builder::copyOnDeath
); );
/* TODO 1.21.5 tests
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testCrossWorldTeleport(TestContext context) { public void testCrossWorldTeleport(TestContext context) {
MinecraftServer server = context.getWorld().getServer(); MinecraftServer server = context.getWorld().getServer();
@ -107,4 +91,6 @@ public class AttachmentCopyTests implements FabricGameTest {
converted.discard(); converted.discard();
context.complete(); context.complete();
} }
*/
} }

View file

@ -19,28 +19,10 @@ package net.fabricmc.fabric.test.attachment.gametest;
import com.mojang.logging.LogUtils; import com.mojang.logging.LogUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import net.minecraft.block.Block; public class BlockEntityTests {
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.listener.ClientPlayPacketListener;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
import net.minecraft.registry.Registries;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.test.GameTest;
import net.minecraft.test.GameTestException;
import net.minecraft.test.TestContext;
import net.minecraft.util.math.BlockPos;
import net.fabricmc.fabric.api.attachment.v1.AttachmentTarget;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
import net.fabricmc.fabric.test.attachment.AttachmentTestMod;
import net.fabricmc.fabric.test.attachment.mixin.BlockEntityTypeAccessor;
public class BlockEntityTests implements FabricGameTest {
private static final Logger LOGGER = LogUtils.getLogger(); private static final Logger LOGGER = LogUtils.getLogger();
/* TODO 1.21.5 tests
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testBlockEntitySync(TestContext context) { public void testBlockEntitySync(TestContext context) {
BlockPos pos = BlockPos.ORIGIN.up(); BlockPos pos = BlockPos.ORIGIN.up();
@ -84,4 +66,6 @@ public class BlockEntityTests implements FabricGameTest {
context.complete(); context.complete();
} }
*/
} }

View file

@ -186,7 +186,7 @@ transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator
transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator createAxisRotatedBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/data/BlockStateSupplier; transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator createAxisRotatedBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/data/BlockStateSupplier;
transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator registerAxisRotated (Lnet/minecraft/block/Block;Lnet/minecraft/client/data/TexturedModel$Factory;Lnet/minecraft/client/data/TexturedModel$Factory;)V transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator registerAxisRotated (Lnet/minecraft/block/Block;Lnet/minecraft/client/data/TexturedModel$Factory;Lnet/minecraft/client/data/TexturedModel$Factory;)V
transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator registerCreakingHeart (Lnet/minecraft/block/Block;)V transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator registerCreakingHeart (Lnet/minecraft/block/Block;)V
transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator method_66528 (Lnet/minecraft/client/data/TexturedModel$Factory;Lnet/minecraft/block/Block;Ljava/lang/String;)Lnet/minecraft/util/Identifier; transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator createCreakingHeartModel (Lnet/minecraft/client/data/TexturedModel$Factory;Lnet/minecraft/block/Block;Ljava/lang/String;)Lnet/minecraft/util/Identifier;
transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator createSubModel (Lnet/minecraft/block/Block;Ljava/lang/String;Lnet/minecraft/client/data/Model;Ljava/util/function/Function;)Lnet/minecraft/util/Identifier; transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator createSubModel (Lnet/minecraft/block/Block;Ljava/lang/String;Lnet/minecraft/client/data/Model;Ljava/util/function/Function;)Lnet/minecraft/util/Identifier;
transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator createPressurePlateBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/data/BlockStateSupplier; transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator createPressurePlateBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/data/BlockStateSupplier;
transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator createSlabBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/data/BlockStateSupplier; transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator createSlabBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/data/BlockStateSupplier;
@ -221,9 +221,9 @@ transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator
transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator uploadParticleModel (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;)Lnet/minecraft/util/Identifier; transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator uploadParticleModel (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;)Lnet/minecraft/util/Identifier;
transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator registerBuiltin (Lnet/minecraft/block/Block;)V transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator registerBuiltin (Lnet/minecraft/block/Block;)V
transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator registerWoolAndCarpet (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;)V transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator registerWoolAndCarpet (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;)V
transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator method_66529 (Lnet/minecraft/block/Block;)V transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator registerLeafLitter (Lnet/minecraft/block/Block;)V
transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator registerFlowerbed (Lnet/minecraft/block/Block;)V transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator registerFlowerbed (Lnet/minecraft/block/Block;)V
transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator method_66526 (Lnet/minecraft/block/Block;Lnet/minecraft/state/property/IntProperty;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)V transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator registerSegmentedBlock (Lnet/minecraft/block/Block;Lnet/minecraft/state/property/IntProperty;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)V
transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator registerRandomHorizontalRotations (Lnet/minecraft/client/data/TexturedModel$Factory;[Lnet/minecraft/block/Block;)V transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator registerRandomHorizontalRotations (Lnet/minecraft/client/data/TexturedModel$Factory;[Lnet/minecraft/block/Block;)V
transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator registerSouthDefaultHorizontalFacing (Lnet/minecraft/client/data/TexturedModel$Factory;[Lnet/minecraft/block/Block;)V transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator registerSouthDefaultHorizontalFacing (Lnet/minecraft/client/data/TexturedModel$Factory;[Lnet/minecraft/block/Block;)V
transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator registerGlassAndPane (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;)V transitive-accessible method net/minecraft/client/data/BlockStateModelGenerator registerGlassAndPane (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;)V

View file

@ -37,7 +37,7 @@ public class AttackBlockTests implements ModInitializer {
}); });
// If a chest is attacked and the player holds a lava bucket, delete it! // If a chest is attacked and the player holds a lava bucket, delete it!
AttackBlockCallback.EVENT.register((player, world, hand, pos, side) -> { AttackBlockCallback.EVENT.register((player, world, hand, pos, side) -> {
if (!player.isSpectator() && world.canPlayerModifyAt(player, pos)) { if (!player.isSpectator() && world.canEntityModifyAt(player, pos)) {
if (world.getBlockState(pos).isOf(Blocks.CHEST)) { if (world.getBlockState(pos).isOf(Blocks.CHEST)) {
if (player.getStackInHand(hand).isOf(Items.LAVA_BUCKET)) { if (player.getStackInHand(hand).isOf(Items.LAVA_BUCKET)) {
world.setBlockState(pos, Blocks.AIR.getDefaultState()); world.setBlockState(pos, Blocks.AIR.getDefaultState());

View file

@ -16,28 +16,11 @@
package net.fabricmc.fabric.test.event.interaction; package net.fabricmc.fabric.test.event.interaction;
import net.minecraft.block.Blocks;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.item.Items;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.test.GameTest;
import net.minecraft.test.TestContext;
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.fabricmc.fabric.api.entity.FakePlayer;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
public class FakePlayerTests { public class FakePlayerTests {
/** /**
* Try placing a sign with a fake player. * Try placing a sign with a fake player.
*/ */
/* TODO 1.21.5 tests
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testFakePlayerPlaceSign(TestContext context) { public void testFakePlayerPlaceSign(TestContext context) {
// This is for Fabric internal testing only, if you copy this to your mod you're on your own... // This is for Fabric internal testing only, if you copy this to your mod you're on your own...
@ -63,9 +46,12 @@ public class FakePlayerTests {
context.complete(); context.complete();
} }
*/
/** /**
* Try breaking a beehive with a fake player (see {@code BeehiveBlockMixin}). * Try breaking a beehive with a fake player (see {@code BeehiveBlockMixin}).
*/ */
/* TODO 1.21.5 tests
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testFakePlayerBreakBeehive(TestContext context) { public void testFakePlayerBreakBeehive(TestContext context) {
BlockPos basePos = new BlockPos(0, 1, 0); BlockPos basePos = new BlockPos(0, 1, 0);
@ -81,4 +67,6 @@ public class FakePlayerTests {
context.expectBlock(Blocks.AIR, basePos); context.expectBlock(Blocks.AIR, basePos);
context.complete(); context.complete();
} }
*/
} }

View file

@ -41,7 +41,7 @@ public class UseBlockTests implements ModInitializer {
UseBlockCallback.EVENT.register((player, world, hand, hitResult) -> { UseBlockCallback.EVENT.register((player, world, hand, hitResult) -> {
BlockPos pos = hitResult.getBlockPos(); BlockPos pos = hitResult.getBlockPos();
if (!player.isSpectator() && world.canPlayerModifyAt(player, pos)) { if (!player.isSpectator() && world.canEntityModifyAt(player, pos)) {
if (world.getBlockState(pos).isOf(Blocks.CHEST)) { if (world.getBlockState(pos).isOf(Blocks.CHEST)) {
if (player.getStackInHand(hand).isOf(Items.WATER_BUCKET)) { if (player.getStackInHand(hand).isOf(Items.WATER_BUCKET)) {
world.setBlockState(pos, Blocks.AIR.getDefaultState()); world.setBlockState(pos, Blocks.AIR.getDefaultState());

View file

@ -28,7 +28,7 @@ public class UseEntityTests implements ModInitializer {
public void onInitialize() { public void onInitialize() {
// Disallow interactions with toolsmiths // Disallow interactions with toolsmiths
UseEntityCallback.EVENT.register((player, world, hand, entity, hitResult) -> { UseEntityCallback.EVENT.register((player, world, hand, entity, hitResult) -> {
if (entity instanceof VillagerEntity villager && villager.getVillagerData().getProfession() == VillagerProfession.TOOLSMITH) { if (entity instanceof VillagerEntity villager && villager.getVillagerData().profession().matchesKey(VillagerProfession.TOOLSMITH)) {
return ActionResult.FAIL; return ActionResult.FAIL;
} }

View file

@ -148,6 +148,7 @@ public final class GameRuleFactory {
type -> new BoundedIntRule(type, defaultValue, minimumValue, maximumValue), // Internally use a bounded int rule type -> new BoundedIntRule(type, defaultValue, minimumValue, maximumValue), // Internally use a bounded int rule
changedCallback, changedCallback,
GameRules.Visitor::visitInt, GameRules.Visitor::visitInt,
GameRules.IntRule.class,
FeatureSet.empty() FeatureSet.empty()
); );
} }
@ -226,6 +227,7 @@ public final class GameRuleFactory {
type -> new DoubleRule(type, defaultValue, minimumValue, maximumValue), type -> new DoubleRule(type, defaultValue, minimumValue, maximumValue),
changedCallback, changedCallback,
GameRuleFactory::visitDouble, GameRuleFactory::visitDouble,
DoubleRule.class,
FeatureSet.empty() FeatureSet.empty()
); );
} }
@ -292,7 +294,8 @@ public final class GameRuleFactory {
type -> new EnumRule<>(type, defaultValue, supportedValues), type -> new EnumRule<>(type, defaultValue, supportedValues),
changedCallback, changedCallback,
supportedValues, supportedValues,
GameRuleFactory::visitEnum GameRuleFactory::visitEnum,
(Class<EnumRule<E>>) (Object) EnumRule.class
); );
} }

View file

@ -35,8 +35,8 @@ import net.fabricmc.fabric.api.gamerule.v1.rule.EnumRule;
public final class EnumRuleType<E extends Enum<E>> extends GameRules.Type<EnumRule<E>> { public final class EnumRuleType<E extends Enum<E>> extends GameRules.Type<EnumRule<E>> {
private final E[] supportedValues; private final E[] supportedValues;
public EnumRuleType(Function<GameRules.Type<EnumRule<E>>, EnumRule<E>> ruleFactory, BiConsumer<MinecraftServer, EnumRule<E>> changeCallback, E[] supportedValues, GameRules.Acceptor<EnumRule<E>> acceptor) { public EnumRuleType(Function<GameRules.Type<EnumRule<E>>, EnumRule<E>> ruleFactory, BiConsumer<MinecraftServer, EnumRule<E>> changeCallback, E[] supportedValues, GameRules.Acceptor<EnumRule<E>> acceptor, Class<EnumRule<E>> enumRuleClass) {
super(null, ruleFactory, changeCallback, acceptor, FeatureSet.empty()); super(null, ruleFactory, changeCallback, acceptor, enumRuleClass, FeatureSet.empty());
this.supportedValues = supportedValues; this.supportedValues = supportedValues;
} }

View file

@ -1,6 +1,6 @@
accessWidener v1 named accessWidener v1 named
extendable method net/minecraft/world/GameRules$Type <init> (Ljava/util/function/Supplier;Ljava/util/function/Function;Ljava/util/function/BiConsumer;Lnet/minecraft/world/GameRules$Acceptor;Lnet/minecraft/resource/featuretoggle/FeatureSet;)V extendable method net/minecraft/world/GameRules$Type <init> (Ljava/util/function/Supplier;Ljava/util/function/Function;Ljava/util/function/BiConsumer;Lnet/minecraft/world/GameRules$Acceptor;Ljava/lang/Class;Lnet/minecraft/resource/featuretoggle/FeatureSet;)V
accessible method net/minecraft/world/GameRules$Type <init> (Ljava/util/function/Supplier;Ljava/util/function/Function;Ljava/util/function/BiConsumer;Lnet/minecraft/world/GameRules$Acceptor;Lnet/minecraft/resource/featuretoggle/FeatureSet;)V accessible method net/minecraft/world/GameRules$Type <init> (Ljava/util/function/Supplier;Ljava/util/function/Function;Ljava/util/function/BiConsumer;Lnet/minecraft/world/GameRules$Acceptor;Ljava/lang/Class;Lnet/minecraft/resource/featuretoggle/FeatureSet;)V
accessible class net/minecraft/world/GameRules$Acceptor accessible class net/minecraft/world/GameRules$Acceptor
accessible class net/minecraft/client/gui/screen/world/EditGameRulesScreen$RuleWidgetFactory accessible class net/minecraft/client/gui/screen/world/EditGameRulesScreen$RuleWidgetFactory
accessible field net/minecraft/client/gui/screen/world/EditGameRulesScreen$NamedRuleWidget name Ljava/util/List; accessible field net/minecraft/client/gui/screen/world/EditGameRulesScreen$NamedRuleWidget name Ljava/util/List;

View file

@ -38,7 +38,7 @@ public class ArmorKnockbackResistanceTest implements ModInitializer {
@Override @Override
public void onInitialize() { public void onInitialize() {
RegistryKey<Item> registryKey = RegistryKey.of(RegistryKeys.ITEM, Identifier.of("fabric-item-api-v1-testmod", "wooden_boots")); RegistryKey<Item> registryKey = RegistryKey.of(RegistryKeys.ITEM, Identifier.of("fabric-item-api-v1-testmod", "wooden_boots"));
Registry.register(Registries.ITEM, registryKey, new Item(new Item.Settings().method_66332(WOOD_ARMOR, EquipmentType.BOOTS).registryKey(registryKey))); Registry.register(Registries.ITEM, registryKey, new Item(new Item.Settings().armor(WOOD_ARMOR, EquipmentType.BOOTS).registryKey(registryKey)));
} }
private static ArmorMaterial createTestArmorMaterial() { private static ArmorMaterial createTestArmorMaterial() {

View file

@ -76,7 +76,7 @@ public class CustomDamageTest implements ModInitializer {
public static class WeirdPick extends Item { public static class WeirdPick extends Item {
protected WeirdPick(RegistryKey<Item> registryKey) { protected WeirdPick(RegistryKey<Item> registryKey) {
super(new Item.Settings().method_66330(ToolMaterial.GOLD, 3f, 5f).customDamage(WEIRD_DAMAGE_HANDLER).registryKey(registryKey)); super(new Item.Settings().pickaxe(ToolMaterial.GOLD, 3f, 5f).customDamage(WEIRD_DAMAGE_HANDLER).registryKey(registryKey));
} }
@Override @Override

View file

@ -16,26 +16,13 @@
package net.fabricmc.fabric.test.item.gametest; package net.fabricmc.fabric.test.item.gametest;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.BrewingStandBlockEntity;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.PotionContentsComponent;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.potion.Potion;
import net.minecraft.potion.Potions;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.test.GameTest;
import net.minecraft.test.TestContext;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; public class BrewingStandGameTest {
import net.fabricmc.fabric.test.item.CustomDamageTest;
public class BrewingStandGameTest implements FabricGameTest {
private static final int BREWING_TIME = 800; private static final int BREWING_TIME = 800;
private static final BlockPos POS = new BlockPos(0, 1, 0); private static final BlockPos POS = new BlockPos(0, 1, 0);
/* TODO 1.21.5 tests
@GameTest(templateName = EMPTY_STRUCTURE) @GameTest(templateName = EMPTY_STRUCTURE)
public void basicBrewing(TestContext context) { public void basicBrewing(TestContext context) {
context.setBlockState(POS, Blocks.BREWING_STAND); context.setBlockState(POS, Blocks.BREWING_STAND);
@ -153,4 +140,6 @@ public class BrewingStandGameTest implements FabricGameTest {
itemStack.set(DataComponentTypes.POTION_CONTENTS, new PotionContentsComponent(potion)); itemStack.set(DataComponentTypes.POTION_CONTENTS, new PotionContentsComponent(potion));
return itemStack; return itemStack;
} }
*/
} }

View file

@ -16,34 +16,8 @@
package net.fabricmc.fabric.test.item.gametest; package net.fabricmc.fabric.test.item.gametest;
import java.util.List; public class CustomEnchantmentEffectsGameTest {
import java.util.Optional; /* TODO 1.21.5 tests
import net.minecraft.component.EnchantmentEffectComponentTypes;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.effect.EnchantmentEffectEntry;
import net.minecraft.enchantment.effect.EnchantmentValueEffect;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.mob.CreeperEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.entry.RegistryEntry;
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;
import net.minecraft.world.GameMode;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
import net.fabricmc.fabric.test.item.CustomEnchantmentEffectsTest;
public class CustomEnchantmentEffectsGameTest implements FabricGameTest {
@GameTest(templateName = "fabric-item-api-v1-testmod:bedrock_platform") @GameTest(templateName = "fabric-item-api-v1-testmod:bedrock_platform")
public void weirdImpalingSetsFireToTargets(TestContext context) { public void weirdImpalingSetsFireToTargets(TestContext context) {
BlockPos pos = new BlockPos(3, 3, 3); BlockPos pos = new BlockPos(3, 3, 3);
@ -88,4 +62,6 @@ public class CustomEnchantmentEffectsGameTest implements FabricGameTest {
DynamicRegistryManager registryManager = context.getWorld().getRegistryManager(); DynamicRegistryManager registryManager = context.getWorld().getRegistryManager();
return registryManager.getOrThrow(RegistryKeys.ENCHANTMENT); return registryManager.getOrThrow(RegistryKeys.ENCHANTMENT);
} }
*/
} }

View file

@ -16,21 +16,8 @@
package net.fabricmc.fabric.test.item.gametest; package net.fabricmc.fabric.test.item.gametest;
import java.util.function.Consumer; public class DefaultItemComponentGameTest {
/* TODO 1.21.5 tests
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.FireworksComponent;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.test.GameTest;
import net.minecraft.test.GameTestException;
import net.minecraft.test.TestContext;
import net.minecraft.text.Text;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
public class DefaultItemComponentGameTest implements FabricGameTest {
@GameTest(templateName = EMPTY_STRUCTURE) @GameTest(templateName = EMPTY_STRUCTURE)
public void modify(TestContext context) { public void modify(TestContext context) {
Consumer<Text> checkText = text -> { Consumer<Text> checkText = text -> {
@ -90,4 +77,6 @@ public class DefaultItemComponentGameTest implements FabricGameTest {
context.assertTrue(expectedName.contains(itemName), errorMessage.formatted(itemName, expectedName)); context.assertTrue(expectedName.contains(itemName), errorMessage.formatted(itemName, expectedName));
context.complete(); context.complete();
} }
*/
} }

View file

@ -16,22 +16,17 @@
package net.fabricmc.fabric.test.item.gametest; package net.fabricmc.fabric.test.item.gametest;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.AbstractFurnaceBlockEntity; import net.minecraft.block.entity.AbstractFurnaceBlockEntity;
import net.minecraft.block.entity.FurnaceBlockEntity; import net.minecraft.block.entity.FurnaceBlockEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.test.GameTest;
import net.minecraft.test.TestContext; import net.minecraft.test.TestContext;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; public class FurnaceGameTest {
import net.fabricmc.fabric.test.item.CustomDamageTest;
public class FurnaceGameTest implements FabricGameTest {
private static final int COOK_TIME = 200; private static final int COOK_TIME = 200;
private static final BlockPos POS = new BlockPos(0, 1, 0); private static final BlockPos POS = new BlockPos(0, 1, 0);
/* TODO 1.21.5 tests
@GameTest(templateName = EMPTY_STRUCTURE) @GameTest(templateName = EMPTY_STRUCTURE)
public void basicSmelt(TestContext context) { public void basicSmelt(TestContext context) {
context.setBlockState(POS, Blocks.FURNACE); context.setBlockState(POS, Blocks.FURNACE);
@ -98,6 +93,8 @@ public class FurnaceGameTest implements FabricGameTest {
context.complete(); context.complete();
} }
*/
private void setInputs(FurnaceBlockEntity blockEntity, ItemStack ingredient, ItemStack fuel) { private void setInputs(FurnaceBlockEntity blockEntity, ItemStack ingredient, ItemStack fuel) {
blockEntity.setStack(0, ingredient); blockEntity.setStack(0, ingredient);
blockEntity.setStack(1, fuel); blockEntity.setStack(1, fuel);
@ -108,7 +105,8 @@ public class FurnaceGameTest implements FabricGameTest {
ItemStack currentStack = blockEntity.getStack(i); ItemStack currentStack = blockEntity.getStack(i);
ItemStack expectedStack = stacks[i]; ItemStack expectedStack = stacks[i];
RecipeGameTest.assertStacks(currentStack, expectedStack, extraErrorInfo); throw new AssertionError("Not implemented yet");
// RecipeGameTest.assertStacks(currentStack, expectedStack, extraErrorInfo);
} }
} }

View file

@ -16,21 +16,8 @@
package net.fabricmc.fabric.test.item.gametest; package net.fabricmc.fabric.test.item.gametest;
import java.util.List; public class RecipeGameTest {
/* TODO 1.21.5 tests
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.recipe.CraftingRecipe;
import net.minecraft.recipe.input.CraftingRecipeInput;
import net.minecraft.test.GameTest;
import net.minecraft.test.GameTestException;
import net.minecraft.test.TestContext;
import net.minecraft.util.collection.DefaultedList;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
import net.fabricmc.fabric.test.item.CustomDamageTest;
public class RecipeGameTest implements FabricGameTest {
@GameTest(templateName = EMPTY_STRUCTURE) @GameTest(templateName = EMPTY_STRUCTURE)
public void vanillaRemainderTest(TestContext context) { public void vanillaRemainderTest(TestContext context) {
CraftingRecipeInput inventory = CraftingRecipeInput.create(1, 2, List.of( CraftingRecipeInput inventory = CraftingRecipeInput.create(1, 2, List.of(
@ -96,4 +83,6 @@ public class RecipeGameTest implements FabricGameTest {
stack.setDamage(damage); stack.setDamage(damage);
return stack; return stack;
} }
*/
} }

View file

@ -22,6 +22,7 @@ import java.util.function.Consumer;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import net.minecraft.registry.RegistryKey;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.village.TradeOffers; import net.minecraft.village.TradeOffers;
import net.minecraft.village.VillagerProfession; import net.minecraft.village.VillagerProfession;
@ -49,7 +50,7 @@ public final class TradeOfferHelper {
* @param level the profession level the villager must be to offer the trades * @param level the profession level the villager must be to offer the trades
* @param factories a consumer to provide the factories * @param factories a consumer to provide the factories
*/ */
public static void registerVillagerOffers(VillagerProfession profession, int level, Consumer<List<TradeOffers.Factory>> factories) { public static void registerVillagerOffers(RegistryKey<VillagerProfession> profession, int level, Consumer<List<TradeOffers.Factory>> factories) {
TradeOfferInternals.registerVillagerOffers(profession, level, (trades, rebalanced) -> factories.accept(trades)); TradeOfferInternals.registerVillagerOffers(profession, level, (trades, rebalanced) -> factories.accept(trades));
} }
@ -74,7 +75,7 @@ public final class TradeOfferHelper {
* @param factories a consumer to provide the factories * @param factories a consumer to provide the factories
*/ */
@ApiStatus.Experimental @ApiStatus.Experimental
public static void registerVillagerOffers(VillagerProfession profession, int level, VillagerOffersAdder factories) { public static void registerVillagerOffers(RegistryKey<VillagerProfession> profession, int level, VillagerOffersAdder factories) {
TradeOfferInternals.registerVillagerOffers(profession, level, factories); TradeOfferInternals.registerVillagerOffers(profession, level, factories);
} }

View file

@ -1,185 +0,0 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.api.object.builder.v1.villager;
import static com.google.common.base.Preconditions.checkState;
import java.util.function.Predicate;
import com.google.common.collect.ImmutableSet;
import org.jetbrains.annotations.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.item.Item;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.sound.SoundEvent;
import net.minecraft.util.Identifier;
import net.minecraft.village.TradeOffers;
import net.minecraft.village.VillagerProfession;
import net.minecraft.world.poi.PointOfInterestType;
/**
* Allows for the creation of new {@link VillagerProfession}s.
*
* <p>The texture for the villagers are located at <code>assets/IDENTIFIER_NAMESPACE/textures/entity/villager/profession/IDENTIFIER_PATH.png</code>
*
* <p>A corresponding <code>IDENTIFIER_PATH.mcmeta</code> file exits in the same directory to define properties such as the {@link net.minecraft.client.render.entity.feature.VillagerResourceMetadata.HatType HatType} this profession would use.
*
* <p>Note this does not register any trades to these villagers. To register trades, add a new entry with your profession as the key to {@link TradeOffers#PROFESSION_TO_LEVELED_TRADE}.
*
* @deprecated Replaced by access widener for {@link VillagerProfession#VillagerProfession}
* in Fabric Transitive Access Wideners (v1).
*/
@Deprecated
public final class VillagerProfessionBuilder {
private final ImmutableSet.Builder<Item> gatherableItemsBuilder = ImmutableSet.builder();
private final ImmutableSet.Builder<Block> secondaryJobSiteBlockBuilder = ImmutableSet.builder();
private Identifier identifier;
private Predicate<RegistryEntry<PointOfInterestType>> pointOfInterestType;
private Predicate<RegistryEntry<PointOfInterestType>> acquirableJobSite;
@Nullable
private SoundEvent workSoundEvent;
private VillagerProfessionBuilder() {
}
/**
* Creates a builder instance to allow for creation of a {@link VillagerProfession}.
*
* @return A new builder.
*/
public static VillagerProfessionBuilder create() {
return new VillagerProfessionBuilder();
}
/**
* The Identifier used to identify this villager profession.
*
* @param id The identifier to assign to this profession.
* @return this builder
*/
public VillagerProfessionBuilder id(Identifier id) {
this.identifier = id;
return this;
}
/**
* The {@link PointOfInterestType} the Villager of this profession will search for when finding a workstation.
*
* @param key The {@link PointOfInterestType} the Villager will attempt to find.
* @return this builder.
*/
public VillagerProfessionBuilder workstation(RegistryKey<PointOfInterestType> key) {
jobSite(entry -> entry.matchesKey(key));
return workstation(entry -> entry.matchesKey(key));
}
/**
* The {@link PointOfInterestType} the Villager of this profession will search for when finding a workstation.
*
* @param predicate The {@link PointOfInterestType} the Villager will attempt to find.
* @return this builder.
*/
public VillagerProfessionBuilder workstation(Predicate<RegistryEntry<PointOfInterestType>> predicate) {
this.pointOfInterestType = predicate;
return this;
}
public VillagerProfessionBuilder jobSite(Predicate<RegistryEntry<PointOfInterestType>> predicate) {
this.acquirableJobSite = predicate;
return this;
}
/**
* Items that a Villager may harvest in this profession.
*
* <p>In Vanilla, this is used by the farmer to define what type of crops the farmer can harvest.
*
* @param items Items harvestable by this profession.
* @return this builder.
*/
public VillagerProfessionBuilder harvestableItems(Item... items) {
this.gatherableItemsBuilder.add(items);
return this;
}
/**
* Items that a Villager may harvest in this profession.
*
* <p>In Vanilla, this is used by the farmer to define what type of crops the farmer can harvest.
*
* @param items Items harvestable by this profession.
* @return this builder.
*/
public VillagerProfessionBuilder harvestableItems(Iterable<Item> items) {
this.gatherableItemsBuilder.addAll(items);
return this;
}
/**
* A collection of blocks blocks which may suffice as a secondary job site for a Villager.
*
* <p>In Vanilla, this is used by the {@link VillagerProfession#FARMER Farmer} to stay near {@link Blocks#FARMLAND Farmland} when at it's job site.
*
* @param blocks Collection of secondary job site blocks.
* @return this builder.
*/
public VillagerProfessionBuilder secondaryJobSites(Block... blocks) {
this.secondaryJobSiteBlockBuilder.add(blocks);
return this;
}
/**
* A collection of blocks blocks which may suffice as a secondary job site for a Villager.
*
* <p>In Vanilla, this is used by the {@link VillagerProfession#FARMER Farmer} to stay near {@link Blocks#FARMLAND Farmland} when at it's job site.
*
* @param blocks Collection of secondary job site blocks.
* @return this builder.
*/
public VillagerProfessionBuilder secondaryJobSites(Iterable<Block> blocks) {
this.secondaryJobSiteBlockBuilder.addAll(blocks);
return this;
}
/**
* Provides the sound made when a Villager works.
*
* @param workSoundEvent The {@link SoundEvent} to be played.
* @return this builder.
*/
public VillagerProfessionBuilder workSound(@Nullable SoundEvent workSoundEvent) {
this.workSoundEvent = workSoundEvent;
return this;
}
/**
* Creates the {@link VillagerProfession}.
*
* @return a new {@link VillagerProfession}.
* @throws IllegalStateException if the builder is missing an {@link Identifier id} and {@link PointOfInterestType workstation}.
*/
public VillagerProfession build() {
checkState(this.identifier != null, "An Identifier is required to build a new VillagerProfession.");
checkState(this.pointOfInterestType != null, "A PointOfInterestType is required to build a new VillagerProfession.");
checkState(this.acquirableJobSite != null, "A PointOfInterestType is required for the acquirableJobSite to build a new VillagerProfession.");
return new VillagerProfession(this.identifier.toString(), this.pointOfInterestType, this.acquirableJobSite, this.gatherableItemsBuilder.build(), this.secondaryJobSiteBlockBuilder.build(), this.workSoundEvent);
}
}

View file

@ -1,79 +0,0 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.api.object.builder.v1.villager;
import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.util.Identifier;
import net.minecraft.village.VillagerProfession;
import net.minecraft.village.VillagerType;
import net.minecraft.world.biome.Biome;
/**
* Utilities related to the creation of {@link VillagerType}s.
* Not to be confused with a {@link VillagerProfession}, a villager type defines the appearance of a villager.
*
* <p>Creation and registration of custom villager types may be done by using {@link VillagerTypeHelper#register(Identifier)}.
*
* <p>Creation and registration of a villager type does not guarantee villagers of a specific type will be created in a world.
* Typically the villager type is bound to a specific group of biomes.
* To allow a villager type to be spawned in a specific biome, use {@link VillagerTypeHelper#addVillagerTypeToBiome(RegistryKey, VillagerType)}.
*
* <p>The texture used for the appearance of the villager is located at {@code assets/IDENTIFIER_NAMESPACE/textures/entity/villager/type/IDENTIFIER_PATH.png}.
*
* @deprecated Replaced by access wideners for {@link VillagerType#create} and {@link VillagerType#BIOME_TO_TYPE}
* in Fabric Transitive Access Wideners (v1).
*/
@Deprecated
public final class VillagerTypeHelper {
private static final Logger LOGGER = LoggerFactory.getLogger(VillagerTypeHelper.class);
/**
* Creates and registers a new villager type.
*
* @param id the id of the villager type
* @return a new villager type
*/
public static VillagerType register(Identifier id) {
Objects.requireNonNull(id, "Id of villager type cannot be null");
return Registry.register(Registries.VILLAGER_TYPE, id, new VillagerType(id.toString()));
}
/**
* Sets the biome a villager type can spawn in.
*
* @param biomeKey the registry key of the biome
* @param villagerType the villager type
*/
public static void addVillagerTypeToBiome(RegistryKey<Biome> biomeKey, VillagerType villagerType) {
Objects.requireNonNull(biomeKey, "Biome registry key cannot be null");
Objects.requireNonNull(villagerType, "Villager type cannot be null");
if (VillagerType.BIOME_TO_TYPE.put(biomeKey, villagerType) != null) {
LOGGER.debug("Overriding existing Biome -> VillagerType registration for Biome {}", biomeKey.getValue().toString());
}
}
private VillagerTypeHelper() {
}
}

View file

@ -32,6 +32,7 @@ import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import net.minecraft.registry.RegistryKey;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.Util; import net.minecraft.util.Util;
import net.minecraft.village.TradeOffers; import net.minecraft.village.TradeOffers;
@ -51,9 +52,9 @@ public final class TradeOfferInternals {
*/ */
private static void initVillagerTrades() { private static void initVillagerTrades() {
if (!(TradeOffers.REBALANCED_PROFESSION_TO_LEVELED_TRADE instanceof HashMap)) { if (!(TradeOffers.REBALANCED_PROFESSION_TO_LEVELED_TRADE instanceof HashMap)) {
Map<VillagerProfession, Int2ObjectMap<TradeOffers.Factory[]>> map = new HashMap<>(TradeOffers.REBALANCED_PROFESSION_TO_LEVELED_TRADE); Map<RegistryKey<VillagerProfession>, Int2ObjectMap<TradeOffers.Factory[]>> map = new HashMap<>(TradeOffers.REBALANCED_PROFESSION_TO_LEVELED_TRADE);
for (Map.Entry<VillagerProfession, Int2ObjectMap<TradeOffers.Factory[]>> trade : TradeOffers.PROFESSION_TO_LEVELED_TRADE.entrySet()) { for (Map.Entry<RegistryKey<VillagerProfession>, Int2ObjectMap<TradeOffers.Factory[]>> trade : TradeOffers.PROFESSION_TO_LEVELED_TRADE.entrySet()) {
if (!map.containsKey(trade.getKey())) map.put(trade.getKey(), trade.getValue()); if (!map.containsKey(trade.getKey())) map.put(trade.getKey(), trade.getValue());
} }
@ -63,7 +64,7 @@ public final class TradeOfferInternals {
// synchronized guards against concurrent modifications - Vanilla does not mutate the underlying arrays (as of 1.16), // synchronized guards against concurrent modifications - Vanilla does not mutate the underlying arrays (as of 1.16),
// so reads will be fine without locking. // so reads will be fine without locking.
public static synchronized void registerVillagerOffers(VillagerProfession profession, int level, TradeOfferHelper.VillagerOffersAdder factory) { public static synchronized void registerVillagerOffers(RegistryKey<VillagerProfession> profession, int level, TradeOfferHelper.VillagerOffersAdder factory) {
Objects.requireNonNull(profession, "VillagerProfession may not be null."); Objects.requireNonNull(profession, "VillagerProfession may not be null.");
initVillagerTrades(); initVillagerTrades();
registerOffers(TradeOffers.PROFESSION_TO_LEVELED_TRADE.computeIfAbsent(profession, key -> new Int2ObjectOpenHashMap<>()), level, trades -> factory.onRegister(trades, false)); registerOffers(TradeOffers.PROFESSION_TO_LEVELED_TRADE.computeIfAbsent(profession, key -> new Int2ObjectOpenHashMap<>()), level, trades -> factory.onRegister(trades, false));

View file

@ -16,6 +16,7 @@
package net.fabricmc.fabric.mixin.object.builder; package net.fabricmc.fabric.mixin.object.builder;
import java.util.Set;
import java.util.stream.Stream; import java.util.stream.Stream;
import com.llamalad7.mixinextras.sugar.Local; import com.llamalad7.mixinextras.sugar.Local;
@ -26,7 +27,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.registry.DefaultedRegistry; import net.minecraft.registry.RegistryKey;
import net.minecraft.util.math.random.Random; import net.minecraft.util.math.random.Random;
import net.minecraft.village.TradeOffer; import net.minecraft.village.TradeOffer;
import net.minecraft.village.TradeOffers; import net.minecraft.village.TradeOffers;
@ -41,8 +42,8 @@ public abstract class TradeOffersTypeAwareBuyForOneEmeraldFactoryMixin {
* We want to prevent this default logic so modded villager types will work. * We want to prevent this default logic so modded villager types will work.
* So we return an empty stream so an exception is never thrown. * So we return an empty stream so an exception is never thrown.
*/ */
@Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/registry/DefaultedRegistry;stream()Ljava/util/stream/Stream;")) @Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Ljava/util/Set;stream()Ljava/util/stream/Stream;"))
private <T> Stream<T> disableVanillaCheck(DefaultedRegistry<VillagerType> instance) { private <T> Stream<T> disableVanillaCheck(Set<RegistryKey<VillagerType>> instance) {
return Stream.empty(); return Stream.empty();
} }

View file

@ -12,7 +12,6 @@ mutable field net/minecraft/village/TradeOffers REBALANCED_WANDERING_TRADER_TRAD
accessible method net/minecraft/entity/SpawnRestriction register (Lnet/minecraft/entity/EntityType;Lnet/minecraft/entity/SpawnLocation;Lnet/minecraft/world/Heightmap$Type;Lnet/minecraft/entity/SpawnRestriction$SpawnPredicate;)V accessible method net/minecraft/entity/SpawnRestriction register (Lnet/minecraft/entity/EntityType;Lnet/minecraft/entity/SpawnLocation;Lnet/minecraft/world/Heightmap$Type;Lnet/minecraft/entity/SpawnRestriction$SpawnPredicate;)V
accessible field net/minecraft/village/VillagerType BIOME_TO_TYPE Ljava/util/Map; accessible field net/minecraft/village/VillagerType BIOME_TO_TYPE Ljava/util/Map;
accessible method net/minecraft/village/VillagerType <init> (Ljava/lang/String;)V
accessible method net/minecraft/block/WoodType register (Lnet/minecraft/block/WoodType;)Lnet/minecraft/block/WoodType; accessible method net/minecraft/block/WoodType register (Lnet/minecraft/block/WoodType;)Lnet/minecraft/block/WoodType;
accessible method net/minecraft/block/BlockSetType register (Lnet/minecraft/block/BlockSetType;)Lnet/minecraft/block/BlockSetType; accessible method net/minecraft/block/BlockSetType register (Lnet/minecraft/block/BlockSetType;)Lnet/minecraft/block/BlockSetType;

View file

@ -16,8 +16,6 @@
package net.fabricmc.fabric.test.object.builder; package net.fabricmc.fabric.test.object.builder;
import java.util.Collections;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
@ -60,11 +58,6 @@ final class EntityTypeBuilderGenericsTest {
super(entityType, world); super(entityType, world);
} }
@Override
public Iterable<ItemStack> getArmorItems() {
return Collections.emptyList();
}
@Override @Override
public ItemStack getEquippedStack(EquipmentSlot slot) { public ItemStack getEquippedStack(EquipmentSlot slot) {
return ItemStack.EMPTY; return ItemStack.EMPTY;

View file

@ -19,14 +19,11 @@ package net.fabricmc.fabric.test.object.builder;
import java.util.List; import java.util.List;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.test.GameTest;
import net.minecraft.test.TestContext; import net.minecraft.test.TestContext;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
public class ObjectBuilderGameTest { public class ObjectBuilderGameTest {
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) // @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) TODO 1.21.5 tests
public void testBlockUse(TestContext context) { public void testBlockUse(TestContext context) {
List<Block> blocks = List.of(BlockEntityTypeBuilderTest.INITIAL_BETRAYAL_BLOCK, BlockEntityTypeBuilderTest.ADDED_BETRAYAL_BLOCK, BlockEntityTypeBuilderTest.FIRST_MULTI_BETRAYAL_BLOCK, BlockEntityTypeBuilderTest.SECOND_MULTI_BETRAYAL_BLOCK); List<Block> blocks = List.of(BlockEntityTypeBuilderTest.INITIAL_BETRAYAL_BLOCK, BlockEntityTypeBuilderTest.ADDED_BETRAYAL_BLOCK, BlockEntityTypeBuilderTest.FIRST_MULTI_BETRAYAL_BLOCK, BlockEntityTypeBuilderTest.SECOND_MULTI_BETRAYAL_BLOCK);
BlockPos.Mutable pos = BlockPos.ORIGIN.up().mutableCopy(); BlockPos.Mutable pos = BlockPos.ORIGIN.up().mutableCopy();

View file

@ -16,9 +16,17 @@
package net.fabricmc.fabric.test.recipe.ingredient; package net.fabricmc.fabric.test.recipe.ingredient;
import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.Objects; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.List;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import net.minecraft.Bootstrap;
import net.minecraft.SharedConstants;
import net.minecraft.component.ComponentChanges; import net.minecraft.component.ComponentChanges;
import net.minecraft.component.DataComponentTypes; import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.NbtComponent; import net.minecraft.component.type.NbtComponent;
@ -28,41 +36,41 @@ import net.minecraft.item.Items;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.Ingredient;
import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.test.GameTest;
import net.minecraft.test.GameTestException;
import net.minecraft.test.TestContext;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Util; import net.minecraft.util.Util;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
import net.fabricmc.fabric.api.recipe.v1.ingredient.DefaultCustomIngredients; import net.fabricmc.fabric.api.recipe.v1.ingredient.DefaultCustomIngredients;
public class IngredientMatchTests { public class IngredientMatchTests {
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @BeforeAll
public void testAllIngredient(TestContext context) { static void beforeAll() {
SharedConstants.createGameVersion();
Bootstrap.initialize();
}
@Test
public void testAllIngredient() {
Ingredient allIngredient = DefaultCustomIngredients.all(Ingredient.ofItems(Items.APPLE, Items.CARROT), Ingredient.ofItems(Items.STICK, Items.CARROT)); Ingredient allIngredient = DefaultCustomIngredients.all(Ingredient.ofItems(Items.APPLE, Items.CARROT), Ingredient.ofItems(Items.STICK, Items.CARROT));
assertEquals(1, allIngredient.getMatchingItems().toList().size()); assertEquals(1, allIngredient.getMatchingItems().toList().size());
assertEquals(Items.CARROT, allIngredient.getMatchingItems().toList().getFirst().value()); assertEquals(Items.CARROT, allIngredient.getMatchingItems().toList().getFirst().value());
assertEquals(false, allIngredient.getMatchingItems().toList().isEmpty()); assertFalse(allIngredient.getMatchingItems().toList().isEmpty());
assertEquals(false, allIngredient.test(new ItemStack(Items.APPLE))); assertFalse(allIngredient.test(new ItemStack(Items.APPLE)));
assertEquals(true, allIngredient.test(new ItemStack(Items.CARROT))); assertTrue(allIngredient.test(new ItemStack(Items.CARROT)));
assertEquals(false, allIngredient.test(new ItemStack(Items.STICK))); assertFalse(allIngredient.test(new ItemStack(Items.STICK)));
Ingredient emptyAllIngredient = DefaultCustomIngredients.all(Ingredient.ofItems(Items.APPLE), Ingredient.ofItems(Items.STICK)); Ingredient emptyAllIngredient = DefaultCustomIngredients.all(Ingredient.ofItems(Items.APPLE), Ingredient.ofItems(Items.STICK));
assertEquals(0, emptyAllIngredient.getMatchingItems().toList().size()); assertEquals(0, emptyAllIngredient.getMatchingItems().toList().size());
assertEquals(true, emptyAllIngredient.getMatchingItems().toList().isEmpty()); assertTrue(emptyAllIngredient.getMatchingItems().toList().isEmpty());
assertEquals(false, emptyAllIngredient.test(new ItemStack(Items.APPLE))); assertFalse(emptyAllIngredient.test(new ItemStack(Items.APPLE)));
assertEquals(false, emptyAllIngredient.test(new ItemStack(Items.STICK))); assertFalse(emptyAllIngredient.test(new ItemStack(Items.STICK)));
context.complete();
} }
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @Test
public void testAnyIngredient(TestContext context) { public void testAnyIngredient() {
Ingredient anyIngredient = DefaultCustomIngredients.any(Ingredient.ofItems(Items.APPLE, Items.CARROT), Ingredient.ofItems(Items.STICK, Items.CARROT)); Ingredient anyIngredient = DefaultCustomIngredients.any(Ingredient.ofItems(Items.APPLE, Items.CARROT), Ingredient.ofItems(Items.STICK, Items.CARROT));
assertEquals(4, anyIngredient.getMatchingItems().toList().size()); assertEquals(4, anyIngredient.getMatchingItems().toList().size());
@ -70,32 +78,28 @@ public class IngredientMatchTests {
assertEquals(Items.CARROT, anyIngredient.getMatchingItems().toList().get(1).value()); assertEquals(Items.CARROT, anyIngredient.getMatchingItems().toList().get(1).value());
assertEquals(Items.STICK, anyIngredient.getMatchingItems().toList().get(2).value()); assertEquals(Items.STICK, anyIngredient.getMatchingItems().toList().get(2).value());
assertEquals(Items.CARROT, anyIngredient.getMatchingItems().toList().get(3).value()); assertEquals(Items.CARROT, anyIngredient.getMatchingItems().toList().get(3).value());
assertEquals(false, anyIngredient.getMatchingItems().toList().isEmpty()); assertFalse(anyIngredient.getMatchingItems().toList().isEmpty());
assertEquals(true, anyIngredient.test(new ItemStack(Items.APPLE))); assertTrue(anyIngredient.test(new ItemStack(Items.APPLE)));
assertEquals(true, anyIngredient.test(new ItemStack(Items.CARROT))); assertTrue(anyIngredient.test(new ItemStack(Items.CARROT)));
assertEquals(true, anyIngredient.test(new ItemStack(Items.STICK))); assertTrue(anyIngredient.test(new ItemStack(Items.STICK)));
context.complete();
} }
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @Test
public void testDifferenceIngredient(TestContext context) { public void testDifferenceIngredient() {
Ingredient differenceIngredient = DefaultCustomIngredients.difference(Ingredient.ofItems(Items.APPLE, Items.CARROT), Ingredient.ofItems(Items.STICK, Items.CARROT)); Ingredient differenceIngredient = DefaultCustomIngredients.difference(Ingredient.ofItems(Items.APPLE, Items.CARROT), Ingredient.ofItems(Items.STICK, Items.CARROT));
assertEquals(1, differenceIngredient.getMatchingItems().toList().size()); assertEquals(1, differenceIngredient.getMatchingItems().toList().size());
assertEquals(Items.APPLE, differenceIngredient.getMatchingItems().toList().getFirst().value()); assertEquals(Items.APPLE, differenceIngredient.getMatchingItems().toList().getFirst().value());
assertEquals(false, differenceIngredient.getMatchingItems().toList().isEmpty()); assertFalse(differenceIngredient.getMatchingItems().toList().isEmpty());
assertEquals(true, differenceIngredient.test(new ItemStack(Items.APPLE))); assertTrue(differenceIngredient.test(new ItemStack(Items.APPLE)));
assertEquals(false, differenceIngredient.test(new ItemStack(Items.CARROT))); assertFalse(differenceIngredient.test(new ItemStack(Items.CARROT)));
assertEquals(false, differenceIngredient.test(new ItemStack(Items.STICK))); assertFalse(differenceIngredient.test(new ItemStack(Items.STICK)));
context.complete();
} }
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @Test
public void testComponentIngredient(TestContext context) { public void testComponentIngredient() {
final Ingredient baseIngredient = Ingredient.ofItems(Items.DIAMOND_PICKAXE, Items.NETHERITE_PICKAXE, Items.STICK); final Ingredient baseIngredient = Ingredient.ofItems(Items.DIAMOND_PICKAXE, Items.NETHERITE_PICKAXE, Items.STICK);
final Ingredient undamagedIngredient = DefaultCustomIngredients.components( final Ingredient undamagedIngredient = DefaultCustomIngredients.components(
baseIngredient, baseIngredient,
@ -110,8 +114,8 @@ public class IngredientMatchTests {
ItemStack renamedUndamagedDiamondPickaxe = new ItemStack(Items.DIAMOND_PICKAXE); ItemStack renamedUndamagedDiamondPickaxe = new ItemStack(Items.DIAMOND_PICKAXE);
renamedUndamagedDiamondPickaxe.set(DataComponentTypes.CUSTOM_NAME, Text.literal("Renamed")); renamedUndamagedDiamondPickaxe.set(DataComponentTypes.CUSTOM_NAME, Text.literal("Renamed"));
assertEquals(true, undamagedIngredient.test(renamedUndamagedDiamondPickaxe)); assertTrue(undamagedIngredient.test(renamedUndamagedDiamondPickaxe));
assertEquals(false, noNameUndamagedIngredient.test(renamedUndamagedDiamondPickaxe)); assertFalse(noNameUndamagedIngredient.test(renamedUndamagedDiamondPickaxe));
assertEquals(3, undamagedIngredient.getMatchingItems().toList().size()); assertEquals(3, undamagedIngredient.getMatchingItems().toList().size());
ItemStack result0 = undamagedIngredient.getMatchingItems().toList().getFirst().value().getDefaultStack(); ItemStack result0 = undamagedIngredient.getMatchingItems().toList().getFirst().value().getDefaultStack();
@ -121,19 +125,19 @@ public class IngredientMatchTests {
assertEquals(Items.NETHERITE_PICKAXE, result1.getItem()); assertEquals(Items.NETHERITE_PICKAXE, result1.getItem());
assertEquals(ComponentChanges.EMPTY, result0.getComponentChanges()); assertEquals(ComponentChanges.EMPTY, result0.getComponentChanges());
assertEquals(ComponentChanges.EMPTY, result1.getComponentChanges()); assertEquals(ComponentChanges.EMPTY, result1.getComponentChanges());
assertEquals(false, undamagedIngredient.getMatchingItems().toList().isEmpty()); assertFalse(undamagedIngredient.getMatchingItems().toList().isEmpty());
// Undamaged is fine // Undamaged is fine
assertEquals(true, undamagedIngredient.test(new ItemStack(Items.DIAMOND_PICKAXE))); assertTrue(undamagedIngredient.test(new ItemStack(Items.DIAMOND_PICKAXE)));
assertEquals(true, undamagedIngredient.test(new ItemStack(Items.NETHERITE_PICKAXE))); assertTrue(undamagedIngredient.test(new ItemStack(Items.NETHERITE_PICKAXE)));
// Damaged is not fine // Damaged is not fine
ItemStack damagedDiamondPickaxe = new ItemStack(Items.DIAMOND_PICKAXE); ItemStack damagedDiamondPickaxe = new ItemStack(Items.DIAMOND_PICKAXE);
damagedDiamondPickaxe.setDamage(10); damagedDiamondPickaxe.setDamage(10);
assertEquals(false, undamagedIngredient.test(damagedDiamondPickaxe)); assertFalse(undamagedIngredient.test(damagedDiamondPickaxe));
// Checking for DAMAGE component requires the item is damageable in the first place // Checking for DAMAGE component requires the item is damageable in the first place
assertEquals(false, undamagedIngredient.test(new ItemStack(Items.STICK))); assertFalse(undamagedIngredient.test(new ItemStack(Items.STICK)));
// Custom data is strictly matched, like any other component with multiple fields // Custom data is strictly matched, like any other component with multiple fields
final NbtCompound requiredData = new NbtCompound(); final NbtCompound requiredData = new NbtCompound();
@ -149,21 +153,19 @@ public class IngredientMatchTests {
requiredDataStack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(requiredData)); requiredDataStack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(requiredData));
ItemStack extraDataStack = new ItemStack(Items.DIAMOND_PICKAXE); ItemStack extraDataStack = new ItemStack(Items.DIAMOND_PICKAXE);
extraDataStack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(extraData)); extraDataStack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(extraData));
assertEquals(true, customDataIngredient.test(requiredDataStack)); assertTrue(customDataIngredient.test(requiredDataStack));
assertEquals(false, customDataIngredient.test(extraDataStack)); assertFalse(customDataIngredient.test(extraDataStack));
// Default value is ignored in components(ItemStack) // Default value is ignored in components(ItemStack)
final Ingredient damagedPickaxeIngredient = DefaultCustomIngredients.components(renamedUndamagedDiamondPickaxe); final Ingredient damagedPickaxeIngredient = DefaultCustomIngredients.components(renamedUndamagedDiamondPickaxe);
ItemStack renamedDamagedDiamondPickaxe = renamedUndamagedDiamondPickaxe.copy(); ItemStack renamedDamagedDiamondPickaxe = renamedUndamagedDiamondPickaxe.copy();
renamedDamagedDiamondPickaxe.setDamage(10); renamedDamagedDiamondPickaxe.setDamage(10);
assertEquals(true, damagedPickaxeIngredient.test(renamedUndamagedDiamondPickaxe)); assertTrue(damagedPickaxeIngredient.test(renamedUndamagedDiamondPickaxe));
assertEquals(true, damagedPickaxeIngredient.test(renamedDamagedDiamondPickaxe)); assertTrue(damagedPickaxeIngredient.test(renamedDamagedDiamondPickaxe));
context.complete();
} }
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @Test
public void testCustomDataIngredient(TestContext context) { public void testCustomDataIngredient() {
final NbtCompound requiredNbt = Util.make(new NbtCompound(), nbt -> { final NbtCompound requiredNbt = Util.make(new NbtCompound(), nbt -> {
nbt.putInt("keyA", 1); nbt.putInt("keyA", 1);
}); });
@ -181,29 +183,21 @@ public class IngredientMatchTests {
final Ingredient customDataIngredient = DefaultCustomIngredients.customData(baseIngredient, requiredNbt); final Ingredient customDataIngredient = DefaultCustomIngredients.customData(baseIngredient, requiredNbt);
ItemStack stack = new ItemStack(Items.STICK); ItemStack stack = new ItemStack(Items.STICK);
assertEquals(false, customDataIngredient.test(stack)); assertFalse(customDataIngredient.test(stack));
stack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(requiredNbt)); stack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(requiredNbt));
assertEquals(true, customDataIngredient.test(stack)); assertTrue(customDataIngredient.test(stack));
// This is a non-strict matching // This is a non-strict matching
stack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(acceptedNbt)); stack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(acceptedNbt));
assertEquals(true, customDataIngredient.test(stack)); assertTrue(customDataIngredient.test(stack));
stack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(rejectedNbt1)); stack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(rejectedNbt1));
assertEquals(false, customDataIngredient.test(stack)); assertFalse(customDataIngredient.test(stack));
stack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(rejectedNbt2)); stack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(rejectedNbt2));
assertEquals(false, customDataIngredient.test(stack)); assertFalse(customDataIngredient.test(stack));
List<RegistryEntry<Item>> matchingItems = customDataIngredient.getMatchingItems().toList(); List<RegistryEntry<Item>> matchingItems = customDataIngredient.getMatchingItems().toList();
assertEquals(1, matchingItems.size()); assertEquals(1, matchingItems.size());
assertEquals(Items.STICK, matchingItems.getFirst().value()); assertEquals(Items.STICK, matchingItems.getFirst().value());
// Test disabled as the vanilla API no longer exposes the stack with data. // Test disabled as the vanilla API no longer exposes the stack with data.
// assertEquals(NbtComponent.of(requiredNbt), matchingItems.getFirst().value().getDefaultStack().get(DataComponentTypes.CUSTOM_DATA)); // assertEquals(NbtComponent.of(requiredNbt), matchingItems.getFirst().value().getDefaultStack().get(DataComponentTypes.CUSTOM_DATA));
context.complete();
}
private static <T> void assertEquals(T expected, T actual) {
if (!Objects.equals(expected, actual)) {
throw new GameTestException(String.format("assertEquals failed%nexpected: %s%n but was: %s", expected, actual));
}
} }
} }

View file

@ -16,31 +16,43 @@
package net.fabricmc.fabric.test.recipe.ingredient; package net.fabricmc.fabric.test.recipe.ingredient;
import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import com.mojang.serialization.Codec;
import com.mojang.serialization.JsonOps; import com.mojang.serialization.JsonOps;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import net.minecraft.Bootstrap;
import net.minecraft.SharedConstants;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.Ingredient;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.Registries;
import net.minecraft.registry.RegistryOps; import net.minecraft.registry.RegistryOps;
import net.minecraft.test.GameTest;
import net.minecraft.test.GameTestException;
import net.minecraft.test.TestContext;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
import net.fabricmc.fabric.api.recipe.v1.ingredient.DefaultCustomIngredients; import net.fabricmc.fabric.api.recipe.v1.ingredient.DefaultCustomIngredients;
import net.fabricmc.fabric.impl.recipe.ingredient.CustomIngredientInit;
public class SerializationTests { public class SerializationTests {
@BeforeAll
static void beforeAll() {
SharedConstants.createGameVersion();
Bootstrap.initialize();
new CustomIngredientInit().onInitialize();
}
/** /**
* Check that trying to use a custom ingredient inside an array ingredient fails. * Check that trying to use a custom ingredient inside an array ingredient fails.
*/ */
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @Test
public void testArrayDeserialization(TestContext context) { public void testArrayDeserialization() {
String ingredientJson = """ String ingredientJson = """
[ [
{ {
@ -57,37 +69,31 @@ public class SerializationTests {
"""; """;
JsonElement json = JsonParser.parseString(ingredientJson); JsonElement json = JsonParser.parseString(ingredientJson);
try { assertThrows(JsonParseException.class, () -> {
Ingredient.CODEC.parse(JsonOps.INSTANCE, json).getOrThrow(JsonParseException::new); Ingredient.CODEC.parse(JsonOps.INSTANCE, json).getOrThrow(JsonParseException::new);
throw new GameTestException("Using a custom ingredient inside an array ingredient should have failed."); });
} catch (JsonParseException e) {
context.complete();
}
} }
/** /**
* Check that we can serialise and deserialize a custom ingredient. * Check that we can serialise and deserialize a custom ingredient.
*/ */
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @Test
public void testCustomIngredientSerialization(TestContext context) { public void testCustomIngredientSerialization() {
for (boolean allowEmpty : List.of(false, true)) { RegistryOps<JsonElement> registryOps = RegistryOps.of(JsonOps.INSTANCE, DynamicRegistryManager.of(Registries.REGISTRIES));
String ingredientJson = """
String ingredientJson = """
{"ingredients":["minecraft:stone"],"fabric:type":"fabric:all"} {"ingredients":["minecraft:stone"],"fabric:type":"fabric:all"}
""".trim(); """.trim();
RegistryOps<JsonElement> registryOps = context.getWorld().getRegistryManager().getOps(JsonOps.INSTANCE); Ingredient ingredient = DefaultCustomIngredients.all(
Ingredient ingredient = DefaultCustomIngredients.all( Ingredient.ofItems(Items.STONE)
Ingredient.ofItems(Items.STONE) );
); JsonObject json = Ingredient.CODEC.encodeStart(registryOps, ingredient).getOrThrow(IllegalStateException::new).getAsJsonObject();
Codec<Ingredient> ingredientCodec = Ingredient.CODEC; assertEquals(json.toString(), ingredientJson, "Unexpected json: " + json);
JsonObject json = ingredientCodec.encodeStart(registryOps, ingredient).getOrThrow(IllegalStateException::new).getAsJsonObject();
context.assertTrue(json.toString().equals(ingredientJson), "Unexpected json: " + json);
// Make sure that we can deserialize it
Ingredient deserialized = ingredientCodec.parse(registryOps, json).getOrThrow(JsonParseException::new);
context.assertTrue(deserialized.getCustomIngredient() != null, "Custom ingredient was not deserialized");
context.assertTrue(deserialized.getCustomIngredient().getSerializer() == ingredient.getCustomIngredient().getSerializer(), "Serializer did not match");
}
context.complete(); // Make sure that we can deserialize it
Ingredient deserialized = Ingredient.CODEC.parse(registryOps, json).getOrThrow(JsonParseException::new);
assertNotNull(deserialized.getCustomIngredient(), "Custom ingredient was not deserialized");
assertSame(deserialized.getCustomIngredient().getSerializer(), ingredient.getCustomIngredient().getSerializer(), "Serializer did not match");
} }
} }

View file

@ -27,18 +27,16 @@ import net.minecraft.recipe.ShapelessRecipe;
import net.minecraft.recipe.input.CraftingRecipeInput; import net.minecraft.recipe.input.CraftingRecipeInput;
import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.RegistryKeys;
import net.minecraft.test.GameTest;
import net.minecraft.test.GameTestException; import net.minecraft.test.GameTestException;
import net.minecraft.test.TestContext; import net.minecraft.test.TestContext;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
public class ShapelessRecipeMatchTests { public class ShapelessRecipeMatchTests {
/** /**
* The recipe requires at least one undamaged pickaxe. * The recipe requires at least one undamaged pickaxe.
*/ */
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) // @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) TODO 1.21.5 tests
public void testShapelessMatch(TestContext context) { public void testShapelessMatch(TestContext context) {
RegistryKey<Recipe<?>> recipeKey = RegistryKey.of(RegistryKeys.RECIPE, Identifier.of("fabric-recipe-api-v1-testmod", "test_shapeless_match")); RegistryKey<Recipe<?>> recipeKey = RegistryKey.of(RegistryKeys.RECIPE, Identifier.of("fabric-recipe-api-v1-testmod", "test_shapeless_match"));
ShapelessRecipe recipe = (ShapelessRecipe) context.getWorld().getRecipeManager().get(recipeKey).get().value(); ShapelessRecipe recipe = (ShapelessRecipe) context.getWorld().getRecipeManager().get(recipeKey).get().value();
@ -50,14 +48,14 @@ public class ShapelessRecipeMatchTests {
List<ItemStack> damagedPickaxes = Collections.nCopies(9, damagedPickaxe); List<ItemStack> damagedPickaxes = Collections.nCopies(9, damagedPickaxe);
if (recipe.matches(CraftingRecipeInput.create(3, 3, damagedPickaxes), context.getWorld())) { if (recipe.matches(CraftingRecipeInput.create(3, 3, damagedPickaxes), context.getWorld())) {
throw new GameTestException("Recipe should not match with only damaged pickaxes"); throw new GameTestException(Text.literal("Recipe should not match with only damaged pickaxes"), 0);
} }
List<ItemStack> oneUndamagedPickaxe = new LinkedList<>(damagedPickaxes); List<ItemStack> oneUndamagedPickaxe = new LinkedList<>(damagedPickaxes);
oneUndamagedPickaxe.set(0, undamagedPickaxe); oneUndamagedPickaxe.set(0, undamagedPickaxe);
if (!recipe.matches(CraftingRecipeInput.create(3, 3, oneUndamagedPickaxe), context.getWorld())) { if (!recipe.matches(CraftingRecipeInput.create(3, 3, oneUndamagedPickaxe), context.getWorld())) {
throw new GameTestException("Recipe should match with at least one undamaged pickaxe"); throw new GameTestException(Text.literal("Recipe should match with at least one undamaged pickaxe"), 0);
} }
context.complete(); context.complete();

View file

@ -32,7 +32,7 @@ import net.minecraft.block.BlockState;
import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.WeightedBakedModel; import net.minecraft.client.render.model.WeightedBakedModel;
import net.minecraft.util.collection.Pool; import net.minecraft.util.collection.Pool;
import net.minecraft.util.collection.Present; import net.minecraft.util.collection.Weighted;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.math.random.Random; import net.minecraft.util.math.random.Random;
@ -52,7 +52,7 @@ abstract class WeightedBakedModelMixin implements FabricBakedModel {
@Inject(at = @At("RETURN"), method = "<init>") @Inject(at = @At("RETURN"), method = "<init>")
private void onInit(Pool<BakedModel> dataPool, CallbackInfo ci) { private void onInit(Pool<BakedModel> dataPool, CallbackInfo ci) {
for (Present<BakedModel> model : models.getEntries()) { for (Weighted<BakedModel> model : models.getEntries()) {
if (!model.value().isVanillaAdapter()) { if (!model.value().isVanillaAdapter()) {
isVanilla = false; isVanilla = false;
break; break;

View file

@ -72,7 +72,7 @@ public class RandomSupplierTest implements ClientModInitializer {
private static WeightedBakedModel createWeightedBakedModel() { private static WeightedBakedModel createWeightedBakedModel() {
var checkingModel = new RandomCheckingBakedModel(); var checkingModel = new RandomCheckingBakedModel();
Pool.Builder<BakedModel> weightedBuilder = Pool.method_66215(); Pool.Builder<BakedModel> weightedBuilder = Pool.builder();
weightedBuilder.add(checkingModel, 1); weightedBuilder.add(checkingModel, 1);
weightedBuilder.add(checkingModel, 2); weightedBuilder.add(checkingModel, 2);
@ -81,7 +81,7 @@ public class RandomSupplierTest implements ClientModInitializer {
new MultipartBakedModel.Selector(state -> true, weighted), new MultipartBakedModel.Selector(state -> true, weighted),
new MultipartBakedModel.Selector(state -> true, weighted))); new MultipartBakedModel.Selector(state -> true, weighted)));
Pool.Builder<BakedModel> weightedAgainBuilder = Pool.method_66215(); Pool.Builder<BakedModel> weightedAgainBuilder = Pool.builder();
weightedAgainBuilder.add(multipart, 1); weightedAgainBuilder.add(multipart, 1);
weightedAgainBuilder.add(multipart, 2); weightedAgainBuilder.add(multipart, 2);

View file

@ -41,7 +41,7 @@ public class TooltipComponentTestInit implements ModInitializer {
public static final ArmorMaterial TEST_ARMOR_MATERIAL = createTestArmorMaterial(); public static final ArmorMaterial TEST_ARMOR_MATERIAL = createTestArmorMaterial();
public static final RegistryKey<Item> CUSTOM_ARMOR_ITEM_KEY = RegistryKey.of(RegistryKeys.ITEM, Identifier.of("fabric-rendering-v1-testmod", "test_chest")); public static final RegistryKey<Item> CUSTOM_ARMOR_ITEM_KEY = RegistryKey.of(RegistryKeys.ITEM, Identifier.of("fabric-rendering-v1-testmod", "test_chest"));
public static final Item CUSTOM_ARMOR_ITEM = new Item(new Item.Settings().method_66332(TEST_ARMOR_MATERIAL, EquipmentType.CHESTPLATE).registryKey(CUSTOM_ARMOR_ITEM_KEY)); public static final Item CUSTOM_ARMOR_ITEM = new Item(new Item.Settings().armor(TEST_ARMOR_MATERIAL, EquipmentType.CHESTPLATE).registryKey(CUSTOM_ARMOR_ITEM_KEY));
@Override @Override
public void onInitialize() { public void onInitialize() {

View file

@ -5,7 +5,6 @@ loom {
} }
testDependencies(project, [ testDependencies(project, [
':fabric-gametest-api-v1',
':fabric-lifecycle-events-v1', ':fabric-lifecycle-events-v1',
':fabric-resource-loader-v0' ':fabric-resource-loader-v0'
]) ])

View file

@ -0,0 +1,130 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.test.resource.conditions;
import com.mojang.serialization.JsonOps;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import net.minecraft.Bootstrap;
import net.minecraft.SharedConstants;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryOps;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.resource.conditions.v1.ResourceCondition;
import net.fabricmc.fabric.api.resource.conditions.v1.ResourceConditions;
public class ResourceConditionsUnitTest {
private static final String TESTMOD_ID = "fabric-resource-conditions-api-v1-testmod";
private static final String API_MOD_ID = "fabric-resource-conditions-api-v1";
private static final String UNKNOWN_MOD_ID = "fabric-tiny-potato-api-v1";
private static final RegistryKey<? extends Registry<Object>> UNKNOWN_REGISTRY_KEY = RegistryKey.ofRegistry(Identifier.of(TESTMOD_ID, "unknown_registry"));
private static final Identifier UNKNOWN_ENTRY_ID = Identifier.of(TESTMOD_ID, "tiny_potato");
private static void expectCondition(String name, ResourceCondition condition, boolean expected) {
RegistryWrapper.WrapperLookup registryLookup = DynamicRegistryManager.of(Registries.REGISTRIES);
boolean actual = condition.test(new RegistryOps.CachedRegistryInfoGetter(registryLookup));
if (actual != expected) {
throw new AssertionError("Test \"%s\" for condition %s failed; expected %s, got %s".formatted(name, condition.getType().id(), expected, actual));
}
// Test serialization
ResourceCondition.CODEC.encodeStart(JsonOps.INSTANCE, condition).getOrThrow(message -> new AssertionError("Could not serialize \"%s\": %s".formatted(name, message)));
}
@BeforeAll
static void beforeAll() {
SharedConstants.createGameVersion();
Bootstrap.initialize();
}
@Test
public void logics() {
ResourceCondition alwaysTrue = ResourceConditions.alwaysTrue();
ResourceCondition alwaysFalse = ResourceConditions.not(alwaysTrue);
ResourceCondition trueAndTrue = ResourceConditions.and(alwaysTrue, alwaysTrue);
ResourceCondition trueAndFalse = ResourceConditions.and(alwaysTrue, alwaysFalse);
ResourceCondition emptyAnd = ResourceConditions.and();
ResourceCondition trueOrFalse = ResourceConditions.or(alwaysTrue, alwaysFalse);
ResourceCondition falseOrFalse = ResourceConditions.or(alwaysFalse, alwaysFalse);
ResourceCondition emptyOr = ResourceConditions.or();
expectCondition("always true", alwaysTrue, true);
expectCondition("always false", alwaysFalse, false);
expectCondition("true and true", trueAndTrue, true);
expectCondition("true and false", trueAndFalse, false);
expectCondition("vacuous truth", emptyAnd, true);
expectCondition("true or false", trueOrFalse, true);
expectCondition("false or false", falseOrFalse, false);
expectCondition("empty OR is always false", emptyOr, false);
}
@Test
public void allModsLoaded() {
ResourceCondition testmod = ResourceConditions.allModsLoaded(TESTMOD_ID);
ResourceCondition testmodAndApi = ResourceConditions.allModsLoaded(TESTMOD_ID, API_MOD_ID);
ResourceCondition unknownMod = ResourceConditions.allModsLoaded(UNKNOWN_MOD_ID);
ResourceCondition unknownAndTestmod = ResourceConditions.allModsLoaded(UNKNOWN_MOD_ID, TESTMOD_ID);
ResourceCondition noMod = ResourceConditions.allModsLoaded();
expectCondition("one loaded mod", testmod, true);
expectCondition("two loaded mods", testmodAndApi, true);
expectCondition("one unloaded mod", unknownMod, false);
expectCondition("both loaded and unloaded mods", unknownAndTestmod, false);
expectCondition("no mod", noMod, true);
}
@Test
public void anyModsLoaded() {
ResourceCondition testmod = ResourceConditions.anyModsLoaded(TESTMOD_ID);
ResourceCondition testmodAndApi = ResourceConditions.anyModsLoaded(TESTMOD_ID, API_MOD_ID);
ResourceCondition unknownMod = ResourceConditions.anyModsLoaded(UNKNOWN_MOD_ID);
ResourceCondition unknownAndTestmod = ResourceConditions.anyModsLoaded(UNKNOWN_MOD_ID, TESTMOD_ID);
ResourceCondition noMod = ResourceConditions.anyModsLoaded();
expectCondition("one loaded mod", testmod, true);
expectCondition("two loaded mods", testmodAndApi, true);
expectCondition("one unloaded mod", unknownMod, false);
expectCondition("both loaded and unloaded mods", unknownAndTestmod, true);
expectCondition("no mod", noMod, false);
}
@Test
public void registryContains() {
RegistryKey<Block> dirtKey = Registries.BLOCK.getKey(Blocks.DIRT).orElseThrow();
ResourceCondition dirt = ResourceConditions.registryContains(dirtKey);
ResourceCondition dirtAndUnknownBlock = ResourceConditions.registryContains(dirtKey, RegistryKey.of(RegistryKeys.BLOCK, UNKNOWN_ENTRY_ID));
ResourceCondition emptyBlock = ResourceConditions.registryContains(RegistryKeys.BLOCK, new Identifier[]{});
ResourceCondition unknownRegistry = ResourceConditions.registryContains(UNKNOWN_REGISTRY_KEY, UNKNOWN_ENTRY_ID);
ResourceCondition emptyUnknown = ResourceConditions.registryContains(UNKNOWN_REGISTRY_KEY, new Identifier[]{});
expectCondition("dirt", dirt, true);
expectCondition("dirt and unknown block", dirtAndUnknownBlock, false);
expectCondition("block registry, empty check", emptyBlock, true);
expectCondition("unknown registry, non-empty", unknownRegistry, false);
expectCondition("unknown registry, empty", emptyUnknown, true);
}
}

View file

@ -16,20 +16,8 @@
package net.fabricmc.fabric.test.resource.conditions; package net.fabricmc.fabric.test.resource.conditions;
import net.minecraft.block.entity.BannerPattern;
import net.minecraft.loot.LootTable;
import net.minecraft.recipe.ServerRecipeManager;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryEntryLookup;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.ReloadableRegistries;
import net.minecraft.test.GameTest;
import net.minecraft.test.TestContext;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
public class ConditionalResourcesTest { public class ConditionalResourcesTest {
private static final String MOD_ID = "fabric-resource-conditions-api-v1-testmod"; private static final String MOD_ID = "fabric-resource-conditions-api-v1-testmod";
@ -37,6 +25,7 @@ public class ConditionalResourcesTest {
return Identifier.of(MOD_ID, path); return Identifier.of(MOD_ID, path);
} }
/* TODO 1.21.5 tests
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void conditionalRecipes(TestContext context) { public void conditionalRecipes(TestContext context) {
ServerRecipeManager manager = context.getWorld().getRecipeManager(); ServerRecipeManager manager = context.getWorld().getRecipeManager();
@ -137,4 +126,6 @@ public class ConditionalResourcesTest {
context.complete(); context.complete();
} }
*/
} }

View file

@ -16,33 +16,16 @@
package net.fabricmc.fabric.test.resource.conditions; package net.fabricmc.fabric.test.resource.conditions;
import java.util.stream.Collectors;
import com.mojang.serialization.JsonOps; import com.mojang.serialization.JsonOps;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry; import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryOps; import net.minecraft.registry.RegistryOps;
import net.minecraft.registry.RegistryWrapper; import net.minecraft.registry.RegistryWrapper;
import net.minecraft.registry.tag.BiomeTags;
import net.minecraft.registry.tag.BlockTags;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.resource.featuretoggle.FeatureFlag;
import net.minecraft.resource.featuretoggle.FeatureFlags;
import net.minecraft.test.GameTest;
import net.minecraft.test.TestContext; import net.minecraft.test.TestContext;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.world.biome.BiomeKeys;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
import net.fabricmc.fabric.api.resource.conditions.v1.ResourceCondition; import net.fabricmc.fabric.api.resource.conditions.v1.ResourceCondition;
import net.fabricmc.fabric.api.resource.conditions.v1.ResourceConditions;
import net.fabricmc.fabric.impl.resource.conditions.ResourceConditionsImpl;
public class DefaultResourceConditionsTest { public class DefaultResourceConditionsTest {
private static final String TESTMOD_ID = "fabric-resource-conditions-api-v1-testmod"; private static final String TESTMOD_ID = "fabric-resource-conditions-api-v1-testmod";
@ -63,63 +46,7 @@ public class DefaultResourceConditionsTest {
ResourceCondition.CODEC.encodeStart(JsonOps.INSTANCE, condition).getOrThrow(message -> new AssertionError("Could not serialize \"%s\": %s".formatted(name, message))); ResourceCondition.CODEC.encodeStart(JsonOps.INSTANCE, condition).getOrThrow(message -> new AssertionError("Could not serialize \"%s\": %s".formatted(name, message)));
} }
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) /* TODO 1.21.5 tests
public void logics(TestContext context) {
ResourceCondition alwaysTrue = ResourceConditions.alwaysTrue();
ResourceCondition alwaysFalse = ResourceConditions.not(alwaysTrue);
ResourceCondition trueAndTrue = ResourceConditions.and(alwaysTrue, alwaysTrue);
ResourceCondition trueAndFalse = ResourceConditions.and(alwaysTrue, alwaysFalse);
ResourceCondition emptyAnd = ResourceConditions.and();
ResourceCondition trueOrFalse = ResourceConditions.or(alwaysTrue, alwaysFalse);
ResourceCondition falseOrFalse = ResourceConditions.or(alwaysFalse, alwaysFalse);
ResourceCondition emptyOr = ResourceConditions.or();
expectCondition(context, "always true", alwaysTrue, true);
expectCondition(context, "always false", alwaysFalse, false);
expectCondition(context, "true and true", trueAndTrue, true);
expectCondition(context, "true and false", trueAndFalse, false);
expectCondition(context, "vacuous truth", emptyAnd, true);
expectCondition(context, "true or false", trueOrFalse, true);
expectCondition(context, "false or false", falseOrFalse, false);
expectCondition(context, "empty OR is always false", emptyOr, false);
context.complete();
}
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void allModsLoaded(TestContext context) {
ResourceCondition testmod = ResourceConditions.allModsLoaded(TESTMOD_ID);
ResourceCondition testmodAndApi = ResourceConditions.allModsLoaded(TESTMOD_ID, API_MOD_ID);
ResourceCondition unknownMod = ResourceConditions.allModsLoaded(UNKNOWN_MOD_ID);
ResourceCondition unknownAndTestmod = ResourceConditions.allModsLoaded(UNKNOWN_MOD_ID, TESTMOD_ID);
ResourceCondition noMod = ResourceConditions.allModsLoaded();
expectCondition(context, "one loaded mod", testmod, true);
expectCondition(context, "two loaded mods", testmodAndApi, true);
expectCondition(context, "one unloaded mod", unknownMod, false);
expectCondition(context, "both loaded and unloaded mods", unknownAndTestmod, false);
expectCondition(context, "no mod", noMod, true);
context.complete();
}
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void anyModsLoaded(TestContext context) {
ResourceCondition testmod = ResourceConditions.anyModsLoaded(TESTMOD_ID);
ResourceCondition testmodAndApi = ResourceConditions.anyModsLoaded(TESTMOD_ID, API_MOD_ID);
ResourceCondition unknownMod = ResourceConditions.anyModsLoaded(UNKNOWN_MOD_ID);
ResourceCondition unknownAndTestmod = ResourceConditions.anyModsLoaded(UNKNOWN_MOD_ID, TESTMOD_ID);
ResourceCondition noMod = ResourceConditions.anyModsLoaded();
expectCondition(context, "one loaded mod", testmod, true);
expectCondition(context, "two loaded mods", testmodAndApi, true);
expectCondition(context, "one unloaded mod", unknownMod, false);
expectCondition(context, "both loaded and unloaded mods", unknownAndTestmod, true);
expectCondition(context, "no mod", noMod, false);
context.complete();
}
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void featuresEnabled(TestContext context) { public void featuresEnabled(TestContext context) {
ResourceCondition vanilla = ResourceConditions.featuresEnabled(FeatureFlags.VANILLA); ResourceCondition vanilla = ResourceConditions.featuresEnabled(FeatureFlags.VANILLA);
@ -140,20 +67,6 @@ public class DefaultResourceConditionsTest {
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void registryContains(TestContext context) { public void registryContains(TestContext context) {
// Static registry
RegistryKey<Block> dirtKey = Registries.BLOCK.getKey(Blocks.DIRT).orElseThrow();
ResourceCondition dirt = ResourceConditions.registryContains(dirtKey);
ResourceCondition dirtAndUnknownBlock = ResourceConditions.registryContains(dirtKey, RegistryKey.of(RegistryKeys.BLOCK, UNKNOWN_ENTRY_ID));
ResourceCondition emptyBlock = ResourceConditions.registryContains(RegistryKeys.BLOCK, new Identifier[]{});
ResourceCondition unknownRegistry = ResourceConditions.registryContains(UNKNOWN_REGISTRY_KEY, UNKNOWN_ENTRY_ID);
ResourceCondition emptyUnknown = ResourceConditions.registryContains(UNKNOWN_REGISTRY_KEY, new Identifier[]{});
expectCondition(context, "dirt", dirt, true);
expectCondition(context, "dirt and unknown block", dirtAndUnknownBlock, false);
expectCondition(context, "block registry, empty check", emptyBlock, true);
expectCondition(context, "unknown registry, non-empty", unknownRegistry, false);
expectCondition(context, "unknown registry, empty", emptyUnknown, true);
// Dynamic registry (in vitro; separate testmod needs to determine if this actually functions while loading) // Dynamic registry (in vitro; separate testmod needs to determine if this actually functions while loading)
ResourceCondition plains = ResourceConditions.registryContains(BiomeKeys.PLAINS); ResourceCondition plains = ResourceConditions.registryContains(BiomeKeys.PLAINS);
ResourceCondition unknownBiome = ResourceConditions.registryContains(RegistryKey.of(RegistryKeys.BIOME, UNKNOWN_ENTRY_ID)); ResourceCondition unknownBiome = ResourceConditions.registryContains(RegistryKey.of(RegistryKeys.BIOME, UNKNOWN_ENTRY_ID));
@ -200,4 +113,6 @@ public class DefaultResourceConditionsTest {
context.complete(); context.complete();
} }
*/
} }

View file

@ -67,7 +67,7 @@ public class BoxBlock extends BlockWithEntity {
} }
@Override @Override
public void method_66388(BlockState state, ServerWorld world, BlockPos pos, boolean moved) { public void onStateReplaced(BlockState state, ServerWorld world, BlockPos pos, boolean moved) {
BlockEntity be = world.getBlockEntity(pos); BlockEntity be = world.getBlockEntity(pos);
if (be instanceof Inventory) { if (be instanceof Inventory) {
@ -75,7 +75,7 @@ public class BoxBlock extends BlockWithEntity {
world.updateComparators(pos, this); world.updateComparators(pos, this);
} }
super.method_66388(state, world, pos, moved); super.onStateReplaced(state, world, pos, moved);
} }
@Override @Override

View file

@ -16,45 +16,12 @@
package net.fabricmc.fabric.test.transfer.gametests; package net.fabricmc.fabric.test.transfer.gametests;
import org.apache.commons.lang3.mutable.MutableInt;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.ComparatorBlock;
import net.minecraft.block.ComposterBlock;
import net.minecraft.block.JukeboxBlock;
import net.minecraft.block.entity.BrewingStandBlockEntity;
import net.minecraft.block.entity.ChiseledBookshelfBlockEntity;
import net.minecraft.block.entity.FurnaceBlockEntity;
import net.minecraft.block.entity.HopperBlockEntity;
import net.minecraft.block.entity.ShulkerBoxBlockEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.state.property.Properties;
import net.minecraft.test.GameTest;
import net.minecraft.test.GameTestException;
import net.minecraft.test.TestContext;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
import net.fabricmc.fabric.api.transfer.v1.item.InventoryStorage;
import net.fabricmc.fabric.api.transfer.v1.item.ItemStorage;
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant;
import net.fabricmc.fabric.api.transfer.v1.storage.SlottedStorage;
import net.fabricmc.fabric.api.transfer.v1.storage.Storage;
import net.fabricmc.fabric.api.transfer.v1.storage.StorageUtil;
import net.fabricmc.fabric.api.transfer.v1.transaction.Transaction;
import net.fabricmc.fabric.test.transfer.mixin.AbstractFurnaceBlockEntityAccessor;
public class VanillaStorageTests { public class VanillaStorageTests {
/** /**
* Regression test for https://github.com/FabricMC/fabric/issues/1972. * Regression test for https://github.com/FabricMC/fabric/issues/1972.
* Ensures that furnace cook time is only reset when extraction is actually committed. * Ensures that furnace cook time is only reset when extraction is actually committed.
*/ */
/*
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testFurnaceCookTime(TestContext context) { public void testFurnaceCookTime(TestContext context) {
BlockPos pos = new BlockPos(0, 1, 0); BlockPos pos = new BlockPos(0, 1, 0);
@ -98,12 +65,15 @@ public class VanillaStorageTests {
}); });
} }
*/
/** /**
* Tests that the passed block doesn't update adjacent comparators until the very end of a committed transaction. * Tests that the passed block doesn't update adjacent comparators until the very end of a committed transaction.
* *
* @param block A block with an Inventory block entity. * @param block A block with an Inventory block entity.
* @param variant The variant to try to insert (needs to be supported by the Inventory). * @param variant The variant to try to insert (needs to be supported by the Inventory).
*/ */
/*
private static void testComparatorOnInventory(TestContext context, Block block, ItemVariant variant) { private static void testComparatorOnInventory(TestContext context, Block block, ItemVariant variant) {
World world = context.getWorld(); World world = context.getWorld();
@ -142,25 +112,34 @@ public class VanillaStorageTests {
context.complete(); context.complete();
} }
*/
/** /**
* Tests that containers such as chests don't update adjacent comparators until the very end of a committed transaction. * Tests that containers such as chests don't update adjacent comparators until the very end of a committed transaction.
*/ */
/*
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testChestComparator(TestContext context) { public void testChestComparator(TestContext context) {
testComparatorOnInventory(context, Blocks.CHEST, ItemVariant.of(Items.DIAMOND)); testComparatorOnInventory(context, Blocks.CHEST, ItemVariant.of(Items.DIAMOND));
} }
*/
/** /**
* Same as {@link #testChestComparator} but for chiseled bookshelves, because their implementation is very... strange. * Same as {@link #testChestComparator} but for chiseled bookshelves, because their implementation is very... strange.
*/ */
/*
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testChiseledBookshelfComparator(TestContext context) { public void testChiseledBookshelfComparator(TestContext context) {
testComparatorOnInventory(context, Blocks.CHISELED_BOOKSHELF, ItemVariant.of(Items.BOOK)); testComparatorOnInventory(context, Blocks.CHISELED_BOOKSHELF, ItemVariant.of(Items.BOOK));
} }
*/
/** /**
* Test for chiseled bookshelves, because their implementation is very... strange. * Test for chiseled bookshelves, because their implementation is very... strange.
*/ */
/*
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testChiseledBookshelf(TestContext context) { public void testChiseledBookshelf(TestContext context) {
ItemVariant book = ItemVariant.of(Items.BOOK); ItemVariant book = ItemVariant.of(Items.BOOK);
@ -221,9 +200,12 @@ public class VanillaStorageTests {
context.complete(); context.complete();
} }
*/
/** /**
* Tests that shulker boxes cannot be inserted into other shulker boxes. * Tests that shulker boxes cannot be inserted into other shulker boxes.
*/ */
/*
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testShulkerNoInsert(TestContext context) { public void testShulkerNoInsert(TestContext context) {
BlockPos pos = new BlockPos(0, 2, 0); BlockPos pos = new BlockPos(0, 2, 0);
@ -238,11 +220,14 @@ public class VanillaStorageTests {
context.complete(); context.complete();
} }
*/
/** /**
* {@link Inventory#isValid(int, ItemStack)} is supposed to be independent of the stack size. * {@link Inventory#isValid(int, ItemStack)} is supposed to be independent of the stack size.
* However, to limit some stackable inputs to a size of 1, brewing stands and furnaces don't follow this rule in all cases. * However, to limit some stackable inputs to a size of 1, brewing stands and furnaces don't follow this rule in all cases.
* This test ensures that the Transfer API works around this issue for furnaces. * This test ensures that the Transfer API works around this issue for furnaces.
*/ */
/*
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testBadFurnaceIsValid(TestContext context) { public void testBadFurnaceIsValid(TestContext context) {
BlockPos pos = new BlockPos(0, 1, 0); BlockPos pos = new BlockPos(0, 1, 0);
@ -259,9 +244,12 @@ public class VanillaStorageTests {
context.complete(); context.complete();
} }
*/
/** /**
* Same as {@link #testBadFurnaceIsValid(TestContext)}, but for brewing stands. * Same as {@link #testBadFurnaceIsValid(TestContext)}, but for brewing stands.
*/ */
/*
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testBadBrewingStandIsValid(TestContext context) { public void testBadBrewingStandIsValid(TestContext context) {
BlockPos pos = new BlockPos(0, 1, 0); BlockPos pos = new BlockPos(0, 1, 0);
@ -284,9 +272,12 @@ public class VanillaStorageTests {
context.complete(); context.complete();
} }
*/
/** /**
* Regression test for <a href="https://github.com/FabricMC/fabric/issues/2810">double chest wrapper only updating modified halves</a>. * Regression test for <a href="https://github.com/FabricMC/fabric/issues/2810">double chest wrapper only updating modified halves</a>.
*/ */
/*
@GameTest(templateName = "fabric-transfer-api-v1-testmod:double_chest_comparators", skyAccess = true) @GameTest(templateName = "fabric-transfer-api-v1-testmod:double_chest_comparators", skyAccess = true)
public void testDoubleChestComparator(TestContext context) { public void testDoubleChestComparator(TestContext context) {
BlockPos chestPos = new BlockPos(2, 1, 2); BlockPos chestPos = new BlockPos(2, 1, 2);
@ -336,9 +327,12 @@ public class VanillaStorageTests {
context.complete(); context.complete();
} }
*/
/** /**
* Regression test for <a href="https://github.com/FabricMC/fabric/issues/3017">composters not always incrementing their level on the first insert</a>. * Regression test for <a href="https://github.com/FabricMC/fabric/issues/3017">composters not always incrementing their level on the first insert</a>.
*/ */
/*
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testComposterFirstInsert(TestContext context) { public void testComposterFirstInsert(TestContext context) {
BlockPos pos = new BlockPos(0, 1, 0); BlockPos pos = new BlockPos(0, 1, 0);
@ -363,9 +357,12 @@ public class VanillaStorageTests {
context.complete(); context.complete();
} }
*/
/** /**
* Regression test for <a href="https://github.com/FabricMC/fabric/issues/3485">jukeboxes having their state changed mid-transaction</a>. * Regression test for <a href="https://github.com/FabricMC/fabric/issues/3485">jukeboxes having their state changed mid-transaction</a>.
*/ */
/*
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testJukeboxState(TestContext context) { public void testJukeboxState(TestContext context) {
BlockPos pos = new BlockPos(2, 2, 2); BlockPos pos = new BlockPos(2, 2, 2);
@ -381,4 +378,6 @@ public class VanillaStorageTests {
context.checkBlockState(pos, state -> state.get(JukeboxBlock.HAS_RECORD), () -> "Jukebox should have its state changed"); context.checkBlockState(pos, state -> state.get(JukeboxBlock.HAS_RECORD), () -> "Jukebox should have its state changed");
context.complete(); context.complete();
} }
*/
} }

View file

@ -20,16 +20,14 @@ import static net.fabricmc.fabric.test.transfer.TestUtil.assertEquals;
import net.minecraft.fluid.Fluids; import net.minecraft.fluid.Fluids;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
import net.minecraft.test.GameTest;
import net.minecraft.test.TestContext; import net.minecraft.test.TestContext;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidConstants; import net.fabricmc.fabric.api.transfer.v1.fluid.FluidConstants;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariantAttributes; import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariantAttributes;
public class WorldDependentAttributesTest { public class WorldDependentAttributesTest {
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) //@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) TODO 1.21.5 tests
public void testViscosity(TestContext context) { public void testViscosity(TestContext context) {
ServerWorld overworld = context.getWorld(); ServerWorld overworld = context.getWorld();
ServerWorld nether = overworld.getServer().getWorld(ServerWorld.NETHER); ServerWorld nether = overworld.getServer().getWorld(ServerWorld.NETHER);

View file

@ -90,7 +90,6 @@ transitive-accessible method net/minecraft/text/TranslatableTextContent getArg (
# Villagers # Villagers
transitive-accessible field net/minecraft/village/VillagerType BIOME_TO_TYPE Ljava/util/Map; transitive-accessible field net/minecraft/village/VillagerType BIOME_TO_TYPE Ljava/util/Map;
transitive-accessible method net/minecraft/village/VillagerType <init> (Ljava/lang/String;)V
# Access stack list in SimpleInventory # Access stack list in SimpleInventory
transitive-accessible field net/minecraft/inventory/SimpleInventory heldStacks Lnet/minecraft/util/collection/DefaultedList; transitive-accessible field net/minecraft/inventory/SimpleInventory heldStacks Lnet/minecraft/util/collection/DefaultedList;
@ -181,6 +180,7 @@ transitive-accessible method net/minecraft/block/EndRodBlock <init> (Lnet/minecr
transitive-accessible method net/minecraft/block/EnderChestBlock <init> (Lnet/minecraft/block/AbstractBlock$Settings;)V transitive-accessible method net/minecraft/block/EnderChestBlock <init> (Lnet/minecraft/block/AbstractBlock$Settings;)V
transitive-accessible method net/minecraft/block/FarmlandBlock <init> (Lnet/minecraft/block/AbstractBlock$Settings;)V transitive-accessible method net/minecraft/block/FarmlandBlock <init> (Lnet/minecraft/block/AbstractBlock$Settings;)V
transitive-accessible method net/minecraft/block/FletchingTableBlock <init> (Lnet/minecraft/block/AbstractBlock$Settings;)V transitive-accessible method net/minecraft/block/FletchingTableBlock <init> (Lnet/minecraft/block/AbstractBlock$Settings;)V
transitive-accessible method net/minecraft/block/FlowerbedBlock <init> (Lnet/minecraft/block/AbstractBlock$Settings;)V
transitive-accessible method net/minecraft/block/FluidBlock <init> (Lnet/minecraft/fluid/FlowableFluid;Lnet/minecraft/block/AbstractBlock$Settings;)V transitive-accessible method net/minecraft/block/FluidBlock <init> (Lnet/minecraft/fluid/FlowableFluid;Lnet/minecraft/block/AbstractBlock$Settings;)V
transitive-accessible method net/minecraft/block/FungusBlock <init> (Lnet/minecraft/registry/RegistryKey;Lnet/minecraft/block/Block;Lnet/minecraft/block/AbstractBlock$Settings;)V transitive-accessible method net/minecraft/block/FungusBlock <init> (Lnet/minecraft/registry/RegistryKey;Lnet/minecraft/block/Block;Lnet/minecraft/block/AbstractBlock$Settings;)V
transitive-accessible method net/minecraft/block/FurnaceBlock <init> (Lnet/minecraft/block/AbstractBlock$Settings;)V transitive-accessible method net/minecraft/block/FurnaceBlock <init> (Lnet/minecraft/block/AbstractBlock$Settings;)V

View file

@ -85,7 +85,6 @@ transitive-accessible method net/minecraft/text/TranslatableTextContent getArg (
# Villagers # Villagers
transitive-accessible field net/minecraft/village/VillagerType BIOME_TO_TYPE Ljava/util/Map; transitive-accessible field net/minecraft/village/VillagerType BIOME_TO_TYPE Ljava/util/Map;
transitive-accessible method net/minecraft/village/VillagerType <init> (Ljava/lang/String;)V
# Access stack list in SimpleInventory # Access stack list in SimpleInventory
transitive-accessible field net/minecraft/inventory/SimpleInventory heldStacks Lnet/minecraft/util/collection/DefaultedList; transitive-accessible field net/minecraft/inventory/SimpleInventory heldStacks Lnet/minecraft/util/collection/DefaultedList;

View file

@ -1,62 +1,62 @@
org.gradle.jvmargs=-Xmx2560M org.gradle.jvmargs=-Xmx2560M
org.gradle.parallel=true org.gradle.parallel=true
version=0.114.3 version=0.114.4
minecraft_version=25w02a minecraft_version=25w03a
yarn_version=+build.1 yarn_version=+build.1
loader_version=0.16.10 loader_version=0.16.10
installer_version=1.0.1 installer_version=1.0.1
prerelease=true prerelease=true
curseforge_minecraft_version=1.21.4-Snapshot curseforge_minecraft_version=1.21.5-Snapshot
# Do not manually update, use the bumpversions task: # Do not manually update, use the bumpversions task:
fabric-api-base-version=0.4.55 fabric-api-base-version=0.4.56
fabric-api-lookup-api-v1-version=1.6.87 fabric-api-lookup-api-v1-version=1.6.88
fabric-biome-api-v1-version=16.0.0 fabric-biome-api-v1-version=16.0.1
fabric-block-api-v1-version=1.0.32 fabric-block-api-v1-version=1.0.32
fabric-block-view-api-v2-version=1.0.20 fabric-block-view-api-v2-version=1.0.20
fabric-blockrenderlayer-v1-version=2.0.9 fabric-blockrenderlayer-v1-version=2.0.10
fabric-client-gametest-api-v1-version=3.1.0 fabric-client-gametest-api-v1-version=3.1.0
fabric-command-api-v1-version=1.2.63 fabric-command-api-v1-version=1.2.64
fabric-command-api-v2-version=2.2.42 fabric-command-api-v2-version=2.2.43
fabric-commands-v0-version=0.2.80 fabric-commands-v0-version=0.2.81
fabric-content-registries-v0-version=9.1.16 fabric-content-registries-v0-version=10.0.0
fabric-crash-report-info-v1-version=0.3.7 fabric-crash-report-info-v1-version=0.3.7
fabric-data-attachment-api-v1-version=1.5.0 fabric-data-attachment-api-v1-version=1.5.1
fabric-data-generation-api-v1-version=22.2.7 fabric-data-generation-api-v1-version=22.2.8
fabric-dimensions-v1-version=4.0.11 fabric-dimensions-v1-version=4.0.11
fabric-entity-events-v1-version=2.0.13 fabric-entity-events-v1-version=2.0.14
fabric-events-interaction-v0-version=4.0.4 fabric-events-interaction-v0-version=4.0.5
fabric-game-rule-api-v1-version=1.0.64 fabric-game-rule-api-v1-version=1.0.65
fabric-gametest-api-v1-version=2.0.23 fabric-gametest-api-v1-version=2.0.23
fabric-item-api-v1-version=11.1.16 fabric-item-api-v1-version=11.1.17
fabric-item-group-api-v1-version=4.1.25 fabric-item-group-api-v1-version=4.1.26
fabric-key-binding-api-v1-version=1.0.58 fabric-key-binding-api-v1-version=1.0.58
fabric-keybindings-v0-version=0.2.56 fabric-keybindings-v0-version=0.2.56
fabric-lifecycle-events-v1-version=2.5.5 fabric-lifecycle-events-v1-version=2.5.6
fabric-loot-api-v2-version=3.0.35 fabric-loot-api-v2-version=3.0.36
fabric-loot-api-v3-version=1.0.23 fabric-loot-api-v3-version=1.0.24
fabric-message-api-v1-version=6.0.26 fabric-message-api-v1-version=6.0.27
fabric-model-loading-api-v1-version=4.2.2 fabric-model-loading-api-v1-version=4.2.3
fabric-networking-api-v1-version=4.3.11 fabric-networking-api-v1-version=4.3.12
fabric-object-builder-api-v1-version=18.0.10 fabric-object-builder-api-v1-version=19.0.0
fabric-particles-v1-version=4.0.15 fabric-particles-v1-version=4.0.16
fabric-recipe-api-v1-version=8.0.9 fabric-recipe-api-v1-version=8.0.10
fabric-registry-sync-v0-version=6.1.6 fabric-registry-sync-v0-version=6.1.7
fabric-renderer-api-v1-version=5.0.4 fabric-renderer-api-v1-version=5.0.5
fabric-renderer-indigo-version=2.0.4 fabric-renderer-indigo-version=2.0.5
fabric-rendering-data-attachment-v1-version=0.3.58 fabric-rendering-data-attachment-v1-version=0.3.58
fabric-rendering-fluids-v1-version=3.1.20 fabric-rendering-fluids-v1-version=3.1.21
fabric-rendering-v1-version=10.1.3 fabric-rendering-v1-version=10.1.4
fabric-resource-conditions-api-v1-version=5.0.14 fabric-resource-conditions-api-v1-version=5.0.15
fabric-resource-loader-v0-version=3.0.13 fabric-resource-loader-v0-version=3.0.13
fabric-screen-api-v1-version=2.0.39 fabric-screen-api-v1-version=2.0.40
fabric-screen-handler-api-v1-version=1.3.113 fabric-screen-handler-api-v1-version=1.3.114
fabric-sound-api-v1-version=1.0.33 fabric-sound-api-v1-version=1.0.33
fabric-tag-api-v1-version=1.0.4 fabric-tag-api-v1-version=1.0.5
fabric-transfer-api-v1-version=5.4.10 fabric-transfer-api-v1-version=5.4.11
fabric-transitive-access-wideners-v1-version=6.3.3 fabric-transitive-access-wideners-v1-version=6.3.4
fabric-convention-tags-v1-version=2.1.14 fabric-convention-tags-v1-version=2.1.15
fabric-convention-tags-v2-version=2.11.0 fabric-convention-tags-v2-version=2.11.1
fabric-client-tags-api-v1-version=1.1.30 fabric-client-tags-api-v1-version=1.1.31

View file

@ -42,7 +42,7 @@ include 'fabric-dimensions-v1'
include 'fabric-entity-events-v1' include 'fabric-entity-events-v1'
include 'fabric-events-interaction-v0' include 'fabric-events-interaction-v0'
include 'fabric-game-rule-api-v1' include 'fabric-game-rule-api-v1'
include 'fabric-gametest-api-v1' //include 'fabric-gametest-api-v1'
include 'fabric-item-api-v1' include 'fabric-item-api-v1'
include 'fabric-item-group-api-v1' include 'fabric-item-group-api-v1'
include 'fabric-key-binding-api-v1' include 'fabric-key-binding-api-v1'