Creating Custom Inventories, HELP D:

Ooooooh, okay. That’s a pretty cool way to do the inventory system then. Confusing at first, but it makes sense now. Thank ya!

Not just inventories, that’s how the entire event system works. e.g. DestructEntityEvent being a supertype of DestructEntityEvent.Destruct, or ClientConnectionEvent with ClientConnectionEvent.Join

These can also be controlled by having the supertype (e.g. ClickInventoryEvent) as the event, and using the @Include or @Exclude annotations on your listener method in order to specify specific types.

Ah, brilliant. If you don’t mind, could you show a brief example of the @Include and @Exclude? For instance, could that be used with a ClickInventoryEvent and specifically exclude just the, say, shift clicking but all other “click types” are included?

Exactly.

@Listener
@Exclude(ClickInventoryEvent.Shift.class)
public void onClick(ClickInventoryEvent e, @First Player p) {

Oh that’s awesome. Okay, last question I think. How do I get the item that was clicked? I use
“event.getCursorTransaction().getOriginal().createStack()” yet whenever I try to interact with that, I get a NullPointerException. Since I’m doing the clicking, I know that the slot I’m clicking on isn’t null or empty.

And what happens when you do .getFinal() instead of .getOriginal()?

Okay, that’s progress! So I’m cancelling the event so a player can’t take that item. The first time you click it, it works just fine. If I click it a second time, then it says “No value present”. I’m not sure why’d that’d be happening if I’m not allowing the player to take the item. Besides that, the last issue is closing the inventory. I’m using player.closeInventory(Cause.of(NamedCause.of("Server Action", this))); but that’s not doing anything. Thanks again for all the help :smiley:

There’s still some kinks to work out in the implementation. Custom inventories and such are very new.

Oh okay. That’s fair. Well at least we narrowed it down to those two things. I guess I’ll continue here once they’ve worked on it more. Thank ya much!

what are u coding for? look like chestcommand plugin?

Trying create custom inventory menu, but have problem when try set smallest dimension parameters - example archetype is CHEST and when set dimension 9,2, got exception java.lang.IndexOutOfBoundsException: Index: 18
When set dimension 9,4, all is ok. Howto create only 2 lines custom inventory?

my code:

			Player player = (Player)src;
			Inventory vrmmenu = Inventory.builder().of(InventoryArchetypes.CHEST)
					.property(InventoryDimension.PROPERTY_NAM, new InventoryDimension(9, 2))
					.property(InventoryTitle.PROPERTY_NAME, InventoryTitle.of(Text.builder("Vote Rewards").color(TextColors.DARK_AQUA).style(TextStyles.BOLD).build()))
					.build(this.plugin);
			ItemStack emer = ItemStack.of(ItemTypes.EMERALD, 1);
			emer.offer(Keys.DISPLAY_NAME, Text.of("Emerald"));
			List itemLore = new ArrayList();
			itemLore.add(Text.of(TextColors.GOLD,"1 Vote"));
			emer.offer(Keys.ITEM_LORE , itemLore);
			vrmmenu.query(new SlotPos(1,1)).set(emer);
			vrmmenu.query(new SlotPos(0,0)).set(ItemStack.of(ItemTypes.ACACIA_DOOR, 1));
			vrmmenu.query(new SlotPos(2,1)).set(ItemStack.of(ItemTypes.IRON_INGOT, 1));
			//TODO 
			
			player.openInventory(vrmmenu, Cause.of(NamedCause.of("plugin", plugin), NamedCause.source(player)));
1 Like

I would also be interested in learning if you can create a persistent custom inventory.
EG, you have an special item you’ve re-purposed to “open” this chest. That chest would be unique to the player, like a portable enderchest, when you close the inventory and re-open, any changes to the inventory would have been saved and shown.

Theoretically this is definitely possible using Data.

You’d create a DataTranslator for Inventories, store the inventory to the data, and add it to the item.

The major limitation is that only one plugin could have the translator registered - due to the way datamanager is implemented.

The translator could iterate through the inv and save to disk - creating a new inv from the serialized state when called.

Simple :stuck_out_tongue_winking_eye:

1 Like

That code works fine for me:

Are you using the latest version?
If it still happens please provide the StrackTrace

Im testing it in latest spongevanilla build 149

stacktrace:

[15:48:49] [Server thread/ERROR] [Sponge]: Error occurred while executing command 'vrm' for source EntityPlayerMP['HunterzCZ'/308, l='world', x=61,50, y=64,00, z=257,50]: Index: 18
java.lang.IndexOutOfBoundsException: Index: 18
        at org.spongepowered.common.item.inventory.lens.impl.collections.DynamicLensCollectionImpl.checkIndex(DynamicLensCollectionImpl.java:156) ~[DynamicLensCollectionImpl.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.lens.impl.collections.DynamicLensCollectionImpl.getLens(DynamicLensCollectionImpl.java:94) ~[DynamicLensCollectionImpl.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.lens.impl.collections.DynamicLensCollectionImpl.get(DynamicLensCollectionImpl.java:89) ~[DynamicLensCollectionImpl.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.lens.impl.collections.SlotCollection.getSlot(SlotCollection.java:133) ~[SlotCollection.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.lens.impl.comp.Inventory2DLensImpl.init(Inventory2DLensImpl.java:101) ~[Inventory2DLensImpl.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.lens.impl.comp.Inventory2DLensImpl.init(Inventory2DLensImpl.java:85) ~[Inventory2DLensImpl.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.lens.impl.AbstractLens.init(AbstractLens.java:111) ~[AbstractLens.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.lens.impl.comp.Inventory2DLensImpl.(Inventory2DLensImpl.java:74) ~[Inventory2DLensImpl.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.lens.impl.comp.InventoryRowLensImpl.(InventoryRowLensImpl.java:52) ~[InventoryRowLensImpl.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.lens.impl.comp.InventoryRowLensImpl.(InventoryRowLensImpl.java:48) ~[InventoryRowLensImpl.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.lens.impl.comp.GridInventoryLensImpl.init(GridInventoryLensImpl.java:78) ~[GridInventoryLensImpl.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.lens.impl.AbstractLens.init(AbstractLens.java:111) ~[AbstractLens.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.lens.impl.comp.Inventory2DLensImpl.(Inventory2DLensImpl.java:74) ~[Inventory2DLensImpl.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.lens.impl.comp.GridInventoryLensImpl.(GridInventoryLensImpl.java:69) ~[GridInventoryLensImpl.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.lens.impl.comp.GridInventoryLensImpl.(GridInventoryLensImpl.java:57) ~[GridInventoryLensImpl.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.custom.CustomLens.init(CustomLens.java:65) ~[CustomLens.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.custom.CustomLens.(CustomLens.java:50) ~[CustomLens.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.custom.CustomInventory.handler$onConstructed$zgj000(CustomInventory.java:74) ~[CustomInventory.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.custom.CustomInventory.(CustomInventory.java:105) ~[CustomInventory.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.item.inventory.SpongeInventoryBuilder.build(SpongeInventoryBuilder.java:84) ~[SpongeInventoryBuilder.class:1.10.2-6.0.0-BETA-149]
        at net.rebelgames.voterewardmenu.VRMCommand.execute(VRMCommand.java:42) ~[VRMCommand.class:?]
        at org.spongepowered.api.command.spec.CommandSpec.process(CommandSpec.java:351) ~[CommandSpec.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.api.command.dispatcher.SimpleDispatcher.process(SimpleDispatcher.java:333) ~[SimpleDispatcher.class:1.10.2-6.0.0-BETA-149]
        at org.spongepowered.common.command.SpongeCommandManager.process(SpongeCommandManager.java:291) [SpongeCommandManager.class:1.10.2-6.0.0-BETA-149]
        at net.minecraft.command.ServerCommandManager.func_71556_a(SourceFile:82) [bd.class:?]
        at net.minecraft.network.NetHandlerPlayServer.func_147361_d(SourceFile:825) [me.class:?]
        at net.minecraft.network.NetHandlerPlayServer.func_147354_a(SourceFile:812) [me.class:?]
        at net.minecraft.network.play.client.CPacketChatMessage.func_148833_a(SourceFile:37) [im.class:?]
        at net.minecraft.network.play.client.CPacketChatMessage.func_148833_a(SourceFile:9) [im.class:?]
        at org.spongepowered.common.network.PacketUtil.onProcessPacket(PacketUtil.java:123) [PacketUtil.class:1.10.2-6.0.0-BETA-149]
        at net.minecraft.network.PacketThreadUtil$1.redirect$onProcessPacket$zio000(SourceFile:39) [fl$1.class:?]
        at net.minecraft.network.PacketThreadUtil$1.run(SourceFile:13) [fl$1.class:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_111]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_111]
        at net.minecraft.util.Util.func_181617_a(SourceFile:45) [h.class:?]
        at net.minecraft.server.MinecraftServer.func_71190_q(SourceFile:140) [MinecraftServer.class:?]
        at net.minecraft.server.dedicated.DedicatedServer.func_71190_q(SourceFile:338) [ld.class:?]
        at net.minecraft.server.MinecraftServer.func_71217_p(SourceFile:554) [MinecraftServer.class:?]
        at net.minecraft.server.MinecraftServer.run(SourceFile:458) [MinecraftServer.class:?]
        at java.lang.Thread.run(Thread.java:745) [?:1.8.0_111]


With SpongeForge works for me too. Thx.