Dyeing of Sheep

Discussion in 'Plugin Development' started by pie_flavor, Mar 4, 2015.

Thread Status:
Not open for further replies.
  1. Offline

    pie_flavor

    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.
     
  2. 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);
    }
     
  3. Offline

    pie_flavor

  4. @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);
        }
     
    Last edited: Mar 7, 2015
  5. Offline

    pie_flavor

    @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].
     
  6. @pie_flavor
    That's weird, this worked 100% fine for me, could you show me your code?
     
  7. Offline

    pie_flavor

  8. @pie_flavor
    Thanks, good luck with solving it youself ;)
     
Thread Status:
Not open for further replies.

Share This Page