Solved Removing certain item on a PlayerDeathEvent

Discussion in 'Plugin Development' started by CodeAX2, Feb 19, 2017.

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

    CodeAX2

    Hello there! I am currently creating a plugin in which emeralds are used as a form of currency. here is my dilemma: when a player dies, I want them to keep all of their items, but lose, say 25%, of all of the emeralds in their inventory. How would I go about doing this? I'm fairly new to java, but I am able to understand semi-complicated code. Any thoughts on how I could do this?
     
  2. Offline

    Zombie_Striker

    @CodeAX2
    1. on player death
    2. create an int. This represents the amount of emeralds a player has.
    3. For loop through the inventory's contents.
    4. If the item from the loop is equal to an emerald, add the amount to the int.
    5. Exit the for loop.
    6. Now, divide the int by 4 (for 25 percent). This is now the amount you need to remove
    7. For loop again through the inventory again.
    8. If the type is equal to emeralds, check if the amount is greater than or equal to the int.
    9. If it is, set the amount equal to the amount minus the int. Reset the item and break out of the loop.
    10. If it is not, subtract the amount from the int and remove the itemstack.
     
  3. Offline

    CodeAX2

    1. How do I set up the for loop to look through the players inventory? Do i just need to do
    for(int i = 0; i < SPOTS_IN_INVENTORY; i++) ?
    2. And then what exactly do I put into the for loop?
    3. How do I reset the item?

    Sorry I'm kinda a noob at this still
     
  4. Offline

    Irantwomiles

    1) yes
    2) inside the for loop you want to get each item so you can check if it is the emerald or not, and if it is the emerald keep track of the value somewhere so you can access it later.
    3) I'm not sure what you mean by reset the item, but like @Zombie_Striker said, you'd want to divide that integer you kept track of by 4 (25%) and subtract it by the original amount.

    After you follow those steps you need to get the players inventory on the PlayerRespawnEvent and add the players items back to their inventory. I would personally use a HashMap<UUID, ArrayList<ItemStack>> to keep track of stuff when the player dies so that way it would be really easy to modify the list inside the hashmap and add the items back, but it might get messy nesting a collection inside a collection.
     
  5. Offline

    Zombie_Striker

    @CodeAX2
    1. Yes
    2. To get the itemstack, use Inventory#get(int-from-for-loop)
    3. Inventory#setItem(int-from-for-loop, modified-item)
     
  6. Offline

    CodeAX2

    Not sure where to go from where now.
    Code:
                Inventory inv = e.getEntity().getInventory();
                for(int i = 0; i < 36; i++){
                    Items items = inv.get(i);
                    if(items.equals(Material.EMERALD)){
    inv.get(i); returns an error, since I probably set it up wrong. how could I fix it? And then also, how do I get the amount of the item? I think it is something like this:
    Int newAmount = items.getAmount();
    But Im not sure.....
     
  7. Offline

    Zombie_Striker

    @CodeAX2
    1. Item is not the same as an ItemStack. Item is the entity that is dropped on the ground. ItemStack is the items in inventories. That should have thrown an error.
    2. Items (or itemstacks) are not equal to Materials. Those are two different types of objects. Use items.getType() to get the itemstack's type.
    3. Did you create the int yet? If so, now you will want to add the itemstakc's amount to the int (int+=items.getAmount() )
     
  8. Offline

    CodeAX2

    So, I believe I set up the code correctly, but it doesn't seem to work in game. There are no errors in eclipse. Not sure if this effects anything, but gamerule keepInventory is set to true. Here is my code:

    Code:
    package Adventure;
    
    import org.bukkit.Material;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.entity.PlayerDeathEvent;
    import org.bukkit.inventory.ItemStack;
    
    
    public class PlayerDeaths implements Listener {
        public PlayerDeaths(Adventure plugin){
            plugin.getServer().getPluginManager().registerEvents(this, plugin);
        }
       
       
        @EventHandler
        public void onPlayerDeath(PlayerDeathEvent e){
                int amnt = 0;
                for(int  i = 0; i < 32; i++){
                    ItemStack emeralds = e.getEntity().getInventory().getItem(i);
                    if(emeralds.getType() == Material.EMERALD){
                        int newamount = emeralds.getAmount();
                        amnt += newamount;
                    }
                }
                amnt /= 4;
                for(int i = 0; i < 32; i++){
                    ItemStack emeralds = e.getEntity().getInventory().getItem(i);
                    if(emeralds.getType() == Material.EMERALD){
                        int emeraldsAmnt = emeralds.getAmount();
                        if(emeralds.getAmount() >= amnt){
                            emeralds.setAmount(emeraldsAmnt - amnt);
                            break;
                        } else {
                            amnt -= emeraldsAmnt;
                            emeralds.setAmount(0);
                        }
                    }
                }
            }
     
  9. Offline

    PhantomUnicorns

    What part is not working? Also I think if you save the itemstacks in a variable it won't work try setting the itemstack you created at the end to the same int value, e.i. iventory.setItem(int, item);
    If ^ doesn't work debug it and show your results!
     
  10. Offline

    CodeAX2

    I tried adding in a few of the things you suggested. Here is my code:
    Code:
        @EventHandler
        public void onPlayerDeath(PlayerDeathEvent e){
                int amnt = 0;
                int newamount = 0;
                for(int  i = 0; i < 32; i++){
                    ItemStack emeralds = e.getEntity().getInventory().getItem(i);
                    if(emeralds.getType() == Material.EMERALD){
                        newamount = emeralds.getAmount();
                        amnt += newamount;
                    }
                }
                amnt /= 4;
                for(int i = 0; i < 32; i++){
                    ItemStack emeralds = e.getEntity().getInventory().getItem(i);
                    if(emeralds.getType() == Material.EMERALD){
                        int emeraldsAmnt = emeralds.getAmount();
                        if(emeraldsAmnt >= amnt){
                            e.getEntity().getInventory().remove(new ItemStack(Material.EMERALD, amnt));
                            break;
                        } else {
                            amnt -= emeraldsAmnt;
                            e.getEntity().getInventory().remove(emeralds);
                        }
                    }
                }
            }
    It still is not working in game. I'm not sure what part of my code isn't working. Also debug didn't work for me :/
     
  11. Offline

    dNiym

    Okay by debug he means put some system.out's in for letting you know what the code is doing in the console.

    Speaking of which have you looked at the console when a player dies? Any errors? If so pastebin them.


    Sent from my iPhone using Tapatalk
     
  12. Offline

    CodeAX2

    After doing some testing and troubleshooting, I have come to the conclusion that this part in my code is not working:

    Code:
    if(emeralds.getType().equals(Material.EMERALD)){
                        amnt = amnt + emeralds.getAmount();
                    }
    What I'm assuming is happening, is that as it sweeps your inventory, when the program comes across an empty spot, it ends the whole loop for some reason, since that spot has a null item. This is supported by my server's console:

    Show Spoiler

    [21:10:10 ERROR]: Could not pass event PlayerDeathEvent to Adventure v1.0
    org.bukkit.event.EventException
    at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:298) ~[craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:501) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:486) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at org.bukkit.craftbukkit.v1_11_R1.event.CraftEventFactory.callPlayerDeathEvent(CraftEventFactory.java:410) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at net.minecraft.server.v1_11_R1.EntityPlayer.die(EntityPlayer.java:417) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at net.minecraft.server.v1_11_R1.EntityLiving.damageEntity(EntityLiving.java:923) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at net.minecraft.server.v1_11_R1.EntityHuman.damageEntity(EntityHuman.java:782) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at net.minecraft.server.v1_11_R1.EntityPlayer.damageEntity(EntityPlayer.java:502) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at net.minecraft.server.v1_11_R1.EntityLiving.Q(EntityLiving.java:118) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at net.minecraft.server.v1_11_R1.CommandKill.execute(SourceFile:35) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at org.bukkit.craftbukkit.v1_11_R1.command.VanillaCommandWrapper.dispatchVanillaCommand(VanillaCommandWrapper.java:109) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at org.bukkit.craftbukkit.v1_11_R1.command.VanillaCommandWrapper.execute(VanillaCommandWrapper.java:38) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:140) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at org.bukkit.craftbukkit.v1_11_R1.CraftServer.dispatchCommand(CraftServer.java:629) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at net.minecraft.server.v1_11_R1.PlayerConnection.handleCommand(PlayerConnection.java:1285) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at net.minecraft.server.v1_11_R1.PlayerConnection.a(PlayerConnection.java:1145) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at net.minecraft.server.v1_11_R1.PacketPlayInChat.a(SourceFile:37) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at net.minecraft.server.v1_11_R1.PacketPlayInChat.a(SourceFile:9) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at net.minecraft.server.v1_11_R1.PlayerConnectionUtils$1.run(SourceFile:13) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_111]
    at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_111]
    at net.minecraft.server.v1_11_R1.SystemUtils.a(SourceFile:46) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at net.minecraft.server.v1_11_R1.MinecraftServer.D(MinecraftServer.java:695) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at net.minecraft.server.v1_11_R1.DedicatedServer.D(DedicatedServer.java:360) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at net.minecraft.server.v1_11_R1.MinecraftServer.C(MinecraftServer.java:650) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at net.minecraft.server.v1_11_R1.MinecraftServer.run(MinecraftServer.java:554) [craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_111]
    Caused by: java.lang.NullPointerException
    at Adventure.PlayerDeaths.onPlayerDeath(PlayerDeaths.java:22) ~[?:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_111]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_111]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_111]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_111]
    at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:296) ~[craftbukkit-1.11.2.jar:git-Bukkit-a1d3777]
    ... 27 more


    So, how on earth do I fix this!?!?
     
  13. Offline

    dNiym

    You could simply add an If statement to check if the item at the slot is null, if so continue;

    I prefer to do a for loop on just the items in the inventory instead of checking it on a per slot basis, personally so:

    for(ItemStack is:player.getInventory())
    if(is.getType() == Material.EMERALD)
    //do stuff


    Sent from my iPhone using Tapatalk
     
  14. Offline

    CodeAX2

    I think there was some sort of issue with the code u sent. Possible the emoji. Could you resent the code?
     
  15. Offline

    dNiym

  16. Offline

    CodeAX2

    Thank you all! It finally worked exactly how it should! I am extremely grateful since I have been working on this issue all day! You are all wonderful and helpful people!
     
    dNiym likes this.
  17. Offline

    dNiym

    Be sure and edit your title to solved so that hopefully it will answer others questions!


    Sent from my iPhone using Tapatalk
     
  18. Offline

    Zombie_Striker

    @CodeAX2
    If your problem has been solved, mark this thread as solved.
     
Thread Status:
Not open for further replies.

Share This Page