package com.infinityraider.agricraft.tiles.analyzer; import com.infinityraider.agricraft.init.AgriItems; import com.infinityraider.agricraft.items.ItemJournal; import com.infinityraider.infinitylib.block.tile.TileEntityRotatableBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentString; import com.agricraft.agricore.core.AgriCore; import com.infinityraider.agricraft.api.misc.IAgriDisplayable; import java.util.List; import net.minecraft.util.ITickable; import com.infinityraider.agricraft.api.seed.AgriSeed; import com.infinityraider.agricraft.apiimpl.SeedRegistry; import com.infinityraider.agricraft.reference.AgriNBT; import com.infinityraider.agricraft.utility.StackHelper; import java.util.Optional; public class TileEntitySeedAnalyzer extends TileEntityRotatableBase implements ISidedInventory, ITickable, IAgriDisplayable { public static final int SPECIMEN_SLOT_ID = 36; public static final int JOURNAL_SLOT_ID = 37; private static final int[] SLOTS = new int[]{ SPECIMEN_SLOT_ID, JOURNAL_SLOT_ID }; /** * The SEED that the SEED analyzer contains. * * Defaults to null, for empty. */ private ItemStack specimen = null; /** * The journal that the SEED analyzer contains. * * Defaults to null, for empty. */ private ItemStack journal = null; /** * The current progress of the SEED analyzer. */ private int progress = 0; @Override protected void writeRotatableTileNBT(NBTTagCompound tag) { if (this.specimen != null && this.specimen.getItem() != null) { NBTTagCompound seedTag = new NBTTagCompound(); this.specimen.writeToNBT(seedTag); tag.setTag(AgriNBT.SEED, seedTag); } if (this.journal != null && this.journal.getItem() != null) { NBTTagCompound journalTag = new NBTTagCompound(); this.journal.writeToNBT(journalTag); tag.setTag(AgriItems.getInstance().JOURNAL.getUnlocalizedName(), journalTag); } tag.setInteger("progress", this.progress); } @Override protected void readRotatableTileNBT(NBTTagCompound tag) { if (tag.hasKey(AgriNBT.SEED)) { this.specimen = ItemStack.loadItemStackFromNBT(tag.getCompoundTag(AgriNBT.SEED)); } else { //Not certain this is required... Unsure if networking thing? this.specimen = null; } if (tag.hasKey(AgriItems.getInstance().JOURNAL.getUnlocalizedName())) { this.journal = ItemStack.loadItemStackFromNBT(tag.getCompoundTag(AgriItems.getInstance().JOURNAL.getUnlocalizedName())); } else { this.journal = null; } this.progress = tag.getInteger("progress"); } /** * Determines if the SEED analyzer contains a SEED or trowel in its analyze * slot. A null check on {@link #getSpecimen()} should return the same. * * @return if a SEED or trowel is present. */ public final boolean hasSpecimen() { return this.hasSeed(); } /** * Retrieves the item in the analyzer's analyze slot. (Does not remove). May * be either a SEED or a trowel. * * @return the item in the analyze slot. */ public final ItemStack getSpecimen() { return this.specimen; } /** * Determines if the analyzer has a <em>valid</em> SEED in its analyze slot. * * @return if the analyze slot contains a <em>valid</em> SEED. */ public final boolean hasSeed() { return SeedRegistry.getInstance().hasAdapter(specimen); } public final void setProgress(int value) { this.progress = value; } public final int getProgress() { return this.progress; } /** * Calculates the number of ticks it takes to analyze the SEED. * * @return ticks to analyze SEED. */ public final int maxProgress() { return 100; } /** * Determines if a stack is valid for analyzation. * * @param stack the stack to check. * @return if the stack is valid. */ public static boolean isValid(ItemStack stack) { return SeedRegistry.getInstance().hasAdapter(stack); } /** * Determines if a contained specimen has already been ANALYZED. * * @return if the specimen has been ANALYZED. */ public final boolean isSpecimenAnalyzed() { if (this.specimen != null) { Optional<AgriSeed> seed = SeedRegistry.getInstance().valueOf(specimen); return seed.isPresent() && seed.get().getStat().isAnalyzed(); } return false; } /** * Called every tick. * * Used to update the progress counter. */ @Override public void update() { boolean change = false; if (this.isAnalyzing()) { //increment progress counter this.progress = progress < this.maxProgress() ? progress + 1 : this.maxProgress(); //if progress is complete analyze the SEED if (progress == this.maxProgress() && !worldObj.isRemote) { this.analyze(); change = true; } } if (change) { this.markForUpdate(); this.worldObj.addBlockEvent(this.getPos(), this.worldObj.getBlockState(getPos()).getBlock(), 0, 0); this.worldObj.notifyBlockOfStateChange(getPos(), this.getBlockType()); } } /** * Analyzes the current SEED. * * Marked for cleanup. */ public void analyze() { //analyze the SEED final Optional<AgriSeed> wrapper = SeedRegistry.getInstance().valueOf(specimen); if (wrapper.isPresent()) { AgriSeed seed = wrapper.get(); seed = seed.withStat(seed.getStat().withAnalyzed(true)); seed.getStat().writeToNBT(StackHelper.getTag(specimen)); if (this.hasJournal()) { ((ItemJournal) journal.getItem()).addEntry(journal, seed.getPlant()); } } } /** * Checks if the analyzer is analyzing. * * @return if the analyzer is analyzing. */ public final boolean isAnalyzing() { return this.specimen != null && !this.isSpecimenAnalyzed() && progress < maxProgress(); } /** * checks if there is a journal in the analyzer. * * @return if the analyzer contains a journal. */ public final boolean hasJournal() { return (this.journal != null && this.journal.getItem() != null); } /** * Retrieves the journal from the analyzer. (Does not remove). * * @return the journal from the analyzer. */ public final ItemStack getJournal() { return this.journal; } /** * Returns the scaled progress percentage. Rounds the progress up. * * @param scale ??? * @return the scaled progress percentage. */ public final int getProgressScaled(int scale) { return Math.round(((float) this.progress * scale) / ((float) this.maxProgress())); } //Inventory methods //----------------- @Override public int[] getSlotsForFace(EnumFacing side) { return SLOTS; } //check if item can be inserted @Override public boolean canInsertItem(int slot, ItemStack stack, EnumFacing direction) { switch (slot) { case SPECIMEN_SLOT_ID: return isValid(stack); case JOURNAL_SLOT_ID: return this.journal == null && this.isItemValidForSlot(slot, stack); default: return false; } } //check if an item can be extracted @Override public boolean canExtractItem(int slot, ItemStack itemStackIn, EnumFacing direction) { if (slot == SPECIMEN_SLOT_ID && this.specimen != null && this.specimen.hasTagCompound()) { return this.isSpecimenAnalyzed(); } return false; } //returns the INVENTORY SIZE @Override public int getSizeInventory() { return 2; } //returns the stack in the slot @Override public ItemStack getStackInSlot(int slot) { switch (slot) { case SPECIMEN_SLOT_ID: return this.specimen; case JOURNAL_SLOT_ID: return this.journal; default: return null; } } //decreases the stack in a slot by an amount and returns that amount as an itemstack @Override public ItemStack decrStackSize(int slot, int amount) { ItemStack output = null; switch (slot) { case SPECIMEN_SLOT_ID: if (this.specimen != null) { if (amount < this.specimen.stackSize) { output = this.specimen.splitStack(amount); } else { output = this.specimen.copy(); this.specimen = null; this.markForUpdate(); } } break; case JOURNAL_SLOT_ID: if (this.journal != null) { output = this.journal.copy(); this.journal = null; this.markForUpdate(); } break; } this.progress = 0; return output; } //gets item stack in the slot when closing the INVENTORY @Override public ItemStack removeStackFromSlot(int slot) { ItemStack result; switch (slot) { case SPECIMEN_SLOT_ID: result = this.specimen; this.specimen = null; this.progress = 0; break; case JOURNAL_SLOT_ID: result = this.journal; this.journal = null; break; default: return null; } this.markForUpdate(); return result; } //sets the items in a slot to this stack @Override public void setInventorySlotContents(int slot, ItemStack stack) { switch (slot) { case SPECIMEN_SLOT_ID: this.specimen = stack; if (stack != null && stack.stackSize > getInventoryStackLimit()) { stack.stackSize = getInventoryStackLimit(); } this.progress = isSpecimenAnalyzed() ? maxProgress() : 0; this.markForUpdate(); return; case JOURNAL_SLOT_ID: this.journal = stack; this.markForUpdate(); return; } } //returns the maximum stacksize @Override public final int getInventoryStackLimit() { return 64; } //if this is usable by a player @Override public boolean isUseableByPlayer(EntityPlayer player) { return worldObj.getTileEntity(pos) == this && player.getDistanceSq(pos.add(0.5, 0.5, 0.5)) <= 64.0; } /** * Opens the INVENTORY. (Empty method). * * @param player */ @Override public void openInventory(EntityPlayer player) { } /** * Closes the INVENTORY. (Empty method). * * @param player */ @Override public void closeInventory(EntityPlayer player) { } /** * Checks if a stack is valid for a slot. * * @param slot * @param stack * @return if the item is valid. */ @Override public boolean isItemValidForSlot(int slot, ItemStack stack) { switch (slot) { case SPECIMEN_SLOT_ID: return TileEntitySeedAnalyzer.isValid(stack); case JOURNAL_SLOT_ID: return StackHelper.isValid(stack, ItemJournal.class); default: return false; } } @Override public String getName() { return "container.agricraft:seedAnalyzer"; } @Override public boolean hasCustomName() { return true; } @Override public ITextComponent getDisplayName() { return new TextComponentString("container.agricraft:seedAnalyzer"); } @Override public int getField(int id) { return 0; } @Override public void setField(int id, int value) { } @Override public int getFieldCount() { return 0; } @Override public void clear() { this.specimen = null; this.journal = null; } @Override public void addDisplayInfo(List information) { information.add(AgriCore.getTranslator().translate("agricraft_tooltip.analyzer") + ": " + (this.hasSpecimen() ? specimen.getDisplayName() : AgriCore.getTranslator().translate("agricraft_tooltip.none"))); } }