package gtPlusPlus.xmod.gregtech.api.metatileentity.implementations.base; import static gregtech.api.enums.GTValues.V; import static gregtech.api.util.GTStructureUtility.buildHatchAdder; import static gregtech.api.util.GTUtility.formatNumbers; import static gregtech.api.util.GTUtility.validMTEList; import static mcp.mobius.waila.api.SpecialChars.GREEN; import static mcp.mobius.waila.api.SpecialChars.RED; import static mcp.mobius.waila.api.SpecialChars.RESET; import java.util.ArrayList; import java.util.Collections; import java.util.List; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.StatCollector; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.FluidStack; import gregtech.GTMod; import gregtech.api.enums.Textures; import gregtech.api.interfaces.IHatchElement; import gregtech.api.interfaces.ITexture; import gregtech.api.interfaces.metatileentity.IMetaTileEntity; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.logic.ProcessingLogic; import gregtech.api.metatileentity.implementations.MTEHatch; import gregtech.api.metatileentity.implementations.MTEHatchInput; import gregtech.api.metatileentity.implementations.MTEHatchOutput; import gregtech.api.objects.GTRenderedTexture; import gregtech.api.recipe.RecipeMap; import gregtech.api.util.GTUtility; import gregtech.api.util.GTWaila; import gregtech.api.util.HatchElementBuilder; import gregtech.api.util.IGTHatchAdder; import gregtech.api.util.shutdown.ShutDownReasonRegistry; import gtPlusPlus.core.util.minecraft.FluidUtils; import gtPlusPlus.xmod.gregtech.api.metatileentity.implementations.MTEHatchSteamBusOutput; import gtPlusPlus.xmod.gregtech.api.metatileentity.implementations.MteHatchSteamBusInput; import mcp.mobius.waila.api.IWailaConfigHandler; import mcp.mobius.waila.api.IWailaDataAccessor; public abstract class MTESteamMultiBase> extends GTPPMultiBlockBase { public ArrayList mSteamInputs = new ArrayList<>(); public ArrayList mSteamOutputs = new ArrayList<>(); public ArrayList mSteamInputFluids = new ArrayList<>(); protected static final String TT_steaminputbus = StatCollector.translateToLocal("GTPP.MBTT.SteamInputBus"); protected static final String TT_steamoutputbus = StatCollector.translateToLocal("GTPP.MBTT.SteamOutputBus"); protected static final String TT_steamhatch = StatCollector.translateToLocal("GTPP.MBTT.SteamHatch"); protected static final String HIGH_PRESSURE_TOOLTIP_NOTICE = "Processing Speed & Steam Consumption is doubled under High Pressure"; public MTESteamMultiBase(String aName) { super(aName); } public MTESteamMultiBase(int aID, String aName, String aNameRegional) { super(aID, aName, aNameRegional); } @Override public ITexture[] getTexture(final IGregTechTileEntity aBaseMetaTileEntity, final ForgeDirection side, final ForgeDirection facing, final int aColorIndex, final boolean aActive, final boolean aRedstone) { if (side == facing) { return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(getCasingTextureIndex()), aActive ? getFrontOverlayActive() : getFrontOverlay() }; } return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(getCasingTextureIndex()) }; } protected abstract GTRenderedTexture getFrontOverlay(); protected abstract GTRenderedTexture getFrontOverlayActive(); public abstract int getTierRecipes(); private int getCasingTextureIndex() { return 10; } @Override protected ProcessingLogic createProcessingLogic() { return new ProcessingLogic().setMaxParallelSupplier(this::getMaxParallelRecipes); } @Override protected void setProcessingLogicPower(ProcessingLogic logic) { logic.setAvailableVoltage(V[getTierRecipes()]); // We need to trick the GT_ParallelHelper we have enough amps for all recipe parallels. logic.setAvailableAmperage(getMaxParallelRecipes()); logic.setAmperageOC(false); } public ArrayList getAllSteamStacks() { ArrayList aFluids = new ArrayList<>(); FluidStack aSteam = FluidUtils.getSteam(1); for (FluidStack aFluid : this.getStoredFluids()) { if (aFluid.isFluidEqual(aSteam)) { aFluids.add(aFluid); } } return aFluids; } public int getTotalSteamStored() { int aSteam = 0; for (FluidStack aFluid : getAllSteamStacks()) { aSteam += aFluid.amount; } return aSteam; } public boolean tryConsumeSteam(int aAmount) { if (getTotalSteamStored() <= 0) { return false; } else { return this.depleteInput(FluidUtils.getSteam(aAmount)); } } @Override public int getMaxEfficiency(ItemStack arg0) { return 0; } @Override public void onPostTick(final IGregTechTileEntity aBaseMetaTileEntity, final long aTick) { if (aBaseMetaTileEntity.isServerSide()) { if (this.mUpdate == 1 || this.mStartUpCheck == 1) { this.mSteamInputs.clear(); this.mSteamOutputs.clear(); this.mInputHatches.clear(); this.mSteamInputFluids.clear(); } } super.onPostTick(aBaseMetaTileEntity, aTick); } /** * Called every tick the Machine runs */ @Override public boolean onRunningTick(ItemStack aStack) { if (lEUt < 0) { long aSteamVal = ((-lEUt * 10000) / Math.max(1000, mEfficiency)); // Logger.INFO("Trying to drain "+aSteamVal+" steam per tick."); if (!tryConsumeSteam((int) aSteamVal)) { stopMachine(ShutDownReasonRegistry.POWER_LOSS); return false; } } return true; } @Override public boolean addToMachineList(final IGregTechTileEntity aTileEntity, final int aBaseCasingIndex) { if (aTileEntity == null) { log("Invalid IGregTechTileEntity"); return false; } final IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); if (aMetaTileEntity == null) { log("Invalid IMetaTileEntity"); return false; } // Use this to determine the correct value, then update the hatch texture after. boolean aDidAdd = false; if (aMetaTileEntity instanceof MTEHatchCustomFluidBase) { log("Adding Steam Input Hatch"); aDidAdd = addToMachineListInternal(mSteamInputFluids, aMetaTileEntity, aBaseCasingIndex); } else if (aMetaTileEntity instanceof MteHatchSteamBusInput) { log( "Trying to set recipe map. Type: " + (getRecipeMap() != null ? getRecipeMap().unlocalizedName : "Null")); this.resetRecipeMapForHatch(aTileEntity, getRecipeMap()); log("Adding Steam Input Bus"); aDidAdd = addToMachineListInternal(mSteamInputs, aMetaTileEntity, aBaseCasingIndex); } else if (aMetaTileEntity instanceof MTEHatchSteamBusOutput) { log("Adding Steam Output Bus"); aDidAdd = addToMachineListInternal(mSteamOutputs, aMetaTileEntity, aBaseCasingIndex); } else if (aMetaTileEntity instanceof MTEHatchInput) aDidAdd = addToMachineListInternal(mInputHatches, aMetaTileEntity, aBaseCasingIndex); else if (aMetaTileEntity instanceof MTEHatchOutput); return aDidAdd; } /* * Handle I/O with custom hatches */ @Override public boolean depleteInput(FluidStack aLiquid) { if (aLiquid == null) return false; for (MTEHatchCustomFluidBase tHatch : validMTEList(mSteamInputFluids)) { FluidStack tLiquid = tHatch.getFluid(); if (tLiquid != null && tLiquid.isFluidEqual(aLiquid)) { tLiquid = tHatch.drain(aLiquid.amount, false); if (tLiquid != null && tLiquid.amount >= aLiquid.amount) { tLiquid = tHatch.drain(aLiquid.amount, true); return tLiquid != null && tLiquid.amount >= aLiquid.amount; } } } return false; } @Override public boolean depleteInput(ItemStack aStack) { if (GTUtility.isStackInvalid(aStack)) return false; FluidStack aLiquid = GTUtility.getFluidForFilledItem(aStack, true); if (aLiquid != null) return depleteInput(aLiquid); for (MTEHatchCustomFluidBase tHatch : validMTEList(mSteamInputFluids)) { if (GTUtility.areStacksEqual( aStack, tHatch.getBaseMetaTileEntity() .getStackInSlot(0))) { if (tHatch.getBaseMetaTileEntity() .getStackInSlot(0).stackSize >= aStack.stackSize) { tHatch.getBaseMetaTileEntity() .decrStackSize(0, aStack.stackSize); return true; } } } for (MteHatchSteamBusInput tHatch : validMTEList(mSteamInputs)) { tHatch.mRecipeMap = getRecipeMap(); for (int i = tHatch.getBaseMetaTileEntity() .getSizeInventory() - 1; i >= 0; i--) { if (GTUtility.areStacksEqual( aStack, tHatch.getBaseMetaTileEntity() .getStackInSlot(i))) { if (tHatch.getBaseMetaTileEntity() .getStackInSlot(0).stackSize >= aStack.stackSize) { tHatch.getBaseMetaTileEntity() .decrStackSize(0, aStack.stackSize); return true; } } } } return false; } @Override public ArrayList getStoredFluids() { ArrayList rList = new ArrayList<>(); for (MTEHatchCustomFluidBase tHatch : validMTEList(mSteamInputFluids)) { if (tHatch.getFillableStack() != null) { rList.add(tHatch.getFillableStack()); } } for (MTEHatchInput hatch : this.mInputHatches) if (hatch.getFillableStack() != null) { rList.add(hatch.getFillableStack()); } return rList; } @Override public ArrayList getStoredInputs() { ArrayList rList = new ArrayList<>(); for (MteHatchSteamBusInput tHatch : validMTEList(mSteamInputs)) { tHatch.mRecipeMap = getRecipeMap(); for (int i = tHatch.getBaseMetaTileEntity() .getSizeInventory() - 1; i >= 0; i--) { if (tHatch.getBaseMetaTileEntity() .getStackInSlot(i) != null) { rList.add( tHatch.getBaseMetaTileEntity() .getStackInSlot(i)); } } } return rList; } @Override public boolean addOutput(ItemStack aStack) { if (GTUtility.isStackInvalid(aStack)) return false; aStack = GTUtility.copy(aStack); boolean outputSuccess = true; while (outputSuccess && aStack.stackSize > 0) { outputSuccess = false; ItemStack single = aStack.splitStack(1); for (MTEHatchSteamBusOutput tHatch : validMTEList(mSteamOutputs)) { if (!outputSuccess) { for (int i = tHatch.getSizeInventory() - 1; i >= 0 && !outputSuccess; i--) { if (tHatch.getBaseMetaTileEntity() .addStackToSlot(i, single)) outputSuccess = true; } } } for (MTEHatchOutput tHatch : validMTEList(mOutputHatches)) { if (!outputSuccess && tHatch.outputsItems()) { if (tHatch.getBaseMetaTileEntity() .addStackToSlot(1, single)) outputSuccess = true; } } } return outputSuccess; } @Override public ArrayList getStoredOutputs() { ArrayList rList = new ArrayList<>(); for (MTEHatchSteamBusOutput tHatch : validMTEList(mSteamOutputs)) { for (int i = tHatch.getBaseMetaTileEntity() .getSizeInventory() - 1; i >= 0; i--) { rList.add( tHatch.getBaseMetaTileEntity() .getStackInSlot(i)); } } return rList; } @Override public List getItemOutputSlots(ItemStack[] toOutput) { List ret = new ArrayList<>(); for (final MTEHatch tBus : validMTEList(mSteamOutputs)) { final IInventory tBusInv = tBus.getBaseMetaTileEntity(); for (int i = 0; i < tBusInv.getSizeInventory(); i++) { ret.add(tBus.getStackInSlot(i)); } } return ret; } @Override public void updateSlots() { for (MTEHatchCustomFluidBase tHatch : validMTEList(mSteamInputFluids)) tHatch.updateSlots(); for (MteHatchSteamBusInput tHatch : validMTEList(mSteamInputs)) tHatch.updateSlots(); } @Override public boolean supportsBatchMode() { return false; } @Override public void clearHatches() { super.clearHatches(); mInputHatches.clear(); mSteamInputFluids.clear(); mSteamInputs.clear(); mSteamOutputs.clear(); } @Override public boolean resetRecipeMapForAllInputHatches(RecipeMap aMap) { boolean ret = super.resetRecipeMapForAllInputHatches(aMap); for (MteHatchSteamBusInput hatch : mSteamInputs) { if (resetRecipeMapForHatch(hatch, aMap)) { ret = true; } } for (MTEHatchInput g : this.mInputHatches) { if (resetRecipeMapForHatch(g, aMap)) { ret = true; } } return ret; } @Override public void getWailaBody(ItemStack itemStack, List currentTip, IWailaDataAccessor accessor, IWailaConfigHandler config) { final NBTTagCompound tag = accessor.getNBTData(); if (tag.getBoolean("incompleteStructure")) { currentTip.add(RED + "** INCOMPLETE STRUCTURE **" + RESET); } String efficiency = RESET + " Efficiency: " + tag.getFloat("efficiency") + "%"; if (tag.getBoolean("hasProblems")) { currentTip.add(RED + "** HAS PROBLEMS **" + efficiency); } else if (!tag.getBoolean("incompleteStructure")) { currentTip.add(GREEN + "Running Fine" + efficiency); } boolean isActive = tag.getBoolean("isActive"); if (isActive) { long actualEnergyUsage = tag.getLong("energyUsage"); if (actualEnergyUsage > 0) { currentTip.add( StatCollector .translateToLocalFormatted("GTPP.waila.steam.use", formatNumbers(actualEnergyUsage * 20))); } } currentTip .add(GTWaila.getMachineProgressString(isActive, tag.getInteger("maxProgress"), tag.getInteger("progress"))); // Show ns on the tooltip if (GTMod.gregtechproxy.wailaAverageNS && tag.hasKey("averageNS")) { int tAverageTime = tag.getInteger("averageNS"); currentTip.add("Average CPU load of ~" + formatNumbers(tAverageTime) + " ns"); } super.getMTEWailaBody(itemStack, currentTip, accessor, config); } protected static String getSteamTierTextForWaila(NBTTagCompound tag) { int tierMachine = tag.getInteger("tierMachine"); String tierMachineText; if (tierMachine == 1) { tierMachineText = "Basic"; } else if (tierMachine == 2) { tierMachineText = "High Pressure"; } else { tierMachineText = String.valueOf(tierMachine); } return tierMachineText; } protected static > HatchElementBuilder buildSteamInput(Class typeToken) { return buildHatchAdder(typeToken).adder(MTESteamMultiBase::addToMachineList) .hatchIds(31040) .shouldReject(t -> !t.mSteamInputFluids.isEmpty()); } protected enum SteamHatchElement implements IHatchElement> { InputBus_Steam { @Override public List> mteClasses() { return Collections.singletonList(MteHatchSteamBusInput.class); } @Override public long count(MTESteamMultiBase t) { return t.mSteamInputs.size(); } }, OutputBus_Steam { @Override public List> mteClasses() { return Collections.singletonList(MTEHatchSteamBusOutput.class); } @Override public long count(MTESteamMultiBase t) { return t.mSteamOutputs.size(); } },; @Override public IGTHatchAdder> adder() { return MTESteamMultiBase::addToMachineList; } } @Override public boolean getDefaultHasMaintenanceChecks() { return false; } }