Question regarding the 'pop' sound when picking up an item

Discussion in 'Plugin Development' started by bergerkiller, Dec 29, 2011.

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

    bergerkiller

    How can I fake this sound anywhere in the world? I want a non-player entity to 'pick up' an item, but to truly make that come to life a 'pop' sound would be awesome.

    I tried using:
    Code:
        public static void pickUpAnimation(Item item, Entity by) {
            pickUpAnimation(getNative(item), getNative(by));
        }
        public static void pickUpAnimation(EntityItem item, net.minecraft.server.Entity by) {
            ((WorldServer) item.world).tracker.a(by, new Packet22Collect(item.id, by.id));
        }
    But this crashes the client. Any other way to achieve this?
     
  2. Offline

    Father Of Time

    Not to diverge the topic, but have you ever noticed that when you pick up an item that not only does it make that "pop" sound, but it also performs a scale animation on the item that was picked up? By this I mean if you have 32 wool in your inventory and pick up another it will cause the stack on you to temporarily grow in size and then slowly shrink back down (in the span of like 0.5 seconds).

    I was going to suggest checking out this site about packets:
    http://mc.kev009.com/Protocol#Sound.2Fparticle_effect_.280x3D.29

    But it appears you have already tried that... outside of that I would simply be guessing and sending you on wild goose chases. But as I said above maybe the two effects are interrelated, try to see if you can force the "grow" animation, maybe that will automatically trigger the "pop" sound too (like nether particles).

    Sorry, all I've managed to do is speculate... Good luck though!
     
  3. Offline

    bergerkiller

    @Father Of Time yeah I now use the CLICK1 sound, it does fit pretty well. Would prefer the pop sound though, but afraid it's badly implemented...

    Isn't the 'shrinking' done by the client after receiving the collect packet?
     
  4. Offline

    hatstand

    Couldn't you make the client pick up a fake item, or an item that's removed as it's picked up?
     
  5. Offline

    bergerkiller

    @hatstand Well the problem is that the item isn't collected by a player: it is collected by a storage minecart :)
    It's a new feature for TrainCarts. The movement of the item is already working (storage minecarts attract items and pick them up), all that remains is having a sound play when the minecart picks it up.

    It's basically the third-person sound I need when a player hears *something* pick up an item. Sadly the collect packet (which is used by the players) causes the client to crash if uses with a 'picked up-entity id' other than that of a player.
     
  6. Offline

    Father Of Time

    That's a shame to hear, I too was hoping to find the pop sound awhile back; but due to larger priorities never put much effort into the hunt. I would imagine the animation is handled client side as you've suggested, but I would once again only be speculating.

    I only noticed the animation about a week or two ago when I was having issues with item stack quantities not updating properly when the consumption was being triggered by an ACTION_RIGHT_CLICK_BLOCK. For what ever reason when you right click an object it doesn't update a players inventory, but when you left click it does. I was starring really closely at the stack when consuming from it to see if the count went down, and that's when I noticed the growth animation.

    I would definitely like to invest some research into this, because I am currently cleaning up a shop mod for my server that allows players to purchase and sell potions and enchanted items, and it would be pretty nice to add the pop sounds and growth animations to items that were purchased.

    It saddens me how inaccessible animations/sounds effects are in Minecraft. Particle systems, animations and sound effects are an amazingly great way to create unique feel for game objects. By simply changing a few variables (particle size, color, speed, gravity) you can virtually create an infinite array of looks and feels...

    *dreams of particle systems in Minecraft*

    I know very little about Minecraft effects, so please forgive me if what I am about to suggest is as painfully obvious as I feel saying it; but have you looked into the following function?
    http://jd.bukkit.org/doxygen/dd/daa...1World.html#a07ba2f1e86dc7f30165f78ac3bdd8984

    Code:
    void org.bukkit.World.playEffect     (     Location      location,
            Effect      effect,
            int      data
        )
    
    Plays an effect to all players within a default radius around a given location.
    
    Parameters:
        location    the Location around which players must be to hear the sound
        effect    the Effect
        data    a data bit needed for the RECORD_PLAY, SMOKE, and STEP_SOUND sounds 
    I use it for RiftCraft to play animations on both sides of the teleport (where they teled away from and where they arrive) and I haven't experienced any issues; maybe you can utilize this function to play that sound.

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

    bergerkiller

    @Father Of Time yeah I looked into it, and there are random occasions where it is used for other things too (like piston animations)
    Wish it was a bit more documented...I'll look at the native client coding and look around a bit.
     
  8. Offline

    Father Of Time

    @bergerkiller Awsome, if you remember please report back with your findings, I would love to know more about this function and what all it can handle. I apologize for not assisting you with the hunt, but I am currently at work and don't have any of my software to experiment as I read, which leads to the throwing around of assumptions (like I have done this entire post ;))

    I wish you success with your venture!
     
  9. Offline

    bergerkiller

    @Father Of Time bad news: the client uses the playNote function for blocks only. This means that all it can control is blocks. For example, play notes on note blocks and change pistons. Basically all sounds and animations a block can make, like buttons, levers, pistons and doors. Also things like the bow sounds are there, because of the dispenser shooting sound. No entity sounds can be controlled from there :(
     
  10. Offline

    Father Of Time

    @bergerkiller Well that is weak, no idea why there needs to be a differentiation between an entity sound effect and a block sound effect; a sound is a sound, let people trigger it when they want!

    Also, I noticed you said playNote function, I wasn't aware of this function initially and it does make sense that it would only be able to play block sound effects (since music notes only originate from blocks).

    However, did you ever try utilizing the function I mentioned above, something like this:

    Code:
            World world = //..Your world
            Location location = //..Your location
            Effect effect = new Effect( EFFECTID );
            world.playEffect( SpawnLocation, Effect );
    When I was looking at the Effect enum it was nothing more than an integer associated with an effect name, so essentially you should be able to create a new effect with any id you want (the constructor allows you to pass the effect as a parameter) and then pass it to the playEffect function.

    The only thing I am totally unaware of atm is what ID value the "pop" sound is assigned to, but I would definitely fiddle around with the above code, because so far it has worked for every other application I've tried using it for.

    *Taps foot* is it time for me to go home yet so I can experiment! :oops:
     
  11. Offline

    hatstand

    @bergerkiller I think you misunderstood me - Use the fake pickup to emulate the sound for each player. Probably incredibly inefficient.
     
  12. Offline

    bergerkiller

    @hatstand This would cause the first person sound to play all the time, which means a player hears a loud pop from whatever distance they are. Alternatively I could 'temporarily' spawn a player at the location, send the packet and kill it again, but afraid that the player will be visible for a slick second...

    This is done in the client net server handler; the packet54playnoteblock is used for all 'special' sound effects. The world.playNoteAt finds out the ID of that block and calls playNote on that block type. The block type handles further effects.
    Code:
        public void handleNotePlay(Packet54PlayNoteBlock packet54playnoteblock)
        {
            mc.theWorld.playNoteAt(packet54playnoteblock.xLocation, packet54playnoteblock.yLocation, packet54playnoteblock.zLocation, packet54playnoteblock.instrumentType, packet54playnoteblock.pitch);
        }
    Code:
        public void playNoteAt(int i, int j, int k, int l, int i1)
        {
            int j1 = getBlockId(i, j, k);
            if(j1 > 0)
            {
                Block.blocksList[j1].playBlock(this, i, j, k, l, i1);
            }
        }
    EDIT

    However, I can play sound effects that are not of a certain block fine in the air...let me check a bit more...

    Ok ignore the above, wrong idea at all.
    First of all:
    - Block sounds and animations are done through the 'playNote' packet, which changes based on the block a client sees.
    - Other sounds are called 'Word events' and use the Packet61WorldEvent packet. It is not very well documented.
    Code:
    Packet61WorldEvent packet = new Packet61WorldEvent(packetData, location.getBlockX(), location.getBlockY(), location.getBlockZ(), data);
    Now checking at the client where this packet is used.

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

    Father Of Time

    I am just trying to clarify, sorry for repeating myself. Do we keep talking about two different functions?

    I'm saying:
    World.playEffect

    And you are saying:
    World.playNote

    Is what you are saying is that regardless of which of the above functions you call, both pass the information to the same packet, which is "Packet54playnoteblock"? I just want to make sure that you have already confirmed my suggestion is flawed and moved on, and not that we are simply on two different pages.

    Okay, I think you are saying what I was assuming, that regardless of what function you use they all utilize the same packet to deliver the data to the client, and the client uses the packet data combined with the block data (that its aware of due to being client side) to determine the proper effect to be executed?

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

    bergerkiller

    @Father Of Time now staring at the decompiled client source code. In the client it is called 'playAuxSFX':
    Code:
        public void playAuxSFX(int i, int j, int k, int l, int i1)
        {
            playAuxSFXAtEntity(null, i, j, k, l, i1);
        }
    
        public void playAuxSFXAtEntity(EntityPlayer entityplayer, int i, int j, int k, int l, int i1)
        {
            for(int j1 = 0; j1 < worldAccesses.size(); j1++)
            {
                ((IWorldAccess)worldAccesses.get(j1)).playAuxSFX(entityplayer, i, j, k, l, i1);
            }
    
        }
    Now tracing this back to the effect list.

    Here ya go, all possible effects that can be used.

    The only thing the current API doesn't cover is the use of these spell effects, they seem to go under a separate ID.

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

    caldabeast

    I've been trying to use this so that records can activate jukeboxes, but I can't seem to make the "effect" variable work... Do you know what im doing wrong?

    Code:
    Location jukeboxLoc = jukebox.getLocation();
            boolean useMeta = false;
            World world = poweredBlock.getWorld();
            Effect effect = new Effect(RECORD_PLAY);
            if (jukeboxData == 84 && tuneTypeData != 0) {
                switch (tuneTypeData) {
                case 35: useMeta = true;
                default: break;
                } switch (tuneTypeMeta) {
                case 1: world.playEffect(world, effect, 2,recordIDGoesHereMaybe?);
                }
            }
    And also, do you know what I would use for the second integer in that list (meaning what id's would I use to select which record)?
    bergerkiller
     
  16. Offline

    Zacherl

Thread Status:
Not open for further replies.

Share This Page