package kubatech.api.eig; import static kubatech.api.utils.ItemUtils.readItemStackFromNBT; import static kubatech.api.utils.ItemUtils.writeItemStackToNBT; import java.util.LinkedList; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.util.EnumChatFormatting; import gregtech.api.util.GTUtility; import kubatech.tileentity.gregtech.multiblock.MTEExtremeIndustrialGreenhouse; public abstract class EIGBucket { protected ItemStack seed; protected int seedCount; protected ItemStack[] supportItems; public EIGBucket(ItemStack seed, int seedCount, ItemStack[] supportItem) { this.seed = seed.copy(); this.seed.stackSize = 1; this.seedCount = seedCount; this.supportItems = supportItem; } public EIGBucket(NBTTagCompound nbt) { this.seed = readItemStackFromNBT(nbt.getCompoundTag("seed")); this.seedCount = nbt.getInteger("count"); // parse support items if (nbt.hasKey("supportItems", 9)) { NBTTagList supportItemsNBTList = nbt.getTagList("supportItems", 10); if (supportItemsNBTList.tagCount() > 0) { this.supportItems = new ItemStack[supportItemsNBTList.tagCount()]; for (int i = 0; i < supportItemsNBTList.tagCount(); i++) { this.supportItems[i] = readItemStackFromNBT(supportItemsNBTList.getCompoundTagAt(i)); } } else { supportItems = null; } } else { supportItems = null; } } /** * Creates a persistent save of the bucket's current data. * * @return The nbt data for this bucket. */ public NBTTagCompound save() { NBTTagCompound nbt = new NBTTagCompound(); nbt.setString("type", this.getNBTIdentifier()); nbt.setTag("seed", writeItemStackToNBT(this.seed)); nbt.setInteger("count", this.seedCount); if (this.supportItems != null && this.supportItems.length > 0) { NBTTagList supportItemNBT = new NBTTagList(); for (ItemStack supportItem : this.supportItems) { supportItemNBT.appendTag(writeItemStackToNBT(supportItem)); } nbt.setTag("supportItems", supportItemNBT); } return nbt; } /** * Gets an item stack representing the seeds in this bucket * * @return an item stack representing the seeds in this bucket. */ public ItemStack getSeedStack() { ItemStack copied = this.seed.copy(); copied.stackSize = this.seedCount; return copied; } /** * Gets the number of seeds in this bucket * * @return gets the number of seeds in this bucket. */ public int getSeedCount() { return this.seedCount; } /** * Gets the display name of the seed in this bucket * * @return The display name of the seed. */ public String getDisplayName() { return this.seed.getDisplayName(); } public String getInfoData() { StringBuilder sb = new StringBuilder(); // display invalid buckets, we don't want people to think they lost their seeds or something. sb.append(this.isValid() ? EnumChatFormatting.GREEN : EnumChatFormatting.RED); sb.append("x"); sb.append(this.getSeedCount()); sb.append(" "); sb.append(this.getDisplayName()); this.getAdditionalInfoData(sb); sb.append(EnumChatFormatting.RESET); return sb.toString(); } protected void getAdditionalInfoData(StringBuilder sb) {} /** * Attempts to add seeds to tbe bucket if the input is compatible * * @param input A stack of an item that may be able to be added to our current bucket. * @param maxConsume The maximum amount of seeds to add to this bucket. * @param simulate True if you want to see if you can add more seeds (useful for support item checks) * @return number of seeds consumed, 0 for wrong item, -1 if it missed the support items, -2 if you tried to consume * 0 or less items; */ public int tryAddSeed(MTEExtremeIndustrialGreenhouse greenhouse, ItemStack input, int maxConsume, boolean simulate) { // Abort is input if empty if (input == null || input.stackSize <= 0) return -2; // Cap max to input count maxConsume = Math.min(maxConsume, input.stackSize); // Abort if item isn't an identical seed. if (!GTUtility.areStacksEqual(this.seed, input, false)) return 0; // no support items, consume and exit early. if (this.supportItems == null || this.supportItems.length <= 0) { if (!simulate) { input.stackSize -= maxConsume; this.seedCount += maxConsume; } return maxConsume; } // Check if the item is found LinkedList toConsumeFrom = new LinkedList<>(); supportLoop: for (ItemStack supportItem : this.supportItems) { for (ItemStack otherInput : greenhouse.getStoredInputs()) { // filter usable inputs if (otherInput == null || otherInput.stackSize <= 0) continue; if (!GTUtility.areStacksEqual(supportItem, otherInput, false)) continue; // update max consume again maxConsume = Math.min(maxConsume, otherInput.stackSize); toConsumeFrom.addLast(otherInput); continue supportLoop; } // no support found, no seeds added return -1; } // consume items if (!simulate) { input.stackSize -= maxConsume; for (ItemStack stack : toConsumeFrom) { stack.stackSize -= maxConsume; } this.seedCount += maxConsume; } return maxConsume; } /** * Attempts to remove a seed from the bucket * * @param toRemove The maximum amount of items to remove. * @return The items that were removed from the bucket. Null if the bucket is empty. */ public ItemStack[] tryRemoveSeed(int toRemove, boolean simulate) { // validate inputs toRemove = Math.min(this.seedCount, toRemove); if (toRemove <= 0) return null; // consume and return output ItemStack[] ret = new ItemStack[1 + (this.supportItems == null ? 0 : this.supportItems.length)]; ret[0] = this.seed.copy(); ret[0].stackSize = toRemove; if (this.supportItems != null) { for (int i = 0; i < this.supportItems.length; i++) { ret[i + 1] = this.supportItems[i].copy(); ret[i + 1].stackSize = toRemove; } } if (!simulate) { this.seedCount -= toRemove; } return ret; } /** * Sets the seed count to 0 and returns item stacks representing every item in this bucket. * * @return The contents of the bucket */ public ItemStack[] emptyBucket() { if (this.seedCount <= 0) return null; ItemStack[] ret = new ItemStack[1 + (this.supportItems == null ? 0 : this.supportItems.length)]; ret[0] = this.seed.copy(); ret[0].stackSize = this.seedCount; if (this.supportItems != null) { for (int i = 0; i < this.supportItems.length; i++) { ret[i + 1] = this.supportItems[i].copy(); ret[i + 1].stackSize = this.seedCount; } } this.seedCount = 0; return ret; } /** * Returns true if the bucket can output items. * * @return true if the bucket is valid. */ public boolean isValid() { return this.seed != null && this.seedCount > 0; } /** * Gets the identifier used to identify this class during reconstruction * * @return the identifier for this bucket type. */ protected abstract String getNBTIdentifier(); /** * Adds item drops to the item tracker. * * @param multiplier A multiplier to apply to the output. * @param tracker The item drop tracker */ public abstract void addProgress(double multiplier, EIGDropTable tracker); /** * Attempts to revalidate a seed bucket. If it returns false, attempt to seed and support items and delete the * bucket. * * @param greenhouse The greenhouse that contains the bucket. * @return True if the bucket was successfully validated. {@link EIGBucket#isValid()} should also return true. */ public abstract boolean revalidate(MTEExtremeIndustrialGreenhouse greenhouse); }