Posted May 27, 20214 yr I created a capability for player to write a custom inventory for each player. But I do not really understant how to get the data stored in the capability. Heres some classes: The IStorage Spoiler public class IStorageInstance implements Capability.IStorage<AltarCapabilty> { @Nullable @Override public INBT writeNBT(Capability<AltarCapabilty> capability, AltarCapabilty instance, Direction side) { ListNBT listnbt = new ListNBT(); for(int i = 0; i < 9; ++i) { ItemStack itemstack = instance.getStackInSlot(i); if (!itemstack.isEmpty()) { CompoundNBT compoundnbt = new CompoundNBT(); compoundnbt.putByte("SlotAltar", (byte)i); itemstack.save(compoundnbt); listnbt.add(compoundnbt); } } return listnbt; } @Override public void readNBT(Capability<AltarCapabilty> capability, AltarCapabilty instance, Direction side, INBT nbt) { if(nbt instanceof ListNBT) { ListNBT p_70486_1_ = (ListNBT) nbt; for(int i = 0; i < 9; ++i) { instance.insertItem(i, ItemStack.EMPTY, false); } for(int k = 0; k < p_70486_1_.size(); ++k) { CompoundNBT compoundnbt = p_70486_1_.getCompound(k); int j = compoundnbt.getByte("SlotAltar") & 255; if (j >= 0 && j < 9) { instance.insertItem(j, ItemStack.of(compoundnbt), false); } } } } } The default capability: Spoiler public class DefaultAltarCapability implements AltarCapabilty{ private NonNullList<ItemStack> items = NonNullList.withSize(9, ItemStack.EMPTY); @Override public int getSlots() { return items.size(); } @Nonnull @Override public ItemStack getStackInSlot(int slot) { return items.get(slot); } @Nonnull @Override public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) { if(simulate){ try{ return items.set(slot, stack); } catch (Exception ex){ System.out.println(ex); return stack; } } return items.set(slot, stack); } @Nonnull @Override public ItemStack extractItem(int slot, int amount, boolean simulate) { if(simulate){ try{ items.get(slot).setCount(items.get(slot).getCount() - amount); return items.get(slot); } catch (Exception ex){ System.out.println(ex); return items.get(slot); } } items.get(slot).setCount(items.get(slot).getCount() - amount); return items.get(slot); } @Override public int getSlotLimit(int slot) { return items.get(slot).getMaxStackSize(); } @Override public boolean isItemValid(int slot, @Nonnull ItemStack stack) { return true; } public NonNullList<ItemStack> getItems() { return items; } public void setItems(NonNullList<ItemStack> items) { this.items = items; } } The CapabilitySerializable: Spoiler public class AltarProvider implements ICapabilitySerializable<CompoundNBT> { private final DefaultAltarCapability defaultAltarCapability = new DefaultAltarCapability(); private final LazyOptional<AltarCapabilty> altarCapabilty = LazyOptional.of( ()-> defaultAltarCapability); @Nonnull @Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) { return altarCapabilty.cast(); } @Override public CompoundNBT serializeNBT() { if(CapabilityInstance.ALTAR_CAPABILITY == null){ return new CompoundNBT(); } else { return (CompoundNBT) CapabilityInstance.ALTAR_CAPABILITY.writeNBT(defaultAltarCapability, null); } } @Override public void deserializeNBT(CompoundNBT nbt) { if(CapabilityInstance.ALTAR_CAPABILITY != null){ CapabilityInstance.ALTAR_CAPABILITY.readNBT(defaultAltarCapability, null, nbt); } } } The tile entity: Spoiler public class AltarTileEntity extends LockableTileEntity { public AltarTileEntity() { super(ModTileEntityTypes.ALTAR.get()); } @Override protected ITextComponent getDefaultName() { TextComponent nome = new StringTextComponent("Altar"); return nome; } @Override protected Container createMenu(int containerId, PlayerInventory playerInventory) { Inventory items = loadItems(playerInventory.player); return new ModAltarContainer(ModContainers.ALTAR_TYPE.get(), containerId, playerInventory, items); } @Override public int getContainerSize() { return 9; } @Override public boolean isEmpty() { return true; } @Override public ItemStack getItem(int i) { return this.getItems().get(i); } @Override public ItemStack removeItem(int i, int count) { ItemStack itemstack = ItemStackHelper.removeItem(this.getItems(), i, count); if (!itemstack.isEmpty()) { this.setChanged(); } return itemstack; } @Override public ItemStack removeItemNoUpdate(int i) { return ItemStackHelper.takeItem(this.getItems(), i); } @Override public void setItem(int i, ItemStack item) { this.getItems().set(i, item); if (item.getCount() > this.getMaxStackSize()) { item.setCount(this.getMaxStackSize()); } this.setChanged(); } @Override public boolean stillValid(PlayerEntity playerEntity) { if (this.level.getBlockEntity(this.worldPosition) != this) { return false; } else { return !(playerEntity.distanceToSqr((double)this.worldPosition.getX() + 0.5D, (double)this.worldPosition.getY() + 0.5D, (double)this.worldPosition.getZ() + 0.5D) > 64.0D); } } @Override public void clearContent() { this.getItems().clear(); } protected NonNullList<ItemStack> getItems() { return NonNullList.withSize(9, ItemStack.EMPTY); } private Inventory loadItems(PlayerEntity player){ NonNullList<ItemStack> items = NonNullList.withSize(9, ItemStack.EMPTY); player.getCapability(CapabilityInstance.ALTAR_CAPABILITY).ifPresent(inv ->{ for(int i = 0; i < 9 ; i++){ items.set(i, inv.getStackInSlot(i)); } }); Inventory inventory = new Inventory(9); for(int i = 0; i < 9; i++){ inventory.setItem(i, items.get(i)); } return inventory; } } And the container's class: Spoiler @Mod.EventBusSubscriber public class ModAltarContainer extends Container { private static Container containerInstance; private IInventory altar; private static ContainerType menuType; private NonNullList<Slot> altarSlots = NonNullList.withSize(45, new Slot(altar, 0, 0, 0)); public ModAltarContainer(int i, PlayerInventory playerInventory) { this(ModContainers.ALTAR_TYPE.get(), i, playerInventory, new Inventory(9)); } public ModAltarContainer(@Nullable ContainerType<?> containerType, int containerId, PlayerInventory invPlayer, IInventory inventory) { super(containerType, containerId); containerInstance = this; altar = inventory; altarSlots.clear(); menuType = this.getType(); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { Slot slot = new Slot(altar, j + i * 3, 62 + j * 18, 17 + i * 18); altarSlots.set(j + i * 3, slot); this.addSlot(slot); } } for (int k = 0; k < 3; ++k) { for (int i1 = 0; i1 < 9; ++i1) { Slot slot = new Slot(invPlayer, i1 + k * 9 + 9, 8 + i1 * 18, 84 + k * 18); altarSlots.set(i1 + k * 9 + 9, slot); this.addSlot(slot); } } for (int l = 0; l < 9; ++l) { Slot slot = new Slot(invPlayer, l, 8 + l * 18, 142); altarSlots.set(36 + l, slot); this.addSlot(slot); } } @Override protected Slot addSlot(Slot slot) { return super.addSlot(slot); } @Override public boolean stillValid(PlayerEntity jogador) { return altar.stillValid(jogador); } @Override public ContainerType<?> getType() { return ModContainers.ALTAR_TYPE.get(); } public void removed(PlayerEntity p_75134_1_) { super.removed(p_75134_1_); this.altar.stopOpen(p_75134_1_); } @SubscribeEvent public static void saveAltarItems(PlayerContainerEvent.Close event){ PlayerEntity jogador = event.getPlayer(); if(event.getContainer() instanceof ModAltarContainer){ saveItems(event.getContainer(), jogador); } /* NonNullList<ItemStack> lista = NonNullList.withSize(9, ItemStack.EMPTY); if(event.getContainer().getType().equals(menuType)){ Container cont = event.getContainer(); ListNBT listnbt = new ListNBT(); for(int i = 0; i < 9; i++){ ItemStack itemstack = cont.getItems().get(i); lista.set(i, itemstack); CompoundNBT compoundnbt = new CompoundNBT(); compoundnbt.putByte("SlotAltar", (byte)i); itemstack.save(compoundnbt); listnbt.add(compoundnbt); } new InventoryStorage().readNBT(AltarCapabilityDef.ALTAR_INVENTORY, AltarCapabilityDef.ALTAR_INVENTORY.getDefaultInstance(), null, listnbt); PlayerEvolution.setStats(lista, jogador); } */ } public static void saveItems(Container cont, PlayerEntity jogador){ } @Override public ItemStack clicked(int p_184996_1_, int p_184996_2_, ClickType p_184996_3_, PlayerEntity p_184996_4_) { return super.clicked(p_184996_1_, p_184996_2_, p_184996_3_, p_184996_4_); } @Override public ItemStack quickMoveStack(PlayerEntity p_82846_1_, int p_82846_2_) { ItemStack itemstack = ItemStack.EMPTY; Slot slot = this.slots.get(p_82846_2_); if (slot != null && slot.hasItem()) { ItemStack itemstack1 = slot.getItem(); itemstack = itemstack1.copy(); if (p_82846_2_ < 9) { if (!this.moveItemStackTo(itemstack1, 9, this.slots.size(), true)) { return ItemStack.EMPTY; } } else if (!this.moveItemStackTo(itemstack1, 0, 9, false)) { return ItemStack.EMPTY; } if (itemstack1.isEmpty()) { slot.set(ItemStack.EMPTY); } else { slot.setChanged(); } } return itemstack; } } Edited May 27, 20214 yr by LuccaPossamai
May 27, 20214 yr Why do you have a tile entity? isn't the capability for the player entity? What's the purpose of IStorageInstance? and what's the difference between AltarCapability and DefaultAltarCapability? I think you're under some fundamental misconception over the capability system. Here's what you need: 1. A capability, and a capability is just a class which holds any arbitrary data you need. Since what you want is an "inventory", forge provides an implementation for that, the ItemStackHandler. If you don't require any custom logic on top of just a holder of ItemStacks, you don't even need to extend it, just use the ItemStackHandler capability. 2. A capability provider, which will manage the capabilities for your player. in it you'll handle serialization, and on the getCapability method, you'll check if the requested capability matches your capability, and if it does, return the lazy capability 3. you'll register the capabilities, and attach them on the proper event handler 4. if you want the inventory to be displayed, and interacted with by the player, you'll need the container and a container screen (not a tile entity, those are for blocks).
May 27, 20214 yr Author The tile entity in this context just serves to open the container that allows the player to have acess to this inventory. I change for the ItemStackHandler and I works. But, when I enter the world the capability resets.
May 28, 20214 yr 6 hours ago, LuccaPossamai said: The tile entity in this context just serves to open the container that allows the player to have acess to this inventory. yeah, that's not what tile entities are for. Tile entities are for blocks. what you need to open the container, is an INamedContainerProvider 6 hours ago, LuccaPossamai said: I change for the ItemStackHandler and I works. But, when I enter the world the capability resets. then you're not properly serializing your data, make sure you properly overrode the serializeNBT and deserializeNBT methods in your Capability Provider. and post your new code if you're still with some issues
May 28, 20214 yr Author I use this tile entity for a block, and this block the player use to open the inventory(like an ender chest). I changed the capability to an ItemStackHandler. But every time I enter in the game the inventory resets. The class for ItemStackHandler cap: Spoiler public class DefaultAltarCapability extends ItemStackHandler { public DefaultAltarCapability(){ super(9); } } public class DefaultAltarCapability extends ItemStackHandler { public DefaultAltarCapability(){ super(9); } } The Capability.IStorage: Spoiler public class IStorageInstance implements Capability.IStorage<DefaultAltarCapability> { @Nullable @Override public INBT writeNBT(Capability<DefaultAltarCapability> capability, DefaultAltarCapability instance, Direction side) { ListNBT listnbt = new ListNBT(); for(int i = 0; i < instance.getSlots(); ++i) { ItemStack itemstack = instance.getStackInSlot(i); CompoundNBT compoundnbt = new CompoundNBT(); compoundnbt.putInt("Slot", i); itemstack.save(compoundnbt); listnbt.add(compoundnbt); } CompoundNBT nbt = new CompoundNBT(); nbt.put("Items",listnbt); nbt.putInt("Size",listnbt.size()); return listnbt; } @Override public void readNBT(Capability<DefaultAltarCapability> capability, DefaultAltarCapability instance, Direction side, INBT nbt) { if(nbt instanceof CompoundNBT) { System.out.println("É tag"); CompoundNBT compoundNBT = (CompoundNBT) nbt; ListNBT tagList = compoundNBT.getList("Items", Constants.NBT.TAG_COMPOUND); for (int i = 0; i < tagList.size(); ++i) { instance.insertItem(i, ItemStack.of(tagList.getCompound(i)), false); } } } } The instance of the capability: Spoiler public class CapabilityInstance { @CapabilityInject(DefaultAltarCapability.class) public static Capability<DefaultAltarCapability> ALTAR_CAPABILITY = null; public static void register(){ CapabilityManager.INSTANCE.register(DefaultAltarCapability.class, new IStorageInstance(), DefaultAltarCapability::new ); } } I'm using this to load the items, a add them to an inventory: Spoiler private Inventory loadItems(PlayerEntity player){ Inventory inventory = new Inventory(9); player.getCapability(CapabilityInstance.ALTAR_CAPABILITY).ifPresent(inv ->{ for(int i = 0; i < inv.getSlots(); i++){ inventory.setItem(i, inv.getStackInSlot(i)); } }); return inventory; } And using this, to save the items of the container in the cap: Spoiler @SubscribeEvent public static void saveAltarItems(PlayerContainerEvent.Close event){ PlayerEntity jogador = event.getPlayer(); if(event.getContainer() instanceof ModAltarContainer) { NonNullList<ItemStack> lista = NonNullList.withSize(9, ItemStack.EMPTY); Container cont = event.getContainer(); jogador.getCapability(CapabilityInstance.ALTAR_CAPABILITY).ifPresent( inv ->{ for(int i = 0 ; i < inv.getSlots() ; i++){ inv.setStackInSlot(i, cont.getItems().get(i)); inv.deserializeNBT(inv.serializeNBT()); } }); //PlayerEvolution.setStats(lista, jogador); } }
May 28, 20214 yr 38 minutes ago, LuccaPossamai said: I use this tile entity for a block, and this block the player use to open the inventory(like an ender chest). that doesn't mean you need a tile entity, the data is being stored in the player's capability, not the block 38 minutes ago, LuccaPossamai said: The class for ItemStackHandler cap: public class DefaultAltarCapability extends ItemStackHandler { public DefaultAltarCapability(){ super(9); } } There's no need to extends the ItemStackHandler, just instantiate it 38 minutes ago, LuccaPossamai said: The Capability.IStorage: public class IStorageInstance implements Capability.IStorage<DefaultAltarCapability> { @Nullable @Override public INBT writeNBT(Capability<DefaultAltarCapability> capability, DefaultAltarCapability instance, Direction side) { ListNBT listnbt = new ListNBT(); for(int i = 0; i < instance.getSlots(); ++i) { ItemStack itemstack = instance.getStackInSlot(i); CompoundNBT compoundnbt = new CompoundNBT(); compoundnbt.putInt("Slot", i); itemstack.save(compoundnbt); listnbt.add(compoundnbt); } CompoundNBT nbt = new CompoundNBT(); nbt.put("Items",listnbt); nbt.putInt("Size",listnbt.size()); return listnbt; } @Override public void readNBT(Capability<DefaultAltarCapability> capability, DefaultAltarCapability instance, Direction side, INBT nbt) { if(nbt instanceof CompoundNBT) { System.out.println("É tag"); CompoundNBT compoundNBT = (CompoundNBT) nbt; ListNBT tagList = compoundNBT.getList("Items", Constants.NBT.TAG_COMPOUND); for (int i = 0; i < tagList.size(); ++i) { instance.insertItem(i, ItemStack.of(tagList.getCompound(i)), false); } } } } You don't need to use IStorage, plus they're being removed in the next versions. just do the serialization in the provider 38 minutes ago, LuccaPossamai said: The instance of the capability: public class CapabilityInstance { @CapabilityInject(DefaultAltarCapability.class) public static Capability<DefaultAltarCapability> ALTAR_CAPABILITY = null; public static void register(){ CapabilityManager.INSTANCE.register(DefaultAltarCapability.class, new IStorageInstance(), DefaultAltarCapability::new ); } } and when your CapabilityInstance.register called? 38 minutes ago, LuccaPossamai said: I'm using this to load the items, a add them to an inventory: private Inventory loadItems(PlayerEntity player){ Inventory inventory = new Inventory(9); player.getCapability(CapabilityInstance.ALTAR_CAPABILITY).ifPresent(inv ->{ for(int i = 0; i < inv.getSlots(); i++){ inventory.setItem(i, inv.getStackInSlot(i)); } }); return inventory; } And using this, to save the items of the container in the cap: @SubscribeEvent public static void saveAltarItems(PlayerContainerEvent.Close event){ PlayerEntity jogador = event.getPlayer(); if(event.getContainer() instanceof ModAltarContainer) { NonNullList<ItemStack> lista = NonNullList.withSize(9, ItemStack.EMPTY); Container cont = event.getContainer(); jogador.getCapability(CapabilityInstance.ALTAR_CAPABILITY).ifPresent( inv ->{ for(int i = 0 ; i < inv.getSlots() ; i++){ inv.setStackInSlot(i, cont.getItems().get(i)); inv.deserializeNBT(inv.serializeNBT()); } }); //PlayerEvolution.setStats(lista, jogador); } } What are these for? why are you converting the ItemStackHandler to an Inventory, to use the ItemStackHandler And you didn't show the CapabilityProvider. You're over complicating this, I've already explained what it is that you need: On 5/26/2021 at 11:58 PM, kiou.23 said: 1. A capability, and a capability is just a class which holds any arbitrary data you need. Since what you want is an "inventory", forge provides an implementation for that, the ItemStackHandler. If you don't require any custom logic on top of just a holder of ItemStacks, you don't even need to extend it, just use the ItemStackHandler capability. 2. A capability provider, which will manage the capabilities for your player. in it you'll handle serialization, and on the getCapability method, you'll check if the requested capability matches your capability, and if it does, return the lazy capability 3. you'll register the capabilities, and attach them on the proper event handler 4. if you want the inventory to be displayed, and interacted with by the player, you'll need the container and a container screen (not a tile entity, those are for blocks). your Capability Provider will provide an ItemStackHandler, in this case, handle serialization in the Provider's serialize and deserialize methods and you don't need a TE, at least not for this. the TE is meant to store additional data for blocks, since the data you're storing isn't kept in a block, but in the player, you don't need a Tile entity. to open the container you just need an INamedContainerProvider, which passes any data that the Container needs, to the container. and you'll get this data from the Capability Edited May 28, 20214 yr by kiou.23
May 28, 20214 yr Author Ok, I changed some things. But the inventory still resets. I'm calling the registration of the capability in the setup, maybe this is causing the reset. The attachEvent: Spoiler @Mod.EventBusSubscriber public class AltarCapabilitySetup { @SubscribeEvent public static void attachEntityCapabilities(AttachCapabilitiesEvent<Entity> event) { if(event.getObject() instanceof PlayerEntity) { event.addCapability(new ResourceLocation(ExampleMod.MOD_ID, "altar_inventory"), new CapabilityInstance()); } } } And the Provider/Serializable: Spoiler public class CapabilityInstance implements ICapabilityProvider, ICapabilitySerializable { @CapabilityInject(ItemStackHandler.class) public static Capability<ItemStackHandler> ALTAR_CAPABILITY = null; private final ItemStackHandler ALTAR_HANDLER = new ItemStackHandler(9); private final LazyOptional<ItemStackHandler> ALTAR_LAZY = LazyOptional.of(()-> ALTAR_HANDLER); @Nonnull @Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) { return ALTAR_LAZY.cast(); } @Override public INBT serializeNBT() { if(ALTAR_CAPABILITY == null){ return new CompoundNBT(); } else { return ALTAR_CAPABILITY.writeNBT(ALTAR_HANDLER, null); } } @Override public void deserializeNBT(INBT nbt) { if(ALTAR_CAPABILITY != null) { ALTAR_CAPABILITY.readNBT(ALTAR_HANDLER, null, nbt); } } public static void register() { CapabilityManager.INSTANCE.register(CapabilityInstance.class, new Capability.IStorage<CapabilityInstance>() { @Nullable @Override public INBT writeNBT(Capability<CapabilityInstance> capability, CapabilityInstance instance, Direction side) { return instance.serializeNBT(); } @Override public void readNBT(Capability<CapabilityInstance> capability, CapabilityInstance instance, Direction side, INBT nbt) { instance.serializeNBT(); } }, CapabilityInstance::new); } }
May 29, 20214 yr 1 hour ago, LuccaPossamai said: Ok, I changed some things. But the inventory still resets. I'm calling the registration of the capability in the setup, maybe this is causing the reset. The attachEvent: Reveal hidden contents @Mod.EventBusSubscriber public class AltarCapabilitySetup { @SubscribeEvent public static void attachEntityCapabilities(AttachCapabilitiesEvent<Entity> event) { if(event.getObject() instanceof PlayerEntity) { event.addCapability(new ResourceLocation(ExampleMod.MOD_ID, "altar_inventory"), new CapabilityInstance()); } } } And the Provider/Serializable: Reveal hidden contents public class CapabilityInstance implements ICapabilityProvider, ICapabilitySerializable { @CapabilityInject(ItemStackHandler.class) public static Capability<ItemStackHandler> ALTAR_CAPABILITY = null; private final ItemStackHandler ALTAR_HANDLER = new ItemStackHandler(9); private final LazyOptional<ItemStackHandler> ALTAR_LAZY = LazyOptional.of(()-> ALTAR_HANDLER); @Nonnull @Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) { return ALTAR_LAZY.cast(); } @Override public INBT serializeNBT() { if(ALTAR_CAPABILITY == null){ return new CompoundNBT(); } else { return ALTAR_CAPABILITY.writeNBT(ALTAR_HANDLER, null); } } @Override public void deserializeNBT(INBT nbt) { if(ALTAR_CAPABILITY != null) { ALTAR_CAPABILITY.readNBT(ALTAR_HANDLER, null, nbt); } } public static void register() { CapabilityManager.INSTANCE.register(CapabilityInstance.class, new Capability.IStorage<CapabilityInstance>() { @Nullable @Override public INBT writeNBT(Capability<CapabilityInstance> capability, CapabilityInstance instance, Direction side) { return instance.serializeNBT(); } @Override public void readNBT(Capability<CapabilityInstance> capability, CapabilityInstance instance, Direction side, INBT nbt) { instance.serializeNBT(); } }, CapabilityInstance::new); } } in the provider's serializeNBT you call the IStorage's writeNBT, but in the IStorage's writeNBT you call the provider's serializeNBT. You never actually serialize your data. 1. You don't need an IStorage, just do the serialization in the provider itself. 2. your lazy altar isn't actually lazy. google the concept up. don't initialize the the field on instantiation, instead wait until the capability is requested to initialize it, then cache it. 3. no need to implement ICapabilityProvider, only ICapabilitySerializable, also, you should define the generic parameter of the interface. 4. don't put your capability instance on the capability provider class. that's separation of concerns 101 5. on your getCapability, make sure that the capability being requested is the one you're providing! Hold on, I have a mod with a private repo that uses capabilities. I'll make it public to share it here so you can see some examples EDIT: here's some examples https://github.com/jvcmarcenes/skbackpacks EDIT2: I had forgot, for serializing ItemStackHandlers you can use of CapabilityItemHandler.ITEM_HANDLER_CAPABILITY write/read method Edited May 29, 20214 yr by kiou.23
May 29, 20214 yr Author Ok, with an example the things just get so many clear now. Thanks btw. But, I'm confused. How do I register this Capability. I mean, I tried but, with the serialization, there is no IStorage. I looked in your code, and do not find a field that you register the cap.
May 29, 20214 yr 7 hours ago, LuccaPossamai said: Ok, with an example the things just get so many clear now. Thanks btw. But, I'm confused. How do I register this Capability. I mean, I tried but, with the serialization, there is no IStorage. I looked in your code, and do not find a field that you register the cap. since that's just using an ItemStackHandler, I used the ITEM_HANDLER capability that already exists in CapabilityItemHandler Bur for registration you just create a field, in a class like ModCapabilities, of type Capability<Your Capability class>, and use @CapabilityInject() and I didn't have to use an attach event because I'm using the capability in a custom Item. but for attaching it's the same thing, just listen to the proper event, and call event.addCapabicall, then give it the cap ID and an instance of the cap provider
June 1, 20214 yr Author It worked, thanks. When the player dies, the capability should reset? If yes, how do I do to no reset?
June 1, 20214 yr 3 minutes ago, LuccaPossamai said: It worked, thanks. When the player dies, the capability should reset? If yes, how do I do to no reset? yes, you have to copy all values from the old capability into the new one, do this in the PlayerEvent.Clone
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.