Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[1.16.5] Capabilities attached to ItemStacks continuously trigger writeNBT


Phi
 Share

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

Because I didn't know there were other ways to do it up to just now 😛 

As for the xp, the code should run fine without the check, but else it's just setAlchemyTier(1 or higher) on the playerStats capability on the player

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
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.

 Share



  • Recently Browsing

    No registered users viewing this page.

  • Posts

    • I created a particle using  public class NukeParticle extends BasicParticleType implements IParticleData { public NukeParticle(boolean alwaysShow) { super(alwaysShow); } @Override public BasicParticleType getType() { return ParticleTypes.LARGE_SMOKE; } @Override public String getParameters() { return ParticleTypes.LARGE_SMOKE.getParameters(); } } and when I register it using  public class ParticlesReg { public static final RegistryObject<NukeParticle> YELLOW_PART = Regist.PARTICLES.register("yellow_particle", ()-> new NukeParticle(true)); public static void Register() { } } it just seems to crash anyone got an idea to what is going on the crash log is  ---- Minecraft Crash Report ---- // Shall we play a game? Time: 12/3/21 4:19 PM Description: Rendering overlay java.lang.IllegalStateException: Redundant texture list for particle lndfmod:yellow_particle at net.minecraft.client.particle.ParticleManager.loadTextureLists(ParticleManager.java:217) ~[forge:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A} at net.minecraft.client.particle.ParticleManager.lambda$null$0(ParticleManager.java:169) ~[forge:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A} at java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1640) ~[?:1.8.0_311] {} at java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1632) ~[?:1.8.0_311] {} at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) ~[?:1.8.0_311] {} at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1067) ~[?:1.8.0_311] {} at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1703) ~[?:1.8.0_311] {} at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:172) ~[?:1.8.0_311] {} A detailed walkthrough of the error, its code path and all known details is as follows: --------------------------------------------------------------------------------------- -- Head -- Thread: Render thread Stacktrace: at net.minecraft.client.renderer.GameRenderer.updateCameraAndRender(GameRenderer.java:495) ~[forge:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A} -- Overlay render details -- Details: Overlay name: net.minecraft.client.gui.ResourceLoadProgressGui Stacktrace: at net.minecraft.client.renderer.GameRenderer.updateCameraAndRender(GameRenderer.java:495) ~[forge-1.16.4-35.1.37_mapped_snapshot_20201028-1.16.3-recomp.jar:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A} at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1002) ~[forge-1.16.4-35.1.37_mapped_snapshot_20201028-1.16.3-recomp.jar:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A} at net.minecraft.client.Minecraft.run(Minecraft.java:612) ~[forge-1.16.4-35.1.37_mapped_snapshot_20201028-1.16.3-recomp.jar:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A} at net.minecraft.client.main.Main.main(Main.java:184) ~[forge-1.16.4-35.1.37_mapped_snapshot_20201028-1.16.3-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A} at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_311] {} at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_311] {} at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_311] {} at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_311] {} at net.minecraftforge.userdev.FMLUserdevClientLaunchProvider.lambda$launchService$0(FMLUserdevClientLaunchProvider.java:52) ~[forge-1.16.4-35.1.37_mapped_snapshot_20201028-1.16.3-recomp.jar:?] {} at cpw.mods.modlauncher.LaunchServiceHandlerDecorator.launch(LaunchServiceHandlerDecorator.java:37) [modlauncher-8.0.9.jar:?] {} at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:54) [modlauncher-8.0.9.jar:?] {} at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:72) [modlauncher-8.0.9.jar:?] {} at cpw.mods.modlauncher.Launcher.run(Launcher.java:82) [modlauncher-8.0.9.jar:?] {} at cpw.mods.modlauncher.Launcher.main(Launcher.java:66) [modlauncher-8.0.9.jar:?] {} at net.minecraftforge.userdev.LaunchTesting.main(LaunchTesting.java:105) [forge-1.16.4-35.1.37_mapped_snapshot_20201028-1.16.3-recomp.jar:?] {} -- System Details -- Details: Minecraft Version: 1.16.4 Minecraft Version ID: 1.16.4 Operating System: Windows 10 (amd64) version 10.0 Java Version: 1.8.0_311, Oracle Corporation Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation Memory: 1848128352 bytes (1762 MB) / 3042443264 bytes (2901 MB) up to 7622623232 bytes (7269 MB) CPUs: 12 JVM Flags: 1 total; -XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump ModLauncher: 8.0.9+86+master.3cf110c ModLauncher launch target: fmluserdevclient ModLauncher naming: mcp ModLauncher services: /mixin-0.8.2.jar mixin PLUGINSERVICE /eventbus-4.0.0.jar eventbus PLUGINSERVICE /forge-1.16.4-35.1.37_mapped_snapshot_20201028-1.16.3-launcher.jar object_holder_definalize PLUGINSERVICE /forge-1.16.4-35.1.37_mapped_snapshot_20201028-1.16.3-launcher.jar runtime_enum_extender PLUGINSERVICE /accesstransformers-3.0.1.jar accesstransformer PLUGINSERVICE /forge-1.16.4-35.1.37_mapped_snapshot_20201028-1.16.3-launcher.jar capability_inject_definalize PLUGINSERVICE /forge-1.16.4-35.1.37_mapped_snapshot_20201028-1.16.3-launcher.jar runtimedistcleaner PLUGINSERVICE /mixin-0.8.2.jar mixin TRANSFORMATIONSERVICE /forge-1.16.4-35.1.37_mapped_snapshot_20201028-1.16.3-launcher.jar fml TRANSFORMATIONSERVICE FML: 35.1 Forge: net.minecraftforge:35.1.37 FML Language Providers: javafml@35.1 minecraft@1 Mod List: client-extra.jar |Minecraft |minecraft |1.16.4 |ENQUEUE_IM|a1:d4:5e:04:4f:d3:d6:e0:7b:37:97:cf:77:b0:de:ad:4a:47:ce:8c:96:49:5f:0a:cf:8c:ae:b2:6d:4b:8a:3f forge-1.16.4-35.1.37_mapped_snapshot_20201028-1.16|Forge |forge |35.1.37 |ENQUEUE_IM|NOSIGNATURE main |The Ladon Fr*** Mod 1.16.4 |lndfmod |NONE |SIDED_SETU|NOSIGNATURE Crash Report UUID: 734f5cd3-7a52-470e-ab9e-c51bffee2944 Launched Version: MOD_DEV Backend library: LWJGL version 3.2.2 build 10 Backend API: NVIDIA GeForce GTX 1080/PCIe/SSE2 GL version 4.6.0 NVIDIA 510.10, NVIDIA Corporation GL Caps: Using framebuffer using OpenGL 3.0 Using VBOs: Yes Is Modded: Definitely; Client brand changed to 'forge' Type: Client (map_client.txt) Graphics mode: fancy Resource Packs: Current Language: English (US) CPU: 12x Intel(R) Core(TM) i7-8700K CPU @ 3.70GHz  
    • Alright, so, I have a question. Is it possible to display multiple cameras when spectating as an entity? How would I achieve that? I know ServerPlayer handles the spectating of entities and accepts a single camera but Platin told me it might be possible to have multiple cameras displaying at once.
    • Error in Create, make sure you use the latest version. If you already use it, report the bug to the Mod author.
  • Topics

  • Who's Online (See full list)

×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.