Skip to content

Commit 68755cb

Browse files
committed
Add support for adding new villager trade options.
1 parent 2ae9c2d commit 68755cb

File tree

6 files changed

+197
-0
lines changed

6 files changed

+197
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package net.darkhax.bookshelf.api.entity.merchant;
2+
3+
public enum MerchantTier {
4+
5+
NOVICE(0),
6+
APPRENTICE(10),
7+
JOURNEYMAN(70),
8+
EXPERT(150),
9+
MASTER(250);
10+
11+
private final int requiredExp;
12+
13+
MerchantTier(int requiredExp) {
14+
15+
this.requiredExp = requiredExp;
16+
}
17+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package net.darkhax.bookshelf.api.entity.merchant.trade;
2+
3+
import net.minecraft.world.entity.Entity;
4+
import net.minecraft.world.entity.npc.VillagerTrades;
5+
import net.minecraft.world.item.ItemStack;
6+
import net.minecraft.world.item.Items;
7+
import net.minecraft.world.item.trading.MerchantOffer;
8+
import net.minecraft.world.level.ItemLike;
9+
10+
import java.util.Random;
11+
import java.util.function.Supplier;
12+
13+
public class VillagerBuys implements VillagerTrades.ItemListing {
14+
15+
private final Supplier<ItemStack> stackToBuy;
16+
private final int emeraldCost;
17+
private final int maxUses;
18+
private final int villagerXp;
19+
private final float priceMultiplier;
20+
21+
public VillagerBuys(ItemLike item, int emeraldCost, int maxUses, int villagerXp, float priceMultiplier) {
22+
23+
this(item.asItem().getDefaultInstance(), emeraldCost, maxUses, villagerXp, priceMultiplier);
24+
}
25+
26+
public VillagerBuys(ItemStack stackToBuy, int emeraldCost, int maxUses, int villagerXp, float priceMultiplier) {
27+
28+
this(stackToBuy::copy, emeraldCost, maxUses, villagerXp, priceMultiplier);
29+
}
30+
31+
public VillagerBuys(Supplier<ItemStack> stackToBuy, int emeraldCost, int maxUses, int villagerXp, float priceMultiplier) {
32+
33+
this.stackToBuy = stackToBuy;
34+
this.emeraldCost = emeraldCost;
35+
this.maxUses = maxUses;
36+
this.villagerXp = villagerXp;
37+
this.priceMultiplier = priceMultiplier;
38+
}
39+
40+
public MerchantOffer getOffer(Entity entity, Random random) {
41+
42+
return new MerchantOffer(this.stackToBuy.get(), new ItemStack(Items.EMERALD, this.emeraldCost), this.maxUses, this.villagerXp, this.priceMultiplier);
43+
}
44+
}

Common/src/main/java/net/darkhax/bookshelf/api/registry/RegistryHelper.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public abstract class RegistryHelper {
2929
public final IRegistryEntries<PreparableReloadListener> clientReloadListeners;
3030

3131
public final IRegistryEntries<ICommandBuilder> commands;
32+
public final VillagerTradeEntries trades;
3233

3334
protected RegistryHelper(String ownerId) {
3435

@@ -46,6 +47,7 @@ protected RegistryHelper(String ownerId) {
4647
this.clientReloadListeners = new RegistryEntries<>(ownerId);
4748

4849
this.commands = new RegistryEntries<>(ownerId);
50+
this.trades = new VillagerTradeEntries();
4951
}
5052

5153
public RegistryHelper withCreativeTab(CreativeModeTab tab) {
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package net.darkhax.bookshelf.api.registry;
2+
3+
import com.google.common.collect.ArrayListMultimap;
4+
import com.google.common.collect.Multimap;
5+
import net.darkhax.bookshelf.api.entity.merchant.MerchantTier;
6+
import net.minecraft.world.entity.npc.VillagerProfession;
7+
import net.minecraft.world.entity.npc.VillagerTrades;
8+
9+
import java.util.ArrayList;
10+
import java.util.HashMap;
11+
import java.util.List;
12+
import java.util.Map;
13+
14+
public class VillagerTradeEntries {
15+
16+
private final Map<VillagerProfession, Multimap<Integer, VillagerTrades.ItemListing>> villagerTrades = new HashMap<>();
17+
private final List<VillagerTrades.ItemListing> rareTrades = new ArrayList<>();
18+
private final List<VillagerTrades.ItemListing> commonTrades = new ArrayList<>();
19+
20+
public void addTrade(VillagerProfession profession, int tier, VillagerTrades.ItemListing trade) {
21+
22+
villagerTrades.computeIfAbsent(profession, p -> ArrayListMultimap.create()).put(tier, trade);
23+
}
24+
25+
public void addTrade(VillagerProfession profession, MerchantTier tier, VillagerTrades.ItemListing trade) {
26+
27+
this.addTrade(profession, tier.ordinal() + 1, trade);
28+
}
29+
30+
public void addWanderingTrade(VillagerTrades.ItemListing trade, boolean isRare) {
31+
32+
(isRare ? rareTrades : commonTrades).add(trade);
33+
}
34+
35+
public void addRareWanderingTrade(VillagerTrades.ItemListing trade) {
36+
37+
this.addWanderingTrade(trade, true);
38+
}
39+
40+
public void addCommonWanderingTrade(VillagerTrades.ItemListing trade) {
41+
42+
this.addWanderingTrade(trade, false);
43+
}
44+
45+
public Map<VillagerProfession, Multimap<Integer, VillagerTrades.ItemListing>> getVillagerTrades() {
46+
47+
return this.villagerTrades;
48+
}
49+
50+
public List<VillagerTrades.ItemListing> getRareWanderingTrades() {
51+
52+
return this.rareTrades;
53+
}
54+
55+
public List<VillagerTrades.ItemListing> getCommonWanderingTrades() {
56+
57+
return this.commonTrades;
58+
}
59+
}

Fabric/src/main/java/net/darkhax/bookshelf/impl/registry/RegistryHelperFabric.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package net.darkhax.bookshelf.impl.registry;
22

3+
import com.google.common.collect.Multimap;
34
import com.mojang.brigadier.CommandDispatcher;
5+
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
6+
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
47
import net.darkhax.bookshelf.api.Services;
58
import net.darkhax.bookshelf.api.item.ICreativeTabBuilder;
69
import net.darkhax.bookshelf.api.registry.IRegistryEntries;
@@ -13,6 +16,13 @@
1316
import net.minecraft.core.Registry;
1417
import net.minecraft.resources.ResourceLocation;
1518
import net.minecraft.server.packs.PackType;
19+
import net.minecraft.world.entity.npc.VillagerProfession;
20+
import net.minecraft.world.entity.npc.VillagerTrades;
21+
22+
import java.util.ArrayList;
23+
import java.util.Arrays;
24+
import java.util.List;
25+
import java.util.Map;
1626

1727
public class RegistryHelperFabric extends RegistryHelper {
1828

@@ -46,6 +56,40 @@ public void init() {
4656
}
4757

4858
CommandRegistrationCallback.EVENT.register(this::buildCommands);
59+
this.registerTradeData();
60+
this.registerWanderingTrades();
61+
}
62+
63+
private void registerTradeData() {
64+
65+
for (Map.Entry<VillagerProfession, Multimap<Integer, VillagerTrades.ItemListing>> professionData : this.trades.getVillagerTrades().entrySet()) {
66+
67+
final Int2ObjectMap<VillagerTrades.ItemListing[]> professionTrades = VillagerTrades.TRADES.computeIfAbsent(professionData.getKey(), profession -> new Int2ObjectOpenHashMap<>());
68+
69+
for (int merchantTier : professionData.getValue().keySet()) {
70+
71+
final List<VillagerTrades.ItemListing> tradesForTier = new ArrayList<>(Arrays.asList(professionTrades.getOrDefault(merchantTier, new VillagerTrades.ItemListing[0])));
72+
tradesForTier.addAll(professionData.getValue().get(merchantTier));
73+
professionTrades.put(merchantTier, tradesForTier.toArray(new VillagerTrades.ItemListing[0]));
74+
}
75+
}
76+
}
77+
78+
private void registerWanderingTrades() {
79+
80+
if (!this.trades.getCommonWanderingTrades().isEmpty()) {
81+
82+
final List<VillagerTrades.ItemListing> tradeData = new ArrayList<>(Arrays.asList(VillagerTrades.WANDERING_TRADER_TRADES.get(1)));
83+
tradeData.addAll(this.trades.getCommonWanderingTrades());
84+
VillagerTrades.WANDERING_TRADER_TRADES.put(1, tradeData.toArray(new VillagerTrades.ItemListing[0]));
85+
}
86+
87+
if (!this.trades.getRareWanderingTrades().isEmpty()) {
88+
89+
final List<VillagerTrades.ItemListing> tradeData = new ArrayList<>(Arrays.asList(VillagerTrades.WANDERING_TRADER_TRADES.get(2)));
90+
tradeData.addAll(this.trades.getRareWanderingTrades());
91+
VillagerTrades.WANDERING_TRADER_TRADES.put(2, tradeData.toArray(new VillagerTrades.ItemListing[0]));
92+
}
4993
}
5094

5195
private void buildCommands(CommandDispatcher<CommandSourceStack> dispatcher, boolean isDedicated) {

Forge/src/main/java/net/darkhax/bookshelf/impl/registry/RegistryHelperForge.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package net.darkhax.bookshelf.impl.registry;
22

3+
import com.google.common.collect.Multimap;
34
import com.mojang.brigadier.CommandDispatcher;
5+
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
46
import net.darkhax.bookshelf.api.item.ICreativeTabBuilder;
57
import net.darkhax.bookshelf.api.registry.IRegistryEntries;
68
import net.darkhax.bookshelf.api.registry.RegistryHelper;
@@ -12,6 +14,7 @@
1214
import net.minecraft.world.entity.ai.attributes.Attribute;
1315
import net.minecraft.world.entity.decoration.Motive;
1416
import net.minecraft.world.entity.npc.VillagerProfession;
17+
import net.minecraft.world.entity.npc.VillagerTrades;
1518
import net.minecraft.world.item.Item;
1619
import net.minecraft.world.item.enchantment.Enchantment;
1720
import net.minecraft.world.level.block.Block;
@@ -20,11 +23,16 @@
2023
import net.minecraftforge.event.AddReloadListenerEvent;
2124
import net.minecraftforge.event.RegisterCommandsEvent;
2225
import net.minecraftforge.event.RegistryEvent;
26+
import net.minecraftforge.event.village.VillagerTradesEvent;
27+
import net.minecraftforge.event.village.WandererTradesEvent;
2328
import net.minecraftforge.eventbus.api.Event;
2429
import net.minecraftforge.eventbus.api.EventPriority;
2530
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
2631
import net.minecraftforge.registries.IForgeRegistryEntry;
2732

33+
import java.util.ArrayList;
34+
import java.util.List;
35+
import java.util.Map;
2836
import java.util.function.Consumer;
2937

3038
public class RegistryHelperForge extends RegistryHelper {
@@ -55,6 +63,29 @@ public void init() {
5563
consumeWithEvent(AddReloadListenerEvent.class, this.serverReloadListeners, e -> this.serverReloadListeners.getEntries().values().forEach(e::addListener));
5664

5765
MinecraftForge.EVENT_BUS.addListener(this::buildCommands);
66+
MinecraftForge.EVENT_BUS.addListener(this::registerVillagerTrades);
67+
MinecraftForge.EVENT_BUS.addListener(this::registerWanderingTrades);
68+
}
69+
70+
private void registerVillagerTrades(VillagerTradesEvent event) {
71+
72+
final Multimap<Integer, VillagerTrades.ItemListing> newTrades = this.trades.getVillagerTrades().get(event.getType());
73+
74+
if (newTrades != null) {
75+
76+
final Int2ObjectMap<List<VillagerTrades.ItemListing>> tradeData = event.getTrades();
77+
78+
for (Map.Entry<Integer, VillagerTrades.ItemListing> entry : newTrades.entries()) {
79+
80+
tradeData.computeIfAbsent(entry.getKey(), ArrayList::new).add(entry.getValue());
81+
}
82+
}
83+
}
84+
85+
private void registerWanderingTrades(WandererTradesEvent event) {
86+
87+
event.getGenericTrades().addAll(this.trades.getCommonWanderingTrades());
88+
event.getRareTrades().addAll(this.trades.getRareWanderingTrades());
5889
}
5990

6091
private void buildCommands(RegisterCommandsEvent event) {

0 commit comments

Comments
 (0)