diff options
Diffstat (limited to 'src/main/java/gregtech/api/logic')
16 files changed, 2513 insertions, 0 deletions
diff --git a/src/main/java/gregtech/api/logic/AbstractProcessingLogic.java b/src/main/java/gregtech/api/logic/AbstractProcessingLogic.java new file mode 100644 index 0000000000..3c05d8bed0 --- /dev/null +++ b/src/main/java/gregtech/api/logic/AbstractProcessingLogic.java @@ -0,0 +1,342 @@ +package gregtech.api.logic; + +import java.util.function.Supplier; + +import javax.annotation.Nonnull; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +import gregtech.api.interfaces.tileentity.IVoidable; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.recipe.check.CheckRecipeResult; +import gregtech.api.recipe.check.CheckRecipeResultRegistry; +import gregtech.api.util.GT_OverclockCalculator; +import gregtech.api.util.GT_ParallelHelper; +import gregtech.api.util.GT_Recipe; + +/** + * Logic class to calculate result of recipe check from inputs. + */ +@SuppressWarnings({ "unused", "UnusedReturnValue" }) +public abstract class AbstractProcessingLogic<P extends AbstractProcessingLogic<P>> { + + protected IVoidable machine; + protected Supplier<RecipeMap<?>> recipeMapSupplier; + protected GT_Recipe lastRecipe; + protected RecipeMap<?> lastRecipeMap; + protected ItemStack[] outputItems; + protected FluidStack[] outputFluids; + protected long calculatedEut; + protected int duration; + protected long availableVoltage; + protected long availableAmperage; + protected double overClockTimeReduction = 2.0; + protected double overClockPowerIncrease = 4.0; + protected boolean protectItems; + protected boolean protectFluids; + protected int maxParallel = 1; + protected Supplier<Integer> maxParallelSupplier; + protected int calculatedParallels = 0; + protected int batchSize = 1; + protected float euModifier = 1.0f; + protected float speedBoost = 1.0f; + protected boolean amperageOC = true; + protected boolean isCleanroom; + + // #region Setters + + /** + * Overwrites item output result of the calculation. + */ + public P setOutputItems(ItemStack... itemOutputs) { + this.outputItems = itemOutputs; + return getThis(); + } + + /** + * Overwrites fluid output result of the calculation. + */ + public P setOutputFluids(FluidStack... fluidOutputs) { + this.outputFluids = fluidOutputs; + return getThis(); + } + + public P setIsCleanroom(boolean isCleanroom) { + this.isCleanroom = isCleanroom; + return getThis(); + } + + /** + * Sets max amount of parallel. + */ + public P setMaxParallel(int maxParallel) { + this.maxParallel = maxParallel; + return getThis(); + } + + /** + * Sets method to get max amount of parallel. + */ + public P setMaxParallelSupplier(Supplier<Integer> supplier) { + this.maxParallelSupplier = supplier; + return getThis(); + } + + /** + * Sets batch size for batch mode. + */ + public P setBatchSize(int size) { + this.batchSize = size; + return getThis(); + } + + public P setRecipeMap(RecipeMap<?> recipeMap) { + return setRecipeMapSupplier(() -> recipeMap); + } + + public P setRecipeMapSupplier(Supplier<RecipeMap<?>> supplier) { + this.recipeMapSupplier = supplier; + return getThis(); + } + + public P setEuModifier(float modifier) { + this.euModifier = modifier; + return getThis(); + } + + public P setSpeedBonus(float speedModifier) { + this.speedBoost = speedModifier; + return getThis(); + } + + /** + * Sets machine used for void protection logic. + */ + public P setMachine(IVoidable machine) { + this.machine = machine; + return getThis(); + } + + /** + * Overwrites duration result of the calculation. + */ + public P setDuration(int duration) { + this.duration = duration; + return getThis(); + } + + /** + * Overwrites EU/t result of the calculation. + */ + public P setCalculatedEut(long calculatedEut) { + this.calculatedEut = calculatedEut; + return getThis(); + } + + /** + * Sets voltage of the machine. It doesn't need to be actual voltage (excluding amperage) of the machine; + * For example, most of the multiblock machines set maximum possible input power (including amperage) as voltage + * and 1 as amperage. That way recipemap search will be executed with overclocked voltage. + */ + public P setAvailableVoltage(long voltage) { + availableVoltage = voltage; + return getThis(); + } + + /** + * Sets amperage of the machine. This amperage doesn't involve in EU/t when searching recipemap. + * Useful for preventing tier skip but still considering amperage for parallel. + */ + public P setAvailableAmperage(long amperage) { + availableAmperage = amperage; + return getThis(); + } + + public P setVoidProtection(boolean protectItems, boolean protectFluids) { + this.protectItems = protectItems; + this.protectFluids = protectFluids; + return getThis(); + } + + public P setOverclock(double timeReduction, double powerIncrease) { + this.overClockTimeReduction = timeReduction; + this.overClockPowerIncrease = powerIncrease; + return getThis(); + } + + /** + * Sets overclock ratio to 4/4. + */ + public P enablePerfectOverclock() { + return this.setOverclock(4.0, 4.0); + } + + /** + * Sets whether the multi should use amperage to OC or not + */ + public P setAmperageOC(boolean amperageOC) { + this.amperageOC = amperageOC; + return getThis(); + } + + /** + * Clears calculated results (and provided machine inputs) to prepare for the next machine operation. + */ + public P clear() { + this.calculatedEut = 0; + this.duration = 0; + this.calculatedParallels = 0; + return getThis(); + } + + // #endregion + + // #region Logic + + /** + * Executes the recipe check: Find recipe from recipemap, Calculate parallel, overclock and outputs. + */ + @Nonnull + public abstract CheckRecipeResult process(); + + /** + * Refreshes recipemap to use. Remember to call this before {@link #process} to make sure correct recipemap is used. + * + * @return Recipemap to use now + */ + protected RecipeMap<?> preProcess() { + RecipeMap<?> recipeMap; + if (recipeMapSupplier == null) { + recipeMap = null; + } else { + recipeMap = recipeMapSupplier.get(); + } + if (lastRecipeMap != recipeMap) { + lastRecipe = null; + lastRecipeMap = recipeMap; + } + + if (maxParallelSupplier != null) { + maxParallel = maxParallelSupplier.get(); + } + + return recipeMap; + } + + /** + * Check has been succeeded, so it applies the recipe and calculated parameters. + * At this point, inputs have been already consumed. + */ + @Nonnull + protected CheckRecipeResult applyRecipe(@Nonnull GT_Recipe recipe, @Nonnull GT_ParallelHelper helper, + @Nonnull GT_OverclockCalculator calculator, @Nonnull CheckRecipeResult result) { + if (recipe.mCanBeBuffered) { + lastRecipe = recipe; + } else { + lastRecipe = null; + } + calculatedParallels = helper.getCurrentParallel(); + + if (calculator.getConsumption() == Long.MAX_VALUE) { + return CheckRecipeResultRegistry.POWER_OVERFLOW; + } + if (calculator.getDuration() == Integer.MAX_VALUE) { + return CheckRecipeResultRegistry.DURATION_OVERFLOW; + } + + calculatedEut = calculator.getConsumption(); + + double finalDuration = calculateDuration(recipe, helper, calculator); + if (finalDuration >= Integer.MAX_VALUE) { + return CheckRecipeResultRegistry.DURATION_OVERFLOW; + } + duration = (int) finalDuration; + + CheckRecipeResult hookResult = onRecipeStart(recipe); + if (!hookResult.wasSuccessful()) { + return hookResult; + } + + outputItems = helper.getItemOutputs(); + outputFluids = helper.getFluidOutputs(); + + return result; + } + + /** + * Override to tweak final duration that will be set as a result of this logic class. + */ + protected double calculateDuration(@Nonnull GT_Recipe recipe, @Nonnull GT_ParallelHelper helper, + @Nonnull GT_OverclockCalculator calculator) { + return calculator.getDuration() * helper.getDurationMultiplierDouble(); + } + + /** + * Override to do additional check for found recipe if needed. + */ + @Nonnull + protected CheckRecipeResult validateRecipe(@Nonnull GT_Recipe recipe) { + return CheckRecipeResultRegistry.SUCCESSFUL; + } + + /** + * Override to perform additional logic when recipe starts. + * + * This is called when the recipe processing logic has finished all + * checks, consumed all inputs, but has not yet set the outputs to + * be produced. Returning a result other than SUCCESSFUL will void + * all inputs! + */ + @Nonnull + protected CheckRecipeResult onRecipeStart(@Nonnull GT_Recipe recipe) { + return CheckRecipeResultRegistry.SUCCESSFUL; + } + + /** + * Override to tweak overclock logic if needed. + */ + @Nonnull + protected GT_OverclockCalculator createOverclockCalculator(@Nonnull GT_Recipe recipe) { + return new GT_OverclockCalculator().setRecipeEUt(recipe.mEUt) + .setAmperage(availableAmperage) + .setEUt(availableVoltage) + .setDuration(recipe.mDuration) + .setSpeedBoost(speedBoost) + .setEUtDiscount(euModifier) + .setAmperageOC(amperageOC) + .setDurationDecreasePerOC(overClockTimeReduction) + .setEUtIncreasePerOC(overClockPowerIncrease); + } + // #endregion + + // #region Getters + + public ItemStack[] getOutputItems() { + return outputItems; + } + + public FluidStack[] getOutputFluids() { + return outputFluids; + } + + public int getDuration() { + return duration; + } + + public long getCalculatedEut() { + return calculatedEut; + } + + public int getCurrentParallels() { + return calculatedParallels; + } + + @SuppressWarnings("unchecked") + @Nonnull + public P getThis() { + return (P) this; + } + + // #endregion +} diff --git a/src/main/java/gregtech/api/logic/ComplexParallelProcessingLogic.java b/src/main/java/gregtech/api/logic/ComplexParallelProcessingLogic.java new file mode 100644 index 0000000000..72a74ebd04 --- /dev/null +++ b/src/main/java/gregtech/api/logic/ComplexParallelProcessingLogic.java @@ -0,0 +1,121 @@ +package gregtech.api.logic; + +import java.util.stream.LongStream; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +public class ComplexParallelProcessingLogic<P extends ComplexParallelProcessingLogic<P>> + extends MuTEProcessingLogic<P> { + + protected int maxComplexParallels; + protected ItemStack[][] outputItems; + protected FluidStack[][] outputFluids; + protected long[] calculatedEutValues; + protected int[] durations; + protected int[] progresses; + + public P setMaxComplexParallel(int maxComplexParallels) { + this.maxComplexParallels = maxComplexParallels; + reinitializeProcessingArrays(); + return getThis(); + } + + public ItemStack[] getOutputItems(int index) { + if (index >= 0 && index < maxComplexParallels) { + return outputItems[index]; + } + return null; + } + + public FluidStack[] getOutputFluids(int index) { + if (index >= 0 && index < maxComplexParallels) { + return outputFluids[index]; + } + return null; + } + + @Override + public boolean canWork() { + for (int i = 0; i < maxComplexParallels; i++) { + if (progresses[i] >= durations[i]) { + return machineHost.isAllowedToWork(); + } + } + return false; + } + + @Override + public long getCalculatedEut() { + return LongStream.of(this.calculatedEutValues) + .sum(); + } + + public int getDuration(int index) { + return durations[index]; + } + + public int getProgress(int index) { + return progresses[index]; + } + + @Override + public void progress() { + for (int i = 0; i < maxComplexParallels; i++) { + if (progresses[i] == durations[i]) { + progresses[i] = 0; + durations[i] = 0; + output(i); + continue; + } + progresses[i] = progresses[i] + 1; + } + } + + @Override + public void startCheck() { + for (int i = 0; i < maxComplexParallels; i++) { + if (durations[i] > 0) continue; + recipeResult = process(); + calculatedEutValues[i] = calculatedEut; + durations[i] = duration; + progresses[i] = 0; + outputItems[i] = getOutputItems(); + outputFluids[i] = getOutputFluids(); + } + } + + protected void output(int index) { + setOutputItems(getOutputItems(index)); + setOutputFluids(getOutputFluids(index)); + output(); + } + + protected void reinitializeProcessingArrays() { + ItemStack[][] oldOutputItems = outputItems; + FluidStack[][] oldOutputFluids = outputFluids; + long[] oldCalculatedEutValues = calculatedEutValues; + int[] oldDurations = durations; + int[] oldProgresses = progresses; + outputItems = new ItemStack[maxComplexParallels][]; + outputFluids = new FluidStack[maxComplexParallels][]; + calculatedEutValues = new long[maxComplexParallels]; + durations = new int[maxComplexParallels]; + progresses = new int[maxComplexParallels]; + for (int i = 0; i < oldOutputItems.length; i++) { + outputItems[i] = oldOutputItems[i]; + } + for (int i = 0; i < oldOutputFluids.length; i++) { + outputFluids[i] = oldOutputFluids[i]; + } + for (int i = 0; i < oldCalculatedEutValues.length; i++) { + calculatedEutValues[i] = oldCalculatedEutValues[i]; + } + for (int i = 0; i < oldDurations[i]; i++) { + durations[i] = oldDurations[i]; + } + for (int i = 0; i < oldProgresses.length; i++) { + progresses[i] = oldProgresses[i]; + } + } +} diff --git a/src/main/java/gregtech/api/logic/ControllerFluidLogic.java b/src/main/java/gregtech/api/logic/ControllerFluidLogic.java new file mode 100644 index 0000000000..211c1c2982 --- /dev/null +++ b/src/main/java/gregtech/api/logic/ControllerFluidLogic.java @@ -0,0 +1,152 @@ +package gregtech.api.logic; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraftforge.common.util.Constants; + +import org.apache.commons.lang3.tuple.Pair; + +/** + * Controller logic for Fluid inventories + * + * @author BlueWeabo + */ +public class ControllerFluidLogic { + + private final Map<UUID, FluidInventoryLogic> inventories = new HashMap<>(); + private final Set<Pair<UUID, FluidInventoryLogic>> unallocatedInventories = new HashSet<>(); + + public void addInventory(@Nonnull UUID id, @Nonnull FluidInventoryLogic inventory) { + Pair<UUID, FluidInventoryLogic> found = checkIfInventoryExistsAsUnallocated(inventory); + if (inventory.isUpgradeInventory() && found != null) { + unallocatedInventories.remove(found); + inventories.put(id, found.getRight()); + return; + } + inventories.put(id, inventory); + } + + @Nonnull + public UUID addInventory(@Nonnull FluidInventoryLogic inventory) { + Pair<UUID, FluidInventoryLogic> found = checkIfInventoryExistsAsUnallocated(inventory); + if (inventory.isUpgradeInventory() && found != null) { + unallocatedInventories.remove(found); + inventories.put(found.getLeft(), found.getRight()); + return Objects.requireNonNull(found.getLeft()); + } + UUID generatedUUID = Objects.requireNonNull(UUID.randomUUID()); + inventories.put(generatedUUID, inventory); + return generatedUUID; + } + + @Nullable + private Pair<UUID, FluidInventoryLogic> checkIfInventoryExistsAsUnallocated( + @Nonnull FluidInventoryLogic inventory) { + if (unallocatedInventories.size() == 0) { + return null; + } + return unallocatedInventories.stream() + .filter( + unallocated -> unallocated.getRight() + .getTier() == inventory.getTier()) + .findFirst() + .get(); + } + + /** + * Removes the inventory with said id and gives it back to be processed if needed. + */ + @Nonnull + public FluidInventoryLogic removeInventory(@Nonnull UUID id) { + return Objects.requireNonNull(inventories.remove(id)); + } + + @Nonnull + public FluidInventoryLogic getAllInventoryLogics() { + return new FluidInventoryLogic( + inventories.values() + .stream() + .map(inv -> inv.getInventory()) + .collect(Collectors.toList())); + } + + @Nonnull + public FluidInventoryLogic getInventoryLogic(@Nullable UUID id) { + if (id == null) return getAllInventoryLogics(); + return Objects.requireNonNull(inventories.getOrDefault(id, getAllInventoryLogics())); + } + + @Nonnull + public Set<Entry<UUID, FluidInventoryLogic>> getAllInventoryLogicsAsEntrySet() { + return Objects.requireNonNull(inventories.entrySet()); + } + + @Nonnull + public String getInventoryDisplayName(@Nullable UUID id) { + if (id == null) return ""; + FluidInventoryLogic logic = inventories.get(id); + if (logic == null) return ""; + String displayName = logic.getDisplayName(); + if (displayName == null) return Objects.requireNonNull(id.toString()); + return displayName; + } + + public void setInventoryDisplayName(@Nullable UUID id, @Nullable String displayName) { + if (id == null) return; + FluidInventoryLogic logic = inventories.get(id); + if (logic == null) return; + logic.setDisplayName(displayName); + } + + @Nonnull + public NBTTagCompound saveToNBT() { + NBTTagCompound nbt = new NBTTagCompound(); + NBTTagList inventoriesNBT = new NBTTagList(); + inventories.forEach((uuid, inventory) -> { + NBTTagCompound inventoryNBT = new NBTTagCompound(); + inventoryNBT.setTag("inventory", inventory.saveToNBT()); + inventoryNBT.setString("uuid", uuid.toString()); + inventoryNBT.setInteger( + "invSize", + inventory.getInventory() + .getTanks()); + inventoryNBT.setLong( + "tankCapacity", + inventory.getInventory() + .getTankCapacity(0)); + inventoriesNBT.appendTag(inventoryNBT); + }); + nbt.setTag("inventories", inventoriesNBT); + return nbt; + } + + public void loadFromNBT(@Nonnull NBTTagCompound nbt) { + NBTTagList inventoriesNBT = nbt.getTagList("inventories", Constants.NBT.TAG_COMPOUND); + if (inventoriesNBT == null) return; + for (int i = 0; i < inventoriesNBT.tagCount(); i++) { + NBTTagCompound inventoryNBT = inventoriesNBT.getCompoundTagAt(i); + UUID uuid = UUID.fromString(inventoryNBT.getString("uuid")); + FluidInventoryLogic inventory = new FluidInventoryLogic( + inventoryNBT.getInteger("invSize"), + inventoryNBT.getLong("tankCapacity")); + inventory.loadFromNBT(inventoryNBT.getCompoundTag("inventory")); + if (inventory.isUpgradeInventory()) { + unallocatedInventories.add(Pair.of(uuid, inventory)); + } else { + inventories.put(uuid, inventory); + } + } + } +} diff --git a/src/main/java/gregtech/api/logic/ControllerItemLogic.java b/src/main/java/gregtech/api/logic/ControllerItemLogic.java new file mode 100644 index 0000000000..2863c2f49c --- /dev/null +++ b/src/main/java/gregtech/api/logic/ControllerItemLogic.java @@ -0,0 +1,148 @@ +package gregtech.api.logic; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraftforge.common.util.Constants; + +import org.apache.commons.lang3.tuple.Pair; + +/** + * Logic of the Item logic for the controller. This is controlling all of the inventories. + * + * @author BlueWeabo + */ +public class ControllerItemLogic { + + private final Map<UUID, ItemInventoryLogic> inventories = new HashMap<>(); + private final Set<Pair<UUID, ItemInventoryLogic>> unallocatedInventories = new HashSet<>(); + + public void addInventory(@Nonnull UUID id, @Nonnull ItemInventoryLogic inventory) { + Pair<UUID, ItemInventoryLogic> found = checkIfInventoryExistsAsUnallocated(inventory); + if (inventory.isUpgradeInventory() && found != null) { + unallocatedInventories.remove(found); + inventories.put(id, found.getRight()); + return; + } + inventories.put(id, inventory); + } + + @Nonnull + public UUID addInventory(@Nonnull ItemInventoryLogic inventory) { + Pair<UUID, ItemInventoryLogic> found = checkIfInventoryExistsAsUnallocated(inventory); + if (inventory.isUpgradeInventory() && found != null) { + unallocatedInventories.remove(found); + inventories.put(found.getLeft(), found.getRight()); + return Objects.requireNonNull(found.getLeft()); + } + UUID generatedUUID = Objects.requireNonNull(UUID.randomUUID()); + inventories.put(generatedUUID, inventory); + return generatedUUID; + } + + @Nullable + private Pair<UUID, ItemInventoryLogic> checkIfInventoryExistsAsUnallocated(@Nonnull ItemInventoryLogic inventory) { + if (unallocatedInventories.size() == 0) { + return null; + } + return unallocatedInventories.stream() + .filter( + unallocated -> unallocated.getRight() + .getTier() == inventory.getTier() + && unallocated.getRight() + .getSlots() == inventory.getSlots()) + .findFirst() + .get(); + } + + /** + * Removes the inventory with said id and gives it back to be processed if needed. + */ + @Nonnull + public ItemInventoryLogic removeInventory(@Nonnull UUID id) { + return Objects.requireNonNull(inventories.remove(id)); + } + + @Nonnull + public ItemInventoryLogic getAllInventoryLogics() { + return new ItemInventoryLogic( + inventories.values() + .stream() + .map(inv -> inv.getInventory()) + .collect(Collectors.toList())); + } + + @Nonnull + public ItemInventoryLogic getInventoryLogic(@Nullable UUID id) { + if (id == null) return getAllInventoryLogics(); + return Objects.requireNonNull(inventories.getOrDefault(id, getAllInventoryLogics())); + } + + @Nonnull + public Set<Entry<UUID, ItemInventoryLogic>> getAllInventoryLogicsAsEntrySet() { + return Objects.requireNonNull(inventories.entrySet()); + } + + @Nullable + public String getInventoryDisplayName(@Nullable UUID id) { + if (id == null) return ""; + ItemInventoryLogic logic = inventories.get(id); + if (logic == null) return ""; + String displayName = logic.getDisplayName(); + if (displayName == null) return Objects.requireNonNull(id.toString()); + return displayName; + } + + public void setInventoryDisplayName(@Nullable UUID id, @Nullable String displayName) { + if (id == null) return; + ItemInventoryLogic logic = inventories.get(id); + if (logic == null) return; + logic.setDisplayName(displayName); + } + + @Nonnull + public NBTTagCompound saveToNBT() { + NBTTagCompound nbt = new NBTTagCompound(); + NBTTagList inventoriesNBT = new NBTTagList(); + inventories.forEach((uuid, inventory) -> { + NBTTagCompound inventoryNBT = new NBTTagCompound(); + inventoryNBT.setTag("inventory", inventory.saveToNBT()); + inventoryNBT.setString("uuid", uuid.toString()); + inventoryNBT.setInteger( + "invSize", + inventory.getInventory() + .getSlots()); + inventoriesNBT.appendTag(inventoryNBT); + }); + nbt.setTag("inventories", inventoriesNBT); + return nbt; + } + + public void loadFromNBT(@Nonnull NBTTagCompound nbt) { + NBTTagList inventoriesNBT = nbt.getTagList("inventories", Constants.NBT.TAG_COMPOUND); + if (inventoriesNBT == null) return; + for (int i = 0; i < inventoriesNBT.tagCount(); i++) { + NBTTagCompound inventoryNBT = inventoriesNBT.getCompoundTagAt(i); + UUID uuid = UUID.fromString(inventoryNBT.getString("uuid")); + ItemInventoryLogic inventory = new ItemInventoryLogic(inventoryNBT.getInteger("invSize")); + NBTTagCompound internalInventoryNBT = inventoryNBT.getCompoundTag("inventory"); + if (internalInventoryNBT != null) inventory.loadFromNBT(internalInventoryNBT); + if (inventory.isUpgradeInventory()) { + unallocatedInventories.add(Pair.of(uuid, inventory)); + } else { + inventories.put(uuid, inventory); + } + } + } +} diff --git a/src/main/java/gregtech/api/logic/FluidInventoryLogic.java b/src/main/java/gregtech/api/logic/FluidInventoryLogic.java new file mode 100644 index 0000000000..88c0c954ec --- /dev/null +++ b/src/main/java/gregtech/api/logic/FluidInventoryLogic.java @@ -0,0 +1,269 @@ +package gregtech.api.logic; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; + +import com.gtnewhorizons.modularui.api.fluids.FluidTanksHandler; +import com.gtnewhorizons.modularui.api.fluids.IFluidTankLong; +import com.gtnewhorizons.modularui.api.fluids.IFluidTanksHandler; +import com.gtnewhorizons.modularui.api.fluids.ListFluidHandler; +import com.gtnewhorizons.modularui.api.math.Size; +import com.gtnewhorizons.modularui.api.widget.Widget; +import com.gtnewhorizons.modularui.common.widget.FluidSlotWidget; +import com.gtnewhorizons.modularui.common.widget.Scrollable; + +/** + * Generic Fluid logic for MuTEs. + * + * @author BlueWeabo + */ +public class FluidInventoryLogic { + + private static final int DEFAULT_COLUMNS_PER_ROW = 4; + private static final int POSITION_INTERVAL = 18; + private static final Size SIZE = new Size(18, 18); + + protected String displayName = ""; + @Nonnull + protected final IFluidTanksHandler inventory; + protected final Map<Fluid, IFluidTankLong> fluidToTankMap; + protected int tier = 0; + protected boolean isUpgradeInventory = false; + + public FluidInventoryLogic(int numberOfSlots, long capacityOfEachTank) { + this(new FluidTanksHandler(numberOfSlots, capacityOfEachTank), 0, false); + } + + public FluidInventoryLogic(int numberOfSlots, long capacityOfEachTank, int tier) { + this(new FluidTanksHandler(numberOfSlots, capacityOfEachTank), tier, false); + } + + public FluidInventoryLogic(int numberOfSlots, long capacityOfEachTank, int tier, boolean isUpgradeInventory) { + this(new FluidTanksHandler(numberOfSlots, capacityOfEachTank), tier, isUpgradeInventory); + } + + public FluidInventoryLogic(@Nonnull IFluidTanksHandler inventory, int tier, boolean isUpgradeInventory) { + this.inventory = inventory; + fluidToTankMap = new HashMap<>(inventory.getTanks()); + this.tier = tier; + this.isUpgradeInventory = isUpgradeInventory; + } + + public FluidInventoryLogic(Collection<IFluidTanksHandler> inventories) { + this(new ListFluidHandler(inventories), -1, false); + } + + @Nullable + public String getDisplayName() { + return displayName; + } + + public int getTier() { + return tier; + } + + public boolean isUpgradeInventory() { + return isUpgradeInventory; + } + + public void setDisplayName(@Nullable String displayName) { + this.displayName = displayName; + } + + /** + * + * @return The Fluid Inventory Logic as an NBTTagList to be saved in another nbt as how one wants. + */ + @Nonnull + public NBTTagCompound saveToNBT() { + final NBTTagCompound nbt = new NBTTagCompound(); + final NBTTagList tList = new NBTTagList(); + for (int tankNumber = 0; tankNumber < inventory.getTanks(); tankNumber++) { + final IFluidTankLong tank = inventory.getFluidTank(tankNumber); + if (tank == null) continue; + + final NBTTagCom |
