Skip to content

Commit

Permalink
Add entity:entity_extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
OroArmor committed Sep 27, 2024
1 parent 048d1a0 commit 06ca37e
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 287 deletions.
1 change: 1 addition & 0 deletions fabric-object-builder-api-v1/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ validateMixinNames {

dependencies {
modApi getQslModule("block", "block_entity")
modApi getQslModule("entity", "entity_extensions")
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -38,7 +37,10 @@
* {@link net.minecraft.entity.attribute.DefaultAttributeRegistry#get(EntityType)}.</p>
*
* @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.
Expand Down Expand Up @@ -78,7 +80,7 @@ public static void register(EntityType<? extends LivingEntity> type, DefaultAttr
* @see FabricEntityType.Builder.Living#defaultAttributes(Supplier)
*/
public static void register(EntityType<? extends LivingEntity> 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));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@
/**
* Provides custom comparator output for minecarts resting on detector rails.
* @param <T> the handled minecart type
*
* @deprecated see {@link org.quiltmc.qsl.entity.extensions.api.MinecartComparatorLogic MinecartComparatorLogic}
*/
@Deprecated
@FunctionalInterface
public interface MinecartComparatorLogic<T extends AbstractMinecartEntity> {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<EntityType<?>, MinecartComparatorLogic<?>> LOGICS = new IdentityHashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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<List<TradeOffers.Factory>> factories) {
TradeOfferInternals.registerVillagerOffers(profession, level, (trades, rebalanced) -> factories.accept(trades));
org.quiltmc.qsl.entity.extensions.api.TradeOfferHelper.registerVillagerOffers(profession, level, factories);
}

/**
Expand All @@ -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);
}

/**
Expand All @@ -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<List<TradeOffers.Factory>> factory) {
TradeOfferInternals.registerWanderingTraderOffers(level, factory);
org.quiltmc.qsl.entity.extensions.api.TradeOfferHelper.registerWanderingTraderOffers(level, factory);
}

/**
Expand All @@ -101,7 +104,21 @@ public static void registerWanderingTraderOffers(int level, Consumer<List<TradeO
*/
@ApiStatus.Experimental
public static synchronized void registerRebalancedWanderingTraderOffers(Consumer<WanderingTraderOffersBuilder> 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;
}
});
}));
}

/**
Expand All @@ -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<TradeOffers.Factory> factories, boolean rebalanced);
}

Expand All @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}.
*
* <p>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() {
}
Expand All @@ -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<BlockState> builder = ImmutableSet.builder();

for (Block block : blocks) {
builder.addAll(block.getStateManager().getStates());
}
RegistryKey<PointOfInterestType> 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);
}

/**
Expand All @@ -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<BlockState> blocks) {
final ImmutableSet.Builder<BlockState> builder = ImmutableSet.builder();

return register(id, ticketCount, searchDistance, builder.addAll(blocks).build());
}

// INTERNAL METHODS
RegistryKey<PointOfInterestType> key = org.quiltmc.qsl.entity.extensions.api.PointOfInterestHelper.register(id, ticketCount, searchDistance, blocks);

private static PointOfInterestType register(Identifier id, int ticketCount, int searchDistance, Set<BlockState> 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<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()) {
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<List<TradeOffers.Factory>> factory) {
registerOffers(TradeOffers.WANDERING_TRADER_TRADES, level, factory);
}

// Shared code to register offers for both villagers and wandering traders.
private static void registerOffers(Int2ObjectMap<TradeOffers.Factory[]> leveledTradeMap, int level, Consumer<List<TradeOffers.Factory>> factory) {
final List<TradeOffers.Factory> 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<Identifier> 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<Identifier, TradeOffers.Factory[]> 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<TradeOffers.Factory[], Integer> 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<TradeOffers.Factory[], Integer> 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;
}
}
}

This file was deleted.

Loading

0 comments on commit 06ca37e

Please sign in to comment.