Equipment Slot Listener

Hello everyone, so I’m trying to create a listener to prevent users from removing a REDSTONE_BLOCK or a SLIME (slime block) assigned to their helmet equipment slot. The way I tried to approach was this was by listening to inventory clicks in the equipment slots through the ChangeEntityEquipmentEvent listener, but that didn’t turned out like I hoped. Below is the code I tried. Any help would be greatly appreciated :smiley:

SpongeForge: spongeforge-1.10.2-2477-5.2.0-BETA-2637

@Listener
public void onContestantClickHeadgear(ChangeEntityEquipmentEvent event, @Root Player player){
	
	Optional<ItemStackSnapshot> item = event.getOriginalItemStack();
	
	if(item.isPresent()){
		
		ItemType type = item.get().getType();
		
		if(type.equals(ItemTypes.REDSTONE_BLOCK)||
				type.equals(ItemTypes.SLIME)){
			
			event.setCancelled(true);
		}
	}
}

Update: The following code works sometimes:

@Listener
public void onContestantClickHeadgear(ClickInventoryEvent event, @Root Player player){
	
	event.getTransactions().forEach(t ->{
		
		if(t.getSlot().contains(ItemTypes.REDSTONE_BLOCK)||
				t.getSlot().contains(ItemTypes.SLIME)){
			
			event.setCancelled(true);
			
			return;
		}
	});
}

Here is a gif that illustrates the issue. As it can be seen, when opening the inventory for the first time, and clicking on the specified items works fine the first time, but if tried again, it will fail.

Try debugging on your updated one.

Instead of checking if it contains a item type. Peek the slot to see if it has a itemStack. And then check the type of the itemstack.

The contains method in Slot should do what you want it to do. But its best to see where your code is going wrong

Somehow, I’m getting the same results as the updated code. On itemclick, if the item is 1 slime block or redstone block, I want to cancel the event, but instead it only gets cancelled once.

@Listener
public void onContestantClickHeadgear(ClickInventoryEvent event, @Root Player player){
	
	event.getTransactions().forEach(t ->{
		
		Optional<ItemStack> oItem = t.getSlot().peek();
		
		if(oItem.isPresent()){
			
			ItemStack item = oItem.get();
			
			ItemStack r = ItemStack.of(ItemTypes.REDSTONE_BLOCK, 1);
			ItemStack s = ItemStack.of(ItemTypes.SLIME, 1);
			
			player.sendMessage(Text.of("Item clicked"));
			
			if(item.equalTo(r)||item.equalTo(s)){
				
				player.sendMessage(Text.of("event canceled"));
				
				event.setCancelled(true);
				
				return;
			}
		}
	});
}

I didnt mean create a new itemStack of Redstone block and slime.

I mean this

ItemStack item;
If((item.getType().equals(ItemTypes.REDSTONE_BLOCK)) || (item.getType().equals(ItemTypes.SLIME))){

Unfortunately, the results are the same with the provided code.

Try sending messages to the console saying what item type it is and if its present. Hopefully that will show whats going wrong

When the transaction is picked up, both items types match on console. It’s almost as if it’s not picking up all of the times I’m clicking inside the inventory.

Can i see your most up to date code?

Of course:

@Listener
public void onContestantClickHeadgear(ClickInventoryEvent event, @Root Player player){
	
	event.getTransactions().forEach(t ->{
		
		Optional<ItemStack> oItem = t.getSlot().peek();
		
		if(oItem.isPresent()){
			
			ItemStack item = oItem.get();
			
			//player.sendMessage(Text.of("Item present"));
			player.sendMessage(Text.of(TextColors.AQUA,item.getItem().getType()));
			
			Sponge.getServer().getBroadcastChannel().send(Text.of(ItemTypes.REDSTONE_BLOCK));
			Sponge.getServer().getBroadcastChannel().send(Text.of(ItemTypes.SLIME));
			
			if((item.getItem().getType().equals(ItemTypes.REDSTONE_BLOCK)) || (item.getItem().getType().equals(ItemTypes.SLIME))){
				
				player.sendMessage(Text.of("event canceled"));
				
				event.setCancelled(true);
				
				return;
			}
		}
	});
}

Ok. I have wasted enough of your time. Im going to write the same thing and test it myself. Ill post my code at the end.

edit:

This code is what worked on mine, even have a console just to prove it

@Listener
public void onInventoryClick(ClickInventoryEvent event, @Root Player player) {
	ItemStackSnapshot snapshot = event.getCursorTransaction().getFinal();
	System.out.println("\n Snapshot type: " + snapshot.getType().getName());
	if((snapshot.getType().equals(ItemTypes.REDSTONE_BLOCK)) || (snapshot.getType().equals(ItemTypes.SLIME))) {
		System.out.println("Success");
		return;
	}
	System.out.println("Failed");
	
}

I didn’t check if your code worked, I just started to write the code how I would.

The issue with my last provided code wasn’t if the ItemType was being compared correctly. That part worked fine. The issue was that the listener was not picking up every time a player clicked on either one of the items in thier inventories every time. It worked sometimes. I appreciate the time you’ve committed to assist my issue, though. Thank you.

Ok. Ill do a few more tests to see if i can get a solution.

1 Like