# Solved Removing certain item on a PlayerDeathEvent

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

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?

#1
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.

#2
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

#3
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.

#4
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)

#5
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.....

#6
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() )

#7
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 {
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);
}
}
}
}```

#8
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 :/

#10
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

#11
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:

[21:10:10 ERROR]: Could not pass event PlayerDeathEvent to Adventure v1.0
org.bukkit.event.EventException
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 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]
Caused by: java.lang.NullPointerException
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]
... 27 more

So, how on earth do I fix this!?!?

#12
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 islayer.getInventory())
if(is.getType() == Material.EMERALD)
//do stuff

Sent from my iPhone using Tapatalk

#13
14. Offline

### CodeAX2

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

#14
15. Offline

#15
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!

#16
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

#17
18. Offline

@CodeAX2