package nl.lang2619.bagginses.event; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.event.entity.player.PlayerDropsEvent; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import nl.lang2619.bagginses.Bagginses; import java.util.ListIterator; /** * Created by alex on 23/05/16. */ public class SoulBoundEventHandler { private boolean isSoulBound(ItemStack stack) { try { if (stack != null && stack.getTagCompound() != null && stack.getTagCompound().hasKey("soulbound") && stack.getTagCompound().getBoolean("soulbound")) { return true; } } catch (Exception e){ } return false; } /* * Code taken with love from EnderIO by SleepyTrousers * https://github.com/SleepyTrousers/EnderIO/blob/master/src/main/java/crazypants/enderio/enchantment/EnchantmentSoulBound.java */ /* * This is called the moment the player dies and drops his stuff. * * We go early, so we can get our items before other mods put them into some * grave. Also remove them from the list so they won't get duped. If the * inventory overflows, e.g. because everything there and the armor is * soulbound, let the remainder be dropped/graved. */ @SubscribeEvent(priority = EventPriority.HIGHEST) public void onPlayerDeath(PlayerDropsEvent evt) { if (evt.getEntityPlayer() == null || evt.getEntityPlayer() instanceof FakePlayer || evt.isCanceled()) { return; } if(evt.getEntityPlayer().worldObj.getGameRules().getBoolean("keepInventory")) { return; } ListIterator<EntityItem> iter = evt.getDrops().listIterator(); while (iter.hasNext()) { EntityItem ei = iter.next(); ItemStack item = ei.getEntityItem(); if(isSoulBound(item)) { if (addToPlayerInventory(evt.getEntityPlayer(), item)) { Bagginses.analytics.eventDesign("playerDied:Soulbound", Bagginses.analytics.userPrefix()); iter.remove(); } } } } /* * This is called when the user presses the "respawn" button. The getOriginal() * inventory would be empty, but onPlayerDeath() above placed items in it. * * Note: Without other death-modifying mods, the content of the old inventory * would always fit into the new one (both being empty but for soulbound items * in the old one) and the old one would be discarded just after this method. * But better play it safe and assume that an overflow is possible and that * another mod may move stuff out of the old inventory, too. */ @SubscribeEvent public void onPlayerClone(PlayerEvent.Clone evt) { if (!evt.isWasDeath() || evt.isCanceled()) { return; } if(evt.getOriginal() == null || evt.getEntityPlayer() == null || evt.getEntityPlayer() instanceof FakePlayer) { return; } if(evt.getEntityPlayer().worldObj.getGameRules().getBoolean("keepInventory")) { return; } for (int i = 0; i < evt.getOriginal().inventory.mainInventory.length; i++) { ItemStack item = evt.getOriginal().inventory.mainInventory[i]; if(isSoulBound(item)) { if (addToPlayerInventory(evt.getEntityPlayer(), item)) { evt.getOriginal().inventory.mainInventory[i] = null; } } } for (int i = 0; i < evt.getOriginal().inventory.armorInventory.length; i++) { ItemStack item = evt.getOriginal().inventory.armorInventory[i]; if(isSoulBound(item)) { if (addToPlayerInventory(evt.getEntityPlayer(), item)) { evt.getOriginal().inventory.armorInventory[i] = null; } } } } private boolean addToPlayerInventory(EntityPlayer entityPlayer, ItemStack item) { if(item == null || entityPlayer == null) { return false; } if(item.getItem() instanceof ItemArmor) { ItemArmor arm = (ItemArmor) item.getItem(); int index = 3 - arm.armorType.getIndex(); if(entityPlayer.inventory.armorItemInSlot(index) == null) { entityPlayer.inventory.armorInventory[index] = item; return true; } } InventoryPlayer inv = entityPlayer.inventory; for (int i = 0; i < inv.mainInventory.length; i++) { if(inv.mainInventory[i] == null) { inv.mainInventory[i] = item.copy(); return true; } } return false; } }