MinusKube / SmartInvs

Advanced Inventory API for your Minecraft Bukkit plugins.
https://minuskube.gitbook.io/smartinvs/
Apache License 2.0
262 stars 65 forks source link

If the held item is the same as an item in the player's inventory, its name and lore will be changed to match that item. #218

Closed MichealAPI closed 1 year ago

MichealAPI commented 1 year ago

I'm currently creating a plugin that allows players to sell items to a shop. During testing, I noticed that if a player sells a "Pickaxe" (or any other item defined in the configuration using the "getShopItems" method) and then picks up an identical pickaxe, both items will have their display name and lore changed to match the shop's configuration.


@RequiredArgsConstructor
public class GenericShop implements InventoryProvider {

    private final Shop type;
    @Setter
    private SmartInventory inventory;

    public static SmartInventory getGenericShopInventory(Shop type) {
        GenericShop provider = new GenericShop(type);
        SmartInventory inventory =  SmartInventory.builder()
                .id("genericShopInventory")
                .provider(provider)
                .size(6, 9)
                .manager(instance.getInventoryManager())
                .title(Translatable.translate(Shop.getShopTitleValueOf(type)))
                .build();
        provider.setInventory(inventory);
        return inventory;
    }

    @Override
    public void init(Player player, InventoryContents contents) {
        Pagination pagination = contents.pagination();

        PositionalMap<String, ShopElement> items = ShopUtil.getShopItems(type, true);
        ClickableItem[] clickableItems = new ClickableItem[items.size()];

        for(int i = 0; i < clickableItems.length; i++) {
            int finalPosition = i;
            clickableItems[i] = ClickableItem.of(items.getByPosition(i).getItemStack(), e -> {
                player.closeInventory();
                String id = items.getByPosition(finalPosition).getId();
                player.sendMessage("Clicked on " + id);
            });
        }

        pagination.setItems(clickableItems);
        pagination.setItemsPerPage(7);

        pagination.addToIterator(contents.newIterator(SlotIterator.Type.HORIZONTAL, 1, 1));

        contents.fillBorders(ClickableItem.empty(Commons.getFiller()));
        contents.set(6, 3, ClickableItem.of(new ItemStack(Material.REDSTONE),
                e -> inventory.open(player, pagination.previous().getPage())));
        contents.set(6, 5, ClickableItem.of(new ItemStack(Material.ARROW),
                e -> inventory.open(player, pagination.next().getPage())));
    }

    @Override
    public void update(Player player, InventoryContents contents) {}
}
    public static PositionalMap<String, ShopElement> getShopItems(Shop type, boolean showPrice) {
        FileConfiguration config = instance.getConfigInitializer().getShopConfig();
        PositionalMap<String, ShopElement> shopItems = new PositionalMap<>();

        String shopSection = type.name().toLowerCase();

        if(!config.isConfigurationSection(shopSection)) return shopItems;

        for (String id : config.getConfigurationSection(shopSection).getKeys(false)) {
            ItemStack stack = items.containsKey(id) ? items.get(id).getItemStack() : config.getItemStack(shopSection + "." + id + ".item");

            stack.editMeta(meta -> {
                Component displayName = meta.displayName();
                if(displayName == null) {
                    displayName = Translatable.translate("<gray>(" + id + ")</gray>");
                } else displayName = displayName.append(Translatable.translate("<gray>(" + id + ")</gray>"));
                meta.displayName(displayName);
            });

            Price price = Price.deserializePrice(config.getConfigurationSection(shopSection + "." + id));

            Sy
![javaw_Yv17boHRWX](https://user-images.githubusercontent.com/114824776/222236610-6a3a2431-fa3d-4344-9629-d1af88e090db.gif)
stem.out.println(id + " " + price.getPrice().keySet());
            shopItems.put(id, new ShopElement(id, !showPrice ? stack : addPrice(price, stack), price));
        }

        return shopItems;
    }

javaw_Yv17boHRWX

Janisbtw commented 1 year ago

I assume you use Player#getItemInHand or some other variance of it. What that does, is it gives you a reference to the actual item which is still held in the hand, so whenever it's added to another inventory, it's still the same ItemStack. To prevent that you can create a completely new ItemStack with just the properties of the one in the player's hand.

MichealAPI commented 1 year ago

ItemStack#clone worked as expected. Solved