package openblocks.common.entity; import com.google.common.base.Strings; import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; import io.netty.buffer.ByteBuf; import net.minecraft.block.Block; import net.minecraft.entity.EntityAgeable; import net.minecraft.entity.ai.EntityAIFollowOwner; import net.minecraft.entity.ai.EntityAISwimming; import net.minecraft.entity.effect.EntityLightningBolt; import net.minecraft.entity.passive.EntityTameable; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemNameTag; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; import net.minecraftforge.common.util.Constants; import openblocks.OpenBlocks; import openblocks.OpenBlocksGuiHandler; import openblocks.common.entity.ai.EntityAICollectItem; import openmods.api.VisibleForDocumentation; import openmods.inventory.GenericInventory; import openmods.inventory.IInventoryProvider; import openmods.inventory.legacy.ItemDistribution; @VisibleForDocumentation public class EntityLuggage extends EntityTameable implements IInventoryProvider, IEntityAdditionalSpawnData { private static final int SIZE_SPECIAL = 54; private static final int SIZE_NORMAL = 27; private static final String TAG_ITEM_TAG = "ItemTag"; private static final String TAG_SHINY = "shiny"; protected GenericInventory inventory = createInventory(SIZE_NORMAL); private GenericInventory createInventory(int size) { return new GenericInventory("luggage", false, size) { @Override public boolean isUseableByPlayer(EntityPlayer player) { return !isDead && player.getDistanceSqToEntity(EntityLuggage.this) < 64; } }; } public boolean special; public int lastSound = 0; private NBTTagCompound itemTag; public EntityLuggage(World world) { super(world); setSize(0.5F, 0.5F); setAIMoveSpeed(0.7F); setMoveForward(0); setTamed(true); func_110163_bv(); // set persistent getNavigator().setAvoidsWater(true); getNavigator().setCanSwim(true); this.tasks.addTask(1, new EntityAISwimming(this)); this.tasks.addTask(2, new EntityAIFollowOwner(this, getAIMoveSpeed(), 10.0F, 2.0F)); this.tasks.addTask(3, new EntityAICollectItem(this)); this.dataWatcher.addObject(18, Integer.valueOf(inventory.getSizeInventory())); } public void setSpecial() { if (special) return; special = true; GenericInventory inventory = createInventory(SIZE_SPECIAL); inventory.copyFrom(this.inventory); if (this.dataWatcher != null) { this.dataWatcher.updateObject(18, Integer.valueOf(inventory.getSizeInventory())); } this.inventory = inventory; } public boolean isSpecial() { if (worldObj.isRemote) { return inventory.getSizeInventory() > SIZE_NORMAL; } return special; } @Override public void onLivingUpdate() { super.onLivingUpdate(); if (worldObj.isRemote) { int inventorySize = dataWatcher.getWatchableObjectInt(18); if (inventory.getSizeInventory() != inventorySize) { inventory = createInventory(inventorySize); } } lastSound++; } @Override public boolean isAIEnabled() { return true; } @Override public GenericInventory getInventory() { return inventory; } @Override public ItemStack getPickedResult(MovingObjectPosition target) { return convertToItem(); } @Override public EntityAgeable createChild(EntityAgeable entityageable) { return null; } @Override public boolean interact(EntityPlayer player) { if (!isDead) { final ItemStack heldItem = player.getHeldItem(); if (heldItem != null && heldItem.getItem() instanceof ItemNameTag) return false; if (worldObj.isRemote) { if (player.isSneaking()) spawnPickupParticles(); } else { if (player.isSneaking()) { ItemStack luggageItem = convertToItem(); if (player.inventory.addItemStackToInventory(luggageItem)) setDead(); playSound("random.pop", 0.5f, worldObj.rand.nextFloat() * 0.1f + 0.9f); } else { playSound("random.chestopen", 0.5f, worldObj.rand.nextFloat() * 0.1f + 0.9f); player.openGui(OpenBlocks.instance, OpenBlocksGuiHandler.GuiId.luggage.ordinal(), player.worldObj, getEntityId(), 0, 0); } } } return true; } protected void spawnPickupParticles() { final double py = this.posY + this.height; for (int i = 0; i < 50; i++) { double vx = rand.nextGaussian() * 0.02D; double vz = rand.nextGaussian() * 0.02D; double px = this.posX + this.width * this.rand.nextFloat(); double pz = this.posZ + this.width * this.rand.nextFloat(); this.worldObj.spawnParticle("portal", px, py, pz, vx, -1, vz); } } protected ItemStack convertToItem() { ItemStack luggageItem = new ItemStack(OpenBlocks.Items.luggage); NBTTagCompound tag = itemTag != null? (NBTTagCompound)itemTag.copy() : new NBTTagCompound(); inventory.writeToNBT(tag); luggageItem.setTagCompound(tag); String nameTag = getCustomNameTag(); if (!Strings.isNullOrEmpty(nameTag)) luggageItem.setStackDisplayName(nameTag); return luggageItem; } public void restoreFromStack(ItemStack stack) { final NBTTagCompound tag = stack.getTagCompound(); if (tag != null) { getInventory().readFromNBT(tag); if (getInventory().getSizeInventory() > SIZE_NORMAL) setSpecial(); NBTTagCompound tagCopy = (NBTTagCompound)tag.copy(); tagCopy.removeTag(GenericInventory.TAG_SIZE); tagCopy.removeTag(GenericInventory.TAG_ITEMS); this.itemTag = tagCopy.hasNoTags()? null : tagCopy; } if (stack.hasDisplayName()) setCustomNameTag(stack.getDisplayName()); } public boolean canConsumeStackPartially(ItemStack stack) { return ItemDistribution.testInventoryInsertion(inventory, stack) > 0; } @Override protected void func_145780_a(int x, int y, int z, Block block) { playSound("openblocks:luggage.walk", 0.3F, 0.7F + (worldObj.rand.nextFloat() * 0.5f)); } public void storeItemTag(NBTTagCompound itemTag) { this.itemTag = itemTag; } @Override public void writeEntityToNBT(NBTTagCompound tag) { super.writeEntityToNBT(tag); tag.setBoolean(TAG_SHINY, special); inventory.writeToNBT(tag); if (itemTag != null) tag.setTag(TAG_ITEM_TAG, itemTag); } @Override public void readEntityFromNBT(NBTTagCompound tag) { super.readEntityFromNBT(tag); if (tag.getBoolean(TAG_SHINY)) setSpecial(); inventory.readFromNBT(tag); this.itemTag = tag.hasKey(TAG_ITEM_TAG, Constants.NBT.TAG_COMPOUND)? tag.getCompoundTag(TAG_ITEM_TAG) : null; } @Override public void onStruckByLightning(EntityLightningBolt lightning) { setSpecial(); } @Override public boolean isEntityInvulnerable() { return true; } @Override public void setHealth(float health) { // NO-OP } @Override protected boolean canDespawn() { return false; } @Override public void writeSpawnData(ByteBuf data) { data.writeInt(inventory.getSizeInventory()); } @Override public void readSpawnData(ByteBuf data) { inventory = createInventory(data.readInt()); } @Override public double getMountedYOffset() { return 0.825; } }