Jump to content

Phi

Members
  • Posts

    14
  • Joined

  • Last visited

Everything posted by Phi

  1. I guess because it goes through so many layers behind the scenes that it's hard to understand at first glance what you're supposed to provide where. I'm sure that it's simple enough once you understand how it works, but I'm not there yet. Also I suppose that's kind of what modding is like in general.
  2. Ahhhh I see. Thanks diesieben, these capabilities are still so confusing to me.
  3. How would I check that my capability was the one that was asked for?
  4. Hello, when I load my mod along with other mods, I run into a crash on world load that goes along the lines of "Capability A cannot be cast to Capability B", where Capability A is mine and B is whichever other one. It does this for multiple other mods so I'm guessing I did something stupid, but I have no clue what. The error itself also occurs in the other mods, so I don't know where to look in my code. Some examples: [Render thread/ERROR] [net.minecraftforge.eventbus.EventBus/EVENTBUS]: Exception caught during firing event: dev.stormwatch.vanillaspice.data.DefaultPlayerStats cannot be cast to tschipp.carryon.common.capabilities.Imposition [Server thread/ERROR] [net.minecraftforge.eventbus.EventBus/EVENTBUS]: Exception caught during firing event: dev.stormwatch.vanillaspice.data.DefaultPlayerStats cannot be cast to twilightforest.capabilities.shield.IShieldCapability Any insight would be appreciated. https://github.com/Phi-1/VanillaSpice
  5. 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?
  6. Welp my brain is officially broken. I'll find another way around this problem some other time. Thanks for your help diesieben
  7. Wow okay that is extremely weird. Just to be sure I just ran it again on my own pc and it still shows 0. All my code is the exact same as in the repo.
  8. 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
  9. 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.
  10. So this is not the reason the data gets reset to 0? If not, would you have any idea why it does?
  11. 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
×
×
  • Create New...

Important Information

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