package crazypants.enderio.item; import java.util.ArrayList; import java.util.List; import net.minecraft.block.Block; import net.minecraft.block.BlockFence; import net.minecraft.block.BlockWall; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.boss.IBossDisplayData; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.util.Facing; import net.minecraft.util.IIcon; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; import com.enderio.core.api.client.gui.IResourceTooltipProvider; import com.enderio.core.common.util.DyeColor; import com.enderio.core.common.util.EntityUtil; import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import crazypants.enderio.EnderIO; import crazypants.enderio.EnderIOTab; import crazypants.enderio.ModObject; import crazypants.enderio.config.Config; public class ItemSoulVessel extends Item implements IResourceTooltipProvider { public static ItemSoulVessel create() { ItemSoulVessel result = new ItemSoulVessel(); result.init(); return result; } private IIcon filledIcon; private List<String> blackList; protected ItemSoulVessel() { setCreativeTab(EnderIOTab.tabEnderIO); setUnlocalizedName(ModObject.itemSoulVessel.unlocalisedName); setMaxStackSize(64); blackList = new ArrayList<String>(); for (String ent : Config.soulVesselBlackList) { blackList.add(ent); } } protected void init() { GameRegistry.registerItem(this, ModObject.itemSoulVessel.unlocalisedName); } public void addEntityToBlackList(String entityName) { blackList.add(entityName); } @Override @SideOnly(Side.CLIENT) public void registerIcons(IIconRegister IIconRegister) { itemIcon = IIconRegister.registerIcon("enderio:soulVessel"); filledIcon = IIconRegister.registerIcon("enderio:soulVesselFilled"); } @Override public IIcon getIcon(ItemStack item, int arg1, EntityPlayer arg2, ItemStack arg3, int arg4) { if(containsSoul(item)) { return filledIcon; } return itemIcon; } @Override @SideOnly(Side.CLIENT) public IIcon getIconIndex(ItemStack item) { if(containsSoul(item)) { return filledIcon; } return itemIcon; } @Override @SideOnly(Side.CLIENT) public boolean hasEffect(ItemStack item, int pass) { return containsSoul(item); } @Override public boolean onItemUse(ItemStack itemstack, EntityPlayer player, World world, int x, int y, int z, int side, float xOffset, float yOffset, float zOffset) { if(world.isRemote) { return true; } if(!containsSoul(itemstack)) { return false; } if(player == null) { return false; } Entity mob; NBTTagCompound root = itemstack.stackTagCompound; if(root.hasKey("isStub")) { String entityId = root.getString("id"); mob = EntityList.createEntityByName(entityId, world); } else { mob = EntityList.createEntityFromNBT(root, world); } if (mob == null) { return true; } mob.readFromNBT(root); Block blk = world.getBlock(x,y,z); double spawnX = x + Facing.offsetsXForSide[side] + 0.5; double spawnY = y + Facing.offsetsYForSide[side]; double spawnZ = z + Facing.offsetsZForSide[side] + 0.5; if(side == ForgeDirection.UP.ordinal() && (blk instanceof BlockFence || blk instanceof BlockWall)) { spawnY += 0.5; } mob.setLocationAndAngles(spawnX, spawnY, spawnZ, world.rand.nextFloat() * 360.0F, 0); boolean spaceClear = world.checkNoEntityCollision(mob.boundingBox) && world.getCollidingBoundingBoxes(mob, mob.boundingBox).isEmpty(); if(!spaceClear) { return false; } if(itemstack.hasDisplayName() && mob instanceof EntityLiving) { ((EntityLiving)mob).setCustomNameTag(itemstack.getDisplayName()); } world.spawnEntityInWorld(mob); if(mob instanceof EntityLiving) { ((EntityLiving)mob).playLivingSound(); } Entity riddenByEntity = mob.riddenByEntity; while(riddenByEntity != null) { riddenByEntity.setLocationAndAngles(spawnX, spawnY, spawnZ, world.rand.nextFloat() * 360.0F, 0.0F); world.spawnEntityInWorld(riddenByEntity); if(riddenByEntity instanceof EntityLiving) { ((EntityLiving)riddenByEntity).playLivingSound(); } riddenByEntity = riddenByEntity.riddenByEntity; } if (!player.capabilities.isCreativeMode) { if(itemstack.stackSize > 1) { itemstack.stackSize--; player.inventory.addItemStackToInventory(new ItemStack(this)); player.inventoryContainer.detectAndSendChanges(); } else { itemstack.setTagCompound(null); } } return true; } @Override public boolean itemInteractionForEntity(ItemStack item, EntityPlayer player, EntityLivingBase entity) { if(entity.worldObj.isRemote) { return false; } boolean isCreative = player != null && player.capabilities.isCreativeMode; if(containsSoul(item) && !isCreative) { return false; } if(entity instanceof EntityPlayer) { return false; } String entityId = EntityList.getEntityString(entity); if(isBlackListed(entityId)) { return false; } if(!Config.soulVesselCapturesBosses && entity instanceof IBossDisplayData) { return false; } NBTTagCompound root = new NBTTagCompound(); root.setString("id", entityId); entity.writeToNBT(root); ItemStack capturedMobVessel = new ItemStack(EnderIO.itemSoulVessel); capturedMobVessel.setTagCompound(root); setDisplayNameFromEntityNameTag(capturedMobVessel, entity); player.swingItem(); if(!isCreative) { entity.setDead(); if(entity.isDead) { item.stackSize--; if (!player.inventory.addItemStackToInventory(capturedMobVessel)) { entity.worldObj.spawnEntityInWorld(new EntityItem(entity.worldObj,entity.posX, entity.posY, entity.posZ, capturedMobVessel)); } player.setCurrentItemOrArmor(0, item); ((EntityPlayerMP) player).sendContainerToPlayer(player.inventoryContainer); return true; } } else { if (!player.inventory.addItemStackToInventory(capturedMobVessel)) //Inventory full, drop it in the world! { entity.worldObj.spawnEntityInWorld(new EntityItem(entity.worldObj,entity.posX, entity.posY, entity.posZ, capturedMobVessel)); } ((EntityPlayerMP) player).sendContainerToPlayer(player.inventoryContainer); return true; } return false; } public ItemStack createVesselWithEntityStub(String entityId) { NBTTagCompound root = new NBTTagCompound(); root.setString("id", entityId); root.setBoolean("isStub", true); ItemStack res = new ItemStack(this); res.stackTagCompound = root; return res; } public ItemStack createVesselWithEntity(Entity ent) { String entityId = EntityList.getEntityString(ent); NBTTagCompound root = new NBTTagCompound(); root.setString("id", entityId); ent.writeToNBT(root); ItemStack res = new ItemStack(this); res.stackTagCompound = root; setDisplayNameFromEntityNameTag(res, ent); return res; } private void setDisplayNameFromEntityNameTag(ItemStack item, Entity ent) { if(ent instanceof EntityLiving) { EntityLiving entLiv = (EntityLiving)ent; if(entLiv.hasCustomNameTag()) { String name = entLiv.getCustomNameTag(); if(name.length() > 0) { item.setStackDisplayName(name); } } } } public boolean containsSoul(ItemStack item) { if(item == null) { return false; } if(item.getItem() != this) { return false; } return item.stackTagCompound != null && item.stackTagCompound.hasKey("id"); } public String getMobTypeFromStack(ItemStack item) { if(!containsSoul(item)) { return null; } if(item.stackTagCompound == null || !item.stackTagCompound.hasKey("id")) { return null; } return item.stackTagCompound.getString("id"); } /** Support for displaying fluid name of captured Moo Fluids cow */ private String getFluidNameFromStack(ItemStack item) { if(!containsSoul(item)) { return null; } if(!item.stackTagCompound.hasKey("FluidName")) { return null; } return item.stackTagCompound.getString("FluidName"); } private DyeColor getColorFromStack(ItemStack item) { if(!containsSoul(item)) { return null; } if(!item.stackTagCompound.hasKey("Color")) { return null; } int colorIdx = item.stackTagCompound.getInteger("Color"); if(colorIdx < 0 || colorIdx > 15) { return null; } return DyeColor.values()[15-colorIdx]; } private float getHealthFromStack(ItemStack item) { if(!containsSoul(item)) { return Float.NaN; } if(!item.stackTagCompound.hasKey("HealF")) { return Float.NaN; } return item.stackTagCompound.getFloat("HealF"); } private NBTTagCompound getAttributeFromStack(ItemStack item, String name) { if(!containsSoul(item)) { return null; } NBTBase tag = item.stackTagCompound.getTag("Attributes"); if(tag instanceof NBTTagList) { NBTTagList attributes = (NBTTagList)tag; for(int i=0 ; i<attributes.tagCount() ; i++) { NBTTagCompound attrib = attributes.getCompoundTagAt(i); if(attrib.hasKey("Name") && name.equals(attrib.getString("Name"))) { return attrib; } } } return null; } private float getMaxHealthFromStack(ItemStack item) { NBTTagCompound maxHealthAttrib = getAttributeFromStack(item, "generic.maxHealth"); if(maxHealthAttrib == null) { return Float.NaN; } if(!maxHealthAttrib.hasKey("Base")) { return Float.NaN; } return maxHealthAttrib.getFloat("Base"); } private boolean isBlackListed(String entityId) { for (String str : blackList) { if(str != null && str.equals(entityId)) { return true; } } return false; } @Override public String getUnlocalizedNameForTooltip(ItemStack itemStack) { return getUnlocalizedName(itemStack); } @Override @SideOnly(Side.CLIENT) public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { if(par1ItemStack != null) { String mobName = getMobTypeFromStack(par1ItemStack); if(mobName != null) { par3List.add(EntityUtil.getDisplayNameForEntity(mobName)); } else { par3List.add(EnderIO.lang.localize("item.itemSoulVessel.tooltip.empty")); } float health = getHealthFromStack(par1ItemStack); if(health >= 0) { float maxHealth = getMaxHealthFromStack(par1ItemStack); String msg = EnderIO.lang.localize("item.itemSoulVessel.tooltip.health"); if(maxHealth >= 0) { par3List.add(String.format("%s %3.1f/%3.1f", msg, health, maxHealth)); } else { par3List.add(String.format("%s %3.1f", msg, health)); } } String fluidName = getFluidNameFromStack(par1ItemStack); if(fluidName != null) { Fluid fluid = FluidRegistry.getFluid(fluidName); if(fluid != null) { par3List.add(EnderIO.lang.localize("item.itemSoulVessel.tooltip.fluidname") + " " + fluid.getLocalizedName()); } } DyeColor color = getColorFromStack(par1ItemStack); if(color != null) { par3List.add(EnderIO.lang.localize("item.itemSoulVessel.tooltip.color") + " " + color.getLocalisedName()); } } } }