diff --git a/fabric-object-builder-api-v1/build.gradle b/fabric-object-builder-api-v1/build.gradle index 5032c8304f..e2ab4cf2a0 100644 --- a/fabric-object-builder-api-v1/build.gradle +++ b/fabric-object-builder-api-v1/build.gradle @@ -20,4 +20,5 @@ validateMixinNames { dependencies { modApi getQslModule("block", "block_entity") + modApi getQslModule("entity", "entity_extensions") } diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricDefaultAttributeRegistry.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricDefaultAttributeRegistry.java index 455382f876..a91e68f997 100644 --- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricDefaultAttributeRegistry.java +++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricDefaultAttributeRegistry.java @@ -24,10 +24,9 @@ import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.attribute.DefaultAttributeContainer; +import net.minecraft.entity.attribute.DefaultAttributeRegistry; import net.minecraft.registry.Registries; -import net.fabricmc.fabric.mixin.object.builder.DefaultAttributeRegistryAccessor; - /** * Allows registering custom default attributes for living entities. * @@ -38,7 +37,10 @@ * {@link net.minecraft.entity.attribute.DefaultAttributeRegistry#get(EntityType)}.

* * @see net.minecraft.entity.attribute.DefaultAttributeRegistry + * + * @deprecated see {@link DefaultAttributeRegistry#DEFAULT_ATTRIBUTE_REGISTRY DEFAULT_ATTRIBUTE_REGISTRY} */ +@Deprecated public final class FabricDefaultAttributeRegistry { /** * Private logger, not exposed. @@ -78,7 +80,7 @@ public static void register(EntityType type, DefaultAttr * @see FabricEntityType.Builder.Living#defaultAttributes(Supplier) */ public static void register(EntityType type, DefaultAttributeContainer container) { - if (DefaultAttributeRegistryAccessor.getRegistry().put(type, container) != null) { + if (DefaultAttributeRegistry.DEFAULT_ATTRIBUTE_REGISTRY.put(type, container) != null) { LOGGER.debug("Overriding existing registration for entity type {}", Registries.ENTITY_TYPE.getId(type)); } } diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/MinecartComparatorLogic.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/MinecartComparatorLogic.java index c98de10d4b..1ec247492c 100644 --- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/MinecartComparatorLogic.java +++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/MinecartComparatorLogic.java @@ -23,7 +23,10 @@ /** * Provides custom comparator output for minecarts resting on detector rails. * @param the handled minecart type + * + * @deprecated see {@link org.quiltmc.qsl.entity.extensions.api.MinecartComparatorLogic MinecartComparatorLogic} */ +@Deprecated @FunctionalInterface public interface MinecartComparatorLogic { /** diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/MinecartComparatorLogicRegistry.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/MinecartComparatorLogicRegistry.java index 5270229a33..917406b9e0 100644 --- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/MinecartComparatorLogicRegistry.java +++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/MinecartComparatorLogicRegistry.java @@ -30,7 +30,10 @@ /** * A registry for {@linkplain MinecartComparatorLogic custom minecart comparator logic}. + * + * @deprecated see {@link org.quiltmc.qsl.entity.extensions.api.MinecartComparatorLogic MinecartComparatorLogic} */ +@Deprecated public final class MinecartComparatorLogicRegistry { private static final Logger LOGGER = LoggerFactory.getLogger(MinecartComparatorLogicRegistry.class); private static final Map, MinecartComparatorLogic> LOGICS = new IdentityHashMap<>(); diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/trade/TradeOfferHelper.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/trade/TradeOfferHelper.java index 9fddf47edd..92e6ca9ac0 100644 --- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/trade/TradeOfferHelper.java +++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/trade/TradeOfferHelper.java @@ -30,7 +30,10 @@ /** * Utilities to help with registration of trade offers. + * + * @deprecated see {@link org.quiltmc.qsl.entity.extensions.api.TradeOfferHelper} */ +@Deprecated public final class TradeOfferHelper { /** * Registers trade offer factories for use by villagers. @@ -50,7 +53,7 @@ public final class TradeOfferHelper { * @param factories a consumer to provide the factories */ public static void registerVillagerOffers(VillagerProfession profession, int level, Consumer> factories) { - TradeOfferInternals.registerVillagerOffers(profession, level, (trades, rebalanced) -> factories.accept(trades)); + org.quiltmc.qsl.entity.extensions.api.TradeOfferHelper.registerVillagerOffers(profession, level, factories); } /** @@ -75,7 +78,7 @@ public static void registerVillagerOffers(VillagerProfession profession, int lev */ @ApiStatus.Experimental public static void registerVillagerOffers(VillagerProfession profession, int level, VillagerOffersAdder factories) { - TradeOfferInternals.registerVillagerOffers(profession, level, factories); + org.quiltmc.qsl.entity.extensions.api.TradeOfferHelper.registerVillagerOffers(profession, level, factories); } /** @@ -87,7 +90,7 @@ public static void registerVillagerOffers(VillagerProfession profession, int lev * @param factory a consumer to provide the factories */ public static void registerWanderingTraderOffers(int level, Consumer> factory) { - TradeOfferInternals.registerWanderingTraderOffers(level, factory); + org.quiltmc.qsl.entity.extensions.api.TradeOfferHelper.registerWanderingTraderOffers(level, factory); } /** @@ -101,7 +104,21 @@ public static void registerWanderingTraderOffers(int level, Consumer factory) { - factory.accept(new TradeOfferInternals.WanderingTraderOffersBuilderImpl()); + org.quiltmc.qsl.entity.extensions.api.TradeOfferHelper.registerRebalancedWanderingTraderOffers((builder -> { + factory.accept(new WanderingTraderOffersBuilder() { + @Override + public WanderingTraderOffersBuilder pool(Identifier id, int count, TradeOffers.Factory... factories) { + builder.pool(id, count, factories); + return this; + } + + @Override + public WanderingTraderOffersBuilder addOffersToPool(Identifier pool, TradeOffers.Factory... factories) { + builder.addOffersToPool(pool, factories); + return this; + } + }); + })); } /** @@ -116,7 +133,7 @@ private TradeOfferHelper() { } @FunctionalInterface - public interface VillagerOffersAdder { + public interface VillagerOffersAdder extends org.quiltmc.qsl.entity.extensions.api.TradeOfferHelper.VillagerOffersAdder { void onRegister(List factories, boolean rebalanced); } @@ -129,7 +146,7 @@ public interface VillagerOffersAdder { */ @ApiStatus.NonExtendable @ApiStatus.Experimental - public interface WanderingTraderOffersBuilder { + public interface WanderingTraderOffersBuilder extends org.quiltmc.qsl.entity.extensions.api.TradeOfferHelper.WanderingTraderOffersBuilder { /** * The pool ID for the "buy items" pool. * Two trade offers are picked from this pool. diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/world/poi/PointOfInterestHelper.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/world/poi/PointOfInterestHelper.java index 2ddc5dcab9..2d9d4f552c 100644 --- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/world/poi/PointOfInterestHelper.java +++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/world/poi/PointOfInterestHelper.java @@ -16,26 +16,23 @@ package net.fabricmc.fabric.api.object.builder.v1.world.poi; -import java.util.Set; - -import com.google.common.collect.ImmutableSet; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.registry.Registries; import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.RegistryKeys; import net.minecraft.util.Identifier; import net.minecraft.world.poi.PointOfInterest; import net.minecraft.world.poi.PointOfInterestType; -import net.minecraft.world.poi.PointOfInterestTypes; /** * This class provides utilities to create a {@link PointOfInterestType}. * *

A point of interest is typically used by villagers to specify their workstation blocks, meeting zones and homes. * Points of interest are also used by bees to specify where their bee hive is and nether portals to find existing portals. + * + * @deprecated see {@link org.quiltmc.qsl.entity.extensions.api.PointOfInterestHelper} */ +@Deprecated public final class PointOfInterestHelper { private PointOfInterestHelper() { } @@ -50,13 +47,9 @@ private PointOfInterestHelper() { * @return a new {@link PointOfInterestType}. */ public static PointOfInterestType register(Identifier id, int ticketCount, int searchDistance, Block... blocks) { - final ImmutableSet.Builder builder = ImmutableSet.builder(); - - for (Block block : blocks) { - builder.addAll(block.getStateManager().getStates()); - } + RegistryKey key = org.quiltmc.qsl.entity.extensions.api.PointOfInterestHelper.register(id, ticketCount, searchDistance, blocks); - return register(id, ticketCount, searchDistance, builder.build()); + return Registries.POINT_OF_INTEREST_TYPE.get(key); } /** @@ -69,14 +62,8 @@ public static PointOfInterestType register(Identifier id, int ticketCount, int s * @return a new {@link PointOfInterestType}. */ public static PointOfInterestType register(Identifier id, int ticketCount, int searchDistance, Iterable blocks) { - final ImmutableSet.Builder builder = ImmutableSet.builder(); - - return register(id, ticketCount, searchDistance, builder.addAll(blocks).build()); - } - - // INTERNAL METHODS + RegistryKey key = org.quiltmc.qsl.entity.extensions.api.PointOfInterestHelper.register(id, ticketCount, searchDistance, blocks); - private static PointOfInterestType register(Identifier id, int ticketCount, int searchDistance, Set states) { - return PointOfInterestTypes.register(Registries.POINT_OF_INTEREST_TYPE, RegistryKey.of(RegistryKeys.POINT_OF_INTEREST_TYPE, id), states, ticketCount, searchDistance); + return Registries.POINT_OF_INTEREST_TYPE.get(key); } } diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/impl/object/builder/TradeOfferInternals.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/impl/object/builder/TradeOfferInternals.java index f735309271..2467886528 100644 --- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/impl/object/builder/TradeOfferInternals.java +++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/impl/object/builder/TradeOfferInternals.java @@ -16,136 +16,17 @@ package net.fabricmc.fabric.impl.object.builder; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.function.Consumer; - -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.tuple.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import net.minecraft.util.Identifier; -import net.minecraft.util.Util; -import net.minecraft.village.TradeOffers; -import net.minecraft.village.VillagerProfession; - -import net.fabricmc.fabric.api.object.builder.v1.trade.TradeOfferHelper; - public final class TradeOfferInternals { private static final Logger LOGGER = LoggerFactory.getLogger("fabric-object-builder-api-v1"); private TradeOfferInternals() { } - /** - * Make the rebalanced profession map modifiable, then copy all vanilla - * professions' trades to prevent modifications from propagating to the rebalanced one. - */ - private static void initVillagerTrades() { - if (!(TradeOffers.REBALANCED_PROFESSION_TO_LEVELED_TRADE instanceof HashMap)) { - Map> map = new HashMap<>(TradeOffers.REBALANCED_PROFESSION_TO_LEVELED_TRADE); - - for (Map.Entry> trade : TradeOffers.PROFESSION_TO_LEVELED_TRADE.entrySet()) { - if (!map.containsKey(trade.getKey())) map.put(trade.getKey(), trade.getValue()); - } - - TradeOffers.REBALANCED_PROFESSION_TO_LEVELED_TRADE = map; - } - } - - // 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) { - 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)); - registerOffers(TradeOffers.REBALANCED_PROFESSION_TO_LEVELED_TRADE.computeIfAbsent(profession, key -> new Int2ObjectOpenHashMap<>()), level, trades -> factory.onRegister(trades, true)); - } - - public static synchronized void registerWanderingTraderOffers(int level, Consumer> factory) { - registerOffers(TradeOffers.WANDERING_TRADER_TRADES, level, factory); - } - - // Shared code to register offers for both villagers and wandering traders. - private static void registerOffers(Int2ObjectMap leveledTradeMap, int level, Consumer> factory) { - final List list = new ArrayList<>(); - factory.accept(list); - - final TradeOffers.Factory[] originalEntries = leveledTradeMap.computeIfAbsent(level, key -> new TradeOffers.Factory[0]); - final TradeOffers.Factory[] addedEntries = list.toArray(new TradeOffers.Factory[0]); - - final TradeOffers.Factory[] allEntries = ArrayUtils.addAll(originalEntries, addedEntries); - leveledTradeMap.put(level, allEntries); - } - public static void printRefreshOffersWarning() { Throwable loggingThrowable = new Throwable(); LOGGER.warn("TradeOfferHelper#refreshOffers does not do anything, yet it was called! Stack trace:", loggingThrowable); } - - public static class WanderingTraderOffersBuilderImpl implements TradeOfferHelper.WanderingTraderOffersBuilder { - private static final Object2IntMap ID_TO_INDEX = Util.make(new Object2IntOpenHashMap<>(), idToIndex -> { - idToIndex.put(BUY_ITEMS_POOL, 0); - idToIndex.put(SELL_SPECIAL_ITEMS_POOL, 1); - idToIndex.put(SELL_COMMON_ITEMS_POOL, 2); - }); - - private static final Map DELAYED_MODIFICATIONS = new HashMap<>(); - - /** - * Make the trade list modifiable. - */ - static void initWanderingTraderTrades() { - if (!(TradeOffers.REBALANCED_WANDERING_TRADER_TRADES instanceof ArrayList)) { - TradeOffers.REBALANCED_WANDERING_TRADER_TRADES = new ArrayList<>(TradeOffers.REBALANCED_WANDERING_TRADER_TRADES); - } - } - - @Override - public TradeOfferHelper.WanderingTraderOffersBuilder pool(Identifier id, int count, TradeOffers.Factory... factories) { - if (factories.length == 0) throw new IllegalArgumentException("cannot add empty pool"); - if (count <= 0) throw new IllegalArgumentException("count must be positive"); - - Objects.requireNonNull(id, "id cannot be null"); - - if (ID_TO_INDEX.containsKey(id)) throw new IllegalArgumentException("pool id %s is already registered".formatted(id)); - - Pair pool = Pair.of(factories, count); - initWanderingTraderTrades(); - ID_TO_INDEX.put(id, TradeOffers.REBALANCED_WANDERING_TRADER_TRADES.size()); - TradeOffers.REBALANCED_WANDERING_TRADER_TRADES.add(pool); - TradeOffers.Factory[] delayedModifications = DELAYED_MODIFICATIONS.remove(id); - - if (delayedModifications != null) addOffersToPool(id, delayedModifications); - - return this; - } - - @Override - public TradeOfferHelper.WanderingTraderOffersBuilder addOffersToPool(Identifier pool, TradeOffers.Factory... factories) { - if (!ID_TO_INDEX.containsKey(pool)) { - DELAYED_MODIFICATIONS.compute(pool, (id, current) -> { - if (current == null) return factories; - - return ArrayUtils.addAll(current, factories); - }); - return this; - } - - int poolIndex = ID_TO_INDEX.getInt(pool); - initWanderingTraderTrades(); - Pair poolPair = TradeOffers.REBALANCED_WANDERING_TRADER_TRADES.get(poolIndex); - TradeOffers.Factory[] modified = ArrayUtils.addAll(poolPair.getLeft(), factories); - TradeOffers.REBALANCED_WANDERING_TRADER_TRADES.set(poolIndex, Pair.of(modified, poolPair.getRight())); - return this; - } - } } diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/DefaultAttributeRegistryAccessor.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/DefaultAttributeRegistryAccessor.java deleted file mode 100644 index 13fac8ad08..0000000000 --- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/DefaultAttributeRegistryAccessor.java +++ /dev/null @@ -1,35 +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.mixin.object.builder; - -import java.util.Map; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import net.minecraft.entity.EntityType; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.attribute.DefaultAttributeContainer; -import net.minecraft.entity.attribute.DefaultAttributeRegistry; - -@Mixin(DefaultAttributeRegistry.class) -public interface DefaultAttributeRegistryAccessor { - @Accessor("DEFAULT_ATTRIBUTE_REGISTRY") - static Map, DefaultAttributeContainer> getRegistry() { - throw new AssertionError("mixin dummy"); - } -} diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/DefaultAttributeRegistryMixin.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/DefaultAttributeRegistryMixin.java deleted file mode 100644 index 09a0bd52a5..0000000000 --- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/DefaultAttributeRegistryMixin.java +++ /dev/null @@ -1,46 +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.mixin.object.builder; - -import java.util.IdentityHashMap; -import java.util.Map; - -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import net.minecraft.entity.EntityType; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.attribute.DefaultAttributeContainer; -import net.minecraft.entity.attribute.DefaultAttributeRegistry; - -@Mixin(DefaultAttributeRegistry.class) -public abstract class DefaultAttributeRegistryMixin { - @Shadow - @Final - @Mutable - private static Map, DefaultAttributeContainer> DEFAULT_ATTRIBUTE_REGISTRY; - - @Inject(method = "*", at = @At("TAIL")) - private static void injectAttributes(CallbackInfo ci) { - DEFAULT_ATTRIBUTE_REGISTRY = new IdentityHashMap<>(DEFAULT_ATTRIBUTE_REGISTRY); - } -} diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/TradeOffersTypeAwareBuyForOneEmeraldFactoryMixin.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/TradeOffersTypeAwareBuyForOneEmeraldFactoryMixin.java deleted file mode 100644 index 41d4007884..0000000000 --- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/TradeOffersTypeAwareBuyForOneEmeraldFactoryMixin.java +++ /dev/null @@ -1,58 +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.mixin.object.builder; - -import java.util.stream.Stream; - -import com.llamalad7.mixinextras.sugar.Local; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.entity.Entity; -import net.minecraft.registry.DefaultedRegistry; -import net.minecraft.util.math.random.Random; -import net.minecraft.village.TradeOffer; -import net.minecraft.village.TradeOffers; -import net.minecraft.village.TradedItem; -import net.minecraft.village.VillagerType; - -@Mixin(TradeOffers.TypeAwareBuyForOneEmeraldFactory.class) -public abstract class TradeOffersTypeAwareBuyForOneEmeraldFactoryMixin { - /** - * Vanilla will check the "VillagerType -> Item" map in the stream and throw an exception for villager types not specified in the map. - * This breaks any and all custom villager types. - * 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 = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/registry/DefaultedRegistry;stream()Ljava/util/stream/Stream;")) - private Stream disableVanillaCheck(DefaultedRegistry instance) { - return Stream.empty(); - } - - /** - * To prevent "item" -> "air" trades, if the result of a type aware trade is air, make sure no offer is created. - */ - @Inject(method = "create", at = @At(value = "NEW", target = "net/minecraft/village/TradeOffer"), cancellable = true) - private void failOnNullItem(Entity entity, Random random, CallbackInfoReturnable cir, @Local() TradedItem tradedItem) { - if (tradedItem.itemStack().isEmpty()) { // Will return true for an "empty" item stack that had null passed in the ctor - cir.setReturnValue(null); // Return null to prevent creation of empty trades - } - } -}