Jump to content

[1.16.5] Capabilities attached to ItemStacks continuously trigger writeNBT


Phi

Recommended Posts

Hello, I've been trying to attach a capability to an ItemStack, but while the capability itself attaches fine, any data I write to it is reset to 0 at one point or another. Really the only possible cause that I've been able to find for this is with a Logger in the writeNBT function of the capability class, which shows that it will just continuously call this function while the capability persists.

I've attached the same capability to an Entity instead, which works fine, and I've attached a different previously working capability to an ItemStack which produces the same problem as described above. 

The attach event code (same code with different types of items also produces the problem) :

@SubscribeEvent
public static void onItemAttachCapabilitiesEvent(AttachCapabilitiesEvent<ItemStack> event) {
  if (event.getObject().getItem() instanceof PotionItem) {
    PotionChargesProvider provider = new PotionChargesProvider();
    event.addCapability(new ResourceLocation(VanillaSpice.MOD_ID, "potioncharges"), provider);
    event.addListener(provider::invalidate);
  }
}

The capability class:

public class CapabilityPotionCharges {

    private static final Logger LOGGER = LogManager.getLogger();

    @CapabilityInject(IPotionCharges.class)
    public static Capability<IPotionCharges> POTION_CHARGES_CAPABILITY = null;

    public static void register() {
        CapabilityManager.INSTANCE.register(IPotionCharges.class, new Storage(), DefaultPotionCharges::new);
    }

    private static class Storage implements Capability.IStorage<IPotionCharges> {

        @Nullable
        @Override
        public INBT writeNBT(Capability<IPotionCharges> capability, IPotionCharges instance, Direction side) {
            LOGGER.info("potion writeNBT");
            CompoundNBT tag = new CompoundNBT();
            tag.putInt("charges", instance.getCharges());
            return tag;
        }

        @Override
        public void readNBT(Capability<IPotionCharges> capability, IPotionCharges instance, Direction side, INBT nbt) {
            LOGGER.info("potion readNBT");
            int charges = ((CompoundNBT) nbt).getInt("charges");
            instance.setCharges(charges);
        }

    }

}

The provider class:

public class PotionChargesProvider implements ICapabilitySerializable<CompoundNBT> {

    private final DefaultPotionCharges potionCharges = new DefaultPotionCharges();
    private final LazyOptional<IPotionCharges> potionChargesOptional = LazyOptional.of(() -> potionCharges);

    public void invalidate() { potionChargesOptional.invalidate(); }

    @Nonnull
    @Override
    public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
        return potionChargesOptional.cast();
    }

    @Override
    public CompoundNBT serializeNBT() {
        if (CapabilityPotionCharges.POTION_CHARGES_CAPABILITY == null) {
            return new CompoundNBT();
        } else {
            return (CompoundNBT) CapabilityPotionCharges.POTION_CHARGES_CAPABILITY.writeNBT(potionCharges, null);
        }
    }

    @Override
    public void deserializeNBT(CompoundNBT nbt) {
        if (CapabilityPotionCharges.POTION_CHARGES_CAPABILITY != null) {
            CapabilityPotionCharges.POTION_CHARGES_CAPABILITY.readNBT(potionCharges, null, nbt);
        }
    }

}

The default capability class is just a getter and a setter for a private int.

I'm really hoping there's just something stupid I'm forgetting about ItemStacks, been trying to figure this one out for way too long now.

latest.log

Edited by Phi
Link to comment
Share on other sites

Whenever a player removes a potion from a brewing stand it sets the charges on that potion to 3 (currently also has an xp check on it). Then in LivingEntityUseItemEvent.Start/Finish (I tested both to be sure) it checks the charges, at which point they show as 0.

Link to comment
Share on other sites

Alright, I have identified the problem. First of all I simplified the code to just add an nbt tag to the potion instead of a whole capability. The system now looks like this:

    @SubscribeEvent
    public static void onPlayerBrewPotionEvent(PlayerBrewedPotionEvent event) {
        PlayerEntity player = event.getPlayer();
        ItemStack stack = event.getStack();
        if (!player.level.isClientSide()) {            
            CompoundNBT tag = stack.getTag();
            if (tag == null) { tag = new CompoundNBT(); }
            tag.putInt("vs_charges", 3);
            LOGGER.info(tag.getInt("vs_charges"));
            stack.setTag(tag);
        }
    }

    @SubscribeEvent
    public static void onItemUseFinishEvent(LivingEntityUseItemEvent.Finish event) {
        ItemStack stack = event.getItem();
        LivingEntity entity = event.getEntityLiving();

        if (entity instanceof PlayerEntity && !entity.level.isClientSide()) {
            PlayerEntity player = (PlayerEntity) entity;

            if (stack.getItem() instanceof PotionItem) {
                CompoundNBT tag = stack.getTag();
                int charges = 0;
                if (tag != null) { charges = tag.getInt("vs_charges"); }
                LOGGER.info(charges);
                if (charges > 0) {
                    tag.putInt("vs_charges", charges - 1);
                    stack.setTag(tag);
                    event.setResultStack(stack);
                }
            }
        }
    }

Initially, this had the same problem as before, where on drinking a potion the charges would read 0 again. However it seems that this is only the case when shift-clicking the potion from the brewing stand. If picked up with just a left click, the charges are saved properly and everything works as it should. The shift-clicking problem doesn't extend to any other containers, i.e. if I pick up a potion from a brewing stand and then shift-click it into a chest and back out, it still works properly.

