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
// 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") {
testmodImplementation project(path: ':fabric-gametest-api-v1', configuration: 'namedElements')
testmodClientImplementation project(":fabric-gametest-api-v1").sourceSets.client.output
testmodImplementation project(path: ':fabric-resource-loader-v0', configuration: 'namedElements')
testmodClientImplementation project(":fabric-resource-loader-v0").sourceSets.client.output
}
// if (project.name != "fabric-gametest-api-v1") {
// testmodImplementation project(path: ':fabric-gametest-api-v1', configuration: 'namedElements')
// testmodClientImplementation project(":fabric-gametest-api-v1").sourceSets.client.output
// testmodImplementation project(path: ':fabric-resource-loader-v0', configuration: 'namedElements')
// 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.
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 net.minecraft.test.GameTest;
import net.minecraft.test.TestContext;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
public class FabricApiBaseGameTest {
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
//@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) TODO 1.21.5 tests
public void auditMixins(TestContext context) {
MixinEnvironment.getCurrentEnvironment().audit();

View file

@ -286,7 +286,7 @@ public interface BiomeModificationContext {
* @see BiomeEffects.Builder#music(MusicSound)
*/
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.registry.RegistryKey;
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.SpawnSettings;
import net.minecraft.world.dimension.DimensionOptions;
@ -148,7 +148,7 @@ public final class BiomeSelectors {
SpawnSettings spawnSettings = context.getBiome().getSpawnSettings();
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())) {
return true;
}

View file

@ -46,7 +46,7 @@ import net.minecraft.sound.BiomeMoodSound;
import net.minecraft.sound.MusicSound;
import net.minecraft.sound.SoundEvent;
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.BiomeEffects;
import net.minecraft.world.biome.BiomeParticleConfig;
@ -341,7 +341,7 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
private class SpawnSettingsContextImpl implements SpawnSettingsContext {
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() {
unfreezeSpawners();
@ -374,7 +374,7 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
private void freezeSpawners() {
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()) {
spawners.put(entry.getKey(), Pool.empty());
} else {
@ -399,7 +399,7 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
Objects.requireNonNull(spawnGroup);
Objects.requireNonNull(spawnEntry);
fabricSpawners.get(spawnGroup).add(new Present<>(spawnEntry, weight));
fabricSpawners.get(spawnGroup).add(new Weighted<>(spawnEntry, weight));
}
@Override

View file

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

View file

@ -24,8 +24,6 @@ import org.slf4j.LoggerFactory;
import net.minecraft.item.ItemConvertible;
import net.minecraft.loot.LootTable;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;
import net.minecraft.village.VillagerProfession;
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.
* @param profession the profession to modify
* @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(lootTable, "Loot table identifier cannot be null!");
RegistryKey<LootTable> oldValue = GiveGiftsToHeroTaskAccessor.fabric_getGifts().put(profession, lootTable);
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)
public interface GiveGiftsToHeroTaskAccessor {
@Accessor("GIFTS")
static Map<VillagerProfession, RegistryKey<LootTable>> fabric_getGifts() {
static Map<RegistryKey<VillagerProfession>, RegistryKey<LootTable>> fabric_getGifts() {
throw new AssertionError("Untransformed @Accessor");
}
}

View file

@ -16,32 +16,8 @@
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 {
/* TODO 1.21.5 tests
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testCompostingChanceRegistry(TestContext context) {
BlockPos pos = new BlockPos(0, 1, 0);
@ -244,4 +220,6 @@ public class ContentRegistryGameTest {
context.complete();
});
}
*/
}

View file

@ -17,21 +17,19 @@
package net.fabricmc.fabric.test.content.registry;
import net.minecraft.block.Blocks;
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;
import net.fabricmc.fabric.api.registry.FlammableBlockRegistry;
public class FlammableTest {
/**
* 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) {
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();

View file

@ -16,32 +16,15 @@
package net.fabricmc.fabric.test.attachment.gametest;
import java.util.List;
import java.util.Objects;
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.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.AttachmentType;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
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
public static AttachmentType<IntSupplier> DUMMY = AttachmentRegistry.create(
Identifier.of(AttachmentTestMod.MOD_ID, "dummy")
@ -51,6 +34,7 @@ public class AttachmentCopyTests implements FabricGameTest {
AttachmentRegistry.Builder::copyOnDeath
);
/* TODO 1.21.5 tests
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testCrossWorldTeleport(TestContext context) {
MinecraftServer server = context.getWorld().getServer();
@ -107,4 +91,6 @@ public class AttachmentCopyTests implements FabricGameTest {
converted.discard();
context.complete();
}
*/
}

View file

@ -19,28 +19,10 @@ package net.fabricmc.fabric.test.attachment.gametest;
import com.mojang.logging.LogUtils;
import org.slf4j.Logger;
import net.minecraft.block.Block;
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 {
public class BlockEntityTests {
private static final Logger LOGGER = LogUtils.getLogger();
/* TODO 1.21.5 tests
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testBlockEntitySync(TestContext context) {
BlockPos pos = BlockPos.ORIGIN.up();
@ -84,4 +66,6 @@ public class BlockEntityTests implements FabricGameTest {
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 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 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 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;
@ -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 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 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 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 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

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!
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 (player.getStackInHand(hand).isOf(Items.LAVA_BUCKET)) {
world.setBlockState(pos, Blocks.AIR.getDefaultState());

View file

@ -16,28 +16,11 @@
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 {
/**
* Try placing a sign with a fake player.
*/
/* TODO 1.21.5 tests
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testFakePlayerPlaceSign(TestContext context) {
// 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();
}
*/
/**
* Try breaking a beehive with a fake player (see {@code BeehiveBlockMixin}).
*/
/* TODO 1.21.5 tests
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testFakePlayerBreakBeehive(TestContext context) {
BlockPos basePos = new BlockPos(0, 1, 0);
@ -81,4 +67,6 @@ public class FakePlayerTests {
context.expectBlock(Blocks.AIR, basePos);
context.complete();
}
*/
}

View file

@ -41,7 +41,7 @@ public class UseBlockTests implements ModInitializer {
UseBlockCallback.EVENT.register((player, world, hand, hitResult) -> {
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 (player.getStackInHand(hand).isOf(Items.WATER_BUCKET)) {
world.setBlockState(pos, Blocks.AIR.getDefaultState());

View file

@ -28,7 +28,7 @@ public class UseEntityTests implements ModInitializer {
public void onInitialize() {
// Disallow interactions with toolsmiths
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;
}

View file

@ -148,6 +148,7 @@ public final class GameRuleFactory {
type -> new BoundedIntRule(type, defaultValue, minimumValue, maximumValue), // Internally use a bounded int rule
changedCallback,
GameRules.Visitor::visitInt,
GameRules.IntRule.class,
FeatureSet.empty()
);
}
@ -226,6 +227,7 @@ public final class GameRuleFactory {
type -> new DoubleRule(type, defaultValue, minimumValue, maximumValue),
changedCallback,
GameRuleFactory::visitDouble,
DoubleRule.class,
FeatureSet.empty()
);
}
@ -292,7 +294,8 @@ public final class GameRuleFactory {
type -> new EnumRule<>(type, defaultValue, supportedValues),
changedCallback,
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>> {
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) {
super(null, ruleFactory, changeCallback, acceptor, FeatureSet.empty());
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, enumRuleClass, FeatureSet.empty());
this.supportedValues = supportedValues;
}

View file

@ -1,6 +1,6 @@
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
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
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;Ljava/lang/Class;Lnet/minecraft/resource/featuretoggle/FeatureSet;)V
accessible class net/minecraft/world/GameRules$Acceptor
accessible class net/minecraft/client/gui/screen/world/EditGameRulesScreen$RuleWidgetFactory
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
public void onInitialize() {
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() {

View file

@ -76,7 +76,7 @@ public class CustomDamageTest implements ModInitializer {
public static class WeirdPick extends Item {
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

View file

@ -16,26 +16,13 @@
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.fabricmc.fabric.api.gametest.v1.FabricGameTest;
import net.fabricmc.fabric.test.item.CustomDamageTest;
public class BrewingStandGameTest implements FabricGameTest {
public class BrewingStandGameTest {
private static final int BREWING_TIME = 800;
private static final BlockPos POS = new BlockPos(0, 1, 0);
/* TODO 1.21.5 tests
@GameTest(templateName = EMPTY_STRUCTURE)
public void basicBrewing(TestContext context) {
context.setBlockState(POS, Blocks.BREWING_STAND);
@ -153,4 +140,6 @@ public class BrewingStandGameTest implements FabricGameTest {
itemStack.set(DataComponentTypes.POTION_CONTENTS, new PotionContentsComponent(potion));
return itemStack;
}
*/
}

View file

@ -16,34 +16,8 @@
package net.fabricmc.fabric.test.item.gametest;
import java.util.List;
import java.util.Optional;
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 {
public class CustomEnchantmentEffectsGameTest {
/* TODO 1.21.5 tests
@GameTest(templateName = "fabric-item-api-v1-testmod:bedrock_platform")
public void weirdImpalingSetsFireToTargets(TestContext context) {
BlockPos pos = new BlockPos(3, 3, 3);
@ -88,4 +62,6 @@ public class CustomEnchantmentEffectsGameTest implements FabricGameTest {
DynamicRegistryManager registryManager = context.getWorld().getRegistryManager();
return registryManager.getOrThrow(RegistryKeys.ENCHANTMENT);
}
*/
}

View file

@ -16,21 +16,8 @@
package net.fabricmc.fabric.test.item.gametest;
import java.util.function.Consumer;
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 {
public class DefaultItemComponentGameTest {
/* TODO 1.21.5 tests
@GameTest(templateName = EMPTY_STRUCTURE)
public void modify(TestContext context) {
Consumer<Text> checkText = text -> {
@ -90,4 +77,6 @@ public class DefaultItemComponentGameTest implements FabricGameTest {
context.assertTrue(expectedName.contains(itemName), errorMessage.formatted(itemName, expectedName));
context.complete();
}
*/
}

View file

@ -16,22 +16,17 @@
package net.fabricmc.fabric.test.item.gametest;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.AbstractFurnaceBlockEntity;
import net.minecraft.block.entity.FurnaceBlockEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.test.GameTest;
import net.minecraft.test.TestContext;
import net.minecraft.util.math.BlockPos;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
import net.fabricmc.fabric.test.item.CustomDamageTest;
public class FurnaceGameTest implements FabricGameTest {
public class FurnaceGameTest {
private static final int COOK_TIME = 200;
private static final BlockPos POS = new BlockPos(0, 1, 0);
/* TODO 1.21.5 tests
@GameTest(templateName = EMPTY_STRUCTURE)
public void basicSmelt(TestContext context) {
context.setBlockState(POS, Blocks.FURNACE);
@ -98,6 +93,8 @@ public class FurnaceGameTest implements FabricGameTest {
context.complete();
}
*/
private void setInputs(FurnaceBlockEntity blockEntity, ItemStack ingredient, ItemStack fuel) {
blockEntity.setStack(0, ingredient);
blockEntity.setStack(1, fuel);
@ -108,7 +105,8 @@ public class FurnaceGameTest implements FabricGameTest {
ItemStack currentStack = blockEntity.getStack(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;
import java.util.List;
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 {
public class RecipeGameTest {
/* TODO 1.21.5 tests
@GameTest(templateName = EMPTY_STRUCTURE)
public void vanillaRemainderTest(TestContext context) {
CraftingRecipeInput inventory = CraftingRecipeInput.create(1, 2, List.of(
@ -96,4 +83,6 @@ public class RecipeGameTest implements FabricGameTest {
stack.setDamage(damage);
return stack;
}
*/
}

View file

@ -22,6 +22,7 @@ import java.util.function.Consumer;
import org.jetbrains.annotations.ApiStatus;
import net.minecraft.registry.RegistryKey;
import net.minecraft.util.Identifier;
import net.minecraft.village.TradeOffers;
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 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));
}
@ -74,7 +75,7 @@ public final class TradeOfferHelper {
* @param factories a consumer to provide the factories
*/
@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);
}

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.LoggerFactory;
import net.minecraft.registry.RegistryKey;
import net.minecraft.util.Identifier;
import net.minecraft.util.Util;
import net.minecraft.village.TradeOffers;
@ -51,9 +52,9 @@ public final class TradeOfferInternals {
*/
private static void initVillagerTrades() {
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());
}
@ -63,7 +64,7 @@ public final class TradeOfferInternals {
// synchronized guards against concurrent modifications - Vanilla does not mutate the underlying arrays (as of 1.16),
// 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.");
initVillagerTrades();
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;
import java.util.Set;
import java.util.stream.Stream;
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 net.minecraft.entity.Entity;
import net.minecraft.registry.DefaultedRegistry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.util.math.random.Random;
import net.minecraft.village.TradeOffer;
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.
* 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;"))
private <T> Stream<T> disableVanillaCheck(DefaultedRegistry<VillagerType> instance) {
@Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Ljava/util/Set;stream()Ljava/util/stream/Stream;"))
private <T> Stream<T> disableVanillaCheck(Set<RegistryKey<VillagerType>> instance) {
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 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/BlockSetType register (Lnet/minecraft/block/BlockSetType;)Lnet/minecraft/block/BlockSetType;

View file

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

View file

@ -19,14 +19,11 @@ package net.fabricmc.fabric.test.object.builder;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.test.GameTest;
import net.minecraft.test.TestContext;
import net.minecraft.util.math.BlockPos;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
public class ObjectBuilderGameTest {
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
// @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) TODO 1.21.5 tests
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);
BlockPos.Mutable pos = BlockPos.ORIGIN.up().mutableCopy();

View file

@ -16,9 +16,17 @@
package net.fabricmc.fabric.test.recipe.ingredient;
import java.util.List;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals;
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.DataComponentTypes;
import net.minecraft.component.type.NbtComponent;
@ -28,41 +36,41 @@ import net.minecraft.item.Items;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.recipe.Ingredient;
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.util.Util;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
import net.fabricmc.fabric.api.recipe.v1.ingredient.DefaultCustomIngredients;
public class IngredientMatchTests {
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testAllIngredient(TestContext context) {
@BeforeAll
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));
assertEquals(1, allIngredient.getMatchingItems().toList().size());
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)));
assertEquals(true, allIngredient.test(new ItemStack(Items.CARROT)));
assertEquals(false, allIngredient.test(new ItemStack(Items.STICK)));
assertFalse(allIngredient.test(new ItemStack(Items.APPLE)));
assertTrue(allIngredient.test(new ItemStack(Items.CARROT)));
assertFalse(allIngredient.test(new ItemStack(Items.STICK)));
Ingredient emptyAllIngredient = DefaultCustomIngredients.all(Ingredient.ofItems(Items.APPLE), Ingredient.ofItems(Items.STICK));
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)));
assertEquals(false, emptyAllIngredient.test(new ItemStack(Items.STICK)));
context.complete();
assertFalse(emptyAllIngredient.test(new ItemStack(Items.APPLE)));
assertFalse(emptyAllIngredient.test(new ItemStack(Items.STICK)));
}
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testAnyIngredient(TestContext context) {
@Test
public void testAnyIngredient() {
Ingredient anyIngredient = DefaultCustomIngredients.any(Ingredient.ofItems(Items.APPLE, Items.CARROT), Ingredient.ofItems(Items.STICK, Items.CARROT));
assertEquals(4, anyIngredient.getMatchingItems().toList().size());
@ -70,32 +78,28 @@ public class IngredientMatchTests {
assertEquals(Items.CARROT, anyIngredient.getMatchingItems().toList().get(1).value());
assertEquals(Items.STICK, anyIngredient.getMatchingItems().toList().get(2).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)));
assertEquals(true, anyIngredient.test(new ItemStack(Items.CARROT)));
assertEquals(true, anyIngredient.test(new ItemStack(Items.STICK)));
context.complete();
assertTrue(anyIngredient.test(new ItemStack(Items.APPLE)));
assertTrue(anyIngredient.test(new ItemStack(Items.CARROT)));
assertTrue(anyIngredient.test(new ItemStack(Items.STICK)));
}
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testDifferenceIngredient(TestContext context) {
@Test
public void testDifferenceIngredient() {
Ingredient differenceIngredient = DefaultCustomIngredients.difference(Ingredient.ofItems(Items.APPLE, Items.CARROT), Ingredient.ofItems(Items.STICK, Items.CARROT));
assertEquals(1, differenceIngredient.getMatchingItems().toList().size());
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)));
assertEquals(false, differenceIngredient.test(new ItemStack(Items.CARROT)));
assertEquals(false, differenceIngredient.test(new ItemStack(Items.STICK)));
context.complete();
assertTrue(differenceIngredient.test(new ItemStack(Items.APPLE)));
assertFalse(differenceIngredient.test(new ItemStack(Items.CARROT)));
assertFalse(differenceIngredient.test(new ItemStack(Items.STICK)));
}
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testComponentIngredient(TestContext context) {
@Test
public void testComponentIngredient() {
final Ingredient baseIngredient = Ingredient.ofItems(Items.DIAMOND_PICKAXE, Items.NETHERITE_PICKAXE, Items.STICK);
final Ingredient undamagedIngredient = DefaultCustomIngredients.components(
baseIngredient,
@ -110,8 +114,8 @@ public class IngredientMatchTests {
ItemStack renamedUndamagedDiamondPickaxe = new ItemStack(Items.DIAMOND_PICKAXE);
renamedUndamagedDiamondPickaxe.set(DataComponentTypes.CUSTOM_NAME, Text.literal("Renamed"));
assertEquals(true, undamagedIngredient.test(renamedUndamagedDiamondPickaxe));
assertEquals(false, noNameUndamagedIngredient.test(renamedUndamagedDiamondPickaxe));
assertTrue(undamagedIngredient.test(renamedUndamagedDiamondPickaxe));
assertFalse(noNameUndamagedIngredient.test(renamedUndamagedDiamondPickaxe));
assertEquals(3, undamagedIngredient.getMatchingItems().toList().size());
ItemStack result0 = undamagedIngredient.getMatchingItems().toList().getFirst().value().getDefaultStack();
@ -121,19 +125,19 @@ public class IngredientMatchTests {
assertEquals(Items.NETHERITE_PICKAXE, result1.getItem());
assertEquals(ComponentChanges.EMPTY, result0.getComponentChanges());
assertEquals(ComponentChanges.EMPTY, result1.getComponentChanges());
assertEquals(false, undamagedIngredient.getMatchingItems().toList().isEmpty());
assertFalse(undamagedIngredient.getMatchingItems().toList().isEmpty());
// Undamaged is fine
assertEquals(true, undamagedIngredient.test(new ItemStack(Items.DIAMOND_PICKAXE)));
assertEquals(true, undamagedIngredient.test(new ItemStack(Items.NETHERITE_PICKAXE)));
assertTrue(undamagedIngredient.test(new ItemStack(Items.DIAMOND_PICKAXE)));
assertTrue(undamagedIngredient.test(new ItemStack(Items.NETHERITE_PICKAXE)));
// Damaged is not fine
ItemStack damagedDiamondPickaxe = new ItemStack(Items.DIAMOND_PICKAXE);
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
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
final NbtCompound requiredData = new NbtCompound();
@ -149,21 +153,19 @@ public class IngredientMatchTests {
requiredDataStack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(requiredData));
ItemStack extraDataStack = new ItemStack(Items.DIAMOND_PICKAXE);
extraDataStack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(extraData));
assertEquals(true, customDataIngredient.test(requiredDataStack));
assertEquals(false, customDataIngredient.test(extraDataStack));
assertTrue(customDataIngredient.test(requiredDataStack));
assertFalse(customDataIngredient.test(extraDataStack));
// Default value is ignored in components(ItemStack)
final Ingredient damagedPickaxeIngredient = DefaultCustomIngredients.components(renamedUndamagedDiamondPickaxe);
ItemStack renamedDamagedDiamondPickaxe = renamedUndamagedDiamondPickaxe.copy();
renamedDamagedDiamondPickaxe.setDamage(10);
assertEquals(true, damagedPickaxeIngredient.test(renamedUndamagedDiamondPickaxe));
assertEquals(true, damagedPickaxeIngredient.test(renamedDamagedDiamondPickaxe));
context.complete();
assertTrue(damagedPickaxeIngredient.test(renamedUndamagedDiamondPickaxe));
assertTrue(damagedPickaxeIngredient.test(renamedDamagedDiamondPickaxe));
}
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testCustomDataIngredient(TestContext context) {
@Test
public void testCustomDataIngredient() {
final NbtCompound requiredNbt = Util.make(new NbtCompound(), nbt -> {
nbt.putInt("keyA", 1);
});
@ -181,29 +183,21 @@ public class IngredientMatchTests {
final Ingredient customDataIngredient = DefaultCustomIngredients.customData(baseIngredient, requiredNbt);
ItemStack stack = new ItemStack(Items.STICK);
assertEquals(false, customDataIngredient.test(stack));
assertFalse(customDataIngredient.test(stack));
stack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(requiredNbt));
assertEquals(true, customDataIngredient.test(stack));
assertTrue(customDataIngredient.test(stack));
// This is a non-strict matching
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));
assertEquals(false, customDataIngredient.test(stack));
assertFalse(customDataIngredient.test(stack));
stack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(rejectedNbt2));
assertEquals(false, customDataIngredient.test(stack));
assertFalse(customDataIngredient.test(stack));
List<RegistryEntry<Item>> matchingItems = customDataIngredient.getMatchingItems().toList();
assertEquals(1, matchingItems.size());
assertEquals(Items.STICK, matchingItems.getFirst().value());
// 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));
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;
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.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import com.mojang.serialization.Codec;
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.recipe.Ingredient;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.Registries;
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.impl.recipe.ingredient.CustomIngredientInit;
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.
*/
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testArrayDeserialization(TestContext context) {
@Test
public void testArrayDeserialization() {
String ingredientJson = """
[
{
@ -57,37 +69,31 @@ public class SerializationTests {
""";
JsonElement json = JsonParser.parseString(ingredientJson);
try {
assertThrows(JsonParseException.class, () -> {
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.
*/
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testCustomIngredientSerialization(TestContext context) {
for (boolean allowEmpty : List.of(false, true)) {
String ingredientJson = """
@Test
public void testCustomIngredientSerialization() {
RegistryOps<JsonElement> registryOps = RegistryOps.of(JsonOps.INSTANCE, DynamicRegistryManager.of(Registries.REGISTRIES));
String ingredientJson = """
{"ingredients":["minecraft:stone"],"fabric:type":"fabric:all"}
""".trim();
RegistryOps<JsonElement> registryOps = context.getWorld().getRegistryManager().getOps(JsonOps.INSTANCE);
Ingredient ingredient = DefaultCustomIngredients.all(
Ingredient.ofItems(Items.STONE)
);
Codec<Ingredient> ingredientCodec = Ingredient.CODEC;
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");
}
Ingredient ingredient = DefaultCustomIngredients.all(
Ingredient.ofItems(Items.STONE)
);
JsonObject json = Ingredient.CODEC.encodeStart(registryOps, ingredient).getOrThrow(IllegalStateException::new).getAsJsonObject();
assertEquals(json.toString(), ingredientJson, "Unexpected json: " + json);
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.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.test.GameTest;
import net.minecraft.test.GameTestException;
import net.minecraft.test.TestContext;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
public class ShapelessRecipeMatchTests {
/**
* 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) {
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();
@ -50,14 +48,14 @@ public class ShapelessRecipeMatchTests {
List<ItemStack> damagedPickaxes = Collections.nCopies(9, damagedPickaxe);
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);
oneUndamagedPickaxe.set(0, undamagedPickaxe);
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();

View file

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

View file

@ -72,7 +72,7 @@ public class RandomSupplierTest implements ClientModInitializer {
private static WeightedBakedModel createWeightedBakedModel() {
var checkingModel = new RandomCheckingBakedModel();
Pool.Builder<BakedModel> weightedBuilder = Pool.method_66215();
Pool.Builder<BakedModel> weightedBuilder = Pool.builder();
weightedBuilder.add(checkingModel, 1);
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)));
Pool.Builder<BakedModel> weightedAgainBuilder = Pool.method_66215();
Pool.Builder<BakedModel> weightedAgainBuilder = Pool.builder();
weightedAgainBuilder.add(multipart, 1);
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 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
public void onInitialize() {

View file

@ -5,7 +5,6 @@ loom {
}
testDependencies(project, [
':fabric-gametest-api-v1',
':fabric-lifecycle-events-v1',
':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;
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.fabricmc.fabric.api.gametest.v1.FabricGameTest;
public class ConditionalResourcesTest {
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);
}
/* TODO 1.21.5 tests
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void conditionalRecipes(TestContext context) {
ServerRecipeManager manager = context.getWorld().getRecipeManager();
@ -137,4 +126,6 @@ public class ConditionalResourcesTest {
context.complete();
}
*/
}

View file

@ -16,33 +16,16 @@
package net.fabricmc.fabric.test.resource.conditions;
import java.util.stream.Collectors;
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.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryOps;
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.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.ResourceConditions;
import net.fabricmc.fabric.impl.resource.conditions.ResourceConditionsImpl;
public class DefaultResourceConditionsTest {
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)));
}
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
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();
}
/* TODO 1.21.5 tests
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void featuresEnabled(TestContext context) {
ResourceCondition vanilla = ResourceConditions.featuresEnabled(FeatureFlags.VANILLA);
@ -140,20 +67,6 @@ public class DefaultResourceConditionsTest {
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
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)
ResourceCondition plains = ResourceConditions.registryContains(BiomeKeys.PLAINS);
ResourceCondition unknownBiome = ResourceConditions.registryContains(RegistryKey.of(RegistryKeys.BIOME, UNKNOWN_ENTRY_ID));
@ -200,4 +113,6 @@ public class DefaultResourceConditionsTest {
context.complete();
}
*/
}

View file

@ -67,7 +67,7 @@ public class BoxBlock extends BlockWithEntity {
}
@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);
if (be instanceof Inventory) {
@ -75,7 +75,7 @@ public class BoxBlock extends BlockWithEntity {
world.updateComparators(pos, this);
}
super.method_66388(state, world, pos, moved);
super.onStateReplaced(state, world, pos, moved);
}
@Override

View file

@ -16,45 +16,12 @@
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 {
/**
* Regression test for https://github.com/FabricMC/fabric/issues/1972.
* Ensures that furnace cook time is only reset when extraction is actually committed.
*/
/*
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testFurnaceCookTime(TestContext context) {
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.
*
* @param block A block with an Inventory block entity.
* @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) {
World world = context.getWorld();
@ -142,25 +112,34 @@ public class VanillaStorageTests {
context.complete();
}
*/
/**
* Tests that containers such as chests don't update adjacent comparators until the very end of a committed transaction.
*/
/*
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testChestComparator(TestContext context) {
testComparatorOnInventory(context, Blocks.CHEST, ItemVariant.of(Items.DIAMOND));
}
*/
/**
* Same as {@link #testChestComparator} but for chiseled bookshelves, because their implementation is very... strange.
*/
/*
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testChiseledBookshelfComparator(TestContext context) {
testComparatorOnInventory(context, Blocks.CHISELED_BOOKSHELF, ItemVariant.of(Items.BOOK));
}
*/
/**
* Test for chiseled bookshelves, because their implementation is very... strange.
*/
/*
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testChiseledBookshelf(TestContext context) {
ItemVariant book = ItemVariant.of(Items.BOOK);
@ -221,9 +200,12 @@ public class VanillaStorageTests {
context.complete();
}
*/
/**
* Tests that shulker boxes cannot be inserted into other shulker boxes.
*/
/*
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testShulkerNoInsert(TestContext context) {
BlockPos pos = new BlockPos(0, 2, 0);
@ -238,11 +220,14 @@ public class VanillaStorageTests {
context.complete();
}
*/
/**
* {@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.
* This test ensures that the Transfer API works around this issue for furnaces.
*/
/*
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testBadFurnaceIsValid(TestContext context) {
BlockPos pos = new BlockPos(0, 1, 0);
@ -259,9 +244,12 @@ public class VanillaStorageTests {
context.complete();
}
*/
/**
* Same as {@link #testBadFurnaceIsValid(TestContext)}, but for brewing stands.
*/
/*
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testBadBrewingStandIsValid(TestContext context) {
BlockPos pos = new BlockPos(0, 1, 0);
@ -284,9 +272,12 @@ public class VanillaStorageTests {
context.complete();
}
*/
/**
* 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)
public void testDoubleChestComparator(TestContext context) {
BlockPos chestPos = new BlockPos(2, 1, 2);
@ -336,9 +327,12 @@ public class VanillaStorageTests {
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>.
*/
/*
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void testComposterFirstInsert(TestContext context) {
BlockPos pos = new BlockPos(0, 1, 0);
@ -363,9 +357,12 @@ public class VanillaStorageTests {
context.complete();
}
*/
/**
* 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)
public void testJukeboxState(TestContext context) {
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.complete();
}
*/
}

View file

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

View file

@ -90,7 +90,6 @@ transitive-accessible method net/minecraft/text/TranslatableTextContent getArg (
# Villagers
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
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/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/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/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

View file

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