[SOLVED] Looking for a way to play the Pickup Pop Sound when cancelling pickup event

Discussion in 'Plugin Development' started by haveric, Apr 1, 2012.

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

    haveric

    I'm trying to override the PlayerPickupItemEvent to adjust how stacking works (either limit or increase the amount that can be stacked) after picking up an item.

    In order to do this, I must cancel the event, which then loses the pop sound. Is there any way to play this sound or fake a pickup in order to have it played?

    Thanks,
    Haveric
     
  2. Offline

    CorrieKay

    hmm, try this
    World.playEffect(location, effect, int);
     
  3. Offline

    haveric

    None of those are the 'pop' sound that is used when picking up items.
     
  4. Offline

    CorrieKay

    Yeah, im not sure its possible. Think about it, the pop is a player specific noise, noone else around you hears it but you (uh, that is, i think...)
     
  5. Offline

    Codex Arcanum

    Perhaps you could cancel the item pickup event every time it occurs, then add the items to the player's inventory? That way as far the client is concerned, the player never picked up the item, he just walked by and it happend to appear in his inventory.
     
  6. Offline

    haveric

    That is how I have it right now. The problem is that the default sound that is played when you normally pick up items does not occur when you cancel the event. I'm trying to fake that sound in some way.
     
  7. Offline

    Codex Arcanum

    Oh. Excuse me. I completely misread the OP. I thought the change you were trying to make was *removing* the popping sound.

    I know spout can play arbitrary sounds easily enough, but I bet you want a vanilla solution.

    Thought: You could allow the items to be picked up, then remove the item from the inventory (popping sound occurs normally), then do whatever you want with the item before adding it to the inventory.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 25, 2016
  8. Offline

    CorrieKay

    True, but thats only a workaround. Maybe theres a way to do all of what the OP wants to do without cancelling the event, maybe..?
     
  9. Offline

    Technius

    Let me see what I can do...

    Ok, I believe this should work. It's untested, and you'll need to use craftbukkit.jar for it.
    Code:java
    1. Player player = event.getPlayer();
    2. Item item = event.getItem();
    3. net.minecraft.server.EntityItem mcItem = ((CraftWorld)item).getHandle();
    4. net.minecraft.server.World mcWorld = ((CraftWorld)player.getWorld()).getHandle();
    5. mcWorld.makeSound(mcItem, "random.pop", 0.2F, ((mcItem.random.nextFloat() - mcItem.random.nextFloat()) * 0.7F + 1.0F) * 2.0F);


    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 25, 2016
  10. Offline

    haveric

    I tried to play with that and couldn't get anything to work. I've never worked directly with CraftBukkit though so it's a little strange to me.

    The errors I'm getting running that code are a "Type mismatch: cannot convert from WorldServer to EntityItem" on the third line "((CraftWorld)item).getHandle();"
    and "The field Entity.random is not visible" on the fifth line.
     
  11. Offline

    Giant

    that might because this one:
    "((CraftWorld)item).getHandle();"
    should be:
    "((CraftItem)item).getHandle();"
     
  12. Offline

    haveric

    Here is what I have so far then:

    Code:
            Player player = event.getPlayer();
            Item item = event.getItem();
            net.minecraft.server.EntityItem mcItem = (EntityItem) ((CraftItem)item).getHandle();
            net.minecraft.server.World mcWorld = ((CraftWorld)player.getWorld()).getHandle();
            mcWorld.makeSound(mcItem, "random.pop", 0.2F, ((mcWorld.random.nextFloat() - mcWorld.random.nextFloat()) * 0.7F + 1.0F) * 2.0F);
            item.remove();
            event.setCancelled(true);
    The mcItem.random.nextFloat() is still giving an error that random is not available. I'm assuming this means mcItem is incorrect still. Anyone know what it should be?

    Edit: Modified the code and it now compiles fine. Unfortunately, the sound does not happen. Anybody have an idea why?
     
  13. Offline

    nisovin

    I'm pretty sure the makeSound method doesn't do anything on the server. It's just left over from code being copied from the client. I think something like this should work:

    Code:
    
        public void collectItem(Player player, Item item) {
            Packet22Collect packet = new Packet22Collect(item.getEntityId(), player.getEntityId());
            ((CraftPlayer)player).getHandle().netServerHandler.sendPacket(packet);
        }
    
    You should call this method before calling the remove() method on the Item.
     
    haveric likes this.
  14. Offline

    haveric

    This does the trick, thank you! Now to figure out the other problems with picking up items. I'll create a new issue for that though if I can't figure it out in a couple days.
     
  15. Offline

    haveric

    I know I marked this as solved, but I came upon another problem while fixing a bug that still relates to this. The problem is when you pick up a stack of items with a nearly full inventory. (say you have 1 slot half full, the rest full, and picking up a full stack) Here's my current code to help understand what I'm doing:
    Code:
    Player player = event.getPlayer();
    Item item = event.getItem();
    ItemStack stack = item.getItemStack();
     
    int numLeft = event.getRemaining();
    collectItem(player, item);
    if (numLeft == 0){
     
    item.remove();
    } else {
    ItemStack originalStack = stack.clone();
    originalStack.setAmount(stack.getAmount() + numLeft);
     
    scheduleSetRemainingAmount(player, originalStack, numLeft);
    }
    scheduleSetRemainingAmount finds the first entity matching the picked up entity and sets the correct amount that should be remaining (numLeft).

    This all works fine, except that because I am calling the collectItem, the item visually disappears, although it is still there and can be picked up.

    What I am wondering is if it is possible to create a fake item that can be passed to collectItem() allowing the original to remain visually on screen, while still keeping the 'pop' sound.
     
Thread Status:
Not open for further replies.

Share This Page