I guess this means I'm looking for a way to detect a shift-click in a brewing stand to save the data elsewhere, and then restore it later?

Edited by Phi
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Selamat datang di OLXTOTO, situs slot gacor terpanas yang sedang booming di industri perjudian online. Jika Anda mencari pengalaman bermain yang luar biasa, maka OLXTOTO adalah tempat yang tepat untuk Anda. Dapatkan sensasi tidak biasa dengan variasi slot online terlengkap dan peluang memenangkan jackpot slot maxwin yang sering. Di sini, Anda akan merasakan keseruan yang luar biasa dalam bermain judi slot. DAFTAR OLXTOTO DISINI LOGIN OLXTOTO DISINI AKUN PRO OLXTOTO DISINI   Slot Gacor untuk Sensasi Bermain Maksimal Olahraga cepat dan seru dengan slot gacor di OLXTOTO. Rasakan sensasi bermain maksimal dengan mesin slot yang memberikan kemenangan beruntun. Temukan keberuntungan Anda di antara berbagai pilihan slot gacor yang tersedia dan rasakan kegembiraan bermain judi slot yang tak terlupakan. Situs Slot Terpercaya dengan Pilihan Terlengkap OLXTOTO adalah situs slot terpercaya yang menawarkan pilihan terlengkap dalam perjudian online. Nikmati berbagai genre dan tema slot online yang menarik, dari slot klasik hingga slot video yang inovatif. Dipercaya oleh jutaan pemain, OLXTOTO memberikan pengalaman bermain yang aman dan terjamin.   Jackpot Slot Maxwin Sering Untuk Peluang Besar Di OLXTOTO, kami tidak hanya memberikan hadiah slot biasa, tapi juga memberikan kesempatan kepada pemain untuk memenangkan jackpot slot maxwin yang sering. Dengan demikian, Anda dapat meraih keberuntungan besar dan memenangkan ribuan rupiah sebagai hadiah jackpot slot maxwin kami. Jackpot slot maxwin merupakan peluang besar bagi para pemain judi slot untuk meraih keuntungan yang lebih besar. Dalam permainan kami, Anda tidak harus terpaku pada kemenangan biasa saja. Kami hadir dengan jackpot slot maxwin yang sering, sehingga Anda memiliki peluang yang lebih besar untuk meraih kemenangan besar dengan hadiah yang menggiurkan. Dalam permainan judi slot, pengalaman bermain bukan hanya tentang keseruan dan hiburan semata. Kami memahami bahwa para pemain juga menginginkan kesempatan untuk meraih keberuntungan besar. Oleh karena itu, OLXTOTO hadir dengan jackpot slot maxwin yang sering untuk memberikan peluang besar kepada para pemain kami. Peluang Besar Menang Jackpot Slot Maxwin Peluang menang jackpot slot maxwin di OLXTOTO sangatlah besar. Anda tidak perlu khawatir tentang batasan atau pembatasan dalam meraih jackpot tersebut. Kami ingin memberikan kesempatan kepada semua pemain kami untuk merasakan sensasi menang dalam jumlah yang luar biasa. Jackpot slot maxwin kami dibuka untuk semua pemain judi slot di OLXTOTO. Anda memiliki peluang yang sama dengan pemain lainnya untuk memenangkan hadiah jackpot yang besar. Kami percaya bahwa semua orang memiliki kesempatan untuk meraih keberuntungan besar, dan itulah mengapa kami menyediakan jackpot slot maxwin yang sering untuk memenuhi harapan dan keinginan Anda.  
    • LOGIN DAN DAFTAR DISINI SEKARANG !!!! Blacktogel adalah situs judi slot online yang menjadi pilihan banyak penggemar judi slot gacor di Indonesia. Dengan platform yang sangat user-friendly dan berbagai macam permainan slot yang tersedia, Blacktogel menjadi tempat yang tepat untuk penggemar judi slot online. Dalam artikel ini, kami akan membahas tentang Blacktogel dan keunggulan situs slot gacor online yang disediakan.  
    • Situs bandar slot online Gacor dengan bonus terbesar saat ini sedang menjadi sorotan para pemain judi online. Dengan persaingan yang semakin ketat dalam industri perjudian online, pemain mencari situs yang tidak hanya menawarkan permainan slot yang gacor (sering memberikan kemenangan), tetapi juga bonus terbesar yang bisa meningkatkan peluang menang. Daftar disini : https://gesit.io/googlegopek
    • Situs bandar slot online Gacor dengan bonus terbesar saat ini sedang menjadi sorotan para pemain judi online. Dengan persaingan yang semakin ketat dalam industri perjudian online, pemain mencari situs yang tidak hanya menawarkan permainan slot yang gacor (sering memberikan kemenangan), tetapi juga bonus terbesar yang bisa meningkatkan peluang menang. Daftar disini : https://gesit.io/googlegopek
    • Situs bandar slot online Gacor dengan bonus terbesar saat ini sedang menjadi sorotan para pemain judi online. Dengan persaingan yang semakin ketat dalam industri perjudian online, pemain mencari situs yang tidak hanya menawarkan permainan slot yang gacor (sering memberikan kemenangan), tetapi juga bonus terbesar yang bisa meningkatkan peluang menang. Daftar disini : https://gesit.io/googlegopek
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.