Skip to content

Commit

Permalink
Add pool IDs
Browse files Browse the repository at this point in the history
  • Loading branch information
apple502j committed Sep 11, 2023
1 parent ac08e20 commit 3c32eec
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@

import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;

import org.jetbrains.annotations.ApiStatus;

import net.minecraft.util.Identifier;
import net.minecraft.village.TradeOffers;
import net.minecraft.village.VillagerProfession;

Expand Down Expand Up @@ -130,94 +132,104 @@ public interface VillagerOffersAdder {
@ApiStatus.Experimental
public interface WanderingTraderOffersBuilder {
/**
* The pool index for the "buy items" pool.
* The pool ID for the "buy items" pool.
* Two trade offers are picked from this pool.
*
* <p>In vanilla, this pool contains offers to buy water buckets, baked potatoes, etc.
* for emeralds.
*/
int BUY_ITEMS_POOL = 0;
Identifier BUY_ITEMS_POOL = new Identifier("minecraft", "buy_items");
/**
* The pool index for the "sell special items" pool.
* The pool ID for the "sell special items" pool.
* Two trade offers are picked from this pool.
*
* <p>In vanilla, this pool contains offers to sell logs, enchanted iron pickaxes, etc.
*/
int SELL_SPECIAL_ITEMS_POOL = 1;
Identifier SELL_SPECIAL_ITEMS_POOL = new Identifier("minecraft", "sell_special_items");
/**
* The pool index for the "sell common items" pool.
* The pool ID for the "sell common items" pool.
* Five trade offers are picked from this pool.
*
* <p>In vanilla, this pool contains offers to sell flowers, saplings, etc.
*/
int SELL_COMMON_ITEMS_POOL = 2;
Identifier SELL_COMMON_ITEMS_POOL = new Identifier("minecraft", "sell_common_items");

/**
* Adds a new pool to the offer list. Exactly {@code count} offers are picked from
* {@code factories} and offered to customers.
* @param id the ID to be assigned to this pool, to allow further modification
* @param count the number of offers to be picked from {@code factories}
* @param factories the trade offer factories
* @return this builder, for chaining
* @throws IllegalArgumentException if {@code count} is not positive or if {@code factories} is empty
*/
WanderingTraderOffersBuilder pool(int count, TradeOffers.Factory... factories);
WanderingTraderOffersBuilder pool(Identifier id, int count, TradeOffers.Factory... factories);

/**
* Adds a new pool to the offer list. Exactly {@code count} offers are picked from
* {@code factories} and offered to customers.
* @param id the ID to be assigned to this pool, to allow further modification
* @param count the number of offers to be picked from {@code factories}
* @param factories the trade offer factories
* @return this builder, for chaining
* @throws IllegalArgumentException if {@code count} is not positive or if {@code factories} is empty
*/
default WanderingTraderOffersBuilder pool(int count, Collection<? extends TradeOffers.Factory> factories) {
return pool(count, factories.toArray(TradeOffers.Factory[]::new));
default WanderingTraderOffersBuilder pool(Identifier id, int count, Collection<? extends TradeOffers.Factory> factories) {
return pool(id, count, factories.toArray(TradeOffers.Factory[]::new));
}

/**
* Adds trade offers to the offer list. All offers from {@code factories} are
* offered to each customer.
* @param id the ID to be assigned to this pool, to allow further modification
* @param factories the trade offer factories
* @return this builder, for chaining
* @throws IllegalArgumentException if {@code factories} is empty
*/
default WanderingTraderOffersBuilder addAll(Collection<? extends TradeOffers.Factory> factories) {
return pool(factories.size(), factories);
default WanderingTraderOffersBuilder addAll(Identifier id, Collection<? extends TradeOffers.Factory> factories) {
return pool(id, factories.size(), factories);
}

/**
* Adds trade offers to the offer list. All offers from {@code factories} are
* offered to each customer.
* @param id the ID to be assigned to this pool, to allow further modification
* @param factories the trade offer factories
* @return this builder, for chaining
* @throws IllegalArgumentException if {@code factories} is empty
*/
default WanderingTraderOffersBuilder addAll(TradeOffers.Factory... factories) {
return pool(factories.length, factories);
default WanderingTraderOffersBuilder addAll(Identifier id, TradeOffers.Factory... factories) {
return pool(id, factories.length, factories);
}

/**
* Adds trade offers to an existing pool.
* Adds trade offers to an existing pool identified by an ID.
*
* <p>See the constants for vanilla trade offer pool indices that are always available.
* @param poolIndex the pool index
* <p>See the constants for vanilla trade offer pool IDs that are always available.
* @param pool the pool ID
* @param factories the trade offer factories
* @return this builder, for chaining
* @throws IndexOutOfBoundsException if {@code poolIndex} is out of bounds
* @throws IndexOutOfBoundsException if {@code pool} is out of bounds
*/
WanderingTraderOffersBuilder addOffersToPool(int poolIndex, TradeOffers.Factory... factories);
WanderingTraderOffersBuilder addOffersToPool(Identifier pool, TradeOffers.Factory... factories);

/**
* Adds trade offers to an existing pool.
* Adds trade offers to an existing pool identified by an ID.
*
* <p>See the constants for vanilla trade offer pool indices that are always available.
* @param poolIndex the pool index
* <p>See the constants for vanilla trade offer pool IDs that are always available.
* @param pool the pool ID
* @param factories the trade offer factories
* @return this builder, for chaining
* @throws IndexOutOfBoundsException if {@code poolIndex} is out of bounds
* @throws IndexOutOfBoundsException if {@code pool} is out of bounds
*/
default WanderingTraderOffersBuilder addOffersToPool(int poolIndex, Collection<TradeOffers.Factory> factories) {
return addOffersToPool(poolIndex, factories.toArray(TradeOffers.Factory[]::new));
default WanderingTraderOffersBuilder addOffersToPool(Identifier pool, Collection<TradeOffers.Factory> factories) {
return addOffersToPool(pool, factories.toArray(TradeOffers.Factory[]::new));
}

/**
* Returns all registered pool IDs, including vanilla ones.
* @return an unmodifiable set containing all registered pool IDs
*/
Set<Identifier> getPoolIds();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,25 @@
package net.fabricmc.fabric.impl.object.builder;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
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;

Expand Down Expand Up @@ -88,6 +94,12 @@ public static void printRefreshOffersWarning() {
}

public static class WanderingTraderOffersBuilderImpl implements TradeOfferHelper.WanderingTraderOffersBuilder {
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);
});

/**
* Make the trade list modifiable.
*/
Expand All @@ -98,24 +110,35 @@ static void initWanderingTraderTrades() {
}

@Override
public TradeOfferHelper.WanderingTraderOffersBuilder pool(int count, TradeOffers.Factory... factories) {
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");
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);
return this;
}

@Override
public TradeOfferHelper.WanderingTraderOffersBuilder addOffersToPool(int poolIndex, TradeOffers.Factory... factories) {
Objects.checkIndex(poolIndex, TradeOffers.REBALANCED_WANDERING_TRADER_TRADES.size());
public TradeOfferHelper.WanderingTraderOffersBuilder addOffersToPool(Identifier pool, TradeOffers.Factory... factories) {
if (!ID_TO_INDEX.containsKey(pool)) {
throw new IllegalArgumentException("pool %s is not registered".formatted(pool));
}

int poolIndex = ID_TO_INDEX.getInt(pool);
initWanderingTraderTrades();
Pair<TradeOffers.Factory[], Integer> pool = TradeOffers.REBALANCED_WANDERING_TRADER_TRADES.get(poolIndex);
TradeOffers.Factory[] modified = ArrayUtils.addAll(pool.getLeft(), factories);
TradeOffers.REBALANCED_WANDERING_TRADER_TRADES.set(poolIndex, Pair.of(modified, pool.getRight()));
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;
}

@Override
public Set<Identifier> getPoolIds() {
return Collections.unmodifiableSet(ID_TO_INDEX.keySet());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import net.minecraft.item.Items;
import net.minecraft.registry.Registries;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.random.Random;
import net.minecraft.village.TradeOffer;
import net.minecraft.village.TradeOffers;
Expand All @@ -40,6 +41,9 @@
import net.fabricmc.fabric.api.object.builder.v1.trade.TradeOfferHelper;

public class VillagerTypeTest1 implements ModInitializer {
private static final Identifier FOOD_POOL_ID = ObjectBuilderTestConstants.id("food");
private static final Identifier THING_POOL_ID = ObjectBuilderTestConstants.id("thing");

@Override
public void onInitialize() {
TradeOfferHelper.registerVillagerOffers(VillagerProfession.ARMORER, 1, (factories, rebalanced) -> {
Expand All @@ -58,12 +62,14 @@ public void onInitialize() {

TradeOfferHelper.registerRebalancedWanderingTraderOffers(builder -> {
builder.pool(
1,
FOOD_POOL_ID,
5,
Registries.ITEM.stream().filter(item -> item.getFoodComponent() != null).map(
item -> new SimpleTradeFactory(new TradeOffer(new ItemStack(Items.NETHERITE_INGOT), new ItemStack(item), 3, 4, 0.15F))
).toList()
);
builder.addAll(
THING_POOL_ID,
new SimpleTradeFactory(new TradeOffer(new ItemStack(Items.NETHERITE_INGOT), new ItemStack(Items.MOJANG_BANNER_PATTERN), 1, 4, 0.15F))
);
builder.addOffersToPool(
Expand All @@ -78,6 +84,10 @@ public void onInitialize() {
new SimpleTradeFactory(new TradeOffer(new ItemStack(Items.DIAMOND, 16), new ItemStack(Items.ELYTRA, 1), 1, 4, 0.15F)),
new SimpleTradeFactory(new TradeOffer(new ItemStack(Items.EMERALD, 3), new ItemStack(Items.LEAD, 2), 3, 4, 0.15F))
);
builder.addOffersToPool(
FOOD_POOL_ID,
new SimpleTradeFactory(new TradeOffer(new ItemStack(Items.NETHERITE_INGOT), new ItemStack(Items.EGG), 3, 4, 0.15F))
);
});

CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
Expand Down

0 comments on commit 3c32eec

Please sign in to comment.