Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

I'm trying to add a custom capability to an item that will store a string representing an EntityType, but it seems like the NBT functions keep overriding it! Am I missing something obvious here?

// Class that stores actual data for capability.
public class Pet {
  private EntityType<?> entityType;

  public Pet() {
    this.entityType = null;
  }

  public String getEntityTypeString() {
    if (this.entityType == null) {
      return "";
    }

    return EntityType.getKey(this.entityType).toString();
  }

  public EntityType<?> getEntityType() {
    return this.entityType;
  }

  public void setEntityType(EntityType<?> entityType) {
    this.entityType = entityType;
    Datamine.LOGGER.debug("setEntityType type: " + this.entityType);
  }

  public void setEntityType(String entityType) {
    this.entityType = EntityType.byKey(entityType).orElse(null);
    Datamine.LOGGER.debug("setEntityType string: " + this.entityType);
  }

  public void releaseEntity() {
    this.entityType = null;
  }

  public static class PetStorage implements IStorage<Pet> {
    @Override
    public void readNBT(Capability<Pet> capability, Pet instance, Direction side, INBT nbt) {
      if (nbt instanceof CompoundNBT) {
        instance.setEntityType(((CompoundNBT) nbt).getString("type"));
      }
    }

    @Override
    public INBT writeNBT(Capability<Pet> capability, Pet instance, Direction side) {
      CompoundNBT nbt = new CompoundNBT();
      nbt.putString("type", instance.getEntityTypeString());
      return nbt;
    }
  }

}
public class PetItem extends Item {
  public PetItem(Item.Properties properties) {
    super(properties);
  }

  @Override
  public boolean itemInteractionForEntity(ItemStack stack, PlayerEntity playerIn, LivingEntity target, Hand hand) {
    if (target.world.isRemote) {
      return false;
    }

    Pet pet = stack.getCapability(PetCapability.CAPABILITY_PET).orElse(null);

    if (pet == null) {
      return false;
    }

    if (target instanceof AnimalEntity) {
      Datamine.LOGGER.debug("AnimalEntity: " + target.getType());
      pet.setEntityType(target.getType());
      return true;
    }

    return false;
  }

  @Override
  public ActionResultType onItemUse(ItemUseContext context) {
    Datamine.LOGGER.debug("onItemUse: " + context.getItem().getCapability(PetCapability.CAPABILITY_PET).orElse(null).getEntityType());
    return super.onItemUse(context);
  }

  @Override
  public ICapabilityProvider initCapabilities(ItemStack stack, CompoundNBT nbt) {
    return new PetCapabilityProvider();
  }
}
public class PetCapabilityProvider implements ICapabilitySerializable<INBT> {
  private final Pet pet = new Pet();
  private final LazyOptional<Pet> petOptional = LazyOptional.of(() -> pet);

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

  @Override
  public INBT serializeNBT() {
    return PetCapability.CAPABILITY_PET.writeNBT(this.pet, null);
  }

  @Override
  public void deserializeNBT(INBT nbt) {
    PetCapability.CAPABILITY_PET.readNBT(this.pet, null, nbt);
  }
}
public class PetCapability {
  @CapabilityInject(Pet.class)
  public static Capability<Pet> CAPABILITY_PET = null;

  public static void register() {
    CapabilityManager.INSTANCE.register(Pet.class, new Pet.PetStorage(), () -> new Pet());
  }
}

Thanks in advance!

Edited by Ghost20000

  • Author
56 minutes ago, diesieben07 said:

If this is your item, why are you using a capability for it?

Oh, is there a simpler way to store data in itemstacks? I'm not very proficient with forge (as you can probably tell lol).

56 minutes ago, diesieben07 said:

What do you mean by this?

It sets entityType, but when read/writeNBT are called it's back to null.

  • Author
34 minutes ago, diesieben07 said:

I can't see the issue, this would require use of the debugger to figure out.

Could it somehow be a client-server desync issue? I've been trying to figure it out for a while now...

  • Author
13 hours ago, diesieben07 said:

Maybe. Given the code you have posted it's hard to tell.

Alright, after updating to 1.16 and enduring even more weirdness, I've decided to upload my code to github. If you have the time, I'd love if you looked over it.

Thanks a lot!

  • Author
17 minutes ago, diesieben07 said:

Great. I'll use my telepathic abilities to find the link and tell you in no time.

Oh my god I'm so stupid, sorry about that.

Here you go.

Can you tell I sent that at 2 AM?

  • Author
29 minutes ago, diesieben07 said:

It works fine in survival mode. In creative mode, item stack changes during most item actions are completely ignored by the game (you are just acting on a copied ItemStack which will be discarded afterwards). If you want these changes to stick you need to check for creative mode and if it is active, call setHeldItem manually during your interaction handler.

Thank you so much!!!

Would've never thought that was the case, I'd assume that stuff like buckets have special creative mode checks, but I guess not!

Will mark as solved!

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

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.