I recently filled a request to stop people from being able to dye sheep with Minecraft dye. I wrote the code correctly, but they said it didn't work. I tested it for myself and discovered that there is a client side glitch, where it will set the color client-side regardless of the cancelled state. It matters whether the client sees it in the correct color. With the bow or tool glitch, there's a handy updateInventory() method. No such luck with a sheep. How can I get the client to update? I tried setting a task to set the color 2 ticks later, no luck.
You could send a metadata packet(PacketPlayOutEntityMetadata). It updates an entity's metadata which also contains the sheep's dye color: Code: EntitySheep sheepHandle = ((CraftSheep) sheep).getHandle(); PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(sheepHandle.getId(), sheepHandle.getDataWatcher(), true); for(Player o : sheep.getWorld().getPlayers()) { ((CraftPlayer)o).getHandle().playerConnection.sendPacket(packet); }
@pie_flavor I found a fix, what you tried is setting the event's color 2 ticks later, but the event only checks one moment. If you set the sheep's color(even after 1 tick it works), it's should fix it. I tested some stuff and I managed to make it possible. Note: also add the PlayerInteractEntityEvent because it gives the item back to the player since if the sheep dye event is cancelled the sheep gets messed up. EDIT: Fixed when the dye color is the same as the sheep's color it just adds the item Code: @EventHandler public void onSheepInteract(PlayerInteractEntityEvent e) { final Player p = e.getPlayer(); if(e.getRightClicked() instanceof Sheep && p.getItemInHand() != null && p.getItemInHand().getData() instanceof Dye) { final ItemStack dye = p.getItemInHand().clone(); Sheep sheep = (Sheep) e.getRightClicked(); if(sheep.getColor() == ((Dye)dye.getData()).getColor()) return; dye.setAmount(1); new BukkitRunnable() { @Override public void run() { p.getInventory().addItem(dye); } }.runTaskLater(Bridged.getInstance(), 2L); } } @EventHandler public void onSheepColor(SheepDyeWoolEvent e) { final Sheep sheep = e.getEntity(); final DyeColor color = sheep.getColor(); new BukkitRunnable() { @Override public void run() { sheep.setColor(color); } }.runTaskLater(Bridged.getInstance(), 1L); }
@megamichiel That's actually exactly what I did. Run it 2 ticks later. Still doesn't work. Besides, ops need to be able to color the sheep. Tip: Instead of typing [code], type [code=java].