Trial clearing component predicates for merchant offers in 1.20.6+

This commit is contained in:
fullwall 2024-09-09 19:35:05 +08:00
parent fa4ea79606
commit d4fba3b549
5 changed files with 78 additions and 8 deletions

View File

@ -2,6 +2,7 @@ package net.citizensnpcs.trait;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Function;
@ -33,6 +34,7 @@ import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
@ -74,6 +76,7 @@ import net.citizensnpcs.trait.shop.PermissionAction;
import net.citizensnpcs.trait.shop.PermissionAction.PermissionActionGUI;
import net.citizensnpcs.trait.shop.StoredShops;
import net.citizensnpcs.util.InventoryMultiplexer;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
/**
@ -958,6 +961,7 @@ public class ShopTrait extends Trait {
this.shop = shop;
this.player = player;
Map<Integer, NPCShopItem> tradesMap = Maps.newHashMap();
Set<Integer> clearComponentPredicates = Sets.newHashSet();
Merchant merchant = Bukkit.createMerchant(shop.getTitle());
List<MerchantRecipe> recipes = Lists.newArrayList();
for (NPCShopPage page : shop.pages) {
@ -967,8 +971,12 @@ public class ShopTrait extends Trait {
continue;
MerchantRecipe recipe = new MerchantRecipe(result.clone(), 100000000);
for (NPCShopAction action : item.cost) {
if (action instanceof ItemAction) {
if (!(action instanceof ItemAction))
continue;
ItemAction ia = (ItemAction) action;
if (!ia.compareSimilarity && ia.items.size() > 0) {
clearComponentPredicates.add(recipes.size());
}
for (ItemStack stack : ia.items) {
stack = stack.clone();
recipe.addIngredient(stack);
@ -976,7 +984,6 @@ public class ShopTrait extends Trait {
break;
}
}
}
if (recipe.getIngredients().size() == 0)
continue;
tradesMap.put(recipes.size(), item);
@ -984,6 +991,7 @@ public class ShopTrait extends Trait {
}
}
merchant.setRecipes(recipes);
NMS.clearMerchantComponentPredicates(merchant, clearComponentPredicates);
trades = tradesMap;
view = player.openMerchant(merchant, true);
}

View File

@ -9,6 +9,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Function;
@ -36,6 +37,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Merchant;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.scoreboard.Team;
import org.bukkit.util.Vector;
@ -153,6 +155,10 @@ public class NMS {
BRIDGE.cancelMoveDestination(entity);
}
public static void clearMerchantComponentPredicates(Merchant merchant, Set<Integer> clearComponentPredicates) {
BRIDGE.clearMerchantComponentPredicates(merchant, clearComponentPredicates);
}
public static Iterable<Object> createBundlePacket(List<Object> packets) {
return BRIDGE.createBundlePacket(packets);
}

View File

@ -3,6 +3,7 @@ package net.citizensnpcs.util;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.function.Function;
@ -23,6 +24,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Merchant;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.scoreboard.Team;
import org.bukkit.util.Vector;
@ -63,6 +65,10 @@ public interface NMSBridge {
public void cancelMoveDestination(Entity entity);
public default void clearMerchantComponentPredicates(Merchant merchant, Set<Integer> clearComponentPredicates) {
// TODO: implement for <=1.19.4
}
public default Iterable<Object> createBundlePacket(List<Object> packets) {
return packets;
}

View File

@ -8,7 +8,9 @@ import java.util.Collections;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
@ -39,6 +41,7 @@ import org.bukkit.craftbukkit.v1_20_R4.event.CraftEventFactory;
import org.bukkit.craftbukkit.v1_20_R4.event.CraftPortalEvent;
import org.bukkit.craftbukkit.v1_20_R4.inventory.CraftInventoryAnvil;
import org.bukkit.craftbukkit.v1_20_R4.inventory.CraftInventoryView;
import org.bukkit.craftbukkit.v1_20_R4.inventory.CraftMerchant;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.FishHook;
import org.bukkit.entity.Player;
@ -46,6 +49,7 @@ import org.bukkit.entity.Tameable;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.Merchant;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.scoreboard.Team;
import org.bukkit.util.Vector;
@ -260,6 +264,7 @@ import net.citizensnpcs.util.PlayerAnimation;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponentPredicate;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.ByteArrayTag;
import net.minecraft.nbt.CompoundTag;
@ -356,6 +361,8 @@ import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.trading.ItemCost;
import net.minecraft.world.item.trading.MerchantOffer;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.dimension.end.EndDragonFight;
@ -496,6 +503,24 @@ public class NMSImpl implements NMSBridge {
}
}
@Override
public void clearMerchantComponentPredicates(Merchant merchant, Set<Integer> clearComponentPredicates) {
net.minecraft.world.item.trading.Merchant handle = ((CraftMerchant) merchant).getMerchant();
ListIterator<MerchantOffer> itr = handle.getOffers().listIterator();
for (int i = 0; itr.hasNext(); i++) {
if (!clearComponentPredicates.contains(i))
continue;
MerchantOffer offer = itr.next();
offer.baseCostA = new ItemCost(offer.baseCostA.item(), offer.baseCostA.count(),
DataComponentPredicate.EMPTY, offer.baseCostA.itemStack());
ItemCost costB = offer.getItemCostB().orElseGet(() -> null);
if (costB != null) {
offer.costB = Optional
.of(new ItemCost(costB.item(), costB.count(), DataComponentPredicate.EMPTY, costB.itemStack()));
}
}
}
@Override
@SuppressWarnings("rawtypes")
public Iterable<Object> createBundlePacket(List source) {

View File

@ -8,7 +8,9 @@ import java.util.Collections;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
@ -37,6 +39,7 @@ import org.bukkit.craftbukkit.v1_21_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_21_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_21_R1.event.CraftEventFactory;
import org.bukkit.craftbukkit.v1_21_R1.inventory.CraftInventoryAnvil;
import org.bukkit.craftbukkit.v1_21_R1.inventory.CraftMerchant;
import org.bukkit.craftbukkit.v1_21_R1.inventory.view.CraftAnvilView;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.FishHook;
@ -46,6 +49,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.event.entity.EntityKnockbackEvent.KnockbackCause;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.Merchant;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.scoreboard.Team;
import org.bukkit.util.Vector;
@ -260,6 +264,7 @@ import net.citizensnpcs.util.PlayerAnimation;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponentPredicate;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.ByteArrayTag;
import net.minecraft.nbt.CompoundTag;
@ -356,6 +361,8 @@ import net.minecraft.world.inventory.ContainerLevelAccess;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.trading.ItemCost;
import net.minecraft.world.item.trading.MerchantOffer;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.dimension.end.EndDragonFight;
@ -476,6 +483,24 @@ public class NMSImpl implements NMSBridge {
}
}
@Override
public void clearMerchantComponentPredicates(Merchant merchant, Set<Integer> clearComponentPredicates) {
net.minecraft.world.item.trading.Merchant handle = ((CraftMerchant) merchant).getMerchant();
ListIterator<MerchantOffer> itr = handle.getOffers().listIterator();
for (int i = 0; itr.hasNext(); i++) {
if (!clearComponentPredicates.contains(i))
continue;
MerchantOffer offer = itr.next();
offer.baseCostA = new ItemCost(offer.baseCostA.item(), offer.baseCostA.count(),
DataComponentPredicate.EMPTY, offer.baseCostA.itemStack());
ItemCost costB = offer.getItemCostB().orElseGet(() -> null);
if (costB != null) {
offer.costB = Optional
.of(new ItemCost(costB.item(), costB.count(), DataComponentPredicate.EMPTY, costB.itemStack()));
}
}
}
@Override
@SuppressWarnings("rawtypes")
public Iterable<Object> createBundlePacket(List source) {