diff options
Diffstat (limited to 'src/main/java/bartworks/common/tileentities')
27 files changed, 9296 insertions, 0 deletions
diff --git a/src/main/java/bartworks/common/tileentities/classic/TileEntityDimIDBridge.java b/src/main/java/bartworks/common/tileentities/classic/TileEntityDimIDBridge.java new file mode 100644 index 0000000000..6b00b65054 --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/classic/TileEntityDimIDBridge.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.classic; + +import net.minecraft.tileentity.TileEntity; + +public class TileEntityDimIDBridge extends TileEntity { + + @Override + public boolean canUpdate() { + return false; + } +} diff --git a/src/main/java/bartworks/common/tileentities/classic/TileEntityHeatedWaterPump.java b/src/main/java/bartworks/common/tileentities/classic/TileEntityHeatedWaterPump.java new file mode 100644 index 0000000000..3f973e8eea --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/classic/TileEntityHeatedWaterPump.java @@ -0,0 +1,375 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.classic; + +import java.util.Arrays; +import java.util.Optional; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityFurnace; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidEvent; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidHandler; +import net.minecraftforge.fluids.IFluidTank; + +import com.gtnewhorizons.modularui.api.ModularUITextures; +import com.gtnewhorizons.modularui.api.forge.IItemHandlerModifiable; +import com.gtnewhorizons.modularui.api.forge.InvWrapper; +import com.gtnewhorizons.modularui.api.screen.ITileWithModularUI; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.common.widget.ProgressBar; +import com.gtnewhorizons.modularui.common.widget.SlotWidget; + +import bartworks.API.ITileAddsInformation; +import bartworks.API.ITileDropsContent; +import bartworks.API.ITileHasDifferentTextureSides; +import bartworks.API.modularUI.BWUITextures; +import bartworks.MainMod; +import bartworks.common.configs.ConfigHandler; +import gregtech.api.util.GTUtility; +import gregtech.common.Pollution; + +public class TileEntityHeatedWaterPump extends TileEntity implements ITileDropsContent, IFluidHandler, IFluidTank, + ITileWithModularUI, ITileAddsInformation, ITileHasDifferentTextureSides { + + public static final int FUELSLOT = 0; + public static final Fluid WATER = FluidRegistry.WATER; + public ItemStack fuelstack; + public FluidStack outputstack = new FluidStack(FluidRegistry.WATER, 0); + public int fuel; + public byte tick; + public int maxfuel; + public ItemStack fakestack = new ItemStack(Blocks.water); + + @Override + public void writeToNBT(NBTTagCompound compound) { + NBTTagCompound subItemStack = new NBTTagCompound(); + if (this.fuelstack != null) { + this.fuelstack.writeToNBT(subItemStack); + } + compound.setTag("ItemStack", subItemStack); + NBTTagCompound subFluidStack = new NBTTagCompound(); + this.outputstack.writeToNBT(subFluidStack); + compound.setTag("FluidStack", subFluidStack); + compound.setInteger("fuel", this.fuel); + compound.setInteger("maxfuel", this.maxfuel); + compound.setByte("tick", this.tick); + super.writeToNBT(compound); + } + + @Override + public void readFromNBT(NBTTagCompound compound) { + this.tick = compound.getByte("tick"); + this.fuel = compound.getInteger("fuel"); + this.maxfuel = compound.getInteger("maxfuel"); + this.outputstack = FluidStack.loadFluidStackFromNBT(compound.getCompoundTag("FluidStack")); + if (!compound.getCompoundTag("ItemStack") + .equals(new NBTTagCompound())) + this.fuelstack = ItemStack.loadItemStackFromNBT(compound.getCompoundTag("ItemStack")); + super.readFromNBT(compound); + } + + private boolean checkPreUpdate() { + return (this.fuelstack == null || this.fuelstack.stackSize <= 0) && this.fuel <= 0; + } + + private void fixUnderlflow() { + if (this.fuel < 0) this.fuel = 0; + } + + private void handleRefuel() { + if (this.fuelstack != null && this.fuel == 0) { + this.fuel = this.maxfuel = TileEntityFurnace.getItemBurnTime(this.fuelstack); + --this.fuelstack.stackSize; + if (this.fuelstack.stackSize <= 0) this.fuelstack = fuelstack.getItem() + .getContainerItem(fuelstack); + } + } + + private void handleWaterGeneration() { + if (this.fuel > 0) { + ++this.tick; + --this.fuel; + if (this.tick % 20 == 0) { + if (this.outputstack.amount <= 8000 - ConfigHandler.mbWaterperSec) + this.outputstack.amount += ConfigHandler.mbWaterperSec; + this.tick = 0; + } + } + } + + @Override + public void updateEntity() { + if (this.worldObj.isRemote) return; + + this.pushWaterToAdjacentTiles(); + this.fakestack.setStackDisplayName(this.outputstack.amount + "L Water"); + if (this.checkPreUpdate()) return; + + this.fixUnderlflow(); + this.handleRefuel(); + this.handleWaterGeneration(); + this.causePollution(); + } + + private void pushWaterToAdjacentTiles() { + Arrays.stream(ForgeDirection.values(), 0, 6) // All but Unknown + .forEach( + direction -> Optional + .ofNullable( + this.worldObj.getTileEntity( + this.xCoord + direction.offsetX, + this.yCoord + direction.offsetY, + this.zCoord + direction.offsetZ)) + .ifPresent(te -> { + if (te instanceof IFluidHandler tank) { + if (tank.canFill(direction.getOpposite(), this.outputstack.getFluid())) { + int drainage = tank.fill(direction.getOpposite(), this.outputstack, false); + if (drainage > 0) { + tank.fill(direction.getOpposite(), this.outputstack, true); + this.drain(drainage, true); + } + } + } else if (te instanceof IFluidTank tank) { + int drainage = tank.fill(this.outputstack, false); + if (drainage > 0) { + tank.fill(this.outputstack, true); + this.drain(drainage, true); + } + } + })); + } + + private void causePollution() { + Optional.ofNullable(this.worldObj) + .ifPresent(e -> { + if (e.getTotalWorldTime() % 20 == 0) { + Optional.ofNullable(e.getChunkFromBlockCoords(this.xCoord, this.zCoord)) + .ifPresent(c -> Pollution.addPollution(c, ConfigHandler.pollutionHeatedWaterPumpSecond)); + } + }); + } + + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return new int[] { 0 }; + } + + @Override + public boolean canInsertItem(int p_102007_1_, ItemStack p_102007_2_, int p_102007_3_) { + return TileEntityFurnace.getItemBurnTime(p_102007_2_) > 0; + } + + @Override + public boolean canExtractItem(int p_102008_1_, ItemStack p_102008_2_, int p_102008_3_) { + return false; + } + + @Override + public int getSizeInventory() { + return 2; + } + + @Override + public ItemStack getStackInSlot(int slotIn) { + if (slotIn == 0) return this.fuelstack; + return this.fakestack; + } + + @Override + public ItemStack decrStackSize(int slot, int ammount) { + if (slot != TileEntityHeatedWaterPump.FUELSLOT || this.fuelstack == null || ammount > this.fuelstack.stackSize) + return null; + + return this.fuelstack.splitStack(ammount); + } + + @Override + public ItemStack getStackInSlotOnClosing(int index) { + return null; + } + + @Override + public void setInventorySlotContents(int slot, ItemStack stack) { + if (slot == TileEntityHeatedWaterPump.FUELSLOT) this.fuelstack = stack; + else this.fakestack = stack; + } + + @Override + public String getInventoryName() { + return null; + } + + @Override + public boolean hasCustomInventoryName() { + return false; + } + + @Override + public int getInventoryStackLimit() { + return 64; + } + + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return true; + } + + @Override + public void openInventory() {} + + @Override + public void closeInventory() {} + + @Override + public boolean isItemValidForSlot(int index, ItemStack stack) { + return TileEntityFurnace.getItemBurnTime(stack) > 0 && index == TileEntityHeatedWaterPump.FUELSLOT; + } + + @Override + public FluidStack getFluid() { + return this.outputstack.amount > 0 ? this.outputstack : null; + } + + @Override + public int getFluidAmount() { + return this.outputstack.amount; + } + + @Override + public int getCapacity() { + return 8000; + } + + @Override + public FluidTankInfo getInfo() { + return new FluidTankInfo(this); + } + + @Override + public int fill(FluidStack resource, boolean doFill) { + return 0; + } + + @Override + public FluidStack drain(int maxDrain, boolean doDrain) { + int actualdrain = maxDrain; + if (actualdrain > this.outputstack.amount) actualdrain = this.outputstack.amount; + FluidStack ret = new FluidStack(TileEntityHeatedWaterPump.WATER, actualdrain); + if (ret.amount == 0) ret = null; + if (doDrain) { + this.outputstack.amount -= actualdrain; + FluidEvent.fireEvent( + new FluidEvent.FluidDrainingEvent( + this.outputstack, + this.getWorldObj(), + this.xCoord, + this.yCoord, + this.zCoord, + this, + actualdrain)); + } + return ret; + } + + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + return 0; + } + + @Override + public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { + if (resource != null && resource.getFluid() == TileEntityHeatedWaterPump.WATER + && this.drain(resource.amount, false) != null) return this.drain(resource.amount, doDrain); + return null; + } + + @Override + public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { + return this.drain(maxDrain, doDrain); + } + + @Override + public boolean canFill(ForgeDirection from, Fluid fluid) { + return false; + } + + @Override + public boolean canDrain(ForgeDirection from, Fluid fluid) { + return fluid == null || fluid == TileEntityHeatedWaterPump.WATER; + } + + @Override + public FluidTankInfo[] getTankInfo(ForgeDirection from) { + return new FluidTankInfo[] { this.getInfo() }; + } + + @Override + public String[] getInfoData() { + return new String[] { + StatCollector.translateToLocal("tooltip.tile.waterpump.0.name") + " " + + GTUtility.formatNumbers(ConfigHandler.mbWaterperSec) + + String.format( + StatCollector.translateToLocal("tooltip.tile.waterpump.1.name"), + ConfigHandler.pollutionHeatedWaterPumpSecond), + StatCollector.translateToLocal("tooltip.tile.waterpump.2.name") }; + } + + @Override + public void registerBlockIcons(IIconRegister par1IconRegister) { + ITileHasDifferentTextureSides.texture[ForgeDirection.UP.ordinal()] = par1IconRegister + .registerIcon(MainMod.MOD_ID + ":heatedWaterPumpTop"); + ITileHasDifferentTextureSides.texture[ForgeDirection.DOWN.ordinal()] = par1IconRegister + .registerIcon(MainMod.MOD_ID + ":heatedWaterPumpDown"); + for (int i = 2; i < 7; i++) { + ITileHasDifferentTextureSides.texture[i] = par1IconRegister + .registerIcon(MainMod.MOD_ID + ":heatedWaterPumpSide"); + } + } + + @Override + public ModularWindow createWindow(UIBuildContext buildContext) { + ModularWindow.Builder builder = ModularWindow.builder(176, 166); + builder.setBackground(ModularUITextures.VANILLA_BACKGROUND); + builder.bindPlayerInventory(buildContext.getPlayer()); + final IItemHandlerModifiable invWrapper = new InvWrapper(this); + + builder.widget( + new SlotWidget(invWrapper, 0).setFilter(stack -> TileEntityFurnace.getItemBurnTime(stack) > 0) + .setPos(55, 52)) + .widget( + SlotWidget.phantom(invWrapper, 1) + .disableInteraction() + .setPos(85, 32)) + .widget( + new ProgressBar().setProgress(() -> (float) this.fuel / this.maxfuel) + .setTexture(BWUITextures.PROGRESSBAR_FUEL, 14) + .setDirection(ProgressBar.Direction.UP) + .setPos(56, 36) + .setSize(14, 14)); + + return builder.build(); + } +} diff --git a/src/main/java/bartworks/common/tileentities/classic/TileEntityRotorBlock.java b/src/main/java/bartworks/common/tileentities/classic/TileEntityRotorBlock.java new file mode 100644 index 0000000000..78c7f34710 --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/classic/TileEntityRotorBlock.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.classic; + +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.entity.player.EntityPlayer; + +import bartworks.client.gui.GuiContainerRotorBlock; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import ic2.core.block.kineticgenerator.container.ContainerWindKineticGenerator; +import ic2.core.block.kineticgenerator.tileentity.TileEntityWindKineticGenerator; + +public class TileEntityRotorBlock extends TileEntityWindKineticGenerator { + + public int getGrindPower() { + return super.getKuOutput(); + } + + @Override + public int getKuOutput() { + return 0; + } + + @Override + @SideOnly(Side.CLIENT) + public GuiScreen getGui(EntityPlayer entityPlayer, boolean isAdmin) { + return new GuiContainerRotorBlock(new ContainerWindKineticGenerator(entityPlayer, this)); + } +} diff --git a/src/main/java/bartworks/common/tileentities/debug/MTECreativeScanner.java b/src/main/java/bartworks/common/tileentities/debug/MTECreativeScanner.java new file mode 100644 index 0000000000..a1ccd7d4e3 --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/debug/MTECreativeScanner.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.debug; + +import net.minecraft.util.StatCollector; + +import org.apache.commons.lang3.ArrayUtils; + +import bartworks.util.BWTooltipReference; +import gregtech.api.enums.MachineType; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.common.tileentities.machines.basic.MTEScanner; + +public class MTECreativeScanner extends MTEScanner { + + public MTECreativeScanner(int aID, String aName, String aNameRegional, int aTier) { + super(aID, aName, aNameRegional, aTier); + } + + public MTECreativeScanner(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aDescription, aTextures); + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTECreativeScanner(this.mName, this.mTier, this.mDescriptionArray, this.mTextures); + } + + @Override + public String[] getDescription() { + return ArrayUtils.addAll( + MachineType.SCANNER.tooltipDescription(), + StatCollector.translateToLocal("gt.blockmachines.creativeScanner.desc.1"), + BWTooltipReference.ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS.get()); + } + + @Override + public long maxEUStore() { + return 0; + } + + @Override + protected boolean hasEnoughEnergyToCheckRecipe() { + return true; + } + + @Override + protected boolean drainEnergyForProcess(long aEUt) { + return true; + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + this.mProgresstime = this.mMaxProgresstime; + super.onPostTick(aBaseMetaTileEntity, aTick); + } +} diff --git a/src/main/java/bartworks/common/tileentities/multis/MTEBioVat.java b/src/main/java/bartworks/common/tileentities/multis/MTEBioVat.java new file mode 100644 index 0000000000..b982c0d886 --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/multis/MTEBioVat.java @@ -0,0 +1,834 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.multis; + +import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTWORKS; +import static bartworks.util.BWUtil.ofGlassTiered; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.isAir; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlockAnyMeta; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.onElementPass; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER_GLOW; +import static gregtech.api.util.GTStructureUtility.ofHatchAdder; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; + +import javax.annotation.Nullable; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; + +import org.jetbrains.annotations.NotNull; + +import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits; +import com.gtnewhorizon.structurelib.structure.IStructureDefinition; +import com.gtnewhorizon.structurelib.structure.StructureDefinition; + +import bartworks.API.SideReference; +import bartworks.API.recipe.BartWorksRecipeMaps; +import bartworks.MainMod; +import bartworks.common.configs.ConfigHandler; +import bartworks.common.items.ItemLabParts; +import bartworks.common.loaders.FluidLoader; +import bartworks.common.net.RendererPacket; +import bartworks.common.tileentities.tiered.GT_MetaTileEntity_RadioHatch; +import bartworks.util.BWUtil; +import bartworks.util.BioCulture; +import bartworks.util.Coords; +import bartworks.util.MathUtils; +import bartworks.util.ResultWrongSievert; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.Textures; +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.MTEEnhancedMultiBlockBase; +import gregtech.api.metatileentity.implementations.MTEHatchInput; +import gregtech.api.metatileentity.implementations.MTEHatchOutput; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.recipe.check.CheckRecipeResult; +import gregtech.api.recipe.check.CheckRecipeResultRegistry; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; +import gregtech.api.util.MultiblockTooltipBuilder; +import gregtech.api.util.ParallelHelper; + +public class MTEBioVat extends MTEEnhancedMultiBlockBase<MTEBioVat> { + + public static final HashMap<Coords, Integer> staticColorMap = new HashMap<>(); + + private static final byte TIMERDIVIDER = 20; + + private final HashSet<EntityPlayerMP> playerMPHashSet = new HashSet<>(); + private final ArrayList<GT_MetaTileEntity_RadioHatch> mRadHatches = new ArrayList<>(); + private int height = 1; + private Fluid mFluid = FluidRegistry.LAVA; + private BioCulture mCulture; + private ItemStack mStack; + private boolean needsVisualUpdate = true; + private byte mGlassTier; + private int mSievert; + private int mNeededSievert; + private int mCasing = 0; + private int mExpectedMultiplier = 0; + private int mTimes = 0; + private boolean isVisibleFluid = false; + + public MTEBioVat(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + public MTEBioVat(String aName) { + super(aName); + } + + private static final int CASING_INDEX = 49; + private static final String STRUCTURE_PIECE_MAIN = "main"; + private static final IStructureDefinition<MTEBioVat> STRUCTURE_DEFINITION = StructureDefinition.<MTEBioVat>builder() + .addShape( + STRUCTURE_PIECE_MAIN, + transpose( + new String[][] { { "ccccc", "ccccc", "ccccc", "ccccc", "ccccc" }, + { "ggggg", "gaaag", "gaaag", "gaaag", "ggggg" }, { "ggggg", "gaaag", "gaaag", "gaaag", "ggggg" }, + { "cc~cc", "ccccc", "ccccc", "ccccc", "ccccc" }, })) + .addElement( + 'c', + ofChain( + ofHatchAdder(MTEBioVat::addMaintenanceToMachineList, CASING_INDEX, 1), + ofHatchAdder(MTEBioVat::addOutputToMachineList, CASING_INDEX, 1), + ofHatchAdder(MTEBioVat::addInputToMachineList, CASING_INDEX, 1), + ofHatchAdder(MTEBioVat::addRadiationInputToMachineList, CASING_INDEX, 1), + ofHatchAdder(MTEBioVat::addEnergyInputToMachineList, CASING_INDEX, 1), + onElementPass(e -> e.mCasing++, ofBlock(GregTechAPI.sBlockCasings4, 1)))) + .addElement('a', ofChain(isAir(), ofBlockAnyMeta(FluidLoader.bioFluidBlock))) + .addElement( + 'g', + ofGlassTiered((byte) 1, (byte) 127, (byte) 0, (te, v) -> te.mGlassTier = v, te -> te.mGlassTier, 1)) + .build(); + + @Override + public IStructureDefinition<MTEBioVat> getStructureDefinition() { + return STRUCTURE_DEFINITION; + } + + @Override + protected IAlignmentLimits getInitialAlignmentLimits() { + return (d, r, f) -> d.offsetY == 0 && r.isNotRotated() && f.isNotFlipped(); + } + + @Override + protected MultiblockTooltipBuilder createTooltip() { + MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder(); + tt.addMachineType("Bacterial Vat") + .addInfo("Controller block for the Bacterial Vat") + .addInfo("For maximum efficiency boost keep the Output Hatch always half filled!") + .addSeparator() + .beginStructureBlock(5, 4, 5, false) + .addController("Front bottom center") + .addCasingInfoMin("Clean Stainless Steel Casings", 19, false) + .addOtherStructurePart("Glass", "Hollow two middle layers", 2) + .addStructureInfo("The glass can be any glass, i.e. Tinkers Construct Clear Glass") + .addStructureInfo("Some Recipes need more advanced Glass Types") + .addMaintenanceHatch("Any casing", 1) + .addOtherStructurePart("Radio Hatch", "Any casing", 1) + .addInputBus("Any casing", 1) + .addOutputBus("Any casing", 1) + .addInputHatch("Any casing", 1) + .addOutputHatch("Any casing", 1) + .addEnergyHatch("Any casing", 1) + .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTWORKS); + return tt; + } + + public static int[] specialValueUnpack(int aSpecialValue) { + int[] ret = new int[4]; + ret[0] = aSpecialValue & 0xF; // = glass tier + ret[1] = aSpecialValue >>> 4 & 0b11; // = special value + ret[2] = aSpecialValue >>> 6 & 0b1; // boolean exact svt | 1 = true | 0 = false + ret[3] = aSpecialValue >>> 7 & Integer.MAX_VALUE; // = sievert + return ret; + } + + private int getInputCapacity() { + return this.mInputHatches.stream() + .mapToInt(MTEHatchInput::getCapacity) + .sum(); + } + + private int getOutputCapacity() { + return this.mOutputHatches.stream() + .mapToInt(MTEHatchOutput::getCapacity) + .sum(); + } + + @Override + public int getCapacity() { + int ret = 0; + ret += this.getInputCapacity(); + // ret += getOutputCapacity(); + return ret; + } + + @Override + public int fill(FluidStack resource, boolean doFill) { + return super.fill(resource, doFill); + } + + @Override + public boolean isCorrectMachinePart(ItemStack itemStack) { + return true; + } + + @Override + public RecipeMap<?> getRecipeMap() { + return BartWorksRecipeMaps.bacterialVatRecipes; + } + + /** + * Calculates the expected output multiplier based on the output hatch + * + * @param recipeFluidOutput the recipe fluid output + * @param needEqual if the recipeFluidOutput should be equal to the fluid in the output hatch + * @return the expected output multiplier + */ + private int getExpectedMultiplier(@Nullable FluidStack recipeFluidOutput, boolean needEqual) { + FluidStack storedFluidOutputs = this.getStoredFluidOutputs(); + if (storedFluidOutputs == null) return 1; + if (!needEqual || storedFluidOutputs.isFluidEqual(recipeFluidOutput)) { + return this.calcMod(storedFluidOutputs.amount) + 1; + } + return 1; + } + + private int calcMod(double x) { + double y = this.getOutputCapacity() / 2D, z = ConfigHandler.bioVatMaxParallelBonus; + + int ret = MathUtils.ceilInt((-1D / y * Math.pow(x - y, 2D) + y) / y * z); + return MathUtils.clamp(1, ret, ConfigHandler.bioVatMaxParallelBonus); + } + + @Override + protected ProcessingLogic createProcessingLogic() { + return new ProcessingLogic() { + + @NotNull + @Override + protected CheckRecipeResult validateRecipe(@NotNull GTRecipe recipe) { + if (!BWUtil.areStacksEqualOrNull((ItemStack) recipe.mSpecialItems, MTEBioVat.this.getControllerSlot())) + return CheckRecipeResultRegistry.NO_RECIPE; + int[] conditions = MTEBioVat.specialValueUnpack(recipe.mSpecialValue); + MTEBioVat.this.mNeededSievert = conditions[3]; + + if (MTEBioVat.this.mGlassTier < conditions[0]) { + return CheckRecipeResultRegistry.insufficientMachineTier(conditions[0]); + } + + if (conditions[2] == 0) { + if (MTEBioVat.this.mSievert < MTEBioVat.this.mNeededSievert) { + return ResultWrongSievert.insufficientSievert(MTEBioVat.this.mNeededSievert); + } + } else if (MTEBioVat.this.mSievert != conditions[3]) { + return ResultWrongSievert.wrongSievert(conditions[3]); + } + + return CheckRecipeResultRegistry.SUCCESSFUL; + } + + @NotNull + @Override + protected ParallelHelper createParallelHelper(@NotNull GTRecipe recipe) { + return super.createParallelHelper(recipeWithMultiplier(recipe, inputFluids)); + } + }; + } + + protected GTRecipe recipeWithMultiplier(GTRecipe recipe, FluidStack[] fluidInputs) { + GTRecipe tRecipe = recipe.copy(); + int multiplier = getExpectedMultiplier(recipe.getFluidOutput(0), true); + mExpectedMultiplier = multiplier; + // Calculate max multiplier limited by input fluids + long fluidAmount = 0; + for (FluidStack fluid : fluidInputs) { + if (recipe.mFluidInputs[0].isFluidEqual(fluid)) { + fluidAmount += fluid.amount; + } + } + multiplier = (int) Math.min(multiplier, fluidAmount / recipe.mFluidInputs[0].amount); + // In case multiplier is 0 + multiplier = Math.max(multiplier, 1); + mTimes = multiplier; + tRecipe.mFluidInputs[0].amount *= multiplier; + tRecipe.mFluidOutputs[0].amount *= multiplier; + return tRecipe; + } + + @Override + protected void setupProcessingLogic(ProcessingLogic logic) { + super.setupProcessingLogic(logic); + logic.setSpecialSlotItem(this.getControllerSlot()); + } + + public FluidStack getStoredFluidOutputs() { + // Only one output Hatch + assert this.mOutputHatches.size() == 1; + return this.mOutputHatches.get(0) + .getFluid(); + } + + private boolean addRadiationInputToMachineList(IGregTechTileEntity aTileEntity, int CasingIndex) { + if (aTileEntity == null) { + return false; + } + IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null || !(aMetaTileEntity instanceof GT_MetaTileEntity_RadioHatch)) { + return false; + } else { + ((GT_MetaTileEntity_RadioHatch) aMetaTileEntity).updateTexture(CasingIndex); + return this.mRadHatches.add((GT_MetaTileEntity_RadioHatch) aMetaTileEntity); + } + } + + @Override + public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack itemStack) { + this.mRadHatches.clear(); + this.mGlassTier = 0; + this.mCasing = 0; + + if (!this.checkPiece(STRUCTURE_PIECE_MAIN, 2, 3, 0)) return false; + + return this.mCasing >= 19 && this.mRadHatches.size() <= 1 + && this.mOutputHatches.size() == 1 + && this.mMaintenanceHatches.size() == 1 + && this.mInputHatches.size() > 0 + && this.mEnergyHatches.size() > 0; + } + + @Override + public int getMaxEfficiency(ItemStack itemStack) { + return 10000; + } + + @Override + public int getPollutionPerTick(ItemStack itemStack) { + return 0; + } + + @Override + public int getDamageToComponent(ItemStack itemStack) { + return 0; + } + + private void sendAllRequiredRendererPackets() { + int height = this.reCalculateHeight(); + if (this.mFluid != null && height > 1 && this.reCalculateFluidAmmount() > 0) { + for (int x = -1; x < 2; x++) for (int y = 1; y < height; y++) + for (int z = -1; z < 2; z++) this.sendPackagesOrRenewRenderer(x, y, z, this.mCulture); + } + } + + private void sendPackagesOrRenewRenderer(int x, int y, int z, BioCulture lCulture) { + int xDir = this.getXDir(); + int zDir = this.getZDir(); + + MTEBioVat.staticColorMap.remove( + new Coords( + xDir + x + + this.getBaseMetaTileEntity() + .getXCoord(), + y + this.getBaseMetaTileEntity() + .getYCoord(), + zDir + z + + this.getBaseMetaTileEntity() + .getZCoord(), + this.getBaseMetaTileEntity() + .getWorld().provider.dimensionId)); + MTEBioVat.staticColorMap.put( + new Coords( + xDir + x + + this.getBaseMetaTileEntity() + .getXCoord(), + y + this.getBaseMetaTileEntity() + .getYCoord(), + zDir + z + + this.getBaseMetaTileEntity() + .getZCoord(), + this.getBaseMetaTileEntity() + .getWorld().provider.dimensionId), + lCulture == null ? BioCulture.NULLCULTURE.getColorRGB() : lCulture.getColorRGB()); + + if (SideReference.Side.Server) { + MainMod.BW_Network_instance.sendPacketToAllPlayersInRange( + this.getBaseMetaTileEntity() + .getWorld(), + new RendererPacket( + new Coords( + xDir + x + + this.getBaseMetaTileEntity() + .getXCoord(), + y + this.getBaseMetaTileEntity() + .getYCoord(), + zDir + z + + this.getBaseMetaTileEntity() + .getZCoord(), + this.getBaseMetaTileEntity() + .getWorld().provider.dimensionId), + lCulture == null ? BioCulture.NULLCULTURE.getColorRGB() : lCulture.getColorRGB(), + true), + this.getBaseMetaTileEntity() + .getXCoord(), + this.getBaseMetaTileEntity() + .getZCoord()); + MainMod.BW_Network_instance.sendPacketToAllPlayersInRange( + this.getBaseMetaTileEntity() + .getWorld(), + new RendererPacket( + new Coords( + xDir + x + + this.getBaseMetaTileEntity() + .getXCoord(), + y + this.getBaseMetaTileEntity() + .getYCoord(), + zDir + z + + this.getBaseMetaTileEntity() + .getZCoord(), + this.getBaseMetaTileEntity() + .getWorld().provider.dimensionId), + lCulture == null ? BioCulture.NULLCULTURE.getColorRGB() : lCulture.getColorRGB(), + false), + this.getBaseMetaTileEntity() + .getXCoord(), + this.getBaseMetaTileEntity() + .getZCoord()); + } + this.needsVisualUpdate = true; + } + + private void check_Chunk() { + World aWorld = this.getBaseMetaTileEntity() + .getWorld(); + if (!aWorld.isRemote) { + + for (Object tObject : aWorld.playerEntities) { + if (!(tObject instanceof EntityPlayerMP tPlayer)) { + break; + } + Chunk tChunk = aWorld.getChunkFromBlockCoords( + this.getBaseMetaTileEntity() + .getXCoord(), + this.getBaseMetaTileEntity() + .getZCoord()); + if (tPlayer.getServerForPlayer() + .getPlayerManager() + .isPlayerWatchingChunk(tPlayer, tChunk.xPosition, tChunk.zPosition)) { + if (!this.playerMPHashSet.contains(tPlayer)) { + this.playerMPHashSet.add(tPlayer); + this.sendAllRequiredRendererPackets(); + } + } else { + this.playerMPHashSet.remove(tPlayer); + } + } + } + } + + private void placeFluid() { + this.isVisibleFluid = true; + int xDir = this.getXDir(); + int zDir = this.getZDir(); + this.height = this.reCalculateHeight(); + if (this.mFluid != null && this.height > 1 && this.reCalculateFluidAmmount() > 0) for (int x = -1; x < 2; x++) { + for (int y = 0; y < this.height; y++) { + for (int z = -1; z < 2; z++) { + if (this.getBaseMetaTileEntity() + .getWorld() + .getBlock( + xDir + x + + this.getBaseMetaTileEntity() + .getXCoord(), + y + this.getBaseMetaTileEntity() + .getYCoord(), + zDir + z + + this.getBaseMetaTileEntity() + .getZCoord()) + .equals(Blocks.air)) + this.getBaseMetaTileEntity() + .getWorld() + .setBlock( + xDir + x + + this.getBaseMetaTileEntity() + .getXCoord(), + y + this.getBaseMetaTileEntity() + .getYCoord(), + zDir + z + + this.getBaseMetaTileEntity() + .getZCoord(), + FluidLoader.bioFluidBlock); + } + } + } + } + + private void removeFluid(int xDir, int zDir) { + this.isVisibleFluid = false; + + for (int x = -1; x < 2; x++) { + for (int y = 1; y < 3; y++) { + for (int z = -1; z < 2; z++) { + if (this.getBaseMetaTileEntity() + .getWorld() + .getBlock( + xDir + x + + this.getBaseMetaTileEntity() + .getXCoord(), + y + this.getBaseMetaTileEntity() + .getYCoord(), + zDir + z + + this.getBaseMetaTileEntity() + .getZCoord()) + .equals(FluidLoader.bioFluidBlock)) + this.getBaseMetaTileEntity() + .getWorld() + .setBlockToAir( + xDir + x + + this.getBaseMetaTileEntity() + .getXCoord(), + y + this.getBaseMetaTileEntity() + .getYCoord(), + zDir + z + + this.getBaseMetaTileEntity() + .getZCoord()); + MTEBioVat.staticColorMap.remove( + new Coords( + xDir + x + + this.getBaseMetaTileEntity() + .getXCoord(), + y + this.getBaseMetaTileEntity() + .getYCoord(), + zDir + z + + this.getBaseMetaTileEntity() + .getZCoord()), + this.getBaseMetaTileEntity() + .getWorld().provider.dimensionId); + } + } + } + } + + private int reCalculateFluidAmmount() { + return this.getStoredFluids() + .stream() + .mapToInt(fluidStack -> fluidStack.amount) + .sum(); + } + + private int reCalculateHeight() { + return this.reCalculateFluidAmmount() > this.getCapacity() / 4 - 1 + ? this.reCalculateFluidAmmount() >= this.getCapacity() / 2 ? 3 : 2 + : 1; + } + + public void doAllVisualThings() { + if (this.getBaseMetaTileEntity() + .isServerSide()) { + if (this.mMachine) { + ItemStack aStack = this.mInventory[1]; + BioCulture lCulture = null; + int xDir = this.getXDir(); + int zDir = this.getZDir(); + + if (this.getBaseMetaTileEntity() + .getTimer() % 200 == 0) { + this.check_Chunk(); + } + + if (this.needsVisualUpdate && this.getBaseMetaTileEntity() + .getTimer() % MTEBioVat.TIMERDIVIDER == 0) { + for (int x = -1; x < 2; x++) + for (int y = 1; y < 3; y++) for (int z = -1; z < 2; z++) this.getBaseMetaTileEntity() + .getWorld() + .setBlockToAir( + xDir + x + + this.getBaseMetaTileEntity() + .getXCoord(), + y + this.getBaseMetaTileEntity() + .getYCoord(), + zDir + z + + this.getBaseMetaTileEntity() + .getZCoord()); + } + + this.height = this.reCalculateHeight(); + if (this.mFluid != null && this.height > 1 && this.reCalculateFluidAmmount() > 0) { + if (!BWUtil.areStacksEqualOrNull(aStack, this.mStack) + || this.needsVisualUpdate && this.getBaseMetaTileEntity() + .getTimer() % MTEBioVat.TIMERDIVIDER == 1) { + for (int x = -1; x < 2; x++) { + for (int y = 1; y < this.height; y++) { + for (int z = -1; z < 2; z++) { + if (aStack == null + || aStack.getItem() instanceof ItemLabParts && aStack.getItemDamage() == 0) { + if (this.mCulture == null || aStack == null + || aStack.getTagCompound() == null + || this.mCulture.getID() != aStack.getTagCompound() + .getInteger("ID")) { + lCulture = aStack == null || aStack.getTagCompound() == null ? null + : BioCulture.getBioCulture( + aStack.getTagCompound() + .getString("Name")); + this.sendPackagesOrRenewRenderer(x, y, z, lCulture); + } + } + } + } + } + this.mStack = aStack; + this.mCulture = lCulture; + } + if (this.needsVisualUpdate && this.getBaseMetaTileEntity() + .getTimer() % MTEBioVat.TIMERDIVIDER == 1) { + if (this.getBaseMetaTileEntity() + .isClientSide()) new Throwable().printStackTrace(); + this.placeFluid(); + this.needsVisualUpdate = false; + } + } + } else { + this.onRemoval(); + } + } + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onPostTick(aBaseMetaTileEntity, aTick); + if (this.height != this.reCalculateHeight()) this.needsVisualUpdate = true; + this.doAllVisualThings(); + if (this.getBaseMetaTileEntity() + .isServerSide() && this.mRadHatches.size() == 1) { + this.mSievert = this.mRadHatches.get(0) + .getSievert(); + if (this.getBaseMetaTileEntity() + .isActive() && this.mNeededSievert > this.mSievert) this.mOutputFluids = null; + } + if (aBaseMetaTileEntity.isServerSide() && this.mMaxProgresstime <= 0) { + this.mTimes = 0; + this.mMaxProgresstime = 0; + } + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + aNBT.setInteger("mFluidHeight", this.height); + if (this.mCulture != null && !this.mCulture.getName() + .isEmpty()) aNBT.setString("mCulture", this.mCulture.getName()); + else if ((this.mCulture == null || this.mCulture.getName() + .isEmpty()) && !aNBT.getString("mCulture") + .isEmpty()) { + aNBT.removeTag("mCulture"); + } + if (this.mFluid != null) aNBT.setString("mFluid", this.mFluid.getName()); + aNBT.setInteger("mSievert", this.mSievert); + aNBT.setInteger("mNeededSievert", this.mNeededSievert); + aNBT.setBoolean("isVisibleFluid", this.isVisibleFluid); + super.saveNBTData(aNBT); + } + + @Override + public void onRemoval() { + if (this.isVisibleFluid) { + int xDir = this.getXDir(); + int zDir = this.getZDir(); + this.removeFluid(xDir, zDir); + this.sendRenderPackets(xDir, zDir); + } else if (this.getBaseMetaTileEntity() + .getWorld() + .getWorldTime() % 20 == 7) { + this.sendRenderPackets(); + } + + super.onRemoval(); + } + + private int getXDir() { + return this.getBaseMetaTileEntity() + .getBackFacing().offsetX * 2; + } + + private int getZDir() { + return this.getBaseMetaTileEntity() + .getBackFacing().offsetZ * 2; + } + + private void sendRenderPackets() { + int xDir = this.getXDir(); + int zDir = this.getZDir(); + this.sendRenderPackets(xDir, zDir); + } + + private void sendRenderPackets(int xDir, int zDir) { + if (SideReference.Side.Server) { + for (int x = -1; x < 2; x++) { + for (int y = 1; y < 3; y++) { + for (int z = -1; z < 2; z++) { + MainMod.BW_Network_instance.sendPacketToAllPlayersInRange( + this.getBaseMetaTileEntity() + .getWorld(), + new RendererPacket( + new Coords( + xDir + x + + this.getBaseMetaTileEntity() + .getXCoord(), + y + this.getBaseMetaTileEntity() + .getYCoord(), + zDir + z + + this.getBaseMetaTileEntity() + .getZCoord(), + this.getBaseMetaTileEntity() + .getWorld().provider.dimensionId), + this.mCulture == null ? BioCulture.NULLCULTURE.getColorRGB() + : this.mCulture.getColorRGB(), + true), + this.getBaseMetaTileEntity() + .getXCoord(), + this.getBaseMetaTileEntity() + .getZCoord()); + } + } + } + } + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + this.height = aNBT.getInteger("mFluidHeight"); + this.mCulture = BioCulture.getBioCulture(aNBT.getString("mCulture")); + if (!aNBT.getString("mFluid") + .isEmpty()) this.mFluid = FluidRegistry.getFluid(aNBT.getString("mFluid")); + this.mSievert = aNBT.getInteger("mSievert"); + this.mNeededSievert = aNBT.getInteger("mNeededSievert"); + super.loadNBTData(aNBT); + this.isVisibleFluid = aNBT.getBoolean("isVisibleFluid"); + } + + @Override + public boolean explodesOnComponentBreak(ItemStack itemStack) { + return false; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MTEBioVat(this.mName); + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing, + int aColorIndex, boolean aActive, boolean aRedstone) { + if (side == facing) { + if (aActive) return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE_GLOW) + .extFacing() + .glow() + .build() }; + return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX), TextureFactory.builder() + .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER_GLOW) + .extFacing() + .glow() + .build() }; + } + return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX) }; + } + + @Override + public void construct(ItemStack itemStack, boolean b) { + this.buildPiece(STRUCTURE_PIECE_MAIN, itemStack, b, 2, 3, 0); + } + + @Override + public String[] getInfoData() { + final String[] baseInfoData = super.getInfoData(); + final String[] infoData = new String[baseInfoData.length + 2]; + System.arraycopy(baseInfoData, 0, infoData, 0, baseInfoData.length); + // See https://github.com/GTNewHorizons/GT-New-Horizons-Modpack/issues/11923 + // here we must check the machine is well-formed as otherwise getExpectedMultiplier might error out! + infoData[infoData.length - 2] = StatCollector.translateToLocal("BW.infoData.BioVat.expectedProduction") + ": " + + EnumChatFormatting.GREEN + + (this.mMachine + ? (this.mMaxProgresstime <= 0 ? this.getExpectedMultiplier(null, false) : this.mExpectedMultiplier) + * 100 + : -1) + + EnumChatFormatting.RESET + + " %"; + infoData[infoData.length - 1] = StatCollector.translateToLocal("BW.infoData.BioVat.production") + ": " + + EnumChatFormatting.GREEN + + (this.mMaxProgresstime <= 0 ? 0 : this.mTimes) * 100 + + EnumChatFormatting.RESET + + " %"; + return infoData; + } + + @Override + public boolean supportsVoidProtection() { + return true; + } + + @Override + public boolean supportsBatchMode() { + return true; + } + + @Override + public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer, + float aX, float aY, float aZ) { + if (aPlayer.isSneaking()) { + batchMode = !batchMode; + if (batchMode) { + GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOn")); + } else { + GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOff")); + } + return true; + } + return false; + } + +} diff --git a/src/main/java/bartworks/common/tileentities/multis/MTECircuitAssemblyLine.java b/src/main/java/bartworks/common/tileentities/multis/MTECircuitAssemblyLine.java new file mode 100644 index 0000000000..80f851167d --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/multis/MTECircuitAssemblyLine.java @@ -0,0 +1,672 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.multis; + +import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS; +import static bartworks.util.BWUtil.ofGlassTieredMixed; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.*; +import static gregtech.api.enums.HatchElement.Energy; +import static gregtech.api.enums.HatchElement.InputBus; +import static gregtech.api.enums.HatchElement.InputHatch; +import static gregtech.api.enums.HatchElement.Maintenance; +import static gregtech.api.enums.HatchElement.OutputBus; +import static gregtech.api.enums.SoundResource.IC2_MACHINES_MAGNETIZER_LOOP; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ASSEMBLY_LINE; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ASSEMBLY_LINE_ACTIVE; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ASSEMBLY_LINE_ACTIVE_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ASSEMBLY_LINE_GLOW; +import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY; +import static gregtech.api.util.GTStructureUtility.buildHatchAdder; +import static gregtech.api.util.GTUtility.filterValidMTEs; +import static gregtech.api.util.GTUtility.getColoredTierNameFromTier; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import javax.annotation.Nonnull; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import org.jetbrains.annotations.NotNull; + +import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable; +import com.gtnewhorizon.structurelib.structure.IStructureDefinition; +import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment; +import com.gtnewhorizon.structurelib.structure.StructureDefinition; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.common.widget.CycleButtonWidget; +import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; + +import bartworks.API.modularUI.BWUITextures; +import bartworks.API.recipe.BartWorksRecipeMaps; +import bartworks.system.material.CircuitGeneration.BWMetaItems; +import bartworks.system.material.CircuitGeneration.CircuitImprintLoader; +import bartworks.util.BWTooltipReference; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.SoundResource; +import gregtech.api.enums.Textures; +import gregtech.api.gui.modularui.GTUITextures; +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.MTEEnhancedMultiBlockBase; +import gregtech.api.metatileentity.implementations.MTEHatch; +import gregtech.api.metatileentity.implementations.MTEHatchInput; +import gregtech.api.metatileentity.implementations.MTEHatchInputBus; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.recipe.RecipeMaps; +import gregtech.api.recipe.check.CheckRecipeResult; +import gregtech.api.recipe.check.CheckRecipeResultRegistry; +import gregtech.api.recipe.check.SimpleCheckRecipeResult; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTLanguageManager; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; +import gregtech.api.util.MultiblockTooltipBuilder; +import mcp.mobius.waila.api.IWailaConfigHandler; +import mcp.mobius.waila.api.IWailaDataAccessor; + +public class MTECircuitAssemblyLine extends MTEEnhancedMultiBlockBase<MTECircuitAssemblyLine> + implements ISurvivalConstructable { + + private static final int CASING_INDEX = 16; + + private static final String STRUCTURE_PIECE_FIRST = "first"; + private static final String STRUCTURE_PIECE_NEXT = "next"; + private static final String STRUCTURE_PIECE_NEXT_HINT = "next_hint"; + private static final String STRUCTURE_PIECE_LAST = "last"; + + private static final int MINIMUM_CIRCUIT_ASSEMBLER_LENGTH = 5; + protected static final String IMPRINT_KEY = "Type"; + protected static final String LENGTH_KEY = "Length"; + protected static final String RUNNING_MODE_KEY = "RunningMode"; + + private int length; + private int mode; + private String imprintedItemName; + private ItemStack imprintedStack; + + private static final IStructureDefinition<MTECircuitAssemblyLine> STRUCTURE_DEFINITION = StructureDefinition + .<MTECircuitAssemblyLine>builder() + .addShape( + STRUCTURE_PIECE_FIRST, + transpose(new String[][] { { "~", "G", "G" }, { "g", "l", "g" }, { "b", "i", "b" }, })) + .addShape( + STRUCTURE_PIECE_NEXT, + transpose(new String[][] { { "G", "G", "G" }, { "g", "l", "g" }, { "b", "I", "b" }, })) + .addShape( + STRUCTURE_PIECE_NEXT_HINT, + transpose(new String[][] { { "G", "G", "G" }, { "g", "l", "g" }, { "b", "i", "b" }, })) + .addShape( + STRUCTURE_PIECE_LAST, + transpose(new String[][] { { "G", "G", "G" }, { "g", "l", "g" }, { "b", "o", "b" }, })) + .addElement( + 'G', + buildHatchAdder(MTECircuitAssemblyLine.class).atLeast(Energy) + .casingIndex(CASING_INDEX) + .dot(1) + .buildAndChain(GregTechAPI.sBlockCasings3, 10)) + .addElement('g', ofGlassTieredMixed((byte) 4, (byte) 127, 5)) + .addElement('l', ofBlock(GregTechAPI.sBlockCasings2, 5)) // assembling line casings + .addElement( + 'b', + buildHatchAdder(MTECircuitAssemblyLine.class).atLeast(InputHatch, Maintenance) + .casingIndex(CASING_INDEX) + .dot(2) + .disallowOnly(ForgeDirection.EAST, ForgeDirection.WEST) + .buildAndChain(GregTechAPI.sBlockCasings2, 0)) + .addElement('i', InputBus.newAny(CASING_INDEX, 3, ForgeDirection.DOWN)) + .addElement( + 'I', + buildHatchAdder(MTECircuitAssemblyLine.class).atLeast(InputHatch, InputBus, OutputBus) + .casingIndex(CASING_INDEX) + .dot(2) + .disallowOnly(ForgeDirection.EAST, ForgeDirection.WEST) + .buildAndChain(GregTechAPI.sBlockCasings2, 0)) + .addElement('o', OutputBus.newAny(CASING_INDEX, 2, ForgeDirection.DOWN)) + .build(); + + @Override + public IStructureDefinition<MTECircuitAssemblyLine> getStructureDefinition() { + return STRUCTURE_DEFINITION; + } + + @Override + protected MultiblockTooltipBuilder createTooltip() { + MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder(); + tt.addMachineType("Circuit Assembler/Circuit Assembly Line") + .addInfo("Controller block for the Circuit Assembly Line") + .addInfo("Change Mode with Screwdriver") + .addInfo("Does not lose efficiency when overclocked") + .addInfo( + "--------- " + EnumChatFormatting.GOLD + + StatCollector.translateToLocal("chat.cal.mode.0") + + EnumChatFormatting.GRAY + + " --------") + .addInfo("Imprint this machine with a Circuit Imprint,") + .addInfo("by putting the imprint in the controller") + .addInfo("Every Circuit Assembly Line can only be imprinted ONCE") + .addInfo( + "--------- " + EnumChatFormatting.GOLD + + StatCollector.translateToLocal("chat.cal.mode.1") + + EnumChatFormatting.GRAY + + " --------") + .addInfo( + "Does Circuit Assembler recipes, Minimum Length: " + EnumChatFormatting.RED + + MINIMUM_CIRCUIT_ASSEMBLER_LENGTH + + EnumChatFormatting.GRAY) + .addInfo("Recipe tier in Circuit Assembler mode is at most Energy Hatch tier - 1.") + .addInfo("This mode supports Crafting Input Buffer/Bus and allows bus separation") + .addInfo("") + .addSeparator() + .addInfo(BWTooltipReference.TT_BLUEPRINT) + .beginVariableStructureBlock(2, 7, 3, 3, 3, 3, false) + .addStructureInfo("From Bottom to Top, Left to Right") + .addStructureInfo( + "Layer 1 - Solid Steel Machine Casing, Input bus (Last Output bus), Solid Steel Machine Casing") + .addStructureInfo( + "Layer 2 - " + getColoredTierNameFromTier((byte) 4) + + "+ Tier Glass, Assembling Line Casing, " + + getColoredTierNameFromTier((byte) 4) + + "+ Tier Glass") + .addStructureInfo("Layer 3 - Grate Machine Casing") + .addStructureInfo("Up to 7 repeating slices, last is Output Bus") + .addController("Layer 3 first slice front") + .addOtherStructurePart( + "1x " + StatCollector.translateToLocal("GT5U.MBTT.EnergyHatch"), + "Any layer 3 casing", + 1) + .addInputHatch("Any layer 1 casing", 2) + .addInputBus("As specified on layer 1", 3, 4) + .addOutputBus("As specified in final slice on layer 1", 4) + .addOtherStructurePart(getColoredTierNameFromTier((byte) 4) + "+ Tier Glass", "As specified on layer 2", 5) + .addMaintenanceHatch("Any layer 1 casing", 2) + .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS); + return tt; + } + + public String getTypeForDisplay() { + + if (!isImprinted()) return ""; + return GTLanguageManager.getTranslation( + GTLanguageManager.getTranslateableItemStackName(CircuitImprintLoader.getStackFromTag(this.type))); + } + + private NBTTagCompound type = new NBTTagCompound(); + + public MTECircuitAssemblyLine(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + private MTECircuitAssemblyLine(String aName) { + super(aName); + } + + public boolean isImprinted() { + return !this.type.hasNoTags(); + } + + private boolean imprintMachine(ItemStack itemStack) { + if (isImprinted()) return true; + if (!GTUtility.isStackValid(itemStack)) return false; + if (itemStack.getItem() instanceof BWMetaItems.BW_GT_MetaGenCircuits && itemStack.getItemDamage() == 0 + && itemStack.getTagCompound() != null) { + this.type = itemStack.getTagCompound(); + itemStack.stackSize -= 1; + if (itemStack == getControllerSlot() && itemStack.stackSize <= 0) { + mInventory[getControllerSlotIndex()] = null; + } + this.getBaseMetaTileEntity() + .issueBlockUpdate(); + return true; + } + return false; + } + + @Override + public boolean isCorrectMachinePart(ItemStack itemStack) { + return true; + } + + @Override + public void startSoundLoop(byte aIndex, double aX, double aY, double aZ) { + super.startSoundLoop(aIndex, aX, aY, aZ); + if (aIndex == 20) { + GTUtility.doSoundAtClient(IC2_MACHINES_MAGNETIZER_LOOP, 10, 1.0F, aX, aY, aZ); + } + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + this.type = aNBT.getCompoundTag(IMPRINT_KEY); + this.imprintedItemName = this.type == null ? "" + : GTLanguageManager.getTranslateableItemStackName(ItemStack.loadItemStackFromNBT(this.type)); + mode = aNBT.getInteger(RUNNING_MODE_KEY); + if (aNBT.hasKey(LENGTH_KEY)) { + length = aNBT.getInteger(LENGTH_KEY); + } + super.loadNBTData(aNBT); + } + + @Override + public void setItemNBT(NBTTagCompound aNBT) { + if (isImprinted()) aNBT.setTag(IMPRINT_KEY, this.type); + aNBT.setInteger(RUNNING_MODE_KEY, mode); + super.saveNBTData(aNBT); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + if (isImprinted()) aNBT.setTag(IMPRINT_KEY, this.type); + aNBT.setInteger(RUNNING_MODE_KEY, mode); + aNBT.setInteger(LENGTH_KEY, length); + super.saveNBTData(aNBT); + } + + @Override + public void onLeftclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { + if (mode == 0 && !isImprinted() && getBaseMetaTileEntity().isServerSide()) { + ItemStack heldItem = aPlayer.getHeldItem(); + if (imprintMachine(heldItem)) { + if (heldItem.stackSize <= 0) { + aPlayer.inventory.setInventorySlotContents(aPlayer.inventory.currentItem, null); + } + return; + } + } + super.onLeftclick(aBaseMetaTileEntity, aPlayer); + } + + @Override + public final void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) { + if (getBaseMetaTileEntity().isServerSide()) { + this.mode = (this.mode + 1) % 2; + GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("chat.cal.mode." + this.mode)); + } + super.onScrewdriverRightClick(side, aPlayer, aX, aY, aZ); + } + + @Override + public RecipeMap<?> getRecipeMap() { + if (this.mode == 0) return BartWorksRecipeMaps.circuitAssemblyLineRecipes; + return RecipeMaps.circuitAssemblerRecipes; + } + + @Nonnull + @Override + public Collection<RecipeMap<?>> getAvailableRecipeMaps() { + return Arrays.asList(BartWorksRecipeMaps.circuitAssemblyLineRecipes, RecipeMaps.circuitAssemblerRecipes); + } + + @Override + protected ProcessingLogic createProcessingLogic() { + return new ProcessingLogic() { + + @Override + @Nonnull + protected CheckRecipeResult validateRecipe(@Nonnull GTRecipe recipe) { + // limit CA mode recipes to hatch tier - 1 + if (MTECircuitAssemblyLine.this.mode == 1 + && recipe.mEUt > MTECircuitAssemblyLine.this.getMaxInputVoltage() / 4) { + return CheckRecipeResultRegistry.NO_RECIPE; + } + return CheckRecipeResultRegistry.SUCCESSFUL; + } + }.enablePerfectOverclock(); + } + + @NotNull + @Override + public CheckRecipeResult checkProcessing() { + if (mode == 0) { + if (!isImprinted() && !this.imprintMachine(this.getControllerSlot())) + return SimpleCheckRecipeResult.ofFailure("no_imprint"); + if (this.imprintedItemName == null || this.imprintedStack == null) { + this.imprintedStack = new ItemStack(BWMetaItems.getCircuitParts(), 1, 0); + this.imprintedStack.setTagCompound(this.type); + this.imprintedItemName = GTLanguageManager.getTranslateableItemStackName(this.imprintedStack); + } + } else if (length < MINIMUM_CIRCUIT_ASSEMBLER_LENGTH) { + return SimpleCheckRecipeResult.ofFailure("not_enough_length"); + } + + return super.checkProcessing(); + } + + @Override + protected void setupProcessingLogic(ProcessingLogic logic) { + super.setupProcessingLogic(logic); + logic.setSpecialSlotItem(this.imprintedStack); + } + + @Override + protected SoundResource getProcessStartSound() { + return SoundResource.IC2_MACHINES_MAGNETIZER_LOOP; + } + + @Override + public ArrayList<ItemStack> getStoredInputs() { + if (mode == 0) { + ArrayList<ItemStack> rList = new ArrayList<>(); + for (MTEHatchInputBus tHatch : filterValidMTEs(mInputBusses)) { + tHatch.mRecipeMap = this.getRecipeMap(); + for (int i = 0; i < tHatch.getBaseMetaTileEntity() + .getSizeInventory(); i++) { + if (tHatch.getBaseMetaTileEntity() + .getStackInSlot(i) != null) { + rList.add( + tHatch.getBaseMetaTileEntity() + .getStackInSlot(i)); + break; + } + } + } + return rList; + } + + return super.getStoredInputs(); + } + + @Override + public boolean addInputToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + if (aTileEntity == null) { + return false; + } + IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); + if (aMetaTileEntity instanceof MTEHatchInput) { + ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex); + ((MTEHatchInput) aMetaTileEntity).mRecipeMap = this.getRecipeMap(); + return this.mInputHatches.add((MTEHatchInput) aMetaTileEntity); + } else if (aMetaTileEntity instanceof MTEHatchInputBus) { + ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex); + ((MTEHatchInputBus) aMetaTileEntity).mRecipeMap = this.getRecipeMap(); + return this.mInputBusses.add((MTEHatchInputBus) aMetaTileEntity); + } else { + return false; + } + } + + @Override + public boolean addInputHatchToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + if (aTileEntity == null) { + return false; + } + IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null || !(aMetaTileEntity instanceof MTEHatchInput)) { + return false; + } else { + ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex); + ((MTEHatchInput) aMetaTileEntity).mRecipeMap = this.getRecipeMap(); + return this.mInputHatches.add((MTEHatchInput) aMetaTileEntity); + } + } + + @Override + public int getMaxEfficiency(ItemStack itemStack) { + return 10000; + } + + @Override + public int getPollutionPerTick(ItemStack itemStack) { + return 0; + } + + @Override + public int getDamageToComponent(ItemStack itemStack) { + return 0; + } + + @Override + public boolean explodesOnComponentBreak(ItemStack itemStack) { + return false; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MTECircuitAssemblyLine(this.mName); + } + + private String[] infoDataBuffer; + + @Override + public String[] getInfoData() { + if (this.infoDataBuffer != null) return this.infoDataBuffer; + + String[] oldInfo = super.getInfoData(); + this.infoDataBuffer = new String[oldInfo.length + 1]; + System.arraycopy(oldInfo, 0, this.infoDataBuffer, 0, oldInfo.length); + this.infoDataBuffer[oldInfo.length] = StatCollector.translateToLocal("tooltip.cal.imprintedWith") + " " + + EnumChatFormatting.YELLOW + + this.getTypeForDisplay(); + return this.infoDataBuffer; + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing, + int aColorIndex, boolean aActive, boolean aRedstone) { + if (side == facing) { + if (aActive) return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_ASSEMBLY_LINE_ACTIVE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_ASSEMBLY_LINE_ACTIVE_GLOW) + .extFacing() + .glow() + .build() }; + return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX), TextureFactory.builder() + .addIcon(OVERLAY_FRONT_ASSEMBLY_LINE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_ASSEMBLY_LINE_GLOW) + .extFacing() + .glow() + .build() }; + } + return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX) }; + } + + @Override + public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) { + if (!this.checkPiece(STRUCTURE_PIECE_FIRST, 0, 0, 0)) { + return false; + } + return this.checkMachine(true) || this.checkMachine(false); + } + + private boolean checkMachine(boolean leftToRight) { + + for (int i = 1; i < 7; ++i) { + if (!this.checkPiece(STRUCTURE_PIECE_NEXT, leftToRight ? -i : i, 0, 0)) { + return false; + } + length = i + 1; + + if (!this.mOutputBusses.isEmpty()) { + return this.mEnergyHatches.size() == 1 && this.mMaintenanceHatches.size() == 1; + } + } + + return false; + } + + public void construct(ItemStack stackSize, boolean hintsOnly) { + this.buildPiece(STRUCTURE_PIECE_FIRST, stackSize, hintsOnly, 0, 0, 0); + int tLength = Math.min(stackSize.stackSize + 1, 7); + + for (int i = 1; i < tLength; ++i) { + this.buildPiece(STRUCTURE_PIECE_NEXT, stackSize, hintsOnly, -i, 0, 0); + } + } + + @Override + public int survivalConstruct(ItemStack stackSize, int elementBudget, ISurvivalBuildEnvironment env) { + if (this.mMachine) return -1; + int built; + built = survivialBuildPiece(STRUCTURE_PIECE_FIRST, stackSize, 0, 0, 0, elementBudget, env, false, true); + if (built >= 0) return built; + int tLength = Math.min(stackSize.stackSize + 1, 7); + + for (int i = 1; i < tLength - 1; ++i) { + built = survivialBuildPiece( + STRUCTURE_PIECE_NEXT_HINT, + stackSize, + -i, + 0, + 0, + elementBudget, + env, + false, + true); + if (built >= 0) return built; + } + return survivialBuildPiece( + STRUCTURE_PIECE_LAST, + stackSize, + -(tLength - 1), + 0, + 0, + elementBudget, + env, + false, + true); + } + + @Override + public void addAdditionalTooltipInformation(ItemStack stack, List<String> tooltip) { + if (stack.hasTagCompound() && stack.stackTagCompound.hasKey(IMPRINT_KEY)) { + tooltip.add( + StatCollector.translateToLocal("tooltip.cal.imprintedWith") + " " + + EnumChatFormatting.YELLOW + + StatCollector.translateToLocal( + GTLanguageManager.getTranslateableItemStackName( + ItemStack.loadItemStackFromNBT(stack.stackTagCompound.getCompoundTag("Type"))))); + } + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + super.addUIWidgets(builder, buildContext); + builder + .widget(new FakeSyncWidget.StringSyncer(() -> this.imprintedItemName, val -> this.imprintedItemName = val)); + builder.widget( + new CycleButtonWidget().setToggle(() -> mode == 1, val -> mode = val ? 1 : 0) + .setTextureGetter( + state -> state == 1 ? BWUITextures.OVERLAY_BUTTON_ASSEMBLER_MODE + : BWUITextures.OVERLAY_BUTTON_LINE_MODE) + .setBackground(GTUITextures.BUTTON_STANDARD) + .setPos(80, 91) + .setSize(16, 16) + .dynamicTooltip( + () -> Collections.singletonList(StatCollector.translateToLocal("chat.cal.mode." + mode))) + .setUpdateTooltipEveryTick(true) + .setTooltipShowUpDelay(TOOLTIP_DELAY)); + } + + @Override + public boolean supportsVoidProtection() { + return true; + } + + @Override + public boolean supportsBatchMode() { + return true; + } + + @Override + protected boolean supportsSlotAutomation(int aSlot) { + return aSlot == getControllerSlotIndex(); + } + + @Override + public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer, + float aX, float aY, float aZ) { + if (!aPlayer.isSneaking()) { + if (mode == 0) return false; + inputSeparation = !inputSeparation; + GTUtility.sendChatToPlayer( + aPlayer, + StatCollector.translateToLocal("GT5U.machines.separatebus") + " " + inputSeparation); + return true; + } else { + batchMode = !batchMode; + if (batchMode) { + GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOn")); + } else { + GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOff")); + } + return true; + } + } + + @Override + public boolean supportsInputSeparation() { + return mode != 0; + } + + @Override + public boolean supportsSingleRecipeLocking() { + return true; + } + + @Override + public boolean isInputSeparationEnabled() { + return mode == 1 && super.isInputSeparationEnabled(); + } + + @Override + public void getWailaBody(ItemStack itemStack, List<String> currenttip, IWailaDataAccessor accessor, + IWailaConfigHandler config) { + super.getWailaBody(itemStack, currenttip, accessor, config); + NBTTagCompound tag = accessor.getNBTData(); + currenttip.add( + StatCollector.translateToLocal("GT5U.machines.oreprocessor1") + " " + + EnumChatFormatting.WHITE + + StatCollector.translateToLocal("chat.cal.mode." + tag.getInteger(RUNNING_MODE_KEY))); + if (tag.hasKey("ImprintedWith") && tag.getInteger(RUNNING_MODE_KEY) == 0) currenttip.add( + StatCollector.translateToLocal("tooltip.cal.imprintedWith") + " " + + EnumChatFormatting.YELLOW + + tag.getString("ImprintedWith")); + } + + @Override + public void getWailaNBTData(EntityPlayerMP player, TileEntity tile, NBTTagCompound tag, World world, int x, int y, + int z) { + super.getWailaNBTData(player, tile, tag, world, x, y, z); + String imprintedWith = this.getTypeForDisplay(); + if (!imprintedWith.isEmpty()) tag.setString("ImprintedWith", imprintedWith); + tag.setInteger(RUNNING_MODE_KEY, mode); + } + + @Override + protected boolean supportsCraftingMEBuffer() { + return mode != 0; + } + +} diff --git a/src/main/java/bartworks/common/tileentities/multis/MTEDeepEarthHeatingPump.java b/src/main/java/bartworks/common/tileentities/multis/MTEDeepEarthHeatingPump.java new file mode 100644 index 0000000000..fca10c20fd --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/multis/MTEDeepEarthHeatingPump.java @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.multis; + +import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS; +import static gregtech.api.enums.GTValues.VN; + +import java.lang.reflect.Field; +import java.util.Arrays; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; + +import bartworks.common.configs.ConfigHandler; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.ItemList; +import gregtech.api.enums.Materials; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.implementations.MTEHatchInput; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTUtility; +import gregtech.api.util.MultiblockTooltipBuilder; +import gregtech.common.tileentities.machines.multi.MTEDrillerBase; +import ic2.core.block.reactor.tileentity.TileEntityNuclearReactorElectric; + +public class MTEDeepEarthHeatingPump extends MTEDrillerBase { + + private static float nulearHeatMod = 2f; + private byte mMode; + private byte mTier; + + public MTEDeepEarthHeatingPump(int aID, int tier, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + this.mTier = (byte) tier; + } + + public MTEDeepEarthHeatingPump(String aName, byte mTier) { + super(aName); + this.mTier = mTier; + } + + @Override + @SuppressWarnings("rawtypes") + public void onConfigLoad() { + try { + Class c = TileEntityNuclearReactorElectric.class; + Field f = c.getDeclaredField("huOutputModifier"); + f.setAccessible(true); + MTEDeepEarthHeatingPump.nulearHeatMod = f.getFloat(f); + } catch (SecurityException | IllegalArgumentException | ExceptionInInitializerError | NullPointerException + | IllegalAccessException | NoSuchFieldException e) { + e.printStackTrace(); + } + super.onConfigLoad(); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + aNBT.setByte("mTier", this.mTier); + aNBT.setByte("mMode", this.mMode); + super.saveNBTData(aNBT); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + this.mTier = aNBT.getByte("mTier"); + this.mMode = aNBT.getByte("mMode"); + super.loadNBTData(aNBT); + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MTEDeepEarthHeatingPump(this.mName, this.mTier); + } + + @Override + protected MultiblockTooltipBuilder createTooltip() { + MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder(); + String casings = this.getCasingBlockItem() + .get(0) + .getDisplayName(); + tt.addMachineType("Geothermal Heat Pump") + .addInfo("Consumes " + GTValues.V[this.mTier + 2] + "EU/t") + .addInfo("Has 4 Modes, use the Screwdriver to change them:"); + if (ConfigHandler.DEHPDirectSteam) { + tt.addInfo("0 Idle, 1 Steam, 2 Superheated Steam (requires Distilled Water), 3 Retract") + .addInfo("Explodes when it runs out of Water/Distilled Water") + .addInfo( + "Converts " + (long) (this.mTier * 1200 * 20) + + "L/s Water(minus 10% per Maintenance Problem) to Steam") + .addInfo( + "Converts " + (long) (this.mTier * 600 * 20) + + "L/s Distilled Water(minus 10% per Maintenance Problem) to SuperheatedSteam"); + + } else { + tt.addInfo("0 Idle, 1 & 2 Coolant Heating Mode (no Difference between them), 3 Retract") + .addInfo("Explodes when it runs out of Coolant") + .addInfo( + "Heats up " + (long) (this.mTier * 24 * (double) MTEDeepEarthHeatingPump.nulearHeatMod) * 20 + + "L/s Coolant(minus 10% per Maintenance Problem)"); + } + tt.addSeparator() + .beginStructureBlock(3, 7, 3, false) + .addController("Front bottom") + .addOtherStructurePart(casings, "form the 3x1x3 Base") + .addOtherStructurePart(casings, "1x3x1 pillar above the center of the base (2 minimum total)") + .addOtherStructurePart( + this.getFrameMaterial().mName + " Frame Boxes", + "Each pillar's side and 1x3x1 on top") + .addEnergyHatch(VN[this.getMinTier()] + "+, Any base casing") + .addMaintenanceHatch("Any base casing") + .addInputBus("Mining Pipes, optional, any base casing") + .addInputHatch("Any base casing") + .addOutputHatch("Any base casing") + .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS); + return tt; + } + + @Override + protected ItemList getCasingBlockItem() { + return ItemList.Casing_HeatProof; + } + + @Override + protected Materials getFrameMaterial() { + return Materials.Tungsten; + } + + @Override + protected int getCasingTextureIndex() { + return 11; + } + + @Override + protected int getMinTier() { + return 2 + this.mTier; + } + + @Override + protected boolean checkHatches() { + return !this.mMaintenanceHatches.isEmpty() && !this.mOutputHatches.isEmpty() && !this.mInputHatches.isEmpty(); + } + + private long getFluidFromHatches(Fluid f) { + long ret = 0; + for (MTEHatchInput ih : this.mInputHatches) { + if (ih.getFluid() + .getFluid() + .equals(f)) ret += ih.getFluidAmount(); + } + return ret; + } + + private long getWaterFromHatches(boolean onlyDistilled) { + Fluid toConsume1 = FluidRegistry.WATER; + Fluid toConsume2 = GTModHandler.getDistilledWater(1L) + .getFluid(); + if (onlyDistilled) toConsume1 = toConsume2; + long ret = 0; + for (MTEHatchInput ih : this.mInputHatches) { + if (ih.getFluid() + .getFluid() + .equals(toConsume1) + || ih.getFluid() + .getFluid() + .equals(toConsume2)) + ret += ih.getFluidAmount(); + } + return ret; + } + + @Override + protected boolean workingUpward(ItemStack aStack, int xDrill, int yDrill, int zDrill, int xPipe, int zPipe, + int yHead, int oldYHead) { + if (this.mMode != 3) { + this.isPickingPipes = false; + try { + Field workState = this.getClass() + .getField("workState"); + workState.setInt(this, 0); + } catch (NoSuchFieldError | NoSuchFieldException | IllegalAccessException ignored) {} + return true; + } + return super.workingUpward(aStack, xDrill, yDrill, zDrill, xPipe, zPipe, yHead, oldYHead); + } + + @Override + public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) { + if (this.getBaseMetaTileEntity() + .getWorld().isRemote) return; + ++this.mMode; + if (this.mMode >= 4) this.mMode = 0; + GTUtility.sendChatToPlayer(aPlayer, "Mode: " + this.mMode); + super.onScrewdriverRightClick(side, aPlayer, aX, aY, aZ); + } + + @Override + protected boolean workingDownward(ItemStack aStack, int xDrill, int yDrill, int zDrill, int xPipe, int zPipe, + int yHead, int oldYHead) { + if (this.mMode == 3) { + this.isPickingPipes = true; + try { + Field workState = this.getClass() + .getSuperclass() + .getDeclaredField("workState"); + workState.setInt(this, 2); + } catch (NoSuchFieldError | NoSuchFieldException | IllegalAccessException ignored) {} + return true; + } + + if (this.tryLowerPipeState(false) == 0) { + return true; + } + if (this.waitForPipes()) { + return false; + } + if (this.mMode == 0) { + this.mMode = 1; + } + if (ConfigHandler.DEHPDirectSteam) { + if (this.mMode == 1) { + long steamProduced = this.mTier * 600 * 2L * this.mEfficiency / 10000L; + long waterConsume = (steamProduced + 160) / 160; + + if (this.getWaterFromHatches(false) - waterConsume > 0) { + this.consumeFluid(FluidRegistry.WATER, waterConsume); + this.addOutput(GTModHandler.getSteam(steamProduced)); + } else { + this.explodeMultiblock(); + return false; + } + } else if (this.mMode == 2) { + long steamProduced = this.mTier * 300 * 2L * this.mEfficiency / 10000L; + long waterConsume = (steamProduced + 160) / 160; + + if (this.getWaterFromHatches(true) - waterConsume > 0) { + this.consumeFluid( + GTModHandler.getDistilledWater(1) + .getFluid(), + waterConsume); + this.addOutput(FluidRegistry.getFluidStack("ic2superheatedsteam", (int) steamProduced)); + } else { + this.explodeMultiblock(); + return false; + } + } + } else if (this.mMode == 1 || this.mMode == 2) { + long coolantConverted = (long) (this.mTier * 24 + * (double) MTEDeepEarthHeatingPump.nulearHeatMod + * this.mEfficiency + / 10000L); + if (this.getFluidFromHatches(FluidRegistry.getFluid("ic2coolant")) - coolantConverted > 0) { + this.consumeFluid(FluidRegistry.getFluid("ic2coolant"), coolantConverted); + this.addOutput(FluidRegistry.getFluidStack("ic2hotcoolant", (int) coolantConverted)); + } else { + this.explodeMultiblock(); + return false; + } + } + return true; + } + + private boolean consumeFluid(Fluid fluid, long ammount) { + if (ammount > Integer.MAX_VALUE) { + int[] tmp = new int[(int) (ammount / Integer.MAX_VALUE)]; + Arrays.fill(tmp, (int) (ammount / Integer.MAX_VALUE)); + for (int i = 0; i < tmp.length; i++) { + for (MTEHatchInput ih : this.mInputHatches) { + if (fluid.equals(FluidRegistry.WATER) ? ih.getFluid() + .getFluid() + .equals(fluid) + || ih.getFluid() + .getFluid() + .equals( + GTModHandler.getDistilledWater(1) + .getFluid()) + : ih.getFluid() + .getFluid() + .equals(fluid)) + tmp[i] -= ih.drain((int) ammount, true).amount; + if (tmp[i] <= 0) break; + } + } + + return tmp[tmp.length - 1] <= 0; + } + + long tmp = ammount; + for (MTEHatchInput ih : this.mInputHatches) { + if (fluid.equals(FluidRegistry.WATER) ? ih.getFluid() + .getFluid() + .equals(fluid) + || ih.getFluid() + .getFluid() + .equals( + GTModHandler.getDistilledWater(1) + .getFluid()) + : ih.getFluid() + .getFluid() + .equals(fluid)) + tmp -= ih.drain((int) ammount, true).amount; + if (tmp <= 0) return true; + } + return false; + } + + @Override + protected void setElectricityStats() { + try { + this.mEUt = this.isPickingPipes ? 60 : Math.toIntExact(GTValues.V[this.getMinTier()]); + } catch (ArithmeticException e) { + e.printStackTrace(); + this.mEUt = Integer.MAX_VALUE - 7; + } + this.mProgresstime = 0; + this.mMaxProgresstime = 1; + this.mEfficiency = this.getCurrentEfficiency(null); + this.mEfficiencyIncrease = 10000; + } +} diff --git a/src/main/java/bartworks/common/tileentities/multis/MTEElectricImplosionCompressor.java b/src/main/java/bartworks/common/tileentities/multis/MTEElectricImplosionCompressor.java new file mode 100644 index 0000000000..4b99f97ec5 --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/multis/MTEElectricImplosionCompressor.java @@ -0,0 +1,565 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.multis; + +import static bartworks.common.loaders.ItemRegistry.BW_BLOCKS; +import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTWORKS; +import static bartworks.util.BWTooltipReference.TT; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.isAir; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.onElementPass; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose; +import static gregtech.api.enums.HatchElement.Energy; +import static gregtech.api.enums.HatchElement.ExoticEnergy; +import static gregtech.api.enums.HatchElement.InputBus; +import static gregtech.api.enums.HatchElement.InputHatch; +import static gregtech.api.enums.HatchElement.Maintenance; +import static gregtech.api.enums.HatchElement.OutputBus; +import static gregtech.api.enums.HatchElement.OutputHatch; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_IMPLOSION_COMPRESSOR; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_IMPLOSION_COMPRESSOR_ACTIVE; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_IMPLOSION_COMPRESSOR_ACTIVE_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_IMPLOSION_COMPRESSOR_GLOW; +import static gregtech.api.util.GTStructureUtility.buildHatchAdder; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.Nonnull; + +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; + +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits; +import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable; +import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; +import com.gtnewhorizon.structurelib.structure.AutoPlaceEnvironment; +import com.gtnewhorizon.structurelib.structure.IStructureDefinition; +import com.gtnewhorizon.structurelib.structure.IStructureElement; +import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment; +import com.gtnewhorizon.structurelib.structure.ITierConverter; +import com.gtnewhorizon.structurelib.structure.StructureDefinition; +import com.gtnewhorizon.structurelib.structure.StructureUtility; + +import bartworks.API.recipe.BartWorksRecipeMaps; +import bartworks.MainMod; +import bartworks.client.renderer.EICPistonVisualizer; +import bartworks.common.configs.ConfigHandler; +import bartworks.common.net.EICPacket; +import bartworks.util.Coords; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import fox.spiteful.avaritia.blocks.LudicrousBlocks; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.Mods; +import gregtech.api.enums.SoundResource; +import gregtech.api.enums.Textures; +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.MTEExtendedPowerMultiBlockBase; +import gregtech.api.metatileentity.implementations.MTEHatch; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.recipe.check.CheckRecipeResult; +import gregtech.api.recipe.check.CheckRecipeResultRegistry; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; +import gregtech.api.util.MultiblockTooltipBuilder; +import gregtech.api.util.OverclockCalculator; + +public class MTEElectricImplosionCompressor extends MTEExtendedPowerMultiBlockBase<MTEElectricImplosionCompressor> + implements ISurvivalConstructable { + + private static final boolean pistonEnabled = !ConfigHandler.disablePistonInEIC; + private Boolean piston = true; + private static final SoundResource sound = SoundResource.RANDOM_EXPLODE; + private final ArrayList<ChunkCoordinates> chunkCoordinates = new ArrayList<>(5); + private int mBlockTier = 0; + private int mCasing; + + public MTEElectricImplosionCompressor(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + public MTEElectricImplosionCompressor(String aName) { + super(aName); + } + + private static final int CASING_INDEX = 16; + private static final String STRUCTURE_PIECE_MAIN = "main"; + private static final IStructureDefinition<MTEElectricImplosionCompressor> STRUCTURE_DEFINITION = StructureDefinition + .<MTEElectricImplosionCompressor>builder() + .addShape( + STRUCTURE_PIECE_MAIN, + transpose( + new String[][] { { "ccc", "cec", "ccc" }, { "ttt", "tft", "ttt" }, { "ttt", "tft", "ttt" }, + { "nnn", "nnn", "nnn" }, { "nNn", "NNN", "nNn" }, { "nnn", "nnn", "nnn" }, { "t~t", "tft", "ttt" }, + { "ttt", "tft", "ttt" }, { "CCC", "CeC", "CCC" }, })) + .addElement('c', ofChain(ofBlock(GregTechAPI.sBlockCasings2, 0), ofBlock(GregTechAPI.sBlockCasings3, 4))) + .addElement('t', ofBlock(BW_BLOCKS[2], 1)) + .addElement('f', ofBlock(BW_BLOCKS[2], 0)) + .addElement( + 'n', + StructureUtility.ofBlocksTiered( + tieredBlockConverter(), + getAllBlockTiers(), + 0, + MTEElectricImplosionCompressor::setBlockTier, + MTEElectricImplosionCompressor::getBlockTier)) + .addElement( + 'C', + buildHatchAdder(MTEElectricImplosionCompressor.class) + .atLeast(InputBus, OutputBus, Maintenance, InputHatch, OutputHatch) + .casingIndex(CASING_INDEX) + .dot(1) + .buildAndChain( + onElementPass(x -> ++x.mCasing, ofBlock(GregTechAPI.sBlockCasings2, 0)), + onElementPass(x -> ++x.mCasing, ofBlock(GregTechAPI.sBlockCasings3, 4)))) + .addElement( + 'e', + buildHatchAdder(MTEElectricImplosionCompressor.class).atLeast(Energy.or(ExoticEnergy)) + .casingIndex(CASING_INDEX) + .dot(2) + .buildAndChain( + onElementPass(x -> ++x.mCasing, ofBlock(GregTechAPI.sBlockCasings2, 0)), + onElementPass(x -> ++x.mCasing, ofBlock(GregTechAPI.sBlockCasings3, 4)))) + .addElement('N', new IStructureElement<>() { + + // Much of this based on StructureUtility.ofBlocksTiered + private final List<Pair<Block, Integer>> tiers = getAllBlockTiers(); + + @Override + public boolean check(MTEElectricImplosionCompressor te, World world, int x, int y, int z) { + if (!te.piston && !world.isAirBlock(x, y, z)) return false; + if (te.piston) { + Block candidate = world.getBlock(x, y, z); + int candidateMeta = world.getBlockMetadata(x, y, z); + return getTierOfBlock(candidate, candidateMeta) != -1; + } + return true; + } + + private Pair<Block, Integer> getTier(ItemStack trigger) { + return this.tiers.get(Math.min(Math.max(trigger.stackSize, 1), this.tiers.size()) - 1); + } + + @Override + public boolean spawnHint(MTEElectricImplosionCompressor te, World world, int x, int y, int z, + ItemStack itemStack) { + Pair<Block, Integer> tier = this.getTier(itemStack); + if (te.piston) StructureLibAPI.hintParticle(world, x, y, z, tier.getKey(), tier.getValue()); + return true; + } + + @Override + public boolean placeBlock(MTEElectricImplosionCompressor te, World world, int x, int y, int z, + ItemStack itemStack) { + Pair<Block, Integer> tier = this.getTier(itemStack); + if (te.piston) world.setBlock(x, y, z, tier.getKey(), tier.getValue(), 3); + else world.setBlockToAir(x, y, z); + return true; + } + + @Override + public BlocksToPlace getBlocksToPlace(MTEElectricImplosionCompressor t, World world, int x, int y, int z, + ItemStack trigger, AutoPlaceEnvironment env) { + return BlocksToPlace.createEmpty(); + } + + @Override + public PlaceResult survivalPlaceBlock(MTEElectricImplosionCompressor t, World world, int x, int y, int z, + ItemStack trigger, AutoPlaceEnvironment env) { + return isAir().survivalPlaceBlock(t, world, x, y, z, trigger, env); + } + }) + .build(); + + public static List<Pair<Block, Integer>> getAllBlockTiers() { + return new ArrayList<>() { + + private static final long serialVersionUID = 8171991663102417651L; + + { + this.add(Pair.of(GregTechAPI.sBlockMetal5, 2)); + if (Mods.Avaritia.isModLoaded()) { + this.add(Pair.of(LudicrousBlocks.resource_block, 1)); + } + this.add(Pair.of(GregTechAPI.sBlockMetal9, 4)); + this.add(Pair.of(GregTechAPI.sBlockMetal9, 3)); + this.add(Pair.of(GregTechAPI.sBlockMetal9, 8)); + } + + }; + } + + public static ITierConverter<Integer> tieredBlockConverter() { + return MTEElectricImplosionCompressor::getTierOfBlock; + } + + private static int getTierOfBlock(Block block, int meta) { + if (block == null) { + return -1; + } + if (block == GregTechAPI.sBlockMetal5 && meta == 2) { + return 1; // Neutronium + } + if (block == LudicrousBlocks.resource_block && meta == 1) { + return 2; // Infinity + } + if (block == GregTechAPI.sBlockMetal9) { + return switch (meta) { + case 4 -> 3; // Transcendent Metal + case 3 -> 4; // SpaceTime + case 8 -> 5; // Universium + default -> -1; + }; + } + return -1; + } + + private void setBlockTier(int tier) { + this.mBlockTier = tier; + } + + private int getBlockTier() { + return this.mBlockTier; + } + + @Override + public IStructureDefinition<MTEElectricImplosionCompressor> getStructureDefinition() { + return STRUCTURE_DEFINITION; + } + + @Override + protected IAlignmentLimits getInitialAlignmentLimits() { + return (d, r, f) -> d.offsetY == 0 && r.isNotRotated() && f.isNotFlipped(); + } + + @Override + protected MultiblockTooltipBuilder createTooltip() { + MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder(); + tt.addMachineType("Implosion Compressor") + .addInfo("Explosions are fun") + .addInfo("Controller block for the Electric Implosion Compressor") + .addInfo("Uses electricity instead of Explosives") + .addInfo("Can parallel up to 4^(Tier - 1)") + .addInfo("Tier is determined by containment block") + .addInfo("Valid blocks: Neutronium, Infinity, Transcendent Metal, Spacetime, Universium") + .addInfo("Minimum allowed energy hatch tier is one below recipe tier") + .addInfo("Supports " + TT + " energy hatches") + .addSeparator() + .beginStructureBlock(3, 9, 3, false) + .addController("Front 3rd layer center") + .addCasingInfoMin("Solid Steel Machine Casing", 8, false) + .addStructureInfo("Casings can be replaced with Explosion Warning Signs") + .addOtherStructurePart("Transformer-Winding Blocks", "Outer layer 2,3,7,8") + .addOtherStructurePart("Nickel-Zinc-Ferrite Blocks", "Inner layer 2,3,7,8") + .addOtherStructurePart("Containment Blocks", "Layer 4,5,6") + .addMaintenanceHatch("Any bottom casing", 1) + .addInputBus("Any bottom casing", 1) + .addInputHatch("Any bottom casing", 1) + .addOutputBus("Any bottom casing", 1) + .addEnergyHatch("Bottom middle and/or top middle", 2) + .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTWORKS); + return tt; + } + + @Override + public RecipeMap<?> getRecipeMap() { + return BartWorksRecipeMaps.electricImplosionCompressorRecipes; + } + + @Override + protected ProcessingLogic createProcessingLogic() { + return new ProcessingLogic() { + + @NotNull + @Override + protected CheckRecipeResult validateRecipe(@Nonnull GTRecipe recipe) { + long voltage = MTEElectricImplosionCompressor.this.getAverageInputVoltage(); + // Only allow a minimum of T-1 energy hatch + if (recipe.mEUt > voltage * 4) { + return CheckRecipeResultRegistry.insufficientPower(recipe.mEUt); + } + return CheckRecipeResultRegistry.SUCCESSFUL; + } + + @NotNull + @Override + protected OverclockCalculator createOverclockCalculator(@NotNull GTRecipe recipe) { + // For overclocking we'll allow all power to be used + return super.createOverclockCalculator(recipe) + .setEUt(MTEElectricImplosionCompressor.this.getMaxInputEu()) + .setAmperage(1); + } + }.setMaxParallelSupplier(() -> (int) Math.pow(4, Math.max(this.mBlockTier - 1, 0))); + } + + private void updateChunkCoordinates() { + this.chunkCoordinates.clear(); + + for (int x = -1; x <= 1; x++) for (int z = -1; z <= 1; z++) { + if (Math.abs(x) != 1 || Math.abs(z) != 1) { + int[] abc = { x, -2, z + 1 }; + int[] xyz = { 0, 0, 0 }; + this.getExtendedFacing() + .getWorldOffset(abc, xyz); + xyz[0] += this.getBaseMetaTileEntity() + .getXCoord(); + xyz[1] += this.getBaseMetaTileEntity() + .getYCoord(); + xyz[2] += this.getBaseMetaTileEntity() + .getZCoord(); + this.chunkCoordinates.add(new ChunkCoordinates(xyz[0], xyz[1], xyz[2])); + } + } + } + + @Override + public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) { + super.onFirstTick(aBaseMetaTileEntity); + this.updateChunkCoordinates(); + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onPostTick(aBaseMetaTileEntity, aTick); + + if (pistonEnabled && aBaseMetaTileEntity.isActive() && aTick % 20 == 0) { + if (aBaseMetaTileEntity.isClientSide()) this.animatePiston(aBaseMetaTileEntity); + else if (aBaseMetaTileEntity.hasMufflerUpgrade()) MainMod.BW_Network_instance.sendPacketToAllPlayersInRange( + aBaseMetaTileEntity.getWorld(), + new EICPacket( + new Coords( + aBaseMetaTileEntity.getXCoord(), + aBaseMetaTileEntity.getYCoord(), + aBaseMetaTileEntity.getZCoord()), + true), + aBaseMetaTileEntity.getXCoord(), + aBaseMetaTileEntity.getZCoord()); + } + } + + @Override + public void setExtendedFacing(ExtendedFacing newExtendedFacing) { + super.setExtendedFacing(newExtendedFacing); // Will call stopMachine + + this.updateChunkCoordinates(); + } + + @Override + public boolean isCorrectMachinePart(ItemStack itemStack) { + return true; + } + + @Override + public void stopMachine() { + this.resetPiston(this.mBlockTier); + super.stopMachine(); + } + + private void resetPiston(int tier) { + if (!pistonEnabled) return; + IGregTechTileEntity aBaseMetaTileEntity = this.getBaseMetaTileEntity(); + if (!aBaseMetaTileEntity.isServerSide()) return; + if (!this.piston) { + List<Pair<Block, Integer>> tiers = getAllBlockTiers(); + Pair<Block, Integer> tieredBlock = tiers.get(Math.min(tier, tiers.size()) - 1); + this.chunkCoordinates.forEach(c -> { + // Don't replace real blocks in case user has placed something (e.g. tier upgrade) + if (aBaseMetaTileEntity.getWorld() + .isAirBlock(c.posX, c.posY, c.posZ)) { + aBaseMetaTileEntity.getWorld() + .setBlock(c.posX, c.posY, c.posZ, tieredBlock.getKey(), tieredBlock.getValue(), 3); + } + }); + this.piston = !this.piston; + } + } + + private void activatePiston() { + if (!pistonEnabled) return; + IGregTechTileEntity aBaseMetaTileEntity = this.getBaseMetaTileEntity(); + if (!aBaseMetaTileEntity.isServerSide()) return; + if (this.piston) { + this.chunkCoordinates.forEach( + c -> aBaseMetaTileEntity.getWorld() + .setBlockToAir(c.posX, c.posY, c.posZ)); + this.piston = !this.piston; + } + } + + private void animatePiston(IGregTechTileEntity aBaseMetaTileEntity) { + if (!aBaseMetaTileEntity.getWorld().isRemote) return; + + if (!this.getBaseMetaTileEntity() + .hasMufflerUpgrade()) + GTUtility.doSoundAtClient( + sound, + 10, + 1f, + 1f, + this.chunkCoordinates.get(0).posX, + this.chunkCoordinates.get(0).posY, + this.chunkCoordinates.get(0).posZ); + this.spawnVisualPistonBlocks( + aBaseMetaTileEntity.getWorld(), + this.chunkCoordinates.get(2).posX, + this.chunkCoordinates.get(2).posY, + this.chunkCoordinates.get(2).posZ, + 10); + } + + @SideOnly(Side.CLIENT) + private void spawnVisualPistonBlocks(World world, int x, int y, int z, int age) { + EICPistonVisualizer pistonVisualizer = new EICPistonVisualizer(world, x, y, z, age); + Minecraft.getMinecraft().effectRenderer.addEffect(pistonVisualizer); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + aNBT.setBoolean("piston", this.piston); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + if (aNBT.hasKey("piston")) this.piston = aNBT.getBoolean("piston"); + } + + @Override + public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack itemStack) { + int pistonTier = this.mBlockTier; + this.mCasing = 0; + int mMaxHatchTier = 0; + this.setBlockTier(0); + boolean isOK = this.checkPiece(STRUCTURE_PIECE_MAIN, 1, 6, 0); + + List<MTEHatch> energyHatches = this.getExoticAndNormalEnergyHatchList(); + for (MTEHatch hatch : energyHatches) { + mMaxHatchTier = Math.max(mMaxHatchTier, hatch.mTier); + } + + isOK = isOK && this.mMaintenanceHatches.size() == 1 && energyHatches.size() >= 1; + if (isOK) { + this.activatePiston(); + return true; + } + this.resetPiston(pistonTier); + return false; + } + + @Override + public int getMaxEfficiency(ItemStack itemStack) { + return 10000; + } + + @Override + public int getPollutionPerTick(ItemStack itemStack) { + return 0; + } + + @Override + public int getDamageToComponent(ItemStack itemStack) { + return 0; + } + + @Override + public boolean explodesOnComponentBreak(ItemStack itemStack) { + return false; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MTEElectricImplosionCompressor(this.mName); + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing, + int aColorIndex, boolean aActive, boolean aRedstone) { + if (side == facing) { + if (aActive) return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_IMPLOSION_COMPRESSOR_ACTIVE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_IMPLOSION_COMPRESSOR_ACTIVE_GLOW) + .extFacing() + .glow() + .build() }; + return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX), TextureFactory.builder() + .addIcon(OVERLAY_FRONT_IMPLOSION_COMPRESSOR) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_IMPLOSION_COMPRESSOR_GLOW) + .extFacing() + .glow() + .build() }; + } + return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX) }; + } + + @Override + public void construct(ItemStack itemStack, boolean b) { + this.buildPiece(STRUCTURE_PIECE_MAIN, itemStack, b, 1, 6, 0); + } + + @Override + public int survivalConstruct(ItemStack stackSize, int elementBudget, ISurvivalBuildEnvironment env) { + if (this.mMachine) return -1; + return this.survivialBuildPiece(STRUCTURE_PIECE_MAIN, stackSize, 1, 6, 0, elementBudget, env, false, true); + } + + @Override + public boolean supportsBatchMode() { + return true; + } + + @Override + public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer, + float aX, float aY, float aZ) { + if (aPlayer.isSneaking()) { + batchMode = !batchMode; + if (batchMode) { + GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOn")); + } else { + GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOff")); + } + return true; + } + return false; + } + + @Override + public boolean supportsVoidProtection() { + return true; + } +} diff --git a/src/main/java/bartworks/common/tileentities/multis/MTEHighTempGasCooledReactor.java b/src/main/java/bartworks/common/tileentities/multis/MTEHighTempGasCooledReactor.java new file mode 100644 index 0000000000..73f6593d4f --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/multis/MTEHighTempGasCooledReactor.java @@ -0,0 +1,619 @@ +/* + * Copyright (C) 2022 kuba6000 This program is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. You should have received a copy of the GNU General Public License along with + * this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package bartworks.common.tileentities.multis; + +import static bartworks.API.recipe.BartWorksRecipeMaps.htgrFakeRecipes; +import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_VIA_BARTWORKS; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.onElementPass; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose; +import static gregtech.api.enums.GTValues.AuthorKuba; +import static gregtech.api.util.GTRecipeBuilder.HOURS; +import static gregtech.api.util.GTStructureUtility.ofHatchAdder; +import static gregtech.api.util.GTUtility.filterValidMTEs; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; + +import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits; +import com.gtnewhorizon.structurelib.structure.IStructureDefinition; +import com.gtnewhorizon.structurelib.structure.StructureDefinition; + +import bartworks.common.items.SimpleSubItemClass; +import bartworks.system.material.WerkstoffLoader; +import bartworks.util.MathUtils; +import cpw.mods.fml.common.registry.GameRegistry; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.Materials; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.enums.Textures; +import gregtech.api.enums.TierEU; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.implementations.MTEEnhancedMultiBlockBase; +import gregtech.api.metatileentity.implementations.MTEHatchInput; +import gregtech.api.metatileentity.implementations.MTEHatchOutputBus; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTLanguageManager; +import gregtech.api.util.GTUtility; +import gregtech.api.util.MultiblockTooltipBuilder; + +public class MTEHighTempGasCooledReactor extends MTEEnhancedMultiBlockBase<MTEHighTempGasCooledReactor> { + + private static final int BASECASINGINDEX = 181; + + private static final String STRUCTURE_PIECE_MAIN = "main"; + private static final IStructureDefinition<MTEHighTempGasCooledReactor> STRUCTURE_DEFINITION = StructureDefinition + .<MTEHighTempGasCooledReactor>builder() + .addShape( + STRUCTURE_PIECE_MAIN, + transpose( + new String[][] { + { " BBBBBBB ", " BBBBBBBBB ", "BBBBBBBBBBB", "BBBBBBBBBBB", "BBBBBBBBBBB", "BBBBBBBBBBB", + "BBBBBBBBBBB", "BBBBBBBBBBB", "BBBBBBBBBBB", " BBBBBBBBB ", " BBBBBBB " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " bbb~bbb ", " bbbbbbbbb ", "bbbbbbbbbbb", "bbbbbbbbbbb", "bbbbbbbbbbb", "bbbbbbbbbbb", + "bbbbbbbbbbb", "bbbbbbbbbbb", "bbbbbbbbbbb", " bbbbbbbbb ", " bbbbbbb " }, })) + .addElement('c', onElementPass(x -> x.mCasing++, ofBlock(GregTechAPI.sBlockCasings8, 5))) + .addElement( + 'b', + ofChain( + ofHatchAdder(MTEHighTempGasCooledReactor::addOutputToMachineList, BASECASINGINDEX, 1), + ofHatchAdder(MTEHighTempGasCooledReactor::addMaintenanceToMachineList, BASECASINGINDEX, 1), + ofHatchAdder(MTEHighTempGasCooledReactor::addEnergyInputToMachineList, BASECASINGINDEX, 1), + onElementPass(x -> x.mCasing++, ofBlock(GregTechAPI.sBlockCasings8, 5)))) + .addElement( + 'B', + ofChain( + ofHatchAdder(MTEHighTempGasCooledReactor::addInputToMachineList, BASECASINGINDEX, 2), + onElementPass(x -> x.mCasing++, ofBlock(GregTechAPI.sBlockCasings8, 5)))) + // ofHatchAdderOptional(GT_TileEntity_HTGR::addInputToMachineList, BASECASINGINDEX, 2, + // GregTechAPI.sBlockCasings8, 5)) + .build(); + + private static final int HELIUM_NEEDED = 730000; + public static final int powerUsage = (int) TierEU.RECIPE_LuV; + private static final int maxcapacity = 720000; + private static final int mincapacity = maxcapacity / 10; + private int HeliumSupply; + private int fueltype = -1, fuelsupply = 0; + private boolean empty; + private int emptyticksnodiff = 0; + private int coolanttaking = 0; + private int mCasing = 0; + + public MTEHighTempGasCooledReactor(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + private MTEHighTempGasCooledReactor(String aName) { + super(aName); + } + + @Override + public boolean isCorrectMachinePart(ItemStack itemStack) { + return true; + } + + @Override + public IStructureDefinition<MTEHighTempGasCooledReactor> getStructureDefinition() { + return STRUCTURE_DEFINITION; + } + + @Override + protected MultiblockTooltipBuilder createTooltip() { + MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder(); + tt.addMachineType("Breeder Reactor") + .addInfo("Controller block for the High Temperature Gas-cooled Reactor (HTGR)") + .addInfo(AuthorKuba) + .addInfo("You can clear internal buffer by changing the mode with a screwdriver") + .addInfo("Needs a constant supply of coolant while running") + .addInfo("Needs at least 72k Fuel pebbles to start operation (can hold up to 720k pebbles)") + .addInfo("Consumes up to 2.5% of total Fuel Pellets per Operation depending on efficiency") + .addInfo("Efficiency is calculated exponentially depending on the amount of pebbles in the internal buffer") + .addInfo("and affects total recipe time (at 100% eff, -50% total recipe time") + .addInfo( + "Reactor will take 4 000L/s of coolant multiplied by efficiency and by fuel coolant value (check tooltips)") + .addInfo("Uses " + GTUtility.formatNumbers(powerUsage) + " EU/t") + .addInfo("One Operation takes 1 hour") + .addSeparator() + .beginStructureBlock(11, 12, 11, true) + .addController("Front bottom center") + .addCasingInfoMin("Europium Reinforced Radiation Proof Casings", 500, false) + .addStructureInfo("Corners and the 2 touching blocks are air (cylindric)") + .addInputBus("Any top layer casing", 2) + .addInputHatch("Any top layer casing", 2) + .addOutputBus("Any bottom layer casing", 1) + .addOutputHatch("Any bottom layer casing", 1) + .addEnergyHatch("Any bottom layer casing", 1) + .addMaintenanceHatch("Any bottom layer casing", 1) + .toolTipFinisher(MULTIBLOCK_ADDED_VIA_BARTWORKS.apply(EnumChatFormatting.GOLD + "kuba6000")); + return tt; + } + + @Override + protected IAlignmentLimits getInitialAlignmentLimits() { + return (d, r, f) -> d.offsetY == 0 && r.isNotRotated() && f.isNotFlipped(); + } + + @Override + public void construct(ItemStack stackSize, boolean hintsOnly) { + this.buildPiece("main", stackSize, hintsOnly, 5, 11, 0); + } + + @Override + public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack itemStack) { + this.mCasing = 0; + return this.checkPiece("main", 5, 11, 0) && this.mCasing >= 500 + && this.mMaintenanceHatches.size() == 1 + && this.mInputHatches.size() > 0 + && this.mOutputHatches.size() > 0 + && this.mInputBusses.size() > 0 + && this.mOutputBusses.size() > 0 + && this.mEnergyHatches.size() > 0; + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + this.HeliumSupply = aNBT.getInteger("HeliumSupply"); + this.fueltype = aNBT.getInteger("fueltype"); + this.fuelsupply = aNBT.getInteger("fuelsupply"); + this.empty = aNBT.getBoolean("EmptyMode"); + this.coolanttaking = aNBT.getInteger("coolanttaking"); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + aNBT.setInteger("HeliumSupply", this.HeliumSupply); + aNBT.setInteger("fueltype", this.fueltype); + aNBT.setInteger("fuelsupply", this.fuelsupply); + aNBT.setBoolean("EmptyMode", this.empty); + aNBT.setInteger("coolanttaking", this.coolanttaking); + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onPostTick(aBaseMetaTileEntity, aTick); + if (aBaseMetaTileEntity.isServerSide() && !this.empty) { + boolean updateneeded = false; + if (this.HeliumSupply < MTEHighTempGasCooledReactor.HELIUM_NEEDED) { + for (FluidStack fluidStack : this.getStoredFluids()) { + if (fluidStack.isFluidEqual(Materials.Helium.getGas(1))) { + int toget = Math + .min(MTEHighTempGasCooledReactor.HELIUM_NEEDED - this.HeliumSupply, fluidStack.amount); + fluidStack.amount -= toget; + this.HeliumSupply += toget; + updateneeded = true; + } + } + } + if (this.fuelsupply < maxcapacity) { + this.startRecipeProcessing(); + for (ItemStack itemStack : this.getStoredInputs()) { + int type = -1; + if (itemStack == null || itemStack.getItem() != HTGRMaterials.aHTGR_Materials) continue; + int damage = HTGRMaterials.aHTGR_Materials.getDamage(itemStack); + if ((damage + 1) % HTGRMaterials.MATERIALS_PER_FUEL != HTGRMaterials.USABLE_FUEL_INDEX + 1) + continue; // is fuel + type = damage / HTGRMaterials.MATERIALS_PER_FUEL; + if (this.fueltype == -1) this.fueltype = type; + if (this.fueltype != type) continue; + int toget = Math.min(maxcapacity - this.fuelsupply, itemStack.stackSize); + this.fuelsupply += toget; + itemStack.stackSize -= toget; + updateneeded = true; + } + this.endRecipeProcessing(); + } + if (updateneeded) this.updateSlots(); + } + } + + @Override + public RecipeMap<?> getRecipeMap() { + // Only for visual + return htgrFakeRecipes; + } + + @Override + protected boolean filtersFluid() { + return false; + } + + @Override + public boolean checkRecipe(ItemStack controllerStack) { + + if (this.empty) { + if (this.HeliumSupply > 0 || this.fuelsupply > 0) { + this.mEfficiency = 10000; + this.mMaxProgresstime = 100; + return true; + } + return false; + } + if (this.HeliumSupply < MTEHighTempGasCooledReactor.HELIUM_NEEDED || this.fuelsupply < mincapacity) + return false; + + double eff = Math.min(Math.pow((double) this.fuelsupply / (double) mincapacity, 2D), 100D) / 100D + - (this.getIdealStatus() - this.getRepairStatus()) / 10D; + + if (eff <= 0) return false; + + int toReduce = MathUtils.floorInt(this.fuelsupply * 0.025D * eff); + + final int originalToReduce = toReduce; + int burnedballs = toReduce / 64; + if (burnedballs > 0) toReduce -= burnedballs * 64; + + int meta = this.fueltype * HTGRMaterials.MATERIALS_PER_FUEL + HTGRMaterials.BURNED_OUT_FUEL_INDEX; + + ItemStack[] toOutput = { new ItemStack(HTGRMaterials.aHTGR_Materials, burnedballs, meta), + new ItemStack(HTGRMaterials.aHTGR_Materials, toReduce, meta + 1) }; + if (!this.canOutputAll(toOutput)) return false; + + this.fuelsupply -= originalToReduce; + this.mOutputItems = toOutput; + + // this.updateSlots(); // not needed ? + + this.coolanttaking = (int) (4000D * (this.fueltype * 0.5D + 1) * eff); + + this.mEfficiency = (int) (eff * 10000D); + this.mEfficiencyIncrease = 0; + this.mEUt = -powerUsage; + this.mMaxProgresstime = (int) (72000 * (1d - eff / 2d)); + return true; + } + + private int runningtick = 0; + + @Override + public boolean onRunningTick(ItemStack aStack) { + this.runningtick++; + + if (this.empty) { + if (this.emptyticksnodiff > 20 && this.emptyticksnodiff % 20 != 0) { + this.emptyticksnodiff++; + return true; + } + if (this.HeliumSupply > 0) { + this.addOutput(Materials.Helium.getGas(this.HeliumSupply)); + this.HeliumSupply = 0; + } + if (this.fuelsupply > 0) { + ItemStack iStack = new ItemStack( + HTGRMaterials.aHTGR_Materials, + this.fuelsupply, + HTGRMaterials.MATERIALS_PER_FUEL * this.fueltype + HTGRMaterials.USABLE_FUEL_INDEX); + boolean storedAll = false; + for (MTEHatchOutputBus tHatch : filterValidMTEs(mOutputBusses)) { + if (tHatch.storeAll(iStack)) { + storedAll = true; + break; + } + } + if (!storedAll) { + if (this.fuelsupply == iStack.stackSize) this.emptyticksnodiff++; + else { + this.fuelsupply = iStack.stackSize; + this.emptyticksnodiff = 0; + } + } else { + this.fuelsupply = 0; + this.fueltype = -1; + this.coolanttaking = 0; + } + } + return true; + } + // USE DA POWAH + if (!this.drainEnergyInput(-this.mEUt)) { + this.criticalStopMachine(); + return false; + } + + if (this.runningtick % 20 == 0) { + int takecoolant = this.coolanttaking; + int drainedamount = 0; + + for (MTEHatchInput tHatch : filterValidMTEs(mInputHatches)) { + FluidStack tLiquid = tHatch.getFluid(); + if (tLiquid != null && tLiquid.isFluidEqual(FluidRegistry.getFluidStack("ic2coolant", 1))) { + FluidStack drained = tHatch.drain(takecoolant, true); + takecoolant -= drained.amount; + drainedamount += drained.amount; + if (takecoolant <= 0) break; + } + } + + if (drainedamount > 0) this.addOutput(FluidRegistry.getFluidStack("ic2hotcoolant", drainedamount)); + + this.updateSlots(); + + if (takecoolant > 0) this.stopMachine(); + } + + return true; + } + + @Override + public int getMaxEfficiency(ItemStack itemStack) { + return 10000; + } + + @Override + public int getPollutionPerTick(ItemStack itemStack) { + return 0; + } + + @Override + public int getDamageToComponent(ItemStack itemStack) { + return 0; + } + + @Override + public boolean explodesOnComponentBreak(ItemStack itemStack) { + return false; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MTEHighTempGasCooledReactor(this.mName); + } + + @Override + public String[] getInfoData() { + return new String[] { "Mode:", this.empty ? "Emptying" : "Normal", "Progress:", + GTUtility.formatNumbers(this.mProgresstime / 20) + "s / " + + GTUtility.formatNumbers(this.mMaxProgresstime / 20) + + "s", + "Fuel type:", + this.fueltype == -1 ? "NONE" : "TRISO (" + HTGRMaterials.sHTGR_Fuel[this.fueltype].sEnglish + ")", + "Fuel amount:", GTUtility.formatNumbers(this.fuelsupply) + " pcs.", "Helium-Level:", + GTUtility.formatNumbers(this.HeliumSupply) + "L / " + + GTUtility.formatNumbers(MTEHighTempGasCooledReactor.HELIUM_NEEDED) + + "L", + "Coolant:", GTUtility.formatNumbers(this.coolanttaking) + "L/s", "Problems:", + String.valueOf(this.getIdealStatus() - this.getRepairStatus()) }; + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, + ForgeDirection forgeDirection, int aColorIndex, boolean aActive, boolean aRedstone) { + if (side == forgeDirection) { + if (aActive) return new ITexture[] { + Textures.BlockIcons.getCasingTextureForId(MTEHighTempGasCooledReactor.BASECASINGINDEX), + TextureFactory.builder() + .addIcon(Textures.BlockIcons.OVERLAY_FRONT_HEAT_EXCHANGER_ACTIVE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(Textures.BlockIcons.OVERLAY_FRONT_HEAT_EXCHANGER_ACTIVE_GLOW) + .extFacing() + .glow() + .build() }; + return new ITexture[] { + Textures.BlockIcons.getCasingTextureForId(MTEHighTempGasCooledReactor.BASECASINGINDEX), + TextureFactory.builder() + .addIcon(Textures.BlockIcons.OVERLAY_FRONT_HEAT_EXCHANGER) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(Textures.BlockIcons.OVERLAY_FRONT_HEAT_EXCHANGER_GLOW) + .extFacing() + .glow() + .build() }; + } + return new ITexture[] { + Textures.BlockIcons.getCasingTextureForId(MTEHighTempGasCooledReactor.BASECASINGINDEX) }; + } + + @Override + public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) { + if (this.mMaxProgresstime > 0) { + GTUtility.sendChatToPlayer(aPlayer, "HTGR mode cannot be changed while the machine is running."); + return; + } + this.empty = !this.empty; + GTUtility.sendChatToPlayer( + aPlayer, + "HTGR is now running in " + (this.empty ? "emptying mode." : "normal Operation")); + } + + @Override + public boolean supportsVoidProtection() { + return true; + } + + public static class HTGRMaterials { + + private static class CustomHTGRSimpleSubItemClass extends SimpleSubItemClass { + + HashMap<Integer, String> tooltip = null; + + public CustomHTGRSimpleSubItemClass(HashMap<Integer, String> tooltip, String... tex) { + super(tex); + this.tooltip = tooltip; + } + + @Override + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void addInformation(ItemStack p_77624_1_, EntityPlayer p_77624_2_, List aList, boolean p_77624_4_) { + if (this.tooltip.containsKey(this.getDamage(p_77624_1_))) + aList.add(this.tooltip.get(this.getDamage(p_77624_1_))); + aList.add("Material for High Temperature Gas-cooled Reactor"); + super.addInformation(p_77624_1_, p_77624_2_, aList, p_77624_4_); + } + } + + private static class Base_ { + + public String sName; + public String sEnglish; + + public Base_(String a, String b) { + this.sName = a; + this.sEnglish = b; + } + } + + public static class Fuel_ { + + public String sName; + public String sEnglish; + public ItemStack mainItem; + public ItemStack secondaryItem; + public ItemStack[] recycledItems = { GTValues.NI, GTValues.NI, GTValues.NI, GTValues.NI, GTValues.NI, + GTValues.NI }; + public FluidStack recycledFluid; + public int[] recycleChances; + public String tooltip; + + public Fuel_(String sName, String sEnglish, ItemStack mainItem, ItemStack secondaryItem, + FluidStack recycledFluid, ItemStack[] recycledItems, int[] recycleChances, String tooltip) { + this.sName = sName; + this.sEnglish = sEnglish; + this.mainItem = mainItem; + this.secondaryItem = secondaryItem; + this.recycledFluid = recycledFluid; + System.arraycopy(recycledItems, 0, this.recycledItems, 0, recycledItems.length); + this.recycleChances = recycleChances; + this.tooltip = tooltip; + } + } + + private static class LangEntry_ { + + public String sName; + public String sEnglish; + + public LangEntry_(String a, String b) { + this.sName = a; + this.sEnglish = b; + } + } + + public static final Base_[] sHTGR_Bases = { new Base_("HTGRFuelMixture", "HTGR fuel mixture"), + new Base_("BISOPebbleCompound", "BISO pebble compound"), + new Base_("TRISOPebbleCompound", "TRISO pebble compound"), new Base_("TRISOBall", "TRISO ball"), + new Base_("TRISOPebble", "TRISO pebble"), new Base_("BurnedOutTRISOBall", "Burned out TRISO Ball"), + new Base_("BurnedOutTRISOPebble", "Burned out TRISO Pebble"), }; + public static final int MATERIALS_PER_FUEL = sHTGR_Bases.length; + static final int USABLE_FUEL_INDEX = 4; + static final int BURNED_OUT_FUEL_INDEX = 5; + public static final Fuel_[] sHTGR_Fuel = { new Fuel_( + "Thorium", + "Thorium", + WerkstoffLoader.Thorium232.get(OrePrefixes.dust, 64), + Materials.Uranium235.getDust(4), + GTValues.NF, + new ItemStack[] { Materials.Silicon.getDust(1), Materials.Graphite.getDust(1), Materials.Carbon.getDust(1), + Materials.Lutetium.getDust(1), WerkstoffLoader.Thorium232.get(OrePrefixes.dust, 1) }, + new int[] { 9900 / 4, 9900 / 4, 9900 / 4, 9900 / 4, 162 / 4 }, + "Multiplies coolant by 1"), + new Fuel_( + "Uranium", + "Uranium", + Materials.Uranium.getDust(64), + Materials.Uranium235.getDust(8), + FluidRegistry.getFluidStack("krypton", 4), + new ItemStack[] { Materials.Silicon.getDust(1), Materials.Graphite.getDust(1), + Materials.Carbon.getDust(1), Materials.Lead.getDust(1), Materials.Uranium.getDust(1) }, + new int[] { 9900 / 4, 9900 / 4, 9900 / 4, 5000 / 4, 5000 / 4 }, + "Multiplies coolant by 1.5"), + new Fuel_( + "Plutonium", + "Plutonium", + Materials.Plutonium.getDust(64), + Materials.Plutonium241.getDust(4), + FluidRegistry.getFluidStack("xenon", 4), + new ItemStack[] { Materials.Silicon.getDust(1), Materials.Graphite.getDust(1), + Materials.Carbon.getDust(1), Materials.Lead.getDust(1), Materials.Plutonium.getDust(1) }, + new int[] { 9900 / 4, 9900 / 4, 9900 / 4, 5000 / 4, 5000 / 4 }, + "Multiplies coolant by 2"), }; + public static final CustomHTGRSimpleSubItemClass aHTGR_Materials; + static final ArrayList<LangEntry_> aHTGR_Localizations = new ArrayList<>(); + + static { + String[] sHTGR_Materials = new String[sHTGR_Bases.length * sHTGR_Fuel.length]; + HashMap<Integer, String> tooltip = new HashMap<>(); + int i = 0; + for (Fuel_ fuel : sHTGR_Fuel) for (Base_ base : sHTGR_Bases) { + sHTGR_Materials[i] = "HTGR" + base.sName + fuel.sName; + aHTGR_Localizations.add( + new LangEntry_("item." + sHTGR_Materials[i] + ".name", base.sEnglish + " (" + fuel.sEnglish + ")")); + if ((i + 1) % MATERIALS_PER_FUEL == USABLE_FUEL_INDEX + 1 && fuel.tooltip != null + && !fuel.tooltip.isEmpty()) tooltip.put(i, fuel.tooltip); + i++; + } + aHTGR_Materials = new CustomHTGRSimpleSubItemClass(tooltip, sHTGR_Materials); + } + + public static void registeraTHR_Materials() { + for (LangEntry_ iName : aHTGR_Localizations) + GTLanguageManager.addStringLocalization(iName.sName, iName.sEnglish); + GameRegistry.registerItem(MTEHighTempGasCooledReactor.HTGRMaterials.aHTGR_Materials, "bw.HTGRMaterials"); + } + + public static void register_fake_THR_Recipes() { + + int i = 0; + for (@SuppressWarnings("unused") + Fuel_ fuel : sHTGR_Fuel) { + + GTValues.RA.stdBuilder() + .itemInputs(new ItemStack(MTEHighTempGasCooledReactor.HTGRMaterials.aHTGR_Materials, 64, i + 4)) + .itemOutputs(new ItemStack(MTEHighTempGasCooledReactor.HTGRMaterials.aHTGR_Materials, 1, i + 5)) + .duration(1 * HOURS) + .eut(powerUsage) + .ignoreCollision() + .noOptimize() + .fake() + .addTo(htgrFakeRecipes); + + i += MATERIALS_PER_FUEL; + } + } + } +} diff --git a/src/main/java/bartworks/common/tileentities/multis/MTELESU.java b/src/main/java/bartworks/common/tileentities/multis/MTELESU.java new file mode 100644 index 0000000000..a039aa593c --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/multis/MTELESU.java @@ -0,0 +1,590 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.multis; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.Collections; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizons.modularui.api.NumberFormatMUI; +import com.gtnewhorizons.modularui.api.drawable.Text; +import com.gtnewhorizons.modularui.api.forge.ItemStackHandler; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.common.internal.wrapper.BaseSlot; +import com.gtnewhorizons.modularui.common.widget.DrawableWidget; +import com.gtnewhorizons.modularui.common.widget.DynamicPositionedColumn; +import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; +import com.gtnewhorizons.modularui.common.widget.ProgressBar; +import com.gtnewhorizons.modularui.common.widget.SlotWidget; +import com.gtnewhorizons.modularui.common.widget.TextWidget; + +import bartworks.API.modularUI.BWUITextures; +import bartworks.MainMod; +import bartworks.common.configs.ConfigHandler; +import bartworks.common.loaders.ItemRegistry; +import bartworks.util.BWTooltipReference; +import bartworks.util.ConnectedBlocksChecker; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.enums.Dyes; +import gregtech.api.enums.GTValues; +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.IIconContainer; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.implementations.MTEMultiBlockBase; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTUtility; + +public class MTELESU extends MTEMultiBlockBase { + + private static final byte TEXID_SIDE = 0; + private static final byte TEXID_CHARGING = 1; + private static final byte TEXID_IDLE = 2; + private static final byte TEXID_EMPTY = 3; + private static final IIcon[] iIcons = new IIcon[4]; + private static final IIconContainer[] iIconContainers = new IIconContainer[4]; + private static final ITexture[][] iTextures = new ITexture[4][1]; + public ConnectedBlocksChecker connectedcells; + public final ItemStack[] circuits = new ItemStack[5]; + private final ItemStackHandler circuitsInventoryHandler = new ItemStackHandler(this.circuits) { + + @Override + public int getSlotLimit(int slot) { + return 1; + } + }; + private long mStorage; + + protected static final NumberFormatMUI numberFormat = new NumberFormatMUI(); + + public MTELESU(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + this.mStorage = ConfigHandler.energyPerCell; + } + + public MTELESU(String aName) { + super(aName); + } + + @Override + public boolean isEnetOutput() { + return true; + } + + @Override + public boolean isEnetInput() { + return true; + } + + @Override + public long maxEUStore() { + return this.mStorage >= Long.MAX_VALUE - 1 || this.mStorage < 0 ? Long.MAX_VALUE - 1 : this.mStorage; + } + + @Override + public long maxAmperesIn() { + int ret = 0; + for (int i = 0; i < 5; ++i) if (this.circuits[i] != null && this.circuits[i].getItem() + .equals( + GTUtility.getIntegratedCircuit(0) + .getItem())) + ret += this.circuits[i].getItemDamage(); + return ret > 0 ? ret : 1; + } + + @Override + public long maxAmperesOut() { + return this.maxAmperesIn(); + } + + @Override + public long maxEUInput() { + + for (int i = 1; i < GTValues.V.length; i++) { + if (this.maxEUOutput() <= GTValues.V[i] && this.maxEUOutput() > GTValues.V[i - 1]) + return Math.min(GTValues.V[i], 32768L); + } + + return 8; + } + + @Override + public long maxEUOutput() { + return Math.min(Math.max(this.mStorage / ConfigHandler.energyPerCell, 1L), 32768L); + } + + @Override + public int rechargerSlotStartIndex() { + return 0; + } + + @Override + public int rechargerSlotCount() { + return 1; + } + + @Override + public int dechargerSlotStartIndex() { + return 1; + } + + @Override + public int dechargerSlotCount() { + return 1; + } + + @Override + public boolean isTeleporterCompatible() { + return true; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MTELESU(this.mName); + } + + @Override + public String[] getDescription() { + ArrayList<String> e = new ArrayList<>(); + String[] dsc = StatCollector.translateToLocal("tooltip.tile.lesu.0.name") + .split(";"); + Collections.addAll(e, dsc); + e.add( + StatCollector.translateToLocal("tooltip.tile.lesu.1.name") + " " + + GTUtility.formatNumbers(ConfigHandler.energyPerCell) + + "EU"); + dsc = StatCollector.translateToLocal("tooltip.tile.lesu.2.name") + .split(";"); + Collections.addAll(e, dsc); + e.add(EnumChatFormatting.RED + StatCollector.translateToLocal("tooltip.tile.lesu.3.name")); + e.add(BWTooltipReference.ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS.get()); + return e.toArray(new String[0]); + } + + @Override + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister aBlockIconRegister) { + + for (int i = 0; i < MTELESU.iTextures.length; i++) { + MTELESU.iIcons[i] = aBlockIconRegister.registerIcon(MainMod.MOD_ID + ":LESU_CASING_" + i); + int finalI = i; + MTELESU.iIconContainers[i] = new IIconContainer() { + + @Override + public IIcon getIcon() { + return MTELESU.iIcons[finalI]; + } + + @Override + public IIcon getOverlayIcon() { + return MTELESU.iIcons[finalI]; + } + + @Override + public ResourceLocation getTextureFile() { + return new ResourceLocation(MainMod.MOD_ID + ":LESU_CASING_" + finalI); + } + }; + } + } + + public boolean isClientSide() { + if (this.getWorld() != null) return this.getWorld().isRemote ? FMLCommonHandler.instance() + .getSide() == Side.CLIENT + : FMLCommonHandler.instance() + .getEffectiveSide() == Side.CLIENT; + return FMLCommonHandler.instance() + .getEffectiveSide() == Side.CLIENT; + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing, + int aColorIndex, boolean aActive, boolean aRedstone) { + + ITexture[] ret = {}; + + if (this.isClientSide()) { + + for (int i = 0; i < MTELESU.iTextures.length; i++) { + MTELESU.iTextures[i][0] = TextureFactory + .of(MTELESU.iIconContainers[i], Dyes.getModulation(0, Dyes.MACHINE_METAL.mRGBa)); + } + + if (side == facing && this.getBaseMetaTileEntity() + .getUniversalEnergyStored() <= 0) ret = MTELESU.iTextures[MTELESU.TEXID_EMPTY]; + else if (side == facing && !aActive) ret = MTELESU.iTextures[MTELESU.TEXID_IDLE]; + else if (side == facing && aActive) ret = MTELESU.iTextures[MTELESU.TEXID_CHARGING]; + else ret = MTELESU.iTextures[MTELESU.TEXID_SIDE]; + } + + return ret; + } + + @Override + public boolean canInsertItem(int p_102007_1_, ItemStack p_102007_2_, int p_102007_3_) { + return true; + } + + @Override + public boolean canExtractItem(int p_102008_1_, ItemStack p_102008_2_, int p_102008_3_) { + return true; + } + + @Override + public int getSizeInventory() { + return 6; + } + + @Override + public ItemStack getStackInSlot(int slotIn) { + if (slotIn > 1) return this.circuits[slotIn - 2]; + return this.mInventory[slotIn]; + } + + @Override + public void setInventorySlotContents(int index, ItemStack stack) { + if (index < 2) this.mInventory[index] = stack; + else this.circuits[index - 2] = stack; + } + + @Override + public String getInventoryName() { + return "L.E.S.U."; + } + + @Override + public boolean hasCustomInventoryName() { + return true; + } + + @Override + public int getInventoryStackLimit() { + return 1; + } + + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return true; + } + + @Override + public boolean isItemValidForSlot(int index, ItemStack stack) { + + return switch (index) { + case 0, 1 -> true; + default -> stack != null && stack.getItem() + .equals( + GTUtility.getIntegratedCircuit(0) + .getItem()); + }; + } + + @Override + public boolean isCorrectMachinePart(ItemStack itemStack) { + return true; + } + + @Override + public boolean checkRecipe(ItemStack itemStack) { + return true; + } + + @Override + public boolean isInputFacing(ForgeDirection side) { + return side != this.getBaseMetaTileEntity() + .getFrontFacing(); + } + + @Override + public boolean isOutputFacing(ForgeDirection side) { + return side == this.getBaseMetaTileEntity() + .getFrontFacing(); + } + + @Override + public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) { + this.checkMachine(aBaseMetaTileEntity, null); + super.onFirstTick(aBaseMetaTileEntity); + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (aBaseMetaTileEntity.isServerSide()) { + this.mMaxProgresstime = 1; + if (aTick % 20 == 0) this.checkMachine(aBaseMetaTileEntity, null); + } + } + + @Override + public long getMinimumStoredEU() { + return 0; + } + + @Override + public boolean onRunningTick(ItemStack aStack) { + this.mMaxProgresstime = 1; + return true; + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + aNBT.setIntArray("customCircuitInv", GTUtility.stacksToIntArray(this.circuits)); + super.saveNBTData(aNBT); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + int[] stacks = aNBT.getIntArray("customCircuitInv"); + for (int i = 0; i < stacks.length; i++) { + this.circuits[i] = GTUtility.intToStack(stacks[i]); + } + super.loadNBTData(aNBT); + } + + @Override + public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack itemStack) { + long startingTime = System.nanoTime(); + this.connectedcells = new ConnectedBlocksChecker(); + this.connectedcells.get_connected( + aBaseMetaTileEntity.getWorld(), + aBaseMetaTileEntity.getXCoord(), + aBaseMetaTileEntity.getYCoord(), + aBaseMetaTileEntity.getZCoord(), + ItemRegistry.BW_BLOCKS[1]); + + if (this.connectedcells.get_meta_of_sideblocks( + aBaseMetaTileEntity.getWorld(), + this.getBaseMetaTileEntity() + .getMetaTileID(), + new int[] { aBaseMetaTileEntity.getXCoord(), aBaseMetaTileEntity.getYCoord(), + aBaseMetaTileEntity.getZCoord() }, + true)) { + this.getBaseMetaTileEntity() + .disableWorking(); + this.getBaseMetaTileEntity() + .setActive(false); + this.mStorage = 0; + this.mMaxProgresstime = 0; + this.mProgresstime = 0; + return false; + } + + this.mEfficiency = this.getMaxEfficiency(null); + this.mStorage = ConfigHandler.energyPerCell * this.connectedcells.hashset.size() >= Long.MAX_VALUE - 1 + || ConfigHandler.energyPerCell * this.connectedcells.hashset.size() < 0 ? Long.MAX_VALUE - 1 + : ConfigHandler.energyPerCell * this.connectedcells.hashset.size(); + this.mMaxProgresstime = 1; + this.mProgresstime = 0; + + this.getBaseMetaTileEntity() + .enableWorking(); + this.getBaseMetaTileEntity() + .setActive(true); + + long finishedTime = System.nanoTime(); + // System.out.println("LESU LookUp: "+((finishedTime - startingTime) / 1000000)+"ms"); + if (finishedTime - startingTime > 5000000) MainMod.LOGGER.warn( + "LESU LookUp took longer than 5ms!(" + (finishedTime - startingTime) + + "ns / " + + (finishedTime - startingTime) / 1000000 + + "ms) Owner:" + + this.getBaseMetaTileEntity() + .getOwnerName() + + " Check at x:" + + this.getBaseMetaTileEntity() + .getXCoord() + + " y:" + + this.getBaseMetaTileEntity() + .getYCoord() + + " z:" + + this.getBaseMetaTileEntity() + .getZCoord() + + " DIM-ID: " + + this.getBaseMetaTileEntity() + .getWorld().provider.dimensionId); + return true; + } + + @Override + public int getMaxEfficiency(ItemStack itemStack) { + return 10000; + } + + @Override + public int getPollutionPerTick(ItemStack itemStack) { + return 0; + } + + @Override + public int getDamageToComponent(ItemStack itemStack) { + return 0; + } + + @Override + public boolean explodesOnComponentBreak(ItemStack itemStack) { + return false; + } + + public World getWorld() { + return this.getBaseMetaTileEntity() + .getWorld(); + } + + @Override + public void addGregTechLogo(ModularWindow.Builder builder) { + builder.widget( + new DrawableWidget().setDrawable(GTUITextures.PICTURE_GT_LOGO_17x17_TRANSPARENT_GRAY) + .setSize(17, 17) + .setPos(105, 51)); + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + builder.widget( + new DrawableWidget().setDrawable(GTUITextures.PICTURE_SCREEN_BLACK) + .setPos(7, 4) + .setSize(118, 67)) + .widget(new SlotWidget(new BaseSlot(this.inventoryHandler, 1) { + + @Override + public int getSlotStackLimit() { + return 1; + } + }).setBackground( + this.getGUITextureSet() + .getItemSlot(), + GTUITextures.OVERLAY_SLOT_IN) + .setPos(127, 13)) + .widget(new SlotWidget(new BaseSlot(this.inventoryHandler, 0) { + + @Override + public int getSlotStackLimit() { + return 1; + } + }).setBackground( + this.getGUITextureSet() + .getItemSlot(), + GTUITextures.OVERLAY_SLOT_CHARGER) + .setPos(127, 49)); + for (int i = 0; i < 4; i++) { + builder.widget( + new SlotWidget(this.circuitsInventoryHandler, i).setBackground( + this.getGUITextureSet() + .getItemSlot(), + GTUITextures.OVERLAY_SLOT_INT_CIRCUIT) + .setPos(151, 4 + i * 18)); + } + + final DynamicPositionedColumn screenElements = new DynamicPositionedColumn(); + this.drawTexts(screenElements); + builder.widget(screenElements); + + builder.widget( + new DrawableWidget().setDrawable(BWUITextures.PICTURE_STORED_EU_FRAME) + .setPos(7, 72) + .setSize(118, 7)) + .widget( + new ProgressBar().setProgress( + () -> (float) this.getBaseMetaTileEntity() + .getStoredEU() / this.getBaseMetaTileEntity() + .getEUCapacity()) + .setDirection(ProgressBar.Direction.RIGHT) + .setTexture(BWUITextures.PROGRESSBAR_STORED_EU_116, 116) + .setPos(8, 73) + .setSize(116, 5)); + } + + private long clientEU; + private long clientMaxEU; + private long clientMaxIn; + private long clientMaxOut; + private long clientAmps; + + private void drawTexts(DynamicPositionedColumn screenElements) { + screenElements.setSpace(0) + .setPos(11, 8); + + screenElements.widget( + new TextWidget().setStringSupplier(() -> "EU: " + numberFormat.format(this.clientEU)) + .setDefaultColor(this.COLOR_TEXT_WHITE.get())) + .widget( + new FakeSyncWidget.LongSyncer( + () -> this.getBaseMetaTileEntity() + .getStoredEU(), + val -> clientEU = val)) + .widget( + new TextWidget().setStringSupplier(() -> "MAX: " + numberFormat.format(clientMaxEU)) + .setDefaultColor(this.COLOR_TEXT_WHITE.get())) + .widget( + new FakeSyncWidget.LongSyncer( + () -> this.getBaseMetaTileEntity() + .isActive() + ? this.getBaseMetaTileEntity() + .getOutputVoltage() * ConfigHandler.energyPerCell + : 0, + val -> clientMaxEU = val)) + .widget( + new TextWidget().setStringSupplier(() -> "MAX EU/t IN: " + numberFormat.format(clientMaxIn)) + .setDefaultColor(this.COLOR_TEXT_WHITE.get())) + .widget( + new FakeSyncWidget.LongSyncer( + () -> this.getBaseMetaTileEntity() + .getInputVoltage(), + val -> clientMaxIn = val)) + .widget( + new TextWidget().setStringSupplier(() -> "EU/t OUT: " + numberFormat.format(clientMaxOut)) + .setDefaultColor(this.COLOR_TEXT_WHITE.get())) + .widget( + new FakeSyncWidget.LongSyncer( + () -> this.getBaseMetaTileEntity() + .getOutputVoltage(), + val -> clientMaxOut = val)) + .widget( + new TextWidget().setStringSupplier(() -> "AMP/t IN/OUT: " + numberFormat.format(clientAmps)) + .setDefaultColor(this.COLOR_TEXT_WHITE.get())) + .widget( + new FakeSyncWidget.LongSyncer( + () -> this.getBaseMetaTileEntity() + .getInputAmperage(), + val -> clientAmps = val)) + .widget( + new TextWidget(Text.localised("tooltip.LESU.0.name")).setDefaultColor(Color.YELLOW.getRGB()) + .setEnabled(widget -> this.maxEUStore() >= Long.MAX_VALUE - 1)) + .widget( + new TextWidget(Text.localised("tooltip.LESU.1.name")).setDefaultColor(Color.RED.getRGB()) + .setEnabled( + widget -> !this.getBaseMetaTileEntity() + .isActive())); + } + + @Override + public boolean getDefaultHasMaintenanceChecks() { + return false; + } +} diff --git a/src/main/java/bartworks/common/tileentities/multis/MTEManualTrafo.java b/src/main/java/bartworks/common/tileentities/multis/MTEManualTrafo.java new file mode 100644 index 0000000000..2533fd5213 --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/multis/MTEManualTrafo.java @@ -0,0 +1,363 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.multis; + +import static bartworks.common.loaders.ItemRegistry.BW_BLOCKS; +import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTWORKS; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose; +import static gregtech.api.enums.GTValues.V; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_ACTIVE; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_ACTIVE_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_GLOW; +import static gregtech.api.util.GTStructureUtility.ofHatchAdder; +import static gregtech.api.util.GTStructureUtility.ofHatchAdderOptional; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.structure.IStructureDefinition; +import com.gtnewhorizon.structurelib.structure.IStructureElementNoPlacement; +import com.gtnewhorizon.structurelib.structure.StructureDefinition; + +import gregtech.api.GregTechAPI; +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.implementations.MTEEnhancedMultiBlockBase; +import gregtech.api.metatileentity.implementations.MTEHatchDynamo; +import gregtech.api.metatileentity.implementations.MTEHatchEnergy; +import gregtech.api.metatileentity.implementations.MTETieredMachineBlock; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTUtility; +import gregtech.api.util.MultiblockTooltipBuilder; + +public class MTEManualTrafo extends MTEEnhancedMultiBlockBase<MTEManualTrafo> { + + private byte mode; + private int mTiers; + private boolean upstep = true; + + public MTEManualTrafo(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + public MTEManualTrafo(String aName) { + super(aName); + } + + private static final int CASING_INDEX = 2; + private static final String STRUCTURE_PIECE_BASE = "base"; + private static final String STRUCTURE_PIECE_LAYER = "layer"; + private static final String STRUCTURE_PIECE_TOP = "top"; + private static final String STRUCTURE_PIECE_TAP_LAYER = "taplayer"; + private static final IStructureDefinition<MTEManualTrafo> STRUCTURE_DEFINITION = StructureDefinition + .<MTEManualTrafo>builder() + .addShape(STRUCTURE_PIECE_BASE, transpose(new String[][] { { "b~b", "bbb", "bbb" } })) + .addShape(STRUCTURE_PIECE_LAYER, transpose(new String[][] { { "ttt", "tft", "ttt" } })) + .addShape(STRUCTURE_PIECE_TOP, transpose(new String[][] { { "ooo", "ooo", "ooo" } })) + .addShape( + STRUCTURE_PIECE_TAP_LAYER, + transpose(new String[][] { { " TTT ", "TtttT", "TtftT", "TtttT", " TTT " } })) + .addElement( + 'b', + ofChain( + ofHatchAdder(MTEManualTrafo::addEnergyInputToMachineList, CASING_INDEX, 1), + ofHatchAdder(MTEManualTrafo::addMaintenanceToMachineList, CASING_INDEX, 1), + ofBlock(GregTechAPI.sBlockCasings1, 2))) + .addElement( + 'o', + ofHatchAdderOptional( + MTEManualTrafo::addDynamoToMachineList, + CASING_INDEX, + 2, + GregTechAPI.sBlockCasings1, + 2)) + .addElement('t', ofBlock(BW_BLOCKS[2], 1)) + .addElement('f', ofBlock(BW_BLOCKS[2], 0)) + .addElement('T', new IStructureElementNoPlacement<MTEManualTrafo>() { + + @Override + public boolean check(MTEManualTrafo te, World world, int x, int y, int z) { + if (world.isAirBlock(x, y, z)) return true; + TileEntity tileEntity = world.getTileEntity(x, y, z); + if (tileEntity == null || !(tileEntity instanceof IGregTechTileEntity)) return true; + IMetaTileEntity mte = ((IGregTechTileEntity) tileEntity).getMetaTileEntity(); + if (mte instanceof MTEHatchDynamo || mte instanceof MTEHatchEnergy) { + int intier = te.mEnergyHatches.get(0).mTier; + if (((MTETieredMachineBlock) mte).mTier == intier + (te.upstep ? te.mTiers : -te.mTiers)) { + te.addToMachineList((IGregTechTileEntity) tileEntity, CASING_INDEX); + return true; + } + return false; + } + return true; + } + + @Override + public boolean spawnHint(MTEManualTrafo te, World world, int x, int y, int z, ItemStack itemStack) { + StructureLibAPI.hintParticle(world, x, y, z, StructureLibAPI.getBlockHint(), 2 /* aDots: 3 */); + return true; + } + }) + .build(); + + @Override + public IStructureDefinition<MTEManualTrafo> getStructureDefinition() { + return STRUCTURE_DEFINITION; + } + + @Override + protected MultiblockTooltipBuilder createTooltip() { + final MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder(); + tt.addMachineType("Transformer") + .addInfo("Controller block for the Manual Trafo") + .addInfo("Operates in 4 diffrent modes:") + .addInfo("Mode 1: Circuit 0 in controller: Direct-Upstep") + .addInfo("Mode 2: Circuit 1 in controller: Direct-Downstep") + .addInfo("Mode 3: Circuit 2 in controller: Tapped-Upstep (currently disabled)") + .addInfo("Mode 4: Circuit 2 in controller: Tapped-Downstep (currently disabled)") + .addSeparator() + .beginVariableStructureBlock(3, 3, 3, 10, 3, 3, false) + .addController("Front bottom center") + .addCasingInfoMin("MV Machine Casing", 0, false) + .addOtherStructurePart("Transformer-Winding Blocks", "1 Layer for each tier transformed") + .addOtherStructurePart("Nickel-Zinc-Ferrite Blocks", "Middle of Transformer-Winding Blocks") + .addMaintenanceHatch("Any bottom layer casing", 1) + .addEnergyHatch("Any bottom layer casing", 1) + .addDynamoHatch("Any top layer casing", 2) + .addStructureInfo("---------TAPPED MODE---------") + .addEnergyHatch("Touching Transformer-Winding Blocks", 3) + .addDynamoHatch("Touching Transformer-Winding Blocks", 3) + .addStructureInfo("Hatches touching Transformer-Winding Blocks must be tiered from bottom to top") + .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTWORKS); + return tt; + } + + @Override + public boolean isCorrectMachinePart(ItemStack itemStack) { + return true; + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (!this.getBaseMetaTileEntity() + .isAllowedToWork()) this.stopMachine(); + super.onPostTick(aBaseMetaTileEntity, aTick); + } + + @Override + public boolean onRunningTick(ItemStack aStack) { + if (!this.getBaseMetaTileEntity() + .isAllowedToWork()) { + this.stopMachine(); + return false; + } + + this.mProgresstime = 0; + this.mMaxProgresstime = 1; + + if (this.getBaseMetaTileEntity() + .getTimer() % 40 == 0) if (this.mEfficiency < this.getMaxEfficiency(null)) this.mEfficiency += 100; + else this.mEfficiency = this.getMaxEfficiency(null); + + if (this.mode > 1) { + return false; // this.onRunningTickTabbedMode(); Tapped mode is disable + } + + return this.drainEnergyInput(this.getInputTier() * 2 * this.mEnergyHatches.size()) && this.addEnergyOutput( + this.getInputTier() * 2 * this.mEnergyHatches.size() * this.mEfficiency / this.getMaxEfficiency(null)); + } + + public boolean onRunningTickTabbedMode() { + boolean ret = false; + for (MTEHatchDynamo E : this.mDynamoHatches) { + for (MTEHatchEnergy I : this.mEnergyHatches) { + + long vtt = I.getEUVar() >= V[E.mTier] / 2 && E.getEUVar() < E.maxEUStore() ? I.getEUVar() : 0; + + if (vtt == 0) continue; + + long vtp = E.getEUVar() + vtt; + long avt = Math.min(vtp, E.maxEUStore()); + E.setEUVar(avt); + I.setEUVar(I.getEUVar() - vtt); + ret = true; + } + } + return ret; + } + + @Override + public long getInputTier() { + if (this.mEnergyHatches.size() > 0) return GTUtility.getTier( + this.mEnergyHatches.get(0) + .getBaseMetaTileEntity() + .getInputVoltage()); + return 0L; + } + + @Override + public long getOutputTier() { + if (this.mDynamoHatches.size() > 0) return GTUtility.getTier( + this.mDynamoHatches.get(0) + .getBaseMetaTileEntity() + .getOutputVoltage()); + return 0L; + } + + @Override + public boolean checkRecipe(ItemStack itemStack) { + + if (!this.getBaseMetaTileEntity() + .isAllowedToWork()) { + this.stopMachine(); + return false; + } + if (itemStack == null || !itemStack.getUnlocalizedName() + .startsWith("gt.integrated_circuit")) this.mode = 0; + else this.mode = (byte) Math.min(3, itemStack.getItemDamage()); + this.upstep = this.mode % 2 == 0; + this.mProgresstime = 0; + this.mMaxProgresstime = 1; + this.mEfficiency = Math.max(this.mEfficiency, 100); + return this.upstep ? this.getOutputTier() - this.getInputTier() == this.mTiers + : this.getInputTier() - this.getOutputTier() == this.mTiers; + } + + @Override + public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack itemStack) { + + if (itemStack == null || !itemStack.getUnlocalizedName() + .startsWith("gt.integrated_circuit")) this.mode = 0; + else this.mode = (byte) Math.min(3, itemStack.getItemDamage()); + + this.upstep = this.mode % 2 == 0; + boolean tapmode = this.mode > 1; + + if (!this.checkPiece(STRUCTURE_PIECE_BASE, 1, 0, 0) || this.mEnergyHatches.size() == 0) return false; + + byte intier = this.mEnergyHatches.get(0).mTier; + for (MTEHatchEnergy in : this.mEnergyHatches) if (in.mTier != intier) return false; + + int mHeight; + for (mHeight = 1; mHeight <= 8; mHeight++) { + if (tapmode) { + this.mTiers = mHeight; + if (!this.checkPiece(STRUCTURE_PIECE_TAP_LAYER, 2, mHeight, 1)) break; + } else if (!this.checkPiece(STRUCTURE_PIECE_LAYER, 1, mHeight, 0)) break; + } + if (!this.checkPiece(STRUCTURE_PIECE_TOP, 1, mHeight, 0)) return false; + this.mTiers = mHeight - 1; + + if (this.mDynamoHatches.size() == 0 || this.mMaintenanceHatches.size() != 1 || this.mTiers == 0) return false; + + byte outtier = this.mDynamoHatches.get(0).mTier; + for (MTEHatchDynamo out : this.mDynamoHatches) { + if (out.mTier != outtier) return false; + } + + return true; + } + + @Override + public int getMaxEfficiency(ItemStack itemStack) { + return 10000; + } + + @Override + public int getPollutionPerTick(ItemStack itemStack) { + return 0; + } + + @Override + public int getDamageToComponent(ItemStack itemStack) { + return 0; + } + + @Override + public boolean explodesOnComponentBreak(ItemStack itemStack) { + return true; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MTEManualTrafo(this.mName); + } + + @Override + public void saveNBTData(NBTTagCompound ntag) { + super.saveNBTData(ntag); + ntag.setInteger("mTiers", this.mTiers); + ntag.setByte("mMode", this.mode); + ntag.setBoolean("upstep", this.upstep); + } + + @Override + public void loadNBTData(NBTTagCompound ntag) { + super.loadNBTData(ntag); + this.mTiers = ntag.getInteger("mTiers"); + this.mode = ntag.getByte("mMode"); + this.upstep = ntag.getBoolean("upstep"); + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing, + int aColorIndex, boolean aActive, boolean aRedstone) { + if (side == facing) { + if (aActive) return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_ACTIVE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_ACTIVE_GLOW) + .extFacing() + .glow() + .build() }; + return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX), TextureFactory.builder() + .addIcon(OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_GLOW) + .extFacing() + .glow() + .build() }; + } + return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX) }; + } + + @Override + public void construct(ItemStack itemStack, boolean b) { + if (this.mInventory[1] == null || !this.mInventory[1].getUnlocalizedName() + .startsWith("gt.integrated_circuit")) this.mode = 0; + else this.mode = (byte) Math.min(3, this.mInventory[1].getItemDamage()); + int mHeight = Math.min(itemStack.stackSize, 8); + boolean tapmode = this.mode > 1; + this.buildPiece(STRUCTURE_PIECE_BASE, itemStack, b, 1, 0, 0); + for (int i = 0; i < mHeight; i++) { + if (tapmode) this.buildPiece(STRUCTURE_PIECE_TAP_LAYER, itemStack, b, 2, i + 1, 1); + else this.buildPiece(STRUCTURE_PIECE_LAYER, itemStack, b, 1, i + 1, 0); + } + this.buildPiece(STRUCTURE_PIECE_TOP, itemStack, b, 1, mHeight + 1, 0); + } +} diff --git a/src/main/java/bartworks/common/tileentities/multis/MTEThoriumHighTempReactor.java b/src/main/java/bartworks/common/tileentities/multis/MTEThoriumHighTempReactor.java new file mode 100644 index 0000000000..064bc351fd --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/multis/MTEThoriumHighTempReactor.java @@ -0,0 +1,416 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.multis; + +import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTWORKS; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.onElementPass; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose; +import static gregtech.api.util.GTStructureUtility.ofHatchAdder; +import static gregtech.api.util.GTUtility.filterValidMTEs; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; + +import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits; +import com.gtnewhorizon.structurelib.structure.IStructureDefinition; +import com.gtnewhorizon.structurelib.structure.StructureDefinition; + +import bartworks.common.items.SimpleSubItemClass; +import bartworks.util.MathUtils; +import cpw.mods.fml.common.registry.GameRegistry; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.Materials; +import gregtech.api.enums.Textures; +import gregtech.api.enums.TierEU; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.implementations.MTEEnhancedMultiBlockBase; +import gregtech.api.metatileentity.implementations.MTEHatchInput; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTUtility; +import gregtech.api.util.MultiblockTooltipBuilder; + +public class MTEThoriumHighTempReactor extends MTEEnhancedMultiBlockBase<MTEThoriumHighTempReactor> { + + private static final int BASECASINGINDEX = 44; + + private static final String STRUCTURE_PIECE_MAIN = "main"; + private static final IStructureDefinition<MTEThoriumHighTempReactor> STRUCTURE_DEFINITION = StructureDefinition + .<MTEThoriumHighTempReactor>builder() + .addShape( + STRUCTURE_PIECE_MAIN, + transpose( + new String[][] { + { " BBBBBBB ", " BBBBBBBBB ", "BBBBBBBBBBB", "BBBBBBBBBBB", "BBBBBBBBBBB", "BBBBBBBBBBB", + "BBBBBBBBBBB", "BBBBBBBBBBB", "BBBBBBBBBBB", " BBBBBBBBB ", " BBBBBBB " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " ccccccc ", " c-------c ", "c---------c", "c---------c", "c---------c", "c---------c", + "c---------c", "c---------c", "c---------c", " c-------c ", " ccccccc " }, + { " bbb~bbb ", " bbbbbbbbb ", "bbbbbbbbbbb", "bbbbbbbbbbb", "bbbbbbbbbbb", "bbbbbbbbbbb", + "bbbbbbbbbbb", "bbbbbbbbbbb", "bbbbbbbbbbb", " bbbbbbbbb ", " bbbbbbb " }, })) + .addElement('c', onElementPass(x -> x.mCasing++, ofBlock(GregTechAPI.sBlockCasings3, 12))) + .addElement( + 'b', + ofChain( + ofHatchAdder(MTEThoriumHighTempReactor::addOutputToMachineList, BASECASINGINDEX, 1), + ofHatchAdder(MTEThoriumHighTempReactor::addMaintenanceToMachineList, BASECASINGINDEX, 1), + ofHatchAdder(MTEThoriumHighTempReactor::addEnergyInputToMachineList, BASECASINGINDEX, 1), + onElementPass(x -> x.mCasing++, ofBlock(GregTechAPI.sBlockCasings3, 12)))) + .addElement( + 'B', + ofChain( + ofHatchAdder(MTEThoriumHighTempReactor::addInputToMachineList, BASECASINGINDEX, 2), + onElementPass(x -> x.mCasing++, ofBlock(GregTechAPI.sBlockCasings3, 12)))) + // ofHatchAdderOptional(GT_TileEntity_THTR::addInputToMachineList, BASECASINGINDEX, 2, + // GregTechAPI.sBlockCasings3, 12)) + .build(); + + private static final int HELIUM_NEEDED = 730000; + private static final int powerUsage = (int) TierEU.RECIPE_IV / 2; + private static final int maxcapacity = 675000; + private static final int mincapacity = 100000; + private int HeliumSupply; + private int fuelsupply; + private boolean empty; + private int coolanttaking = 0; + private int mCasing = 0; + + public MTEThoriumHighTempReactor(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + private MTEThoriumHighTempReactor(String aName) { + super(aName); + } + + @Override + public boolean isCorrectMachinePart(ItemStack itemStack) { + return true; + } + + @Override + public IStructureDefinition<MTEThoriumHighTempReactor> getStructureDefinition() { + return STRUCTURE_DEFINITION; + } + + @Override + protected MultiblockTooltipBuilder createTooltip() { + final MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder(); + tt.addMachineType("High Temperature Reactor") + .addInfo("Controller block for the Thorium High Temperature Reactor (THTR)") + .addInfo("Needs to be primed with " + GTUtility.formatNumbers(HELIUM_NEEDED) + " of helium") + .addInfo("Needs a constant supply of coolant while running") + .addInfo("Needs at least 100k Fuel pebbles to start operation (can hold up to 675k pebbles)") + .addInfo("Consumes up to 0.5% of total Fuel Pellets per Operation depending on efficiency") + .addInfo("Efficiency decreases exponentially if the internal buffer is not completely filled") + .addInfo("Reactor will take 4 800L/t of coolant multiplied by efficiency") + .addInfo("Uses " + GTUtility.formatNumbers(powerUsage) + " EU/t") + .addInfo("One Operation takes 9 hours") + .addSeparator() + .beginStructureBlock(11, 12, 11, true) + .addController("Front bottom center") + .addCasingInfoMin("Radiation Proof Casings", 500, false) + .addStructureInfo("Corners and the 2 touching blocks are air (cylindric)") + .addInputBus("Any top layer casing", 2) + .addInputHatch("Any top layer casing", 2) + .addOutputBus("Any bottom layer casing", 1) + .addOutputHatch("Any bottom layer casing", 1) + .addEnergyHatch("Any bottom layer casing", 1) + .addMaintenanceHatch("Any bottom layer casing", 1) + .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTWORKS); + return tt; + } + + @Override + protected IAlignmentLimits getInitialAlignmentLimits() { + return (d, r, f) -> d.offsetY == 0 && r.isNotRotated() && f.isNotFlipped(); + } + + @Override + public void construct(ItemStack stackSize, boolean hintsOnly) { + this.buildPiece(STRUCTURE_PIECE_MAIN, stackSize, hintsOnly, 5, 11, 0); + } + + @Override + public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack itemStack) { + this.mCasing = 0; + return this.checkPiece(STRUCTURE_PIECE_MAIN, 5, 11, 0) && this.mCasing >= 500 + && this.mMaintenanceHatches.size() == 1 + && this.mInputHatches.size() > 0 + && this.mOutputHatches.size() > 0 + && this.mInputBusses.size() > 0 + && this.mOutputBusses.size() > 0 + && this.mEnergyHatches.size() > 0; + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + this.HeliumSupply = aNBT.getInteger("HeliumSupply"); + this.fuelsupply = aNBT.getInteger("fuelsupply"); + this.coolanttaking = aNBT.getInteger("coolanttaking"); + this.empty = aNBT.getBoolean("EmptyMode"); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + aNBT.setInteger("HeliumSupply", this.HeliumSupply); + aNBT.setInteger("fuelsupply", this.fuelsupply); + aNBT.setInteger("coolanttaking", this.coolanttaking); + aNBT.setBoolean("EmptyMode", this.empty); + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onPostTick(aBaseMetaTileEntity, aTick); + if (aBaseMetaTileEntity.isServerSide() && !this.empty) { + if (this.HeliumSupply < MTEThoriumHighTempReactor.HELIUM_NEEDED) { + for (FluidStack fluidStack : this.getStoredFluids()) { + if (fluidStack.isFluidEqual(Materials.Helium.getGas(1))) { + int toget = Math + .min(MTEThoriumHighTempReactor.HELIUM_NEEDED - this.HeliumSupply, fluidStack.amount); + fluidStack.amount -= toget; + this.HeliumSupply += toget; + if (MTEThoriumHighTempReactor.HELIUM_NEEDED == this.HeliumSupply && fluidStack.amount == 0) + fluidStack = null; + } + } + } + if (this.fuelsupply < maxcapacity) { + this.startRecipeProcessing(); + for (ItemStack itemStack : this.getStoredInputs()) { + if (GTUtility.areStacksEqual( + itemStack, + new ItemStack(THTRMaterials.aTHTR_Materials, 1, THTRMaterials.MATERIAL_FUEL_INDEX))) { + int toget = Math.min(maxcapacity - this.fuelsupply, itemStack.stackSize); + if (toget == 0) continue; + itemStack.stackSize -= toget; + this.fuelsupply += toget; + } + } + this.endRecipeProcessing(); + this.updateSlots(); + } + } + } + + @Override + public boolean checkRecipe(ItemStack controllerStack) { + + if (this.empty) { + if (this.HeliumSupply > 0 || this.fuelsupply > 0) { + this.mEfficiency = 10000; + this.mMaxProgresstime = 100; + return true; + } + return false; + } + if (this.HeliumSupply < MTEThoriumHighTempReactor.HELIUM_NEEDED || this.fuelsupply < mincapacity) return false; + + double eff = Math + .min(Math.pow((this.fuelsupply - mincapacity) / ((maxcapacity - mincapacity) / 10D), 2D) + 1, 100D) / 100D + - (this.getIdealStatus() - this.getRepairStatus()) / 10D; + if (eff <= 0D) return false; + + int toReduce = MathUtils.floorInt(this.fuelsupply * 0.005D * eff); + + final int originalToReduce = toReduce; + int burnedballs = toReduce / 64; + if (burnedballs > 0) toReduce -= burnedballs * 64; + + int meta = THTRMaterials.MATERIAL_USED_FUEL_INDEX; + + ItemStack[] toOutput = { new ItemStack(THTRMaterials.aTHTR_Materials, burnedballs, meta), + new ItemStack(THTRMaterials.aTHTR_Materials, toReduce, meta + 1) }; + if (!this.canOutputAll(toOutput)) return false; + + this.fuelsupply -= originalToReduce; + this.mOutputItems = toOutput; + + // this.updateSlots(); not needed ? + + this.coolanttaking = (int) (4800D * eff); + this.mEfficiency = (int) (eff * 10000D); + this.mEUt = -powerUsage; + this.mMaxProgresstime = 648000; + return true; + } + + @Override + public boolean onRunningTick(ItemStack aStack) { + + if (this.empty) { + this.addOutput(Materials.Helium.getGas(this.HeliumSupply)); + this.addOutput( + new ItemStack(THTRMaterials.aTHTR_Materials, this.fuelsupply, THTRMaterials.MATERIAL_FUEL_INDEX)); + this.HeliumSupply = 0; + this.fuelsupply = 0; + this.updateSlots(); + return true; + } + + if (!super.onRunningTick(aStack)) return false; + + int takecoolant = this.coolanttaking; + int drainedamount = 0; + + for (MTEHatchInput tHatch : filterValidMTEs(mInputHatches)) { + FluidStack tLiquid = tHatch.getFluid(); + if (tLiquid != null && tLiquid.isFluidEqual(FluidRegistry.getFluidStack("ic2coolant", 1))) { + FluidStack drained = tHatch.drain(takecoolant, true); + takecoolant -= drained.amount; + drainedamount += drained.amount; + if (takecoolant <= 0) break; + } + } + + if (drainedamount > 0) this.addOutput(FluidRegistry.getFluidStack("ic2hotcoolant", drainedamount)); + + this.updateSlots(); + + return true; + } + + @Override + public int getMaxEfficiency(ItemStack itemStack) { + return 10000; + } + + @Override + public int getPollutionPerTick(ItemStack itemStack) { + return 0; + } + + @Override + public int getDamageToComponent(ItemStack itemStack) { + return 0; + } + + @Override + public boolean explodesOnComponentBreak(ItemStack itemStack) { + return false; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MTEThoriumHighTempReactor(this.mName); + } + + @Override + public String[] getInfoData() { + return new String[] { "Progress:", + GTUtility.formatNumbers(this.mProgresstime / 20) + "secs /" + + GTUtility.formatNumbers(this.mMaxProgresstime / 20) + + "secs", + "TRISO-Pebbles:", + GTUtility.formatNumbers(this.fuelsupply) + "pcs. / " + GTUtility.formatNumbers(this.fuelsupply) + "psc.", + "Helium-Level:", + GTUtility.formatNumbers(this.HeliumSupply) + "L / " + + GTUtility.formatNumbers(MTEThoriumHighTempReactor.HELIUM_NEEDED) + + "L", + "Coolant/t:", GTUtility.formatNumbers(this.mProgresstime == 0 ? 0 : this.coolanttaking) + "L/t", + "Problems:", String.valueOf(this.getIdealStatus() - this.getRepairStatus()) }; + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing, + int aColorIndex, boolean aActive, boolean aRedstone) { + if (side == facing) { + if (aActive) return new ITexture[] { + Textures.BlockIcons.getCasingTextureForId(MTEThoriumHighTempReactor.BASECASINGINDEX), + TextureFactory.builder() + .addIcon(Textures.BlockIcons.OVERLAY_FRONT_HEAT_EXCHANGER_ACTIVE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(Textures.BlockIcons.OVERLAY_FRONT_HEAT_EXCHANGER_ACTIVE_GLOW) + .extFacing() + .glow() + .build() }; + return new ITexture[] { + Textures.BlockIcons.getCasingTextureForId(MTEThoriumHighTempReactor.BASECASINGINDEX), + TextureFactory.builder() + .addIcon(Textures.BlockIcons.OVERLAY_FRONT_HEAT_EXCHANGER) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(Textures.BlockIcons.OVERLAY_FRONT_HEAT_EXCHANGER_GLOW) + .extFacing() + .glow() + .build() }; + } + return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(MTEThoriumHighTempReactor.BASECASINGINDEX) }; + } + + @Override + public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) { + if (this.mMaxProgresstime > 0) { + GTUtility.sendChatToPlayer(aPlayer, "THTR mode cannot be changed while the machine is running."); + return; + } + this.empty = !this.empty; + GTUtility.sendChatToPlayer( + aPlayer, + "THTR is now running in " + (this.empty ? "emptying mode." : "normal Operation")); + } + + @Override + public boolean supportsVoidProtection() { + return true; + } + + public static class THTRMaterials { + + public static final SimpleSubItemClass aTHTR_Materials = new SimpleSubItemClass( + "BISOPelletCompound", // 0 + "BISOPelletBall", // 1 + "TRISOPelletCompound", // 2 + "TRISOPelletBall", // 3 + "TRISOPellet", // 4 + "BurnedOutTRISOPelletBall", // 5 + "BurnedOutTRISOPellet" // 6 + ); + public static final int MATERIAL_FUEL_INDEX = 4; + public static final int MATERIAL_USED_FUEL_INDEX = 5; + + public static void registeraTHR_Materials() { + GameRegistry.registerItem(MTEThoriumHighTempReactor.THTRMaterials.aTHTR_Materials, "bw.THTRMaterials"); + } + } +} diff --git a/src/main/java/bartworks/common/tileentities/multis/MTEWindmill.java b/src/main/java/bartworks/common/tileentities/multis/MTEWindmill.java new file mode 100644 index 0000000000..e60c147b70 --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/multis/MTEWindmill.java @@ -0,0 +1,637 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.multis; + +import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTWORKS; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlockAnyMeta; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofTileAdder; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.onElementPass; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose; +import static gregtech.api.enums.GTValues.V; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityDispenser; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits; +import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable; +import com.gtnewhorizon.structurelib.structure.AutoPlaceEnvironment; +import com.gtnewhorizon.structurelib.structure.IStructureDefinition; +import com.gtnewhorizon.structurelib.structure.IStructureElement; +import com.gtnewhorizon.structurelib.structure.IStructureElementNoPlacement; +import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment; +import com.gtnewhorizon.structurelib.structure.StructureDefinition; +import com.gtnewhorizons.modularui.api.drawable.ItemDrawable; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.common.widget.DrawableWidget; +import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; +import com.gtnewhorizons.modularui.common.widget.SlotWidget; +import com.gtnewhorizons.modularui.common.widget.TextWidget; + +import bartworks.API.modularUI.BWUITextures; +import bartworks.MainMod; +import bartworks.common.items.ItemStonageRotors; +import bartworks.common.loaders.ItemRegistry; +import bartworks.common.tileentities.classic.TileEntityRotorBlock; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.enums.Textures; +import gregtech.api.gui.modularui.GUITextureSet; +import gregtech.api.interfaces.IIconContainer; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.modularui.IGetTitleColor; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.implementations.MTEEnhancedMultiBlockBase; +import gregtech.api.objects.ItemData; +import gregtech.api.recipe.RecipeMaps; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; +import gregtech.api.util.MultiblockTooltipBuilder; +import gregtech.common.items.IDMetaTool01; +import gregtech.common.items.MetaGeneratedTool01; + +public class MTEWindmill extends MTEEnhancedMultiBlockBase<MTEWindmill> + implements ISurvivalConstructable, IGetTitleColor { + + private static final IIcon[] iIcons = new IIcon[2]; + private static final IIconContainer[] iIconContainers = new IIconContainer[2]; + private static final ITexture[] iTextures = new ITexture[3]; + + private TileEntityRotorBlock rotorBlock; + private int mDoor = 0; + private int mHardenedClay = 0; + private int mMulti = 16; + + public MTEWindmill(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + private MTEWindmill(String aName) { + super(aName); + } + + private static final String STRUCTURE_PIECE_MAIN = "main"; + private static final IStructureDefinition<MTEWindmill> STRUCTURE_DEFINITION = StructureDefinition + .<MTEWindmill>builder() + .addShape( + STRUCTURE_PIECE_MAIN, + transpose( + new String[][] { { " ", " ", " ", " p ", " ", " ", " " }, + { " ", " ", " ppp ", " p p ", " ppp ", " ", " " }, + { " ", " ppppp ", " p p ", " p p ", " p p ", " ppppp ", " " }, + { " ppppp ", "p p", "p p", "p p", "p p", "p p", " ppppp " }, + { " ppspp ", "p p", "p p", "p p", "p p", "p p", " ppppp " }, + { " ppppp ", "p p", "p p", "p p", "p p", "p p", " ppppp " }, + { " ", " ppppp ", " p p ", " p p ", " p p ", " ppppp ", " " }, + { " ", " ccc ", " c c ", " c c ", " c c ", " ccc ", " " }, + { " ", " ccc ", " c c ", " c c ", " c c ", " ccc ", " " }, + { " ", " ccc ", " c c ", " c c ", " c c ", " ccc ", " " }, + { " ", " ccc ", " c c ", " c c ", " c c ", " ccc ", " " }, + { " bb~bb ", "bbbbbbb", "bbbbbbb", "bbbbbbb", "bbbbbbb", "bbbbbbb", " bbbbb " }, })) + .addElement('p', ofBlockAnyMeta(Blocks.planks)) + .addElement( + 'c', + ofChain( + onElementPass(t -> t.mHardenedClay++, ofBlock(Blocks.hardened_clay, 0)), + ofTileAdder(MTEWindmill::addDispenserToOutputSet, Blocks.hardened_clay, 0), + onElementPass(t -> t.mDoor++, new IStructureElementNoPlacement<MTEWindmill>() { + + private final IStructureElement<MTEWindmill> delegate = ofBlock(Blocks.wooden_door, 0); + + @Override + public boolean check(MTEWindmill gt_tileEntity_windmill, World world, int x, int y, int z) { + return this.delegate.check(gt_tileEntity_windmill, world, x, y, z); + } + + @Override + public boolean spawnHint(MTEWindmill gt_tileEntity_windmill, World world, int x, int y, int z, + ItemStack trigger) { + return this.delegate.spawnHint(gt_tileEntity_windmill, world, x, y, z, trigger); + } + }))) + .addElement('b', ofBlock(Blocks.brick_block, 0)) + .addElement('s', new IStructureElement<MTEWindmill>() { + + @Override + public boolean check(MTEWindmill t, World world, int x, int y, int z) { + TileEntity tileEntity = world.getTileEntity(x, y, z); + return t.setRotorBlock(tileEntity); + } + + @Override + public boolean spawnHint(MTEWindmill t, World world, int x, int y, int z, ItemStack trigger) { + StructureLibAPI.hintParticle(world, x, y, z, StructureLibAPI.getBlockHint(), 0); + return true; + } + + @Override + public boolean placeBlock(MTEWindmill gt_tileEntity_windmill, World world, int x, int y, int z, + ItemStack trigger) { + return false; + } + + @Override + public BlocksToPlace getBlocksToPlace(MTEWindmill gt_tileEntity_windmill, World world, int x, int y, int z, + ItemStack trigger, AutoPlaceEnvironment env) { + return BlocksToPlace.create(new ItemStack(ItemRegistry.ROTORBLOCK)); + } + }) + .build(); + + @Override + public IStructureDefinition<MTEWindmill> getStructureDefinition() { + return STRUCTURE_DEFINITION; + } + + @Override + protected IAlignmentLimits getInitialAlignmentLimits() { + return (d, r, f) -> d.offsetY == 0 && r.isNotRotated() && f.isNotFlipped(); + } + + @Override + protected MultiblockTooltipBuilder createTooltip() { + MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder(); + tt.addMachineType("Windmill") + .addInfo("Controller block for the Windmill") + .addInfo("A primitive Grinder powered by Kinetic energy") + .addInfo("Speed and output will be affected by wind speed, recipe and rotor") + .addInfo("Please use the Primitive Rotor") + .addInfo("Macerates 16 items at a time") + .addInfo("The structure is too complex!") + .addInfo("Follow the StructureLib hologram projector to build the main structure.") + .addSeparator() + .beginStructureBlock(7, 12, 7, false) + .addController("Front bottom center") + .addCasingInfoMin("Hardened Clay block", 40, false) + .addOtherStructurePart("Dispenser", "Any Hardened Clay block") + .addOtherStructurePart("0-1 Wooden door", "Any Hardened Clay block") + .addStructureHint("Primitive Kinetic Shaftbox", 1) + .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTWORKS); + return tt; + } + + @Override + public boolean isCorrectMachinePart(ItemStack itemStack) { + return true; + } + + private final Set<TileEntityDispenser> tileEntityDispensers = new HashSet<>(); + + @Override + public boolean onRunningTick(ItemStack aStack) { + if (this.mMaxProgresstime > 0) this.mProgresstime += this.rotorBlock.getGrindPower(); + if (!this.rotorBlock.rotorSlot.isEmpty()) this.setRotorDamage(this.rotorBlock, this.rotorBlock.getGrindPower()); + return this.rotorBlock.getGrindPower() > 0; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return true; + } + + @Override + public boolean doRandomMaintenanceDamage() { + return true; + } + + private float[] multiplierRecipe(ItemStack itemStack) { + // will return max and min value of the multiplier, the average of these is used to calculate the multiplier. + final Item item = itemStack.getItem(); + if (item == Items.wheat) { + return new float[] { 1.13f, 1.5f }; + } + final Block block = Block.getBlockFromItem(item); + if (item == Items.bone || block == Blocks.glowstone || block == Blocks.pumpkin) { + return new float[] { 0.8f, 1f }; + } + if (block == Blocks.gravel || block == Blocks.cobblestone + || block == Blocks.stone + || block == Blocks.sandstone + || block == Blocks.clay + || block == Blocks.hardened_clay + || block == Blocks.stained_hardened_clay + || block == Blocks.wool + || block == Blocks.netherrack + || block == Blocks.log + || block == Blocks.log2) { + return new float[] { 1f, 1.5f }; + } + final ItemData association = GTOreDictUnificator.getAssociation(itemStack); + final OrePrefixes prefix = association == null ? null : association.mPrefix; + if (prefix == null || association.mMaterial == null + || association.mMaterial.mMaterial == null + || association.mMaterial.mMaterial.getDust(1) == null) { + return new float[] { 1f, 1f }; + } + if (OrePrefixes.ore == prefix || OrePrefixes.oreNetherrack == prefix + || OrePrefixes.oreEndstone == prefix + || OrePrefixes.oreBlackgranite == prefix + || OrePrefixes.oreRedgranite == prefix + || OrePrefixes.oreMarble == prefix + || OrePrefixes.oreBasalt == prefix) { + return new float[] { 0.5f, 1f }; + } + if (OrePrefixes.stone == prefix || OrePrefixes.stoneBricks == prefix + || OrePrefixes.stoneChiseled == prefix + || OrePrefixes.stoneCobble == prefix + || OrePrefixes.stoneCracked == prefix + || OrePrefixes.stoneMossy == prefix + || OrePrefixes.stoneMossyBricks == prefix + || OrePrefixes.stoneSmooth == prefix + || OrePrefixes.cobblestone == prefix) { + return new float[] { 1f, 1.5f }; + } + return new float[] { 1f, 1f }; + } + + @Override + public boolean checkRecipe(ItemStack itemStack) { + if (itemStack == null || itemStack.getItem() == null) return false; + + if (this.mOutputItems == null) this.mOutputItems = new ItemStack[2]; + + GTRecipe tRecipe = RecipeMaps.maceratorRecipes + .findRecipe(this.getBaseMetaTileEntity(), false, false, V[1], null, itemStack); + if (tRecipe == null) { + return false; + } + + if (tRecipe.getOutput(0) != null) { + // Decrease input stack by appropriate amount (Not always 1) + for (int i = 0; i < this.mMulti; i++) { + if (!tRecipe.isRecipeInputEqual(true, null, itemStack)) { + this.mMulti = i; + break; + } + } + this.updateSlots(); + this.mOutputItems[0] = tRecipe.getOutput(0); + float[] mRecipe = this.multiplierRecipe(itemStack); + float multiper = Math.min( + mRecipe[1], + Math.max( + mRecipe[0], + 2f * (float) Math.sqrt((float) 1 / (this.rotorBlock.getWindStrength() + 1)) + * this.OutputMultiplier(this.rotorBlock) + * (mRecipe[0] + mRecipe[1]))); + int amount = (int) Math.floor(multiper * (this.mOutputItems[0].stackSize * this.mMulti)); + + // Split ItemStack --by gtpp + List<ItemStack> splitStacks = new ArrayList<>(); + while (amount > this.mOutputItems[0].getMaxStackSize()) { + ItemStack tmp = this.mOutputItems[0].copy(); + tmp.stackSize = this.mOutputItems[0].getMaxStackSize(); + amount -= this.mOutputItems[0].getMaxStackSize(); + splitStacks.add(tmp); + } + ItemStack tmp = this.mOutputItems[0].copy(); + tmp.stackSize = amount; + splitStacks.add(tmp); + this.mOutputItems = splitStacks.toArray(new ItemStack[splitStacks.size()]); + } + this.mMaxProgresstime = tRecipe.mDuration * 2 * 100 * this.mMulti / this.getSpeed(this.rotorBlock); + this.mMulti = 16; + return true; + } + + @Override + public void stopMachine() { + this.getBaseMetaTileEntity() + .disableWorking(); + } + + public boolean addDispenserToOutputSet(TileEntity aTileEntity) { + if (aTileEntity instanceof TileEntityDispenser) { + this.tileEntityDispensers.add((TileEntityDispenser) aTileEntity); + return true; + } + return false; + } + + public boolean setRotorBlock(TileEntity aTileEntity) { + if (aTileEntity instanceof TileEntityRotorBlock) { + this.rotorBlock = (TileEntityRotorBlock) aTileEntity; + return true; + } + return false; + } + + @Override + public boolean addOutput(ItemStack aStack) { + if (GTUtility.isStackInvalid(aStack)) return false; + + for (TileEntityDispenser tHatch : this.tileEntityDispensers) { + for (int i = tHatch.getSizeInventory() - 1; i >= 0; i--) { + if (tHatch.getStackInSlot(i) == null || GTUtility.areStacksEqual(tHatch.getStackInSlot(i), aStack) + && aStack.stackSize + tHatch.getStackInSlot(i).stackSize <= 64) { + if (GTUtility.areStacksEqual(tHatch.getStackInSlot(i), aStack)) { + ItemStack merge = tHatch.getStackInSlot(i) + .copy(); + merge.stackSize = aStack.stackSize + tHatch.getStackInSlot(i).stackSize; + tHatch.setInventorySlotContents(i, merge); + } else { + tHatch.setInventorySlotContents(i, aStack.copy()); + } + + if (GTUtility.areStacksEqual(tHatch.getStackInSlot(i), aStack)) { + aStack = null; + return true; + } + tHatch.setInventorySlotContents(i, null); + aStack = null; + return false; + } + } + } + return false; + } + + @Override + public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack itemStack) { + + this.tileEntityDispensers.clear(); + this.mDoor = 0; + this.mHardenedClay = 0; + + return this.checkPiece(STRUCTURE_PIECE_MAIN, 3, 11, 0) && !this.tileEntityDispensers.isEmpty() + && this.mDoor <= 2 + && this.mHardenedClay >= 40; + } + + @Override + public int getCurrentEfficiency(ItemStack itemStack) { + return 10000; + } + + @Override + public void updateSlots() { + if (this.mInventory[1] != null && this.mInventory[1].stackSize <= 0) { + this.mInventory[1] = null; + } + } + + @Override + public int getMaxEfficiency(ItemStack itemStack) { + return 10000; + } + + @Override + public int getPollutionPerTick(ItemStack itemStack) { + return 0; + } + + @Override + public int getDamageToComponent(ItemStack itemStack) { + return 0; + } + + @Override + public boolean explodesOnComponentBreak(ItemStack itemStack) { + return false; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MTEWindmill(this.mName); + } + + @Override + public String[] getInfoData() { + return new String[] { "Progress:", + this.mProgresstime + " Grindings of " + this.mMaxProgresstime + " needed Grindings", "GrindPower:", + this.rotorBlock.getGrindPower() + "KU/t" }; + } + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister aBlockIconRegister) { + MTEWindmill.iIcons[0] = Blocks.brick_block.getIcon(0, 0); + MTEWindmill.iIconContainers[0] = new IIconContainer() { + + @Override + public IIcon getIcon() { + return MTEWindmill.iIcons[0]; + } + + @Override + public IIcon getOverlayIcon() { + return null; + } + + @Override + public ResourceLocation getTextureFile() { + return new ResourceLocation("brick"); + } + }; + + MTEWindmill.iIcons[1] = aBlockIconRegister.registerIcon(MainMod.MOD_ID + ":windmill_top"); + MTEWindmill.iIconContainers[1] = new IIconContainer() { + + @Override + public IIcon getIcon() { + return MTEWindmill.iIcons[1]; + } + + @Override + public IIcon getOverlayIcon() { + return null; + } + + @Override + public ResourceLocation getTextureFile() { + return new ResourceLocation(MainMod.MOD_ID + ":windmill_top"); + } + }; + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing, + int aColorIndex, boolean aActive, boolean aRedstone) { + + ITexture[] ret = new ITexture[6]; + + if (this.isClientSide()) { + + if (facing == side || side == ForgeDirection.DOWN) { + MTEWindmill.iTextures[0] = TextureFactory.of(MTEWindmill.iIconContainers[0]); + Arrays.fill(ret, MTEWindmill.iTextures[0]); + } else if (side == ForgeDirection.UP) { + MTEWindmill.iTextures[1] = TextureFactory.of(MTEWindmill.iIconContainers[1]); + Arrays.fill(ret, MTEWindmill.iTextures[1]); + } else { + MTEWindmill.iTextures[2] = TextureFactory.of(Textures.BlockIcons.COVER_WOOD_PLATE); + Arrays.fill(ret, MTEWindmill.iTextures[2]); + } + } + return ret; + } + + public boolean isClientSide() { + if (this.getBaseMetaTileEntity() + .getWorld() != null) + return this.getBaseMetaTileEntity() + .getWorld().isRemote + ? FMLCommonHandler.instance() + .getSide() == Side.CLIENT + : FMLCommonHandler.instance() + .getEffectiveSide() == Side.CLIENT; + return FMLCommonHandler.instance() + .getEffectiveSide() == Side.CLIENT; + } + + @Override + public void construct(ItemStack itemStack, boolean b) { + this.buildPiece(STRUCTURE_PIECE_MAIN, itemStack, b, 3, 11, 0); + } + + @Override + public int survivalConstruct(ItemStack stackSize, int elementBudget, ISurvivalBuildEnvironment env) { + if (this.mMachine) return -1; + return this.survivialBuildPiece(STRUCTURE_PIECE_MAIN, stackSize, 3, 11, 0, elementBudget, env, false, true); + } + + public float OutputMultiplier(TileEntityRotorBlock rotorBlock) { + try { + return ((ItemStonageRotors) rotorBlock.rotorSlot.get() + .getItem()).getmRotor(); + } catch (Exception e) { + return 1f; + } + } + + public int getSpeed(TileEntityRotorBlock rotorBlock) { + try { + return ((ItemStonageRotors) rotorBlock.rotorSlot.get() + .getItem()).getSpeed(); + } catch (Exception e) { + return 1; + } + } + + public void setRotorDamage(TileEntityRotorBlock rotorBlock, int damage) { + try { + ((ItemStonageRotors) rotorBlock.rotorSlot.get() + .getItem()).damageItemStack(rotorBlock.rotorSlot.get(), damage); + } catch (Exception e) { + rotorBlock.rotorSlot.damage(damage, false); + } + } + + @Override + public GUITextureSet getGUITextureSet() { + return new GUITextureSet().setMainBackground(BWUITextures.BACKGROUND_BROWN) + .setItemSlot(BWUITextures.SLOT_BROWN) + .setTitleTab( + BWUITextures.TAB_TITLE_BROWN, + BWUITextures.TAB_TITLE_DARK_BROWN, + BWUITextures.TAB_TITLE_ANGULAR_BROWN); + } + + @Override + public void addGregTechLogo(ModularWindow.Builder builder) { + builder.widget( + new DrawableWidget().setDrawable(BWUITextures.PICTURE_BW_LOGO_47X21) + .setSize(47, 21) + .setPos(123, 59)); + } + + @Override + public int getTitleColor() { + return this.COLOR_TITLE_WHITE.get(); + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + builder.widget( + new SlotWidget(this.inventoryHandler, 1).setBackground( + this.getGUITextureSet() + .getItemSlot()) + .setPos(59, 35)) + .widget(new DrawableWidget() { + + private static final int DIVIDER = 125; + + @Override + public void onScreenUpdate() { + super.onScreenUpdate(); + if (MTEWindmill.this.mMaxProgresstime > 0) { + if (System.currentTimeMillis() / DIVIDER % 40 == 30) + this.setDrawable(BWUITextures.PICTURE_WINDMILL_ROTATING[3]); + else if (System.currentTimeMillis() / DIVIDER % 40 == 20) + this.setDrawable(BWUITextures.PICTURE_WINDMILL_ROTATING[2]); + else if (System.currentTimeMillis() / DIVIDER % 40 == 10) + this.setDrawable(BWUITextures.PICTURE_WINDMILL_ROTATING[1]); + else if (System.currentTimeMillis() / DIVIDER % 40 == 0) + this.setDrawable(BWUITextures.PICTURE_WINDMILL_ROTATING[0]); + } else { + this.setDrawable(BWUITextures.PICTURE_WINDMILL_EMPTY); + } + } + }.setDrawable(BWUITextures.PICTURE_WINDMILL_EMPTY) + .setPos(85, 27) + .setSize(32, 32)) + .widget(new FakeSyncWidget.IntegerSyncer(() -> this.mMaxProgresstime, val -> this.mMaxProgresstime = val)) + .widget( + new ItemDrawable( + () -> this.mMachine && !this.getBaseMetaTileEntity() + .isActive() + ? MetaGeneratedTool01.INSTANCE + .getToolWithStats(IDMetaTool01.SOFTMALLET.ID, 1, null, null, null) + : null).asWidget() + .setPos(66, 66)) + .widget( + new FakeSyncWidget.BooleanSyncer( + () -> this.getBaseMetaTileEntity() + .isActive(), + val -> this.getBaseMetaTileEntity() + .setActive(val))) + .widget( + new TextWidget(GTUtility.trans("138", "Incomplete Structure.")) + .setDefaultColor(this.COLOR_TEXT_WHITE.get()) + .setMaxWidth(150) + .setEnabled(widget -> !this.mMachine) + .setPos(92, 22)) + .widget(new FakeSyncWidget.BooleanSyncer(() -> this.mMachine, val -> this.mMachine = val)); + } + + @Override + public boolean getDefaultHasMaintenanceChecks() { + return false; + } +} diff --git a/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaBlastFurnace.java b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaBlastFurnace.java new file mode 100644 index 0000000000..8d5ea073db --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaBlastFurnace.java @@ -0,0 +1,430 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.multis.mega; + +import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.withChannel; +import static gregtech.api.enums.HatchElement.*; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_ACTIVE; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_ACTIVE_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.casingTexturePages; +import static gregtech.api.util.GTStructureUtility.buildHatchAdder; +import static gregtech.api.util.GTStructureUtility.ofCoil; +import static gregtech.api.util.GTUtility.filterValidMTEs; + +import java.util.ArrayList; +import java.util.Arrays; + +import javax.annotation.Nonnull; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; + +import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable; +import com.gtnewhorizon.structurelib.structure.IItemSource; +import com.gtnewhorizon.structurelib.structure.IStructureDefinition; +import com.gtnewhorizon.structurelib.structure.StructureDefinition; + +import bartworks.API.BorosilicateGlass; +import bartworks.common.configs.ConfigHandler; +import bartworks.util.BWUtil; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.HeatingCoilLevel; +import gregtech.api.enums.Materials; +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.MTEHatchMuffler; +import gregtech.api.metatileentity.implementations.MTEHatchOutput; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.recipe.RecipeMaps; +import gregtech.api.recipe.check.CheckRecipeResult; +import gregtech.api.recipe.check.CheckRecipeResultRegistry; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; +import gregtech.api.util.MultiblockTooltipBuilder; +import gregtech.api.util.OverclockCalculator; + +public class MTEMegaBlastFurnace extends MegaMultiBlockBase<MTEMegaBlastFurnace> implements ISurvivalConstructable { + + private static final int CASING_INDEX = 11; + private static final IStructureDefinition<MTEMegaBlastFurnace> STRUCTURE_DEFINITION = StructureDefinition + .<MTEMegaBlastFurnace>builder() + .addShape("main", createShape()) + .addElement('=', StructureElementAirNoHint.getInstance()) + .addElement( + 't', + buildHatchAdder(MTEMegaBlastFurnace.class) + .atLeast( + OutputHatch.withAdder(MTEMegaBlastFurnace::addOutputHatchToTopList) + .withCount(t -> t.mPollutionOutputHatches.size())) + .casingIndex(CASING_INDEX) + .dot(1) + .buildAndChain(GregTechAPI.sBlockCasings1, CASING_INDEX)) + .addElement('m', Muffler.newAny(CASING_INDEX, 2)) + .addElement( + 'C', + withChannel("coil", ofCoil(MTEMegaBlastFurnace::setCoilLevel, MTEMegaBlastFurnace::getCoilLevel))) + .addElement( + 'g', + withChannel( + "glass", + BorosilicateGlass + .ofBoroGlass((byte) 0, (byte) 1, Byte.MAX_VALUE, (te, t) -> te.glassTier = t, te -> te.glassTier))) + .addElement( + 'b', + buildHatchAdder(MTEMegaBlastFurnace.class) + .atLeast(InputHatch, OutputHatch, InputBus, OutputBus, Maintenance, Energy.or(ExoticEnergy)) + .casingIndex(CASING_INDEX) + .dot(1) + .buildAndChain(GregTechAPI.sBlockCasings1, CASING_INDEX)) + .build(); + + private static String[][] createShape() { + String[][] raw = new String[20][]; + + raw[0] = new String[15]; + String topCasing = "ttttttttttttttt"; + String middleTopCasing = "tttttttmttttttt"; + raw[0][0] = topCasing; + for (int i = 1; i < 15; i++) { + raw[0][i] = topCasing; + } + raw[0][7] = middleTopCasing; + + raw[1] = new String[15]; + String allGlass = "ggggggggggggggg"; + String allCoil = "gCCCCCCCCCCCCCg"; + String middleLine = "gC===========Cg"; + raw[1][0] = allGlass; + raw[1][1] = allCoil; + raw[1][13] = allCoil; + raw[1][14] = allGlass; + for (int i = 2; i < 13; i++) { + raw[1][i] = middleLine; + } + for (int i = 2; i < 19; i++) { + raw[i] = raw[1]; + } + String bottomCasing = "bbbbbbbbbbbbbbb"; + raw[19] = new String[15]; + for (int i = 0; i < 15; i++) { + raw[19][i] = bottomCasing; + } + + raw[17] = Arrays.copyOf(raw[17], raw[17].length); + raw[17][0] = "ggggggg~ggggggg"; + + return transpose(raw); + } + + private HeatingCoilLevel mCoilLevel; + protected final ArrayList<MTEHatchOutput> mPollutionOutputHatches = new ArrayList<>(); + protected final FluidStack[] pollutionFluidStacks = { Materials.CarbonDioxide.getGas(1000), + Materials.CarbonMonoxide.getGas(1000), Materials.SulfurDioxide.getGas(1000) }; + private int mHeatingCapacity; + private byte glassTier; + private final static int polPtick = ConfigHandler.basePollutionMBFSecond / 20 * ConfigHandler.megaMachinesMax; + + public MTEMegaBlastFurnace(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + public MTEMegaBlastFurnace(String aName) { + super(aName); + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MTEMegaBlastFurnace(this.mName); + } + + @Override + protected MultiblockTooltipBuilder createTooltip() { + MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder(); + tt.addMachineType("Blast Furnace") + .addInfo("Controller block for the Mega Blast Furnace") + .addInfo("You can use some fluids to reduce recipe time. Place the circuit in the Input Bus") + .addInfo("Each 900K over the min. Heat required reduces power consumption by 5% (multiplicatively)") + .addInfo("Each 1800K over the min. Heat allows for an overclock to be upgraded to a perfect overclock.") + .addInfo("That means the EBF will reduce recipe time by a factor 4 instead of 2 (giving 100% efficiency).") + .addInfo("Additionally gives +100K for every tier past MV") + .addInfo( + GTValues.TIER_COLORS[8] + GTValues.VN[8] + + EnumChatFormatting.GRAY + + "-tier glass required for " + + EnumChatFormatting.BLUE + + "Tec" + + EnumChatFormatting.DARK_BLUE + + "Tech" + + EnumChatFormatting.GRAY + + " Laser Hatches.") + .addPollutionAmount(20 * this.getPollutionPerTick(null)) + .addSeparator() + .beginStructureBlock(15, 20, 15, true) + .addController("3rd layer center") + .addCasingInfoRange("Heat Proof Machine Casing", 0, 279, false) + .addOtherStructurePart("864x Heating Coils", "Inner 13x18x13 (Hollow)") + .addOtherStructurePart("1007x Borosilicate Glass", "Outer 15x18x15") + .addStructureInfo("The glass tier limits the Energy Input tier") + .addEnergyHatch("Any bottom layer casing") + .addMaintenanceHatch("Any bottom layer casing") + .addMufflerHatch("Top middle") + .addInputBus("Any bottom layer casing") + .addInputHatch("Any bottom layer casing") + .addOutputBus("Any bottom layer casing") + .addOutputHatch("Gasses, Any top layer casing") + .addStructureInfo("Recovery amount scales with Muffler Hatch tier") + .addOutputHatch("Platline fluids, Any bottom layer casing") + .addStructureHint("This Mega Multiblock is too big to have its structure hologram displayed fully.") + .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS); + return tt; + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + this.glassTier = aNBT.getByte("glasTier"); + if (!aNBT.hasKey(INPUT_SEPARATION_NBT_KEY)) { + this.inputSeparation = aNBT.getBoolean("isBussesSeparate"); + } + if (!aNBT.hasKey(BATCH_MODE_NBT_KEY)) { + this.batchMode = aNBT.getBoolean("mUseMultiparallelMode"); + } + } + + @Override + public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer, + float aX, float aY, float aZ) { + if (!aPlayer.isSneaking()) { + this.inputSeparation = !this.inputSeparation; + GTUtility.sendChatToPlayer( + aPlayer, + StatCollector.translateToLocal("GT5U.machines.separatebus") + " " + this.inputSeparation); + return true; + } + this.batchMode = !this.batchMode; + if (this.batchMode) { + GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOn")); + } else { + GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOff")); + } + return true; + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing, + int aColorIndex, boolean aActive, boolean aRedstone) { + if (side == facing) { + if (aActive) return new ITexture[] { casingTexturePages[0][CASING_INDEX], TextureFactory.builder() + .addIcon(OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_ACTIVE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_ACTIVE_GLOW) + .extFacing() + .glow() + .build() }; + return new ITexture[] { casingTexturePages[0][CASING_INDEX], TextureFactory.builder() + .addIcon(OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_ELECTRIC_BLAST_FURNACE_GLOW) + .extFacing() + .glow() + .build() }; + } + return new ITexture[] { casingTexturePages[0][CASING_INDEX] }; + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + aNBT.setByte("glasTier", this.glassTier); + } + + @Override + public int getPollutionPerTick(ItemStack aStack) { + return polPtick; + } + + public boolean addOutputHatchToTopList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + if (aTileEntity == null) return false; + IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null) return false; + if (aMetaTileEntity instanceof MTEHatchOutput) { + ((MTEHatch) aMetaTileEntity).updateTexture(aBaseCasingIndex); + return this.mPollutionOutputHatches.add((MTEHatchOutput) aMetaTileEntity); + } + return false; + } + + @Override + protected String[] getExtendedInfoData() { + return new String[] { StatCollector.translateToLocal("GT5U.EBF.heat") + ": " + + EnumChatFormatting.GREEN + + GTUtility.formatNumbers(this.mHeatingCapacity) + + EnumChatFormatting.RESET + + " K" }; + } + + @Override + protected ProcessingLogic createProcessingLogic() { + return new ProcessingLogic() { + + @Nonnull + @Override + protected OverclockCalculator createOverclockCalculator(@Nonnull GTRecipe recipe) { + return super.createOverclockCalculator(recipe).setRecipeHeat(recipe.mSpecialValue) + .setMachineHeat(MTEMegaBlastFurnace.this.mHeatingCapacity) + .setHeatOC(true) + .setHeatDiscount(true); + } + + @Override + protected @Nonnull CheckRecipeResult validateRecipe(@Nonnull GTRecipe recipe) { + return recipe.mSpecialValue <= MTEMegaBlastFurnace.this.mHeatingCapacity + ? CheckRecipeResultRegistry.SUCCESSFUL + : CheckRecipeResultRegistry.insufficientHeat(recipe.mSpecialValue); + } + }.setMaxParallel(ConfigHandler.megaMachinesMax); + } + + @Override + public IStructureDefinition<MTEMegaBlastFurnace> getStructureDefinition() { + return STRUCTURE_DEFINITION; + } + + @Override + public void construct(ItemStack stackSize, boolean hintsOnly) { + this.buildPiece("main", stackSize, hintsOnly, 7, 17, 0); + } + + @Override + public int survivalConstruct(ItemStack stackSize, int elementBudget, IItemSource source, EntityPlayerMP actor) { + if (this.mMachine) return -1; + int realBudget = elementBudget >= 200 ? elementBudget : Math.min(200, elementBudget * 5); + this.glassTier = 0; + this.setCoilLevel(HeatingCoilLevel.None); + return this.survivialBuildPiece("main", stackSize, 7, 17, 0, realBudget, source, actor, false, true); + } + + public void setCoilLevel(HeatingCoilLevel aCoilLevel) { + this.mCoilLevel = aCoilLevel; + } + + public HeatingCoilLevel getCoilLevel() { + return this.mCoilLevel; + } + + @Override + public boolean addOutput(FluidStack aLiquid) { + if (aLiquid == null) return false; + FluidStack tLiquid = aLiquid.copy(); + boolean isOutputPollution = false; + for (FluidStack pollutionFluidStack : this.pollutionFluidStacks) { + if (!tLiquid.isFluidEqual(pollutionFluidStack)) continue; + + isOutputPollution = true; + break; + } + ArrayList<MTEHatchOutput> tOutputHatches; + if (isOutputPollution) { + tOutputHatches = this.mPollutionOutputHatches; + int pollutionReduction = 0; + for (MTEHatchMuffler tHatch : filterValidMTEs(mMufflerHatches)) { + pollutionReduction = 100 - tHatch.calculatePollutionReduction(100); + break; + } + tLiquid.amount = tLiquid.amount * pollutionReduction / 100; + } else { + tOutputHatches = this.mOutputHatches; + } + return dumpFluid(tOutputHatches, tLiquid, true) || dumpFluid(tOutputHatches, tLiquid, false); + } + + @Override + public boolean checkMachine(IGregTechTileEntity iGregTechTileEntity, ItemStack itemStack) { + this.mHeatingCapacity = 0; + this.glassTier = 0; + + this.setCoilLevel(HeatingCoilLevel.None); + + this.mPollutionOutputHatches.clear(); + + if (!this.checkPiece("main", 7, 17, 0) || this.getCoilLevel() == HeatingCoilLevel.None + || this.mMaintenanceHatches.size() != 1) return false; + + if (this.glassTier < 8) { + for (int i = 0; i < this.mExoticEnergyHatches.size(); ++i) { + MTEHatch hatch = this.mExoticEnergyHatches.get(i); + if (hatch.getConnectionType() == MTEHatch.ConnectionType.LASER) { + return false; + } + if (this.glassTier < hatch.mTier) { + return false; + } + } + for (int i = 0; i < this.mEnergyHatches.size(); ++i) { + if (this.glassTier < this.mEnergyHatches.get(i).mTier) { + return false; + } + } + } + + this.mHeatingCapacity = (int) this.getCoilLevel() + .getHeat() + 100 * (BWUtil.getTier(this.getMaxInputEu()) - 2); + + return true; + } + + @Override + public RecipeMap<?> getRecipeMap() { + return RecipeMaps.blastFurnaceRecipes; + } + + @Override + public int getRecipeCatalystPriority() { + return -2; + } + + @Override + public boolean supportsInputSeparation() { + return true; + } + + @Override + public boolean supportsBatchMode() { + return true; + } + + @Override + public boolean supportsVoidProtection() { + return true; + } +} diff --git a/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaChemicalReactor.java b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaChemicalReactor.java new file mode 100644 index 0000000000..e1366cec7d --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaChemicalReactor.java @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.multis.mega; + +import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTWORKS; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose; +import static gregtech.api.enums.HatchElement.*; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR_ACTIVE; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR_ACTIVE_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.casingTexturePages; +import static gregtech.api.util.GTStructureUtility.buildHatchAdder; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable; +import com.gtnewhorizon.structurelib.structure.IItemSource; +import com.gtnewhorizon.structurelib.structure.IStructureDefinition; +import com.gtnewhorizon.structurelib.structure.StructureDefinition; + +import bartworks.API.BorosilicateGlass; +import bartworks.common.configs.ConfigHandler; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.GTValues; +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.recipe.RecipeMap; +import gregtech.api.recipe.RecipeMaps; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTUtility; +import gregtech.api.util.MultiblockTooltipBuilder; + +public class MTEMegaChemicalReactor extends MegaMultiBlockBase<MTEMegaChemicalReactor> + implements ISurvivalConstructable { + + private byte glassTier; + + public MTEMegaChemicalReactor(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + public MTEMegaChemicalReactor(String aName) { + super(aName); + } + + @Override + public MultiblockTooltipBuilder createTooltip() { + final MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder(); + tt.addMachineType("Chemical Reactor") + .addInfo("Controller block for the Chemical Reactor") + .addInfo("What molecule do you want to synthesize") + .addInfo("Or you want to replace something in this molecule") + .addInfo( + GTValues.TIER_COLORS[8] + GTValues.VN[8] + + EnumChatFormatting.GRAY + + "-tier glass required for " + + EnumChatFormatting.BLUE + + "Tec" + + EnumChatFormatting.DARK_BLUE + + "Tech" + + EnumChatFormatting.GRAY + + " Laser Hatches.") + .addInfo("The structure is too complex!") + .addInfo("Follow the Structure Lib hologram projector to build the main structure.") + .addSeparator() + .beginStructureBlock(5, 5, 9, false) + .addController("Front center") + .addStructureInfo("46x Chemically Inert Machine Casing (minimum)") + .addStructureInfo("7x Fusion Coil Block") + .addStructureInfo("28x PTFE Pipe Casing") + .addStructureInfo("64x Borosilicate Glass Block (any tier)") + .addStructureInfo("The glass tier limits the Energy Input tier") + .addEnergyHatch("Hint block ", 3) + .addMaintenanceHatch("Hint block ", 2) + .addInputHatch("Hint block ", 1) + .addInputBus("Hint block ", 1) + .addOutputBus("Hint block ", 1) + .addOutputHatch("Hint block ", 1) + .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTWORKS); + return tt; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEMegaChemicalReactor(this.mName); + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing, + int aColorIndex, boolean aActive, boolean aRedstone) { + if (side == facing) { + if (aActive) return new ITexture[] { casingTexturePages[1][48], TextureFactory.builder() + .addIcon(OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR_ACTIVE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR_ACTIVE_GLOW) + .extFacing() + .glow() + .build() }; + return new ITexture[] { casingTexturePages[1][48], TextureFactory.builder() + .addIcon(OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR_GLOW) + .extFacing() + .glow() + .build() }; + } + return new ITexture[] { casingTexturePages[1][48] }; + } + + @Override + public boolean supportsSingleRecipeLocking() { + return true; + } + + @Override + public RecipeMap<?> getRecipeMap() { + return RecipeMaps.multiblockChemicalReactorRecipes; + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + if (!aNBT.hasKey(BATCH_MODE_NBT_KEY)) { + this.batchMode = aNBT.getBoolean("mUseMultiparallelMode"); + } + } + + @Override + public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) { + inputSeparation = !inputSeparation; + GTUtility.sendChatToPlayer( + aPlayer, + StatCollector.translateToLocal("GT5U.machines.separatebus") + " " + inputSeparation); + } + + @Override + public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer, + float aX, float aY, float aZ) { + if (aPlayer.isSneaking()) { + this.batchMode = !this.batchMode; + if (this.batchMode) { + GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOn")); + } else { + GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOff")); + } + return true; + } + return false; + } + + @Override + protected ProcessingLogic createProcessingLogic() { + return new ProcessingLogic().enablePerfectOverclock() + .setMaxParallel(ConfigHandler.megaMachinesMax); + } + + @Override + public void construct(ItemStack aStack, boolean aHintsOnly) { + this.buildPiece(STRUCTURE_PIECE_MAIN, aStack, aHintsOnly, 2, 2, 0); + } + + @Override + public int survivalConstruct(ItemStack stackSize, int elementBudget, IItemSource source, EntityPlayerMP actor) { + if (this.mMachine) return -1; + int realBudget = elementBudget >= 200 ? elementBudget : Math.min(200, elementBudget * 5); + return this + .survivialBuildPiece(STRUCTURE_PIECE_MAIN, stackSize, 2, 2, 0, realBudget, source, actor, false, true); + } + // -------------- TEC TECH COMPAT ---------------- + + @Override + public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) { + this.glassTier = 0; + + if (!this.checkPiece(STRUCTURE_PIECE_MAIN, 2, 2, 0) || this.mMaintenanceHatches.size() != 1) return false; + + if (this.glassTier < 8) { + for (int i = 0; i < this.mExoticEnergyHatches.size(); ++i) { + MTEHatch hatch = this.mExoticEnergyHatches.get(i); + if (hatch.getConnectionType() == MTEHatch.ConnectionType.LASER) { + return false; + } + if (this.glassTier < hatch.mTier) { + return false; + } + } + for (int i = 0; i < this.mEnergyHatches.size(); ++i) { + if (this.glassTier < this.mEnergyHatches.get(i).mTier) { + return false; + } + } + } + + return true; + } + + private static final int CASING_INDEX = 176; + private static final String STRUCTURE_PIECE_MAIN = "main"; + private static final IStructureDefinition<MTEMegaChemicalReactor> STRUCTURE_DEFINITION = StructureDefinition + .<MTEMegaChemicalReactor>builder() + .addShape( + STRUCTURE_PIECE_MAIN, + transpose( + new String[][] { { "ttttt", "dptpd", "dptpd", "dptpd", "dptpd", "dptpd", "dptpd", "dptpd", "ttttt" }, + { "tgggt", " ggg ", " ggg ", " ggg ", " ggg ", " ggg ", " ggg ", " ggg ", "teeet" }, + { "tg~gt", " gcg ", " gcg ", " gcg ", " gcg ", " gcg ", " gcg ", " gcg ", "teret" }, + { "tgggt", " ggg ", " ggg ", " ggg ", " ggg ", " ggg ", " ggg ", " ggg ", "teeet" }, + { "ttttt", "dptpd", "dptpd", "dptpd", "dptpd", "dptpd", "dptpd", "dptpd", "ttttt" }, })) + .addElement('p', ofBlock(GregTechAPI.sBlockCasings8, 1)) + .addElement('t', ofBlock(GregTechAPI.sBlockCasings8, 0)) + .addElement( + 'd', + buildHatchAdder(MTEMegaChemicalReactor.class).atLeast(InputBus, InputHatch, OutputBus, OutputHatch) + .casingIndex(CASING_INDEX) + .dot(1) + .buildAndChain(GregTechAPI.sBlockCasings8, 0)) + .addElement('r', Maintenance.newAny(CASING_INDEX, 2)) + .addElement( + 'e', + buildHatchAdder(MTEMegaChemicalReactor.class) + .atLeast(Energy.or(ExoticEnergy), InputHatch, InputBus, OutputHatch, OutputBus) + .casingIndex(CASING_INDEX) + .dot(3) + .buildAndChain(GregTechAPI.sBlockCasings8, 0)) + .addElement('c', ofChain(ofBlock(GregTechAPI.sBlockCasings4, 7), ofBlock(GregTechAPI.sBlockCasings5, 13))) + .addElement( + 'g', + BorosilicateGlass + .ofBoroGlass((byte) 0, (byte) 1, Byte.MAX_VALUE, (te, t) -> te.glassTier = t, te -> te.glassTier)) + .build(); + + @Override + public IStructureDefinition<MTEMegaChemicalReactor> getStructureDefinition() { + return STRUCTURE_DEFINITION; + } + + @Override + public boolean supportsBatchMode() { + return true; + } + + @Override + public boolean supportsVoidProtection() { + return true; + } + + @Override + public boolean supportsInputSeparation() { + return true; + } +} diff --git a/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaDistillTower.java b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaDistillTower.java new file mode 100644 index 0000000000..382b64fb47 --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaDistillTower.java @@ -0,0 +1,446 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.multis.mega; + +import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.onElementPass; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose; +import static gregtech.api.enums.HatchElement.*; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER_GLOW; +import static gregtech.api.util.GTStructureUtility.buildHatchAdder; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; + +import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable; +import com.gtnewhorizon.structurelib.structure.IItemSource; +import com.gtnewhorizon.structurelib.structure.IStructureDefinition; +import com.gtnewhorizon.structurelib.structure.IStructureElementCheckOnly; +import com.gtnewhorizon.structurelib.structure.StructureDefinition; + +import bartworks.common.configs.ConfigHandler; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.IHatchElement; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.fluid.IFluidStore; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.logic.ProcessingLogic; +import gregtech.api.metatileentity.implementations.MTEHatchOutput; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.recipe.RecipeMaps; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTUtility; +import gregtech.api.util.MultiblockTooltipBuilder; +import gregtech.common.tileentities.machines.MTEHatchOutputME; + +public class MTEMegaDistillTower extends MegaMultiBlockBase<MTEMegaDistillTower> implements ISurvivalConstructable { + + protected static final int CASING_INDEX = 49; + protected static final String STRUCTURE_PIECE_BASE = "base"; + protected static final String STRUCTURE_PIECE_LAYER = "layer"; + protected static final String STRUCTURE_PIECE_TOP_HINT = "top"; + private static final IStructureDefinition<MTEMegaDistillTower> STRUCTURE_DEFINITION; + + static { + IHatchElement<MTEMegaDistillTower> layeredOutputHatch = OutputHatch + .withCount(MTEMegaDistillTower::getCurrentLayerOutputHatchCount) + .withAdder(MTEMegaDistillTower::addLayerOutputHatch); + STRUCTURE_DEFINITION = StructureDefinition.<MTEMegaDistillTower>builder() + .addShape( + STRUCTURE_PIECE_BASE, + transpose( + new String[][] { { "bbbbbbb~bbbbbbb", "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb", + "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb", + "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbb", + "bbbbbbbbbbbbbbb" }, })) + .addShape( + STRUCTURE_PIECE_LAYER, + transpose( + new String[][] { + { "lllllllllllllll", "lcccccccccccccl", "lcccccccccccccl", "lcccccccccccccl", "lcccccccccccccl", + "lcccccccccccccl", "lcccccccccccccl", "lcccccccccccccl", "lcccccccccccccl", + "lcccccccccccccl", "lcccccccccccccl", "lcccccccccccccl", "lcccccccccccccl", + "lcccccccccccccl", "lllllllllllllll" }, + { "lllllllllllllll", "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "lllllllllllllll" }, + { "lllllllllllllll", "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "lllllllllllllll" }, + { "lllllllllllllll", "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "lllllllllllllll" }, + { "lllllllllllllll", "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "lllllllllllllll" }, })) + .addShape( + STRUCTURE_PIECE_TOP_HINT, + transpose( + new String[][] { + { "lllllllllllllll", "lllllllllllllll", "lllllllllllllll", "lllllllllllllll", "lllllllllllllll", + "lllllllllllllll", "lllllllllllllll", "lllllllllllllll", "lllllllllllllll", + "lllllllllllllll", "lllllllllllllll", "lllllllllllllll", "lllllllllllllll", + "lllllllllllllll", "lllllllllllllll" }, + { "lllllllllllllll", "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "lllllllllllllll" }, + { "lllllllllllllll", "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "lllllllllllllll" }, + { "lllllllllllllll", "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "lllllllllllllll" }, + { "lllllllllllllll", "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "l=============l", "l=============l", "l=============l", + "l=============l", "lllllllllllllll" }, })) + .addElement('=', StructureElementAirNoHint.getInstance()) + .addElement( + 'b', + buildHatchAdder(MTEMegaDistillTower.class) + .atLeast(InputHatch, OutputHatch, InputBus, OutputBus, Maintenance, Energy.or(ExoticEnergy)) + .casingIndex(CASING_INDEX) + .dot(1) + .buildAndChain( + onElementPass(MTEMegaDistillTower::onCasingFound, ofBlock(GregTechAPI.sBlockCasings4, 1)))) + .addElement( + 'l', + buildHatchAdder(MTEMegaDistillTower.class) + .atLeast(layeredOutputHatch, Maintenance, Energy.or(ExoticEnergy)) + .casingIndex(CASING_INDEX) + .dot(1) + .buildAndChain( + onElementPass(MTEMegaDistillTower::onCasingFound, ofBlock(GregTechAPI.sBlockCasings4, 1)))) + .addElement('c', (IStructureElementCheckOnly<MTEMegaDistillTower>) (t, world, x, y, z) -> { + if (world.isAirBlock(x, y, z)) { + if (t.mTopState < 1) { + t.mTopState = 0; + return true; + } + // definitely top - cannot be air + return false; + } + // from here on we must be looking at a top layer, since it's not air + if (t.mTopState == 0) + // must be air but failed, so no + return false; + t.mTopState = 1; + // hatch adder + TileEntity tileEntity = world.getTileEntity(x, y, z); + if (tileEntity instanceof IGregTechTileEntity entity && t.addLayerOutputHatch(entity, CASING_INDEX)) { + t.onTopLayerFound(false); + return true; + } + // block adder + if (world.getBlock(x, y, z) == GregTechAPI.sBlockCasings4 && world.getBlockMetadata(x, y, z) == 1) { + t.onTopLayerFound(true); + return true; + } + return false; + }) + .build(); + } + + protected final List<List<MTEHatchOutput>> mOutputHatchesByLayer = new ArrayList<>(); + protected int mHeight; + protected int mCasing; + protected boolean mTopLayerFound; + + // -1 => maybe top, maybe not, 0 => definitely not top, 1 => definitely top + private int mTopState = -1; + + public MTEMegaDistillTower(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + private MTEMegaDistillTower(String aName) { + super(aName); + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEMegaDistillTower(this.mName); + } + + protected void onCasingFound() { + this.mCasing++; + } + + protected int getCurrentLayerOutputHatchCount() { + return this.mOutputHatchesByLayer.size() < this.mHeight || this.mHeight <= 0 ? 0 + : this.mOutputHatchesByLayer.get(this.mHeight - 1) + .size(); + } + + protected boolean addLayerOutputHatch(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + if (aTileEntity == null || aTileEntity.isDead() || !(aTileEntity.getMetaTileEntity() instanceof MTEHatchOutput)) + return false; + while (this.mOutputHatchesByLayer.size() < this.mHeight) this.mOutputHatchesByLayer.add(new ArrayList<>()); + MTEHatchOutput tHatch = (MTEHatchOutput) aTileEntity.getMetaTileEntity(); + tHatch.updateTexture(aBaseCasingIndex); + return this.mOutputHatchesByLayer.get(this.mHeight - 1) + .add(tHatch); + } + + protected void onTopLayerFound(boolean aIsCasing) { + this.mTopLayerFound = true; + if (aIsCasing) this.onCasingFound(); + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing, + int aColorIndex, boolean aActive, boolean aRedstone) { + if (side == facing) { + if (aActive) return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE_GLOW) + .extFacing() + .glow() + .build() }; + return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX), TextureFactory.builder() + .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER_GLOW) + .extFacing() + .glow() + .build() }; + } + return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX) }; + } + + @Override + public RecipeMap<?> getRecipeMap() { + return RecipeMaps.distillationTowerRecipes; + } + + @Override + public int getRecipeCatalystPriority() { + return -1; + } + + @Override + protected MultiblockTooltipBuilder createTooltip() { + final MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder(); + tt.addMachineType("Distillery") + .addInfo("Controller block for the Distillation Tower") + .addInfo("Fluids are only put out at the correct height") + .addInfo("The correct height equals the slot number in the NEI recipe") + .addSeparator() + .beginVariableStructureBlock(15, 15, 16, 56, 15, 15, true) + .addController("Front bottom") + .addOtherStructurePart("Clean Stainless Steel Machine Casing", "15 x h - 5 (minimum)") + .addEnergyHatch("Any casing") + .addMaintenanceHatch("Any casing") + .addInputHatch("Any bottom layer casing") + .addOutputBus("Any bottom layer casing") + .addOutputHatch("2-11x Output Hatches (One per Output Layer except bottom layer)") + .addStructureInfo("An \"Output Layer\" consists of 5 layers!") + .addStructureHint("The interior of this Mega Multiblock's hologram is empty, it should be all air.") + .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS); + return tt; + } + + @Override + public IStructureDefinition<MTEMegaDistillTower> getStructureDefinition() { + return STRUCTURE_DEFINITION; + } + + @Override + public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) { + // reset + this.mOutputHatchesByLayer.forEach(List::clear); + this.mHeight = 1; + this.mTopLayerFound = false; + this.mTopState = -1; + + // check base + if (!this.checkPiece(STRUCTURE_PIECE_BASE, 7, 0, 0)) return false; + + // check each layer + while (this.mHeight < 12) { + if (!checkPiece(STRUCTURE_PIECE_LAYER, 7, mHeight * 5, 0)) { + return false; + } + if (this.mOutputHatchesByLayer.size() < this.mHeight || this.mOutputHatchesByLayer.get(this.mHeight - 1) + .isEmpty()) + // layer without output hatch + return false; + if (mTopLayerFound) { + break; + } + this.mTopState = -1; + // not top + this.mHeight++; + } + + // validate final invariants... + return this.mCasing >= 75 * this.mHeight + 10 && this.mHeight >= 2 + && this.mTopLayerFound + && this.mMaintenanceHatches.size() == 1; + } + + @Override + public void construct(ItemStack stackSize, boolean hintsOnly) { + this.buildPiece(STRUCTURE_PIECE_BASE, stackSize, hintsOnly, 7, 0, 0); + int tTotalHeight = Math.min(12, stackSize.stackSize + 2); // min 2 output layer, so at least 1 + 2 height + for (int i = 1; i < tTotalHeight - 1; i++) { + this.buildPiece(STRUCTURE_PIECE_LAYER, stackSize, hintsOnly, 7, 5 * i, 0); + } + this.buildPiece(STRUCTURE_PIECE_TOP_HINT, stackSize, hintsOnly, 7, 5 * (tTotalHeight - 1), 0); + } + + @Override + public int survivalConstruct(ItemStack stackSize, int elementBudget, IItemSource source, EntityPlayerMP actor) { + if (this.mMachine) return -1; + int realBudget = elementBudget >= 200 ? elementBudget : Math.min(200, elementBudget * 5); + this.mHeight = 0; + int built = this + .survivialBuildPiece(STRUCTURE_PIECE_BASE, stackSize, 7, 0, 0, realBudget, source, actor, false, true); + if (built >= 0) return built; + int tTotalHeight = Math.min(12, stackSize.stackSize + 2); // min 2 output layer, so at least 1 + 2 height + for (int i = 1; i < tTotalHeight - 1; i++) { + this.mHeight = i; + built = this.survivialBuildPiece( + STRUCTURE_PIECE_LAYER, + stackSize, + 7, + 5 * this.mHeight, + 0, + realBudget, + source, + actor, + false, + true); + if (built >= 0) return built; + } + this.mHeight = tTotalHeight - 1; + return this.survivialBuildPiece( + STRUCTURE_PIECE_TOP_HINT, + stackSize, + 7, + 5 * this.mHeight, + 0, + realBudget, + source, + actor, + false, + true); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + if (!aNBT.hasKey(BATCH_MODE_NBT_KEY)) { + this.batchMode = aNBT.getBoolean("mUseMultiparallelMode"); + } + } + + @Override + public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer, + float aX, float aY, float aZ) { + if (aPlayer.isSneaking()) { + this.batchMode = !this.batchMode; + if (this.batchMode) { + GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOn")); + } else { + GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOff")); + } + return true; + } + return false; + } + + @Override + protected ProcessingLogic createProcessingLogic() { + return new ProcessingLogic().setMaxParallel(ConfigHandler.megaMachinesMax); + } + + @Override + public boolean canDumpFluidToME() { + + // All fluids can be dumped to ME only if each layer contains a ME Output Hatch. + for (List<MTEHatchOutput> tLayerOutputHatches : this.mOutputHatchesByLayer) { + + boolean foundMEHatch = false; + + for (IFluidStore tHatch : tLayerOutputHatches) { + if (tHatch instanceof MTEHatchOutputME tMEHatch) { + if (tMEHatch.canAcceptFluid()) { + foundMEHatch = true; + break; + } + } + } + + // Exit if we didn't find a valid hatch on this layer. + if (!foundMEHatch) { + return false; + } + } + + return true; + } + + @Override + protected void addFluidOutputs(FluidStack[] mOutputFluids2) { + for (int i = 0; i < mOutputFluids2.length && i < this.mOutputHatchesByLayer.size(); i++) { + FluidStack tStack = mOutputFluids2[i].copy(); + if (!dumpFluid(this.mOutputHatchesByLayer.get(i), tStack, true)) + dumpFluid(this.mOutputHatchesByLayer.get(i), tStack, false); + } + } + + @Override + public List<? extends IFluidStore> getFluidOutputSlots(FluidStack[] toOutput) { + return this.getFluidOutputSlotsByLayer(toOutput, this.mOutputHatchesByLayer); + } + + @Override + public boolean supportsBatchMode() { + return true; + } + + @Override + public boolean supportsVoidProtection() { + return true; + } +} diff --git a/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaOilCracker.java b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaOilCracker.java new file mode 100644 index 0000000000..4720b0b37c --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaOilCracker.java @@ -0,0 +1,465 @@ +/* + * Copyright (c) 2022 SKYCATV587 Permission is hereby granted, free of charge, to any person obtaining a copy of this + * software and associated documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The + * above copyright notice and this permission notice shall be included in all copies or substantial portions of the + * Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package bartworks.common.tileentities.multis.mega; + +import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTWORKS; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.withChannel; +import static gregtech.api.enums.HatchElement.*; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_OIL_CRACKER; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_OIL_CRACKER_ACTIVE; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_OIL_CRACKER_ACTIVE_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_OIL_CRACKER_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.casingTexturePages; +import static gregtech.api.util.GTStructureUtility.buildHatchAdder; +import static gregtech.api.util.GTStructureUtility.ofCoil; +import static gregtech.api.util.GTUtility.filterValidMTEs; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.Nonnull; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; + +import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable; +import com.gtnewhorizon.structurelib.structure.IItemSource; +import com.gtnewhorizon.structurelib.structure.IStructureDefinition; +import com.gtnewhorizon.structurelib.structure.StructureDefinition; + +import bartworks.API.BorosilicateGlass; +import bartworks.common.configs.ConfigHandler; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.HeatingCoilLevel; +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.MTEHatchMultiInput; +import gregtech.api.metatileentity.implementations.MTEHatchOutput; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.recipe.RecipeMaps; +import gregtech.api.recipe.check.CheckRecipeResult; +import gregtech.api.recipe.maps.OilCrackerBackend; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTUtility; +import gregtech.api.util.MultiblockTooltipBuilder; +import gregtech.common.tileentities.machines.IRecipeProcessingAwareHatch; +import gregtech.common.tileentities.machines.MTEHatchInputME; + +public class MTEMegaOilCracker extends MegaMultiBlockBase<MTEMegaOilCracker> implements ISurvivalConstructable { + + private static final int CASING_INDEX = 49; + private static final String STRUCTURE_PIECE_MAIN = "main"; + private static final IStructureDefinition<MTEMegaOilCracker> STRUCTURE_DEFINITION = StructureDefinition + .<MTEMegaOilCracker>builder() + .addShape( + STRUCTURE_PIECE_MAIN, + transpose( + new String[][] { + { " p p ", "ppgggggggggpp", " pgggggggggp ", " pgggpppgggp ", " pgggpMpgggp ", + " pgggpppgggp ", " pgggggggggp ", "ppgggggggggpp", " p p " }, + { " p p ", "pgggggggggggp", " g c c c c g ", " g c c c c g ", " g c c c c g ", + " g c c c c g ", " g c c c c g ", "pgggggggggggp", " p p " }, + { " p p ", "pgggggggggggp", " g c c c c g ", " p c c p ", " p c c c c p ", + " p c c p ", " g c c c c g ", "pgggggggggggp", " p p " }, + { " p p ", "pgggggggggggp", " g c c c c g ", " p c c c c p ", " l c c c c r ", + " p c c c c p ", " g c c c c g ", "pgggggggggggp", " p p " }, + { " p p ", "pgggggggggggp", " g c c c c g ", " p c c p ", " p c c c c p ", + " p c c p ", " g c c c c g ", "pgggggggggggp", " p p " }, + { " p p ", "pgggggggggggp", " g c c c c g ", " g c c c c g ", " g c c c c g ", + " g c c c c g ", " g c c c c g ", "pgggggggggggp", " p p " }, + { "ppmmmm~mmmmpp", "ppppppppppppp", "ppppppppppppp", "ppppppppppppp", "ppppppppppppp", + "ppppppppppppp", "ppppppppppppp", "ppppppppppppp", "ppmmmmmmmmmpp" }, })) + .addElement('c', withChannel("coil", ofCoil(MTEMegaOilCracker::setCoilLevel, MTEMegaOilCracker::getCoilLevel))) + + .addElement('p', ofBlock(GregTechAPI.sBlockCasings4, 1)) + .addElement( + 'l', + InputHatch.withAdder(MTEMegaOilCracker::addLeftHatchToMachineList) + .newAny(CASING_INDEX, 2)) + .addElement( + 'r', + OutputHatch.withAdder(MTEMegaOilCracker::addRightHatchToMachineList) + .newAny(CASING_INDEX, 3)) + .addElement( + 'm', + buildHatchAdder(MTEMegaOilCracker.class).atLeast(Energy.or(ExoticEnergy), Maintenance, InputBus) + .casingIndex(CASING_INDEX) + .dot(1) + .buildAndChain(GregTechAPI.sBlockCasings4, 1)) + .addElement( + 'M', + InputHatch.withAdder(MTEMegaOilCracker::addMiddleInputToMachineList) + .newAny(CASING_INDEX, 4)) + .addElement( + 'g', + withChannel( + "glass", + BorosilicateGlass + .ofBoroGlass((byte) 0, (byte) 1, Byte.MAX_VALUE, (te, t) -> te.glassTier = t, te -> te.glassTier))) + .build(); + private byte glassTier; + private HeatingCoilLevel heatLevel; + protected final List<MTEHatchInput> mMiddleInputHatches = new ArrayList<>(); + protected int mInputOnSide = -1; + protected int mOutputOnSide = -1; + + public MTEMegaOilCracker(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + public MTEMegaOilCracker(String aName) { + super(aName); + } + + @Override + public MultiblockTooltipBuilder createTooltip() { + final MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder(); + tt.addMachineType("Cracker") + .addInfo("Controller block for the Mega Oil Cracking") + .addInfo("Thermally cracks heavy hydrocarbons into lighter fractions") + .addInfo("More efficient than the Chemical Reactor") + .addInfo("Gives different benefits whether it hydro or steam-cracks:") + .addInfo("Hydro - Consumes 20% less Hydrogen and outputs 25% more cracked fluid") + .addInfo("Steam - Outputs 50% more cracked fluid") + .addInfo("(Values compared to cracking in the Chemical Reactor)") + .addInfo("Place the appropriate circuit in the controller or an input bus") + .addInfo( + GTValues.TIER_COLORS[8] + GTValues.VN[8] + + EnumChatFormatting.GRAY + + "-tier glass required for " + + EnumChatFormatting.BLUE + + "Tec" + + EnumChatFormatting.DARK_BLUE + + "Tech" + + EnumChatFormatting.GRAY + + " Laser Hatches.") + .addSeparator() + .beginStructureBlock(13, 7, 9, true) + .addController("Front bottom") + .addStructureInfo("The glass tier limits the Energy Input tier") + .addInfo("Gets 10% EU/t reduction per coil tier, up to a maximum of 50%") + .addEnergyHatch("Hint block", 1) + .addMaintenanceHatch("Hint block", 1) + .addInputHatch("Hint block", 2, 3) + .addOutputHatch("Hint block", 2, 3) + .addInputHatch("Steam/Hydrogen ONLY, Hint block", 4) + .addInputBus("Optional, for programmed circuit automation. Hint block", 1) + .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTWORKS); + return tt; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEMegaOilCracker(this.mName); + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing, + int aColorIndex, boolean aActive, boolean aRedstone) { + if (side == facing) { + if (aActive) return new ITexture[] { casingTexturePages[0][CASING_INDEX], TextureFactory.builder() + .addIcon(OVERLAY_FRONT_OIL_CRACKER_ACTIVE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_OIL_CRACKER_ACTIVE_GLOW) + .extFacing() + .glow() + .build() }; + return new ITexture[] { casingTexturePages[0][CASING_INDEX], TextureFactory.builder() + .addIcon(OVERLAY_FRONT_OIL_CRACKER) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_OIL_CRACKER_GLOW) + .extFacing() + .glow() + .build() }; + } + return new ITexture[] { casingTexturePages[0][CASING_INDEX] }; + } + + @Override + public RecipeMap<OilCrackerBackend> getRecipeMap() { + return RecipeMaps.crackingRecipes; + } + + @Override + protected ProcessingLogic createProcessingLogic() { + return new ProcessingLogic() { + + @Override + @Nonnull + public CheckRecipeResult process() { + this.setEuModifier(1.0F - Math.min(0.1F * (MTEMegaOilCracker.this.heatLevel.getTier() + 1), 0.5F)); + return super.process(); + } + }.setMaxParallel(ConfigHandler.megaMachinesMax); + } + + public HeatingCoilLevel getCoilLevel() { + return this.heatLevel; + } + + public void setCoilLevel(HeatingCoilLevel aCoilLevel) { + this.heatLevel = aCoilLevel; + } + + @Override + public void construct(ItemStack aStack, boolean aHintsOnly) { + this.buildPiece(STRUCTURE_PIECE_MAIN, aStack, aHintsOnly, 6, 6, 0); + } + + @Override + public int survivalConstruct(ItemStack stackSize, int elementBudget, IItemSource source, EntityPlayerMP actor) { + if (this.mMachine) return -1; + int realBudget = elementBudget >= 200 ? elementBudget : Math.min(200, elementBudget * 5); + return this + .survivialBuildPiece(STRUCTURE_PIECE_MAIN, stackSize, 6, 6, 0, realBudget, source, actor, false, true); + } + // -------------- TEC TECH COMPAT ---------------- + + @Override + public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) { + this.glassTier = 0; + this.mInputOnSide = -1; + this.mOutputOnSide = -1; + this.mMiddleInputHatches.clear(); + + if (!this.checkPiece(STRUCTURE_PIECE_MAIN, 6, 6, 0) || this.mMaintenanceHatches.size() != 1) return false; + + if (this.glassTier < 8) { + for (int i = 0; i < this.mExoticEnergyHatches.size(); ++i) { + MTEHatch hatch = this.mExoticEnergyHatches.get(i); + if (hatch.getConnectionType() == MTEHatch.ConnectionType.LASER) { + return false; + } + if (this.glassTier < hatch.mTier) { + return false; + } + } + for (int i = 0; i < this.mEnergyHatches.size(); ++i) { + if (this.glassTier < this.mEnergyHatches.get(i).mTier) { + return false; + } + } + } + + return true; + } + + private boolean addLeftHatchToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + if (aTileEntity == null) { + return false; + } + IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null) { + return false; + } + if (aMetaTileEntity instanceof MTEHatchInput) { + if (this.mInputOnSide == 1) { + return false; + } + this.mInputOnSide = 0; + this.mOutputOnSide = 1; + MTEHatchInput tHatch = (MTEHatchInput) aMetaTileEntity; + tHatch.updateTexture(aBaseCasingIndex); + tHatch.mRecipeMap = this.getRecipeMap(); + return this.mInputHatches.add(tHatch); + } + if (aMetaTileEntity instanceof MTEHatchOutput) { + if (this.mOutputOnSide == 1) { + return false; + } + this.mInputOnSide = 1; + this.mOutputOnSide = 0; + MTEHatchOutput tHatch = (MTEHatchOutput) aMetaTileEntity; + tHatch.updateTexture(aBaseCasingIndex); + return this.mOutputHatches.add(tHatch); + } + return false; + } + + private boolean addRightHatchToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + if (aTileEntity == null) { + return false; + } + IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null) { + return false; + } + if (aMetaTileEntity instanceof MTEHatchInput) { + if (this.mInputOnSide == 0) { + return false; + } + this.mInputOnSide = 1; + this.mOutputOnSide = 0; + MTEHatchInput tHatch = (MTEHatchInput) aMetaTileEntity; + tHatch.updateTexture(aBaseCasingIndex); + tHatch.mRecipeMap = this.getRecipeMap(); + return this.mInputHatches.add(tHatch); + } + if (aMetaTileEntity instanceof MTEHatchOutput) { + if (this.mOutputOnSide == 0) { + return false; + } + this.mInputOnSide = 0; + this.mOutputOnSide = 1; + MTEHatchOutput tHatch = (MTEHatchOutput) aMetaTileEntity; + tHatch.updateTexture(aBaseCasingIndex); + return this.mOutputHatches.add(tHatch); + } + return false; + } + + private boolean addMiddleInputToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + if (aTileEntity == null) { + return false; + } + IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null) { + return false; + } + if (aMetaTileEntity instanceof MTEHatchInput tHatch) { + tHatch.updateTexture(aBaseCasingIndex); + tHatch.mRecipeMap = this.getRecipeMap(); + return this.mMiddleInputHatches.add(tHatch); + } + return false; + } + + @Override + public ArrayList<FluidStack> getStoredFluids() { + final ArrayList<FluidStack> rList = new ArrayList<>(); + Map<Fluid, FluidStack> inputsFromME = new HashMap<>(); + for (final MTEHatchInput tHatch : filterValidMTEs(mInputHatches)) { + tHatch.mRecipeMap = getRecipeMap(); + if (tHatch instanceof MTEHatchInputME meHatch) { + for (FluidStack tFluid : meHatch.getStoredFluids()) { + if (tFluid != null && !getRecipeMap().getBackend() + .isValidCatalystFluid(tFluid)) { + inputsFromME.put(tFluid.getFluid(), tFluid); + } + } + } else if (tHatch instanceof MTEHatchMultiInput) { + for (final FluidStack tFluid : ((MTEHatchMultiInput) tHatch).getStoredFluid()) { + if (tFluid != null && !getRecipeMap().getBackend() + .isValidCatalystFluid(tFluid)) { + rList.add(tFluid); + } + } + } else { + if (tHatch.getFillableStack() != null) { + if (!getRecipeMap().getBackend() + .isValidCatalystFluid(tHatch.getFillableStack())) rList.add(tHatch.getFillableStack()); + } + } + } + for (final MTEHatchInput tHatch : filterValidMTEs(mMiddleInputHatches)) { + tHatch.mRecipeMap = getRecipeMap(); + if (tHatch instanceof MTEHatchInputME meHatch) { + for (FluidStack tFluid : meHatch.getStoredFluids()) { + if (tFluid != null && getRecipeMap().getBackend() + .isValidCatalystFluid(tFluid)) { + inputsFromME.put(tFluid.getFluid(), tFluid); + } + } + } else if (tHatch instanceof MTEHatchMultiInput) { + for (final FluidStack tFluid : ((MTEHatchMultiInput) tHatch).getStoredFluid()) { + if (tFluid != null && getRecipeMap().getBackend() + .isValidCatalystFluid(tFluid)) { + rList.add(tFluid); + } + } + } else { + if (tHatch.getFillableStack() != null) { + final FluidStack tStack = tHatch.getFillableStack(); + if (getRecipeMap().getBackend() + .isValidCatalystFluid(tStack)) { + rList.add(tStack); + } + } + } + } + if (!inputsFromME.isEmpty()) { + rList.addAll(inputsFromME.values()); + } + return rList; + } + + @Override + public IStructureDefinition<MTEMegaOilCracker> getStructureDefinition() { + return STRUCTURE_DEFINITION; + } + + @Override + public boolean supportsBatchMode() { + return true; + } + + @Override + public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer, + float aX, float aY, float aZ) { + if (aPlayer.isSneaking()) { + batchMode = !batchMode; + if (batchMode) { + GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOn")); + } else { + GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOff")); + } + return true; + } + return false; + } + + @Override + public boolean supportsVoidProtection() { + return true; + } + + @Override + protected void startRecipeProcessing() { + for (MTEHatchInput hatch : filterValidMTEs(mMiddleInputHatches)) { + if (hatch instanceof IRecipeProcessingAwareHatch aware) { + aware.startRecipeProcessing(); + } + } + super.startRecipeProcessing(); + } + + @Override + protected void endRecipeProcessing() { + super.endRecipeProcessing(); + for (MTEHatchInput hatch : filterValidMTEs(mMiddleInputHatches)) { + if (hatch instanceof IRecipeProcessingAwareHatch aware) { + setResultIfFailure(aware.endRecipeProcessing(this)); + } + } + } +} diff --git a/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaVacuumFreezer.java b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaVacuumFreezer.java new file mode 100644 index 0000000000..e47782d980 --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/multis/mega/MTEMegaVacuumFreezer.java @@ -0,0 +1,533 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.multis.mega; + +import static bartworks.util.BWTooltipReference.MULTIBLOCK_ADDED_BY_BARTWORKS; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.onElementPass; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose; +import static gregtech.api.enums.HatchElement.*; +import static gregtech.api.enums.HatchElement.ExoticEnergy; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_VACUUM_FREEZER; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_VACUUM_FREEZER_ACTIVE; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_VACUUM_FREEZER_ACTIVE_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_VACUUM_FREEZER_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.casingTexturePages; +import static gregtech.api.util.GTStructureUtility.buildHatchAdder; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Optional; + +import javax.annotation.Nonnull; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; + +import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable; +import com.gtnewhorizon.structurelib.structure.IItemSource; +import com.gtnewhorizon.structurelib.structure.IStructureDefinition; +import com.gtnewhorizon.structurelib.structure.StructureDefinition; + +import bartworks.common.configs.ConfigHandler; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.Materials; +import gregtech.api.enums.MaterialsUEVplus; +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.MTEHatchInput; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.recipe.RecipeMaps; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; +import gregtech.api.util.MultiblockTooltipBuilder; +import gregtech.api.util.OverclockCalculator; +import gregtech.api.util.shutdown.ShutDownReasonRegistry; +import gregtech.common.blocks.BlockCasingsAbstract; + +public class MTEMegaVacuumFreezer extends MegaMultiBlockBase<MTEMegaVacuumFreezer> implements ISurvivalConstructable { + + public MTEMegaVacuumFreezer(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + public MTEMegaVacuumFreezer(String aName) { + super(aName); + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEMegaVacuumFreezer(this.mName); + } + + private int mCasingFrostProof = 0; + private int mTier = 1; + + private static class SubspaceCoolingFluid { + + public Materials material; + public int perfectOverclocks; + // Consumption per second of runtime + public long amount; + + public SubspaceCoolingFluid(Materials material, int perfectOverclocks, long amount) { + this.material = material; + this.perfectOverclocks = perfectOverclocks; + this.amount = amount; + } + + public FluidStack getStack() { + FluidStack stack = material.getFluid(amount); + // FUCK THIS FUCK THIS FUCK THIS + if (stack == null) { + return material.getMolten(amount); + } + return stack; + } + } + + private static final ArrayList<SubspaceCoolingFluid> SUBSPACE_COOLING_FLUIDS = new ArrayList<>( + Arrays.asList( + new SubspaceCoolingFluid(MaterialsUEVplus.SpaceTime, 1, 7500), + new SubspaceCoolingFluid(MaterialsUEVplus.Space, 2, 5000), + new SubspaceCoolingFluid(MaterialsUEVplus.Eternity, 3, 2500))); + + private SubspaceCoolingFluid currentCoolingFluid = null; + + private static final int CASING_INDEX = 17; + private static final int CASING_INDEX_T2 = ((BlockCasingsAbstract) GregTechAPI.sBlockCasings8).getTextureIndex(14); + private static final String STRUCTURE_PIECE_MAIN = "main"; + private static final String STRUCTURE_PIECE_MAIN_T2 = "main_t2"; + + private static final String[][] structure = transpose( + new String[][] { + { "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", + "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", + "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" }, + { "AAAAAAA~AAAAAAA", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", + "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", + "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAA" } }); + private static final String[][] structure_tier2 = new String[][] { + { "AAAAAAAAAAAAAAA", "ABBBBBBBBBBBBBA", "ABAAAAAAAAAAABA", "ABABBBBBBBBBABA", "ABABAAAAAAABABA", + "ABABABBBBBABABA", "ABABABAAABABABA", "ABABABA~ABABABA", "ABABABAAABABABA", "ABABABBBBBABABA", + "ABABAAAAAAABABA", "ABABBBBBBBBBABA", "ABAAAAAAAAAAABA", "ABBBBBBBBBBBBBA", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "B B", "B B", "B B", "B B", + "B B", "B B", "B B", "B B", "B B", + "B B", "B B", "B B", "B B", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "B B", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "B B", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "B B", "A A", "B B", "B B", + "B B", "B B", "B B", "B B", "B B", + "B B", "B B", "A A", "B B", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "B B", "A A", "B B", "A A", + "A A", "A A", "A A", "A A", "A A", + "A A", "B B", "A A", "B B", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "B B", "A A", "B B", "A A", + "B B", "B B", "B B", "B B", "B B", + "A A", "B B", "A A", "B B", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "B B", "A A", "B B", "A A", + "B B", "A A", "A A", "A A", "B B", + "A A", "B B", "A A", "B B", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "B B", "A A", "B B", "A A", + "B B", "A A", "A A", "A A", "B B", + "A A", "B B", "A A", "B B", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "B B", "A A", "B B", "A A", + "B B", "A A", "A A", "A A", "B B", + "A A", "B B", "A A", "B B", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "B B", "A A", "B B", "A A", + "B B", "B B", "B B", "B B", "B B", + "A A", "B B", "A A", "B B", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "B B", "A A", "B B", "A A", + "A A", "A A", "A A", "A A", "A A", + "A A", "B B", "A A", "B B", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "B B", "A A", "B B", "B B", + "B B", "B B", "B B", "B B", "B B", + "B B", "B B", "A A", "B B", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "B B", "A A", "A A", "A A", + "A A", "A A", "A A", "A A", "A A", + "A A", "A A", "A A", "B B", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "B B", "B B", "B B", "B B", + "B B", "B B", "B B", "B B", "B B", + "B B", "B B", "B B", "B B", "AAAAAAAAAAAAAAA" }, + { "AAAAAAAAAAAAAAA", "ABBBBBBBBBBBBBA", "ABAAAAAAAAAAABA", "ABABBBBBBBBBABA", "ABABAAAAAAABABA", + "ABABABBBBBABABA", "ABABABAAABABABA", "ABABABAAABABABA", "ABABABAAABABABA", "ABABABBBBBABABA", + "ABABAAAAAAABABA", "ABABBBBBBBBBABA", "ABAAAAAAAAAAABA", "ABBBBBBBBBBBBBA", "AAAAAAAAAAAAAAA" } }; + + private static final IStructureDefinition<MTEMegaVacuumFreezer> STRUCTURE_DEFINITION = StructureDefinition + .<MTEMegaVacuumFreezer>builder() + .addShape(STRUCTURE_PIECE_MAIN, structure) + .addShape(STRUCTURE_PIECE_MAIN_T2, structure_tier2) + .addElement( + 'A', + buildHatchAdder(MTEMegaVacuumFreezer.class) + .atLeast(Energy.or(ExoticEnergy), InputHatch, InputBus, OutputHatch, OutputBus, Maintenance) + .casingIndex(CASING_INDEX) + .dot(1) + .buildAndChain(onElementPass(x -> x.mCasingFrostProof++, ofBlock(GregTechAPI.sBlockCasings2, 1)))) + // Infinity Cooled Casing + .addElement('B', ofBlock(GregTechAPI.sBlockCasings8, 14)) + .build(); + + @Override + protected MultiblockTooltipBuilder createTooltip() { + MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder(); + tt.addMachineType("Vacuum Freezer") + .addInfo("Controller Block for the Mega Vacuum Freezer") + .addInfo("Cools hot ingots and cells") + .addSeparator() + .addInfo("Upgrade to Tier 2 to unlock " + EnumChatFormatting.LIGHT_PURPLE + "Subspace Cooling.") + .addInfo( + "To activate " + EnumChatFormatting.LIGHT_PURPLE + + "Subspace Cooling " + + EnumChatFormatting.GRAY + + "supply a coolant while running recipes.") + .addInfo( + EnumChatFormatting.RED + "7500 L/s " + + EnumChatFormatting.DARK_PURPLE + + "Molten SpaceTime" + + EnumChatFormatting.GRAY + + ": " + + EnumChatFormatting.RED + + "1" + + EnumChatFormatting.GRAY + + " perfect overclock.") + .addInfo( + EnumChatFormatting.RED + "5000 L/s " + + EnumChatFormatting.DARK_PURPLE + + "Spatially Enlarged Fluid" + + EnumChatFormatting.GRAY + + ": " + + EnumChatFormatting.RED + + "2" + + EnumChatFormatting.GRAY + + " perfect overclocks.") + .addInfo( + EnumChatFormatting.RED + "2500 L/s " + + EnumChatFormatting.DARK_PURPLE + + "Molten Eternity" + + EnumChatFormatting.GRAY + + ": " + + EnumChatFormatting.RED + + "3" + + EnumChatFormatting.GRAY + + " perfect overclocks.") + .addSeparator() + .addInfo( + EnumChatFormatting.LIGHT_PURPLE + "Reinforcing the structure allows the injection of exotic coolants,") + .addInfo( + EnumChatFormatting.LIGHT_PURPLE + + "enabling the capture of heat energy in miniature tears in spacetime,") + .addInfo(EnumChatFormatting.LIGHT_PURPLE + "massively increasing the efficiency of the cooling process.") + .addSeparator() + .beginStructureBlock(15, 15, 15, true) + .addController("Front center") + .addEnergyHatch("Any Frost Proof Machine Casing", 1) + .addMaintenanceHatch("Any Frost Proof Machine Casing", 1) + .addInputHatch("Any Frost Proof Machine Casing", 1) + .addOutputHatch("Any Frost Proof Machine Casing", 1) + .addInputBus("Any Frost Proof Machine Casing", 1) + .addOutputBus("Any Frost Proof Machine Casing", 1) + .addStructureInfo( + EnumChatFormatting.BLUE + "Base Multi (Tier " + + EnumChatFormatting.DARK_PURPLE + + 1 + + EnumChatFormatting.BLUE + + "):") + .addCasingInfoMinColored( + "Frost Proof Machine Casing", + EnumChatFormatting.GRAY, + 800, + EnumChatFormatting.GOLD, + false) + .addStructureInfo( + EnumChatFormatting.BLUE + "Tier " + + EnumChatFormatting.DARK_PURPLE + + 2 + + EnumChatFormatting.BLUE + + " (Upgrades from Tier " + + EnumChatFormatting.DARK_PURPLE + + 1 + + EnumChatFormatting.BLUE + + "):") + .addCasingInfoMinColored( + "Frost Proof Machine Casing", + EnumChatFormatting.GRAY, + 700, + EnumChatFormatting.GOLD, + false) + .addCasingInfoExactlyColored( + "Infinity Cooled Casing", + EnumChatFormatting.GRAY, + 384, + EnumChatFormatting.GOLD, + false) + .toolTipFinisher(MULTIBLOCK_ADDED_BY_BARTWORKS); + return tt; + } + + @Override + public IStructureDefinition<MTEMegaVacuumFreezer> getStructureDefinition() { + return STRUCTURE_DEFINITION; + } + + @Override + public void construct(ItemStack aStack, boolean aHintsOnly) { + if (aStack.stackSize == 1) { + this.buildPiece(STRUCTURE_PIECE_MAIN, aStack, aHintsOnly, 7, 7, 0); + } else { + this.buildPiece(STRUCTURE_PIECE_MAIN_T2, aStack, aHintsOnly, 7, 7, 0); + } + } + + @Override + public int survivalConstruct(ItemStack stackSize, int elementBudget, IItemSource source, EntityPlayerMP actor) { + if (this.mMachine) return -1; + int realBudget = elementBudget >= 200 ? elementBudget : Math.min(200, elementBudget * 5); + if (stackSize.stackSize == 1) { + return this + .survivialBuildPiece(STRUCTURE_PIECE_MAIN, stackSize, 7, 7, 0, realBudget, source, actor, false, true); + } else { + return this.survivialBuildPiece( + STRUCTURE_PIECE_MAIN_T2, + stackSize, + 7, + 7, + 0, + realBudget, + source, + actor, + false, + true); + } + } + + @Override + public RecipeMap<?> getRecipeMap() { + return RecipeMaps.vacuumFreezerRecipes; + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + if (!aNBT.hasKey(BATCH_MODE_NBT_KEY)) { + this.batchMode = aNBT.getBoolean("mUseMultiparallelMode"); + } + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + } + + @Override + public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer, + float aX, float aY, float aZ) { + if (aPlayer.isSneaking()) { + this.batchMode = !this.batchMode; + if (this.batchMode) { + GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOn")); + } else { + GTUtility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("misc.BatchModeTextOff")); + } + return true; + } + return false; + } + + public SubspaceCoolingFluid findSubspaceCoolingFluid() { + // Loop over all hatches and find the first match with a valid fluid + for (MTEHatchInput hatch : mInputHatches) { + Optional<SubspaceCoolingFluid> fluid = SUBSPACE_COOLING_FLUIDS.stream() + .filter(candidate -> drain(hatch, candidate.getStack(), false)) + .findFirst(); + if (fluid.isPresent()) return fluid.get(); + } + return null; + } + + @Override + protected ProcessingLogic createProcessingLogic() { + return new ProcessingLogic() { + + @Nonnull + @Override + protected OverclockCalculator createOverclockCalculator(@Nonnull GTRecipe recipe) { + // Check if the freezer is T2 + if (mTier == 1) return super.createOverclockCalculator(recipe); + + // First try to detect the current fluid used for subspace cooling. + currentCoolingFluid = findSubspaceCoolingFluid(); + + return super.createOverclockCalculator(recipe) + .setMachineHeat(currentCoolingFluid == null ? 0 : currentCoolingFluid.perfectOverclocks * 1800) + .setRecipeHeat(0) + .setHeatOC(true) + .setHeatDiscount(false); + } + }.setMaxParallel(ConfigHandler.megaMachinesMax); + } + + @Override + protected void runMachine(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.runMachine(aBaseMetaTileEntity, aTick); + // Every second while running, consume subspace coolant fluid + if (mMaxProgresstime > 0 && aTick % 20 == 0) { + // Subspace cooling only allowed for T2 freezer + if (mTier == 2) { + // Try to drain the coolant fluid if it exists. If failed, stop the machine with an error + if (this.currentCoolingFluid != null) { + FluidStack fluid = this.currentCoolingFluid.getStack(); + for (MTEHatchInput hatch : mInputHatches) { + if (drain(hatch, fluid, false)) { + drain(hatch, fluid, true); + return; + } + } + // If we exited this loop without returning from the function, no matching fluid was found, so + // stop the machine - we ran out of coolant + stopMachine(ShutDownReasonRegistry.outOfFluid(fluid)); + } + } + } + } + + // -------------- TEC TECH COMPAT ---------------- + + @Override + public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) { + this.mCasingFrostProof = 0; + this.mTier = 1; + // If check for T1 fails, also do a check for T2 structure + if (!this.checkPiece(STRUCTURE_PIECE_MAIN, 7, 7, 0)) { + // Reset mCasing in between checks, so they don't count again + this.mCasingFrostProof = 0; + if (!this.checkPiece(STRUCTURE_PIECE_MAIN_T2, 7, 7, 0)) { + return false; + } + // Structure is Tier 2 + this.mTier = 2; + } + return this.mMaintenanceHatches.size() == 1 && this.mCasingFrostProof >= 700; + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing, + int aColorIndex, boolean aActive, boolean aRedstone) { + ITexture[] rTexture; + if (side == facing) { + if (aActive) { + rTexture = new ITexture[] { casingTexturePages[0][17], TextureFactory.builder() + .addIcon(OVERLAY_FRONT_VACUUM_FREEZER_ACTIVE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_VACUUM_FREEZER_ACTIVE_GLOW) + .extFacing() + .glow() + .build() }; + } else { + rTexture = new ITexture[] { casingTexturePages[0][17], TextureFactory.builder() + .addIcon(OVERLAY_FRONT_VACUUM_FREEZER) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_VACUUM_FREEZER_GLOW) + .extFacing() + .glow() + .build() }; + } + } else { + rTexture = new ITexture[] { casingTexturePages[0][17] }; + } + return rTexture; + } + + @Override + public String[] getInfoData() { + ArrayList<String> info = new ArrayList<>(Arrays.asList(super.getInfoData())); + info.add("Tier: " + mTier); + if (mTier == 2) { + if (currentCoolingFluid != null) { + info.add( + "Subspace cooling: " + EnumChatFormatting.GREEN + + "Active (" + + currentCoolingFluid.getStack() + .getLocalizedName() + + ")"); + } else { + info.add("Subspace cooling: " + EnumChatFormatting.RED + "Inactive"); + } + } + return info.toArray(new String[] {}); + } + + @Override + public boolean supportsBatchMode() { + return true; + } + + @Override + public boolean supportsVoidProtection() { + return true; + } +} diff --git a/src/main/java/bartworks/common/tileentities/multis/mega/MegaMultiBlockBase.java b/src/main/java/bartworks/common/tileentities/multis/mega/MegaMultiBlockBase.java new file mode 100644 index 0000000000..bac811ede8 --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/multis/mega/MegaMultiBlockBase.java @@ -0,0 +1,212 @@ +package bartworks.common.tileentities.multis.mega; + +import static gregtech.api.util.GTUtility.filterValidMTEs; + +import java.util.Arrays; + +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; + +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.structure.AutoPlaceEnvironment; +import com.gtnewhorizon.structurelib.structure.IStructureElement; + +import bartworks.util.BWTooltipReference; +import bartworks.util.BWUtil; +import gregtech.api.logic.ProcessingLogic; +import gregtech.api.metatileentity.implementations.MTEExtendedPowerMultiBlockBase; +import gregtech.api.metatileentity.implementations.MTEHatch; +import gregtech.api.metatileentity.implementations.MTEHatchEnergy; +import gregtech.api.metatileentity.implementations.MTEHatchMuffler; +import gregtech.api.util.GTUtility; + +public abstract class MegaMultiBlockBase<T extends MegaMultiBlockBase<T>> extends MTEExtendedPowerMultiBlockBase<T> { + + protected MegaMultiBlockBase(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + public MegaMultiBlockBase(String aName) { + super(aName); + } + + protected String[] getExtendedInfoData() { + return new String[0]; + } + + protected long[] getCurrentInfoData() { + long storedEnergy = 0, maxEnergy = 0; + for (MTEHatch hatch : this.getExoticAndNormalEnergyHatchList()) { + storedEnergy += hatch.getBaseMetaTileEntity() + .getStoredEU(); + maxEnergy += hatch.getBaseMetaTileEntity() + .getEUCapacity(); + } + return new long[] { storedEnergy, maxEnergy }; + } + + @Override + public String[] getInfoData() { + int mPollutionReduction = 0; + + for (MTEHatchMuffler tHatch : filterValidMTEs(mMufflerHatches)) { + mPollutionReduction = Math.max(tHatch.calculatePollutionReduction(100), mPollutionReduction); + } + + long[] ttHatches = this.getCurrentInfoData(); + long storedEnergy = ttHatches[0]; + long maxEnergy = ttHatches[1]; + + for (MTEHatchEnergy tHatch : filterValidMTEs(mEnergyHatches)) { + storedEnergy += tHatch.getBaseMetaTileEntity() + .getStoredEU(); + maxEnergy += tHatch.getBaseMetaTileEntity() + .getEUCapacity(); + } + + long nominalV = this.getMaxInputEu(); + String tName = BWUtil.getTierNameFromVoltage(nominalV); + if ("MAX+".equals(tName)) tName = EnumChatFormatting.OBFUSCATED + "MAX+"; + + String[] extendedInfo = this.getExtendedInfoData(); + + String[] baseInfo = { + StatCollector.translateToLocal("GT5U.multiblock.Progress") + ": " + + EnumChatFormatting.GREEN + + GTUtility.formatNumbers(this.mProgresstime / 20) + + EnumChatFormatting.RESET + + " s / " + + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(this.mMaxProgresstime / 20) + + EnumChatFormatting.RESET + + " s", + StatCollector.translateToLocal("GT5U.multiblock.energy") + ": " + + EnumChatFormatting.GREEN + + GTUtility.formatNumbers(storedEnergy) + + EnumChatFormatting.RESET + + " EU / " + + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(maxEnergy) + + EnumChatFormatting.RESET + + " EU", + StatCollector.translateToLocal("GT5U.multiblock.usage") + ": " + + EnumChatFormatting.RED + + GTUtility.formatNumbers(-this.lEUt) + + EnumChatFormatting.RESET + + " EU/t", + StatCollector.translateToLocal("GT5U.multiblock.mei") + ": " + + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(this.getMaxInputVoltage()) + + EnumChatFormatting.RESET + + " EU/t(*" + + GTUtility.formatNumbers(this.getMaxInputAmps()) + + "A) = " + + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(nominalV) + + EnumChatFormatting.RESET, + StatCollector.translateToLocal("GT5U.machines.tier") + ": " + + EnumChatFormatting.YELLOW + + tName + + EnumChatFormatting.RESET, + StatCollector.translateToLocal("GT5U.multiblock.problems") + ": " + + EnumChatFormatting.RED + + (this.getIdealStatus() - this.getRepairStatus()) + + EnumChatFormatting.RESET + + " " + + StatCollector.translateToLocal("GT5U.multiblock.efficiency") + + ": " + + EnumChatFormatting.YELLOW + + this.mEfficiency / 100.0F + + EnumChatFormatting.RESET + + " %", + StatCollector.translateToLocal("GT5U.multiblock.pollution") + ": " + + EnumChatFormatting.GREEN + + mPollutionReduction + + EnumChatFormatting.RESET + + " %" }; + + String[] combinedInfo = Arrays.copyOf(baseInfo, baseInfo.length + extendedInfo.length + 1); + + System.arraycopy(extendedInfo, 0, combinedInfo, baseInfo.length, extendedInfo.length); + + combinedInfo[combinedInfo.length - 1] = BWTooltipReference.BW; + + return combinedInfo; + } + + @Override + public boolean isCorrectMachinePart(ItemStack itemStack) { + return true; + } + + @Override + public int getDamageToComponent(ItemStack itemStack) { + return 0; + } + + @Override + public boolean explodesOnComponentBreak(ItemStack itemStack) { + return false; + } + + @Override + public int getMaxEfficiency(ItemStack itemStack) { + return 10000; + } + + @Override + protected void setProcessingLogicPower(ProcessingLogic logic) { + logic.setAvailableVoltage(this.getMaxInputEu()); + logic.setAvailableAmperage(1); + } + + protected static class StructureElementAirNoHint<T> implements IStructureElement<T> { + + private static final StructureElementAirNoHint<?> INSTANCE = new StructureElementAirNoHint<>(); + + @SuppressWarnings("unchecked") + public static <T> IStructureElement<T> getInstance() { + return (IStructureElement<T>) INSTANCE; + } + + private StructureElementAirNoHint() {} + + @Override + public boolean check(T o, World world, int x, int y, int z) { + return world.isAirBlock(x, y, z); + } + + @Override + public boolean spawnHint(T o, World world, int x, int y, int z, ItemStack trigger) { + if (world.blockExists(x, y, z) && !world.isAirBlock(x, y, z)) + // hint if this is obstructed. in case *someone* ever finish the transparent rendering + StructureLibAPI + .hintParticle(world, x, y, z, StructureLibAPI.getBlockHint(), StructureLibAPI.HINT_BLOCK_META_AIR); + return true; + } + + @Override + public boolean placeBlock(T o, World world, int x, int y, int z, ItemStack trigger) { + world.setBlockToAir(x, y, z); + return true; + } + + @Override + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { + return BlocksToPlace.createEmpty(); + } + + @Override + public PlaceResult survivalPlaceBlock(T o, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { + if (this.check(o, world, x, y, z)) return PlaceResult.SKIP; + if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, env.getActor())) return PlaceResult.REJECT; + world.setBlock(x, y, z, Blocks.air, 0, 2); + return PlaceResult.ACCEPT; + } + } +} diff --git a/src/main/java/bartworks/common/tileentities/tiered/GT_MetaTileEntity_RadioHatch.java b/src/main/java/bartworks/common/tileentities/tiered/GT_MetaTileEntity_RadioHatch.java new file mode 100644 index 0000000000..8e752711ea --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/tiered/GT_MetaTileEntity_RadioHatch.java @@ -0,0 +1,494 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.tiered; + +import static gregtech.api.enums.GTValues.ticksBetweenSounds; + +import java.util.Collections; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizons.modularui.api.ModularUITextures; +import com.gtnewhorizons.modularui.api.drawable.ItemDrawable; +import com.gtnewhorizons.modularui.api.drawable.shapes.Rectangle; +import com.gtnewhorizons.modularui.api.math.Alignment; +import com.gtnewhorizons.modularui.api.math.Color; +import com.gtnewhorizons.modularui.api.math.Pos2d; +import com.gtnewhorizons.modularui.api.math.Size; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.common.widget.ButtonWidget; +import com.gtnewhorizons.modularui.common.widget.DrawableWidget; +import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; +import com.gtnewhorizons.modularui.common.widget.ProgressBar; +import com.gtnewhorizons.modularui.common.widget.ProgressBar.Direction; +import com.gtnewhorizons.modularui.common.widget.TextWidget; +import com.gtnewhorizons.modularui.common.widget.textfield.NumericWidget; + +import bartworks.API.modularUI.BWUITextures; +import bartworks.API.recipe.BartWorksRecipeMaps; +import bartworks.MainMod; +import bartworks.util.BWColorUtil; +import bartworks.util.BWTooltipReference; +import bartworks.util.MathUtils; +import gregtech.api.enums.Materials; +import gregtech.api.enums.Textures; +import gregtech.api.gui.modularui.GTUIInfos; +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.gui.modularui.GUITextureSet; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.modularui.IAddGregtechLogo; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.interfaces.tileentity.RecipeMapWorkable; +import gregtech.api.metatileentity.BaseMetaTileEntity; +import gregtech.api.metatileentity.implementations.MTEHatch; +import gregtech.api.objects.ItemData; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; +import gregtech.common.items.IDMetaTool01; +import gregtech.common.items.MetaGeneratedTool01; + +public class GT_MetaTileEntity_RadioHatch extends MTEHatch implements RecipeMapWorkable, IAddGregtechLogo { + + private final int cap; + public int sievert; + private long timer = 1; + private long decayTime = 1; + private short[] colorForGUI = { 0x02, 0x02, 0x02 }; + private byte mass; + private String material; + private byte coverage; + private ItemStack lastUsedItem = null; + private boolean lastFail = false; + private GTRecipe lastRecipe = null; + + public GT_MetaTileEntity_RadioHatch(int aID, String aName, String aNameRegional, int aTier) { + super( + aID, + aName, + aNameRegional, + aTier, + 1, + new String[] { StatCollector.translateToLocal("tooltip.tile.radhatch.0.name"), + StatCollector.translateToLocal("tooltip.tile.tiereddsc.3.name") + " " + + (aTier - 2) + + " " + + (aTier - 2 >= 2 ? StatCollector.translateToLocal("tooltip.bw.kg.1.name") + : StatCollector.translateToLocal("tooltip.bw.kg.0.name")), + StatCollector.translateToLocal("tooltip.tile.radhatch.1.name"), + BWTooltipReference.ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS.get() }); + this.cap = aTier - 2; + } + + public GT_MetaTileEntity_RadioHatch(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 1, aDescription, aTextures); + this.cap = aTier - 2; + } + + public int getSievert() { + return this.sievert - MathUtils.ceilInt(this.sievert / 100f * this.coverage); + } + + public short[] getColorForGUI() { + if (this.colorForGUI != null) return this.colorForGUI; + return this.colorForGUI = new short[] { 0xFA, 0xFA, 0xFF }; + } + + public byte getMass() { + return this.mass; + } + + public byte getCoverage() { + return this.coverage; + } + + public void setCoverage(short coverage) { + byte nu; + if (coverage > 100) nu = 100; + else if (coverage < 0) nu = 0; + else nu = (byte) coverage; + this.coverage = nu; + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.of(Textures.BlockIcons.OVERLAY_PIPE_IN) }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.of(Textures.BlockIcons.OVERLAY_PIPE_IN) }; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) { + return new GT_MetaTileEntity_RadioHatch(this.mName, this.mTier, this.mDescriptionArray, this.mTextures); + } + + @Override + public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { + GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); + return true; + } + + public void updateSlots() { + if (this.mInventory[0] != null && this.mInventory[0].stackSize <= 0) this.mInventory[0] = null; + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) { + BaseMetaTileEntity myMetaTileEntity = (BaseMetaTileEntity) this.getBaseMetaTileEntity(); + if (myMetaTileEntity.isServerSide()) { + + if (this.mass > 0) { + ++this.timer; + } + + if (this.mass > 0 && (this.decayTime == 0 || this.decayTime > 0 && this.timer % this.decayTime == 0)) { + this.mass--; + if (this.mass == 0) { + this.material = StatCollector.translateToLocal("tooltip.bw.empty.name"); + this.sievert = 0; + } + this.timer = 1; + } + + if (myMetaTileEntity.mTickTimer > myMetaTileEntity.mLastSoundTick + ticksBetweenSounds + && this.sievert > 0) { + this.sendLoopStart((byte) 1); + myMetaTileEntity.mLastSoundTick = myMetaTileEntity.mTickTimer; + } + + if (this.mass == 0) { + ItemStack lStack = this.mInventory[0]; + + if (lStack == null) { + this.colorForGUI = new short[] { 0x37, 0x37, 0x37 }; + return; + } + ItemData itemData = GTOreDictUnificator.getAssociation(lStack); + if (itemData != null) { + Materials mat = itemData.mMaterial.mMaterial; + this.colorForGUI = new short[] { mat.getRGBA()[0], mat.getRGBA()[1], mat.getRGBA()[2] }; + } else { + this.colorForGUI = new short[] { 0x37, 0x37, 0x37 }; + } + + if (this.lastFail && GTUtility.areStacksEqual(this.lastUsedItem, lStack, true)) { + return; + } + + if (!this.lastFail && this.lastUsedItem != null && this.lastRecipe != null) { + if (GTUtility.areStacksEqual(this.lastUsedItem, lStack, true)) { + this.mass = (byte) this.lastRecipe.mDuration; + this.decayTime = this.lastRecipe.mSpecialValue; + this.sievert = this.lastRecipe.mEUt; + this.material = this.lastUsedItem.getDisplayName(); + lStack.stackSize--; + this.updateSlots(); + } else { + this.lastRecipe = null; + } + } + + if (this.lastRecipe == null || this.lastFail) { + this.lastRecipe = BartWorksRecipeMaps.radioHatchRecipes.findRecipe( + this.getBaseMetaTileEntity(), + false, + Integer.MAX_VALUE - 7, + null, + this.mInventory[0]); + if (this.lastRecipe == null) { + this.lastFail = true; + this.lastUsedItem = this.mInventory[0] == null ? null : this.mInventory[0].copy(); + } else { + if (this.lastRecipe.mDuration > this.cap) { + this.lastFail = true; + this.lastUsedItem = this.mInventory[0].copy(); + return; + } + this.lastFail = false; + this.lastUsedItem = this.mInventory[0].copy(); + this.mass = (byte) this.lastRecipe.mDuration; + this.decayTime = this.lastRecipe.mSpecialValue; + this.sievert = this.lastRecipe.mEUt; + this.material = lStack.getDisplayName(); + lStack.stackSize--; + this.updateSlots(); + } + } + } + } + } + + @Override + public boolean isGivingInformation() { + return true; + } + + @Override + public String[] getInfoData() { + if (this.sievert != 0) return new String[] { + StatCollector.translateToLocal("tooltip.tile.radhatch.2.name") + " " + + StatCollector.translateToLocal(this.material), + StatCollector.translateToLocal("tooltip.tile.radhatch.3.name") + " " + this.sievert, + StatCollector.translateToLocal("tooltip.tile.radhatch.4.name") + " " + this.mass, + StatCollector.translateToLocal("tooltip.tile.radhatch.5.name") + " " + + (this.decayTime - this.timer % (this.decayTime * 60)) + + StatCollector.translateToLocal("tooltip.tile.radhatch.6.name") + + "/" + + (this.decayTime - this.timer % this.decayTime) / 20 + + StatCollector.translateToLocal("tooltip.tile.radhatch.7.name") + + "/" + + (this.decayTime - this.timer % this.decayTime) / 20 / 60 + + StatCollector.translateToLocal("tooltip.tile.radhatch.8.name") + + "/" + + (this.decayTime - this.timer % this.decayTime) / 20 / 60 / 60 + + StatCollector.translateToLocal("tooltip.tile.radhatch.9.name") }; + return new String[] { + StatCollector.translateToLocal("tooltip.tile.radhatch.2.name") + " " + + StatCollector.translateToLocal("tooltip.bw.empty.name"), + StatCollector.translateToLocal("tooltip.tile.radhatch.3.name") + " " + "0", + StatCollector.translateToLocal("tooltip.tile.radhatch.4.name") + " " + "0" }; + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public boolean isValidSlot(int aIndex) { + return true; + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return side == this.getBaseMetaTileEntity() + .getFrontFacing() && BartWorksRecipeMaps.radioHatchRecipes.containsInput(aStack); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + aNBT.setByte("mMass", this.mass); + aNBT.setByte("mSv", (byte) (this.sievert - 100)); + aNBT.setByte("mCoverage", this.coverage); + aNBT.setInteger("mTextColor", BWColorUtil.getColorFromRGBArray(this.getColorForGUI())); + if (this.material != null && !this.material.isEmpty()) aNBT.setString("mMaterial", this.material); + aNBT.setLong("timer", this.timer); + aNBT.setLong("decay", this.decayTime); + super.saveNBTData(aNBT); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + this.timer = aNBT.getLong("timer"); + this.mass = aNBT.getByte("mMass"); + this.sievert = aNBT.getByte("mSv") + 100; + this.coverage = aNBT.getByte("mCoverage"); + this.colorForGUI = BWColorUtil.splitColorToRBGArray(aNBT.getInteger("mTextColor")); + this.material = aNBT.getString("mMaterial"); + this.decayTime = aNBT.getLong("decay"); + super.loadNBTData(aNBT); + } + + @Override + public void startSoundLoop(byte aIndex, double aX, double aY, double aZ) { + super.startSoundLoop(aIndex, aX, aY, aZ); + ResourceLocation rl = new ResourceLocation(MainMod.MOD_ID, "hatch.RadOn"); + if (aIndex == 1) { + GTUtility.doSoundAtClient(rl, 10, 1.0F, aX, aY, aZ); + } + } + + @Override + public RecipeMap<?> getRecipeMap() { + // Only for visual + return BartWorksRecipeMaps.radioHatchRecipes; + } + + private static final int RADIATION_SHUTTER_WINDOW_ID = 999; + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + buildContext.addSyncedWindow(RADIATION_SHUTTER_WINDOW_ID, this::createShutterWindow); + + this.getBaseMetaTileEntity() + .add1by1Slot(builder); + builder.widget( + new DrawableWidget().setBackground(BWUITextures.PICTURE_SIEVERT_CONTAINER) + .setPos(61, 9) + .setSize(56, 24)) + .widget( + new ProgressBar().setProgress(() -> this.getSievert() / 148f) + .setDirection(Direction.RIGHT) + .setTexture(BWUITextures.PROGRESSBAR_SIEVERT, 24) + .setPos(65, 13) + .setSize(48, 16)) + .widget( + new DrawableWidget().setBackground(BWUITextures.PICTURE_DECAY_TIME_INSIDE) + .setPos(124, 18) + .setSize(16, 48)) + .widget(new DrawableWidget() { + + @Override + public void draw(float partialTicks) { + if (GT_MetaTileEntity_RadioHatch.this.decayTime > 0) { + int height = MathUtils.ceilInt( + 48 * ((GT_MetaTileEntity_RadioHatch.this.decayTime + - GT_MetaTileEntity_RadioHatch.this.timer % GT_MetaTileEntity_RadioHatch.this.decayTime) + / (float) GT_MetaTileEntity_RadioHatch.this.decayTime)); + new Rectangle() + .setColor( + Color.argb( + GT_MetaTileEntity_RadioHatch.this.colorForGUI[0], + GT_MetaTileEntity_RadioHatch.this.colorForGUI[1], + GT_MetaTileEntity_RadioHatch.this.colorForGUI[2], + 255)) + .draw(new Pos2d(0, 48 - height), new Size(16, height), partialTicks); + } + } + }.dynamicTooltip( + () -> Collections.singletonList( + StatCollector.translateToLocalFormatted( + "tooltip.tile.radhatch.10.name", + this.timer <= 1 ? 0 : (this.decayTime - this.timer) / 20, + this.timer <= 1 ? 0 : this.decayTime / 20))) + .setPos(124, 18) + .setSize(16, 48) + .attachSyncer( + new FakeSyncWidget.LongSyncer(() -> this.decayTime, val -> this.decayTime = val), + builder, + (widget, val) -> widget.notifyTooltipChange()) + .attachSyncer( + new FakeSyncWidget.LongSyncer(() -> this.timer, val -> this.timer = val), + builder, + (widget, val) -> widget.notifyTooltipChange())) + .widget(new FakeSyncWidget.ShortSyncer(() -> this.colorForGUI[0], val -> this.colorForGUI[0] = val)) + .widget(new FakeSyncWidget.ShortSyncer(() -> this.colorForGUI[1], val -> this.colorForGUI[1] = val)) + .widget(new FakeSyncWidget.ShortSyncer(() -> this.colorForGUI[2], val -> this.colorForGUI[2] = val)) + .widget( + new DrawableWidget().setBackground(BWUITextures.PICTURE_DECAY_TIME_CONTAINER) + .setPos(120, 14) + .setSize(24, 56)) + .widget( + new TextWidget() + .setStringSupplier( + () -> StatCollector.translateToLocalFormatted("BW.NEI.display.radhatch.1", this.mass)) + .setTextAlignment(Alignment.Center) + .setPos(65, 62)) + .widget(new FakeSyncWidget.ByteSyncer(() -> this.mass, val -> this.mass = val)) + .widget( + new TextWidget() + .setStringSupplier( + () -> StatCollector.translateToLocalFormatted("BW.NEI.display.radhatch.0", this.getSievert())) + .setTextAlignment(Alignment.Center) + .setPos(60, 72)) + .widget(new FakeSyncWidget.IntegerSyncer(() -> this.sievert, val -> this.sievert = val)) + .widget(new ButtonWidget().setOnClick((clickData, widget) -> { + if (!widget.isClient()) { + widget.getContext() + .openSyncedWindow(RADIATION_SHUTTER_WINDOW_ID); + } + }) + .addTooltip("Radiation Shutter") + .setBackground(GTUITextures.BUTTON_STANDARD) + .setPos(153, 5) + .setSize(18, 18)) + .widget( + new ItemDrawable( + MetaGeneratedTool01.INSTANCE.getToolWithStats(IDMetaTool01.SCREWDRIVER.ID, 1, null, null, null)) + .asWidget() + .setPos(154, 6)); + } + + private ModularWindow createShutterWindow(EntityPlayer player) { + ModularWindow.Builder builder = ModularWindow.builder(176, 107); + builder.setBackground(ModularUITextures.VANILLA_BACKGROUND); + builder.setGuiTint(this.getGUIColorization()); + + builder.widget( + new TextWidget("Radiation Shutter Control").setDefaultColor(this.COLOR_TITLE.get()) + .setPos(10, 9)) + .widget( + new DrawableWidget().setDrawable(BWUITextures.PICTURE_RADIATION_SHUTTER_FRAME) + .setPos(14, 27) + .setSize(55, 54)) + .widget( + new DrawableWidget() + .setDrawable(() -> this.coverage < 100 ? BWUITextures.PICTURE_RADIATION_SHUTTER_INSIDE : null) + .setPos(16, 29) + .setSize(51, 50) + .attachSyncer( + new FakeSyncWidget.ByteSyncer(this::getCoverage, this::setCoverage), + builder, + (widget, val) -> widget.setPos(16, 29 + this.coverage / 2) + .setSize(51, 50 - this.coverage / 2))) + .widget( + new NumericWidget().setSetter(val -> this.coverage = (byte) val) + .setGetter(() -> this.coverage) + .setBounds(0, 100) + .setScrollValues(1, 5, 50) + .setTextColor(Color.WHITE.dark(1)) + .setTextAlignment(Alignment.CenterLeft) + .setBackground(GTUITextures.BACKGROUND_TEXT_FIELD.withOffset(-1, -1, 2, 2)) + .setPos(86, 27) + .setSize(30, 12)) + .widget( + ButtonWidget.closeWindowButton(true) + .setPos(176 - 15, 3)); + + return builder.build(); + } + + @Override + public void addGregTechLogo(ModularWindow.Builder builder) { + builder.widget( + new DrawableWidget().setDrawable(BWUITextures.PICTURE_BW_LOGO_47X21) + .setSize(47, 21) + .setPos(10, 53)); + } + + @Override + public GUITextureSet getGUITextureSet() { + return new GUITextureSet().setMainBackground(GTUITextures.BACKGROUND_SINGLEBLOCK_DEFAULT) + .setGregTechLogo(GTUITextures.PICTURE_GT_LOGO_17x17_TRANSPARENT); + } +} diff --git a/src/main/java/bartworks/common/tileentities/tiered/MTEAcidGenerator.java b/src/main/java/bartworks/common/tileentities/tiered/MTEAcidGenerator.java new file mode 100644 index 0000000000..2713d3dee2 --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/tiered/MTEAcidGenerator.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.tiered; + +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.util.ForgeDirection; + +import bartworks.API.recipe.BartWorksRecipeMaps; +import bartworks.util.BWTooltipReference; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.implementations.MTEBasicGenerator; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.render.TextureFactory; + +public class MTEAcidGenerator extends MTEBasicGenerator { + + public MTEAcidGenerator(int aID, String aName, String aNameRegional, int aTier, ITexture... aTextures) { + super(aID, aName, aNameRegional, aTier, new String[] {}, aTextures); + } + + public MTEAcidGenerator(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aDescription, aTextures); + } + + @Override + public int getPollution() { + return 0; + } + + @Override + public RecipeMap<?> getRecipeMap() { + return BartWorksRecipeMaps.acidGenFuels; + } + + @Override + public int getEfficiency() { + return 100 - 3 * this.mTier; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MTEAcidGenerator(this.mName, this.mTier, this.mDescriptionArray, this.mTextures); + } + + @Override + public ITexture[] getFront(byte aColor) { + return new ITexture[] { super.getFront(aColor)[0], + TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_SOLID_STEEL), + Textures.BlockIcons.OVERLAYS_ENERGY_OUT[this.mTier] }; + } + + @Override + public ITexture[] getBack(byte aColor) { + return new ITexture[] { super.getBack(aColor)[0], + TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_ACIDHAZARD) }; + } + + @Override + public ITexture[] getBottom(byte aColor) { + return new ITexture[] { super.getBottom(aColor)[0], + TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_ACIDHAZARD) }; + } + + @Override + public ITexture[] getTop(byte aColor) { + return new ITexture[] { super.getTop(aColor)[0], + TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_SOLID_STEEL), + TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/chemical_reactor/OVERLAY_FRONT")), + TextureFactory.builder() + .addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/chemical_reactor/OVERLAY_FRONT_GLOW")) + .glow() + .build() }; + } + + @Override + public ITexture[] getSides(byte aColor) { + return new ITexture[] { super.getSides(aColor)[0], + TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_ACIDHAZARD) }; + } + + @Override + public ITexture[] getFrontActive(byte aColor) { + return new ITexture[] { super.getFrontActive(aColor)[0], + TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_SOLID_STEEL), + Textures.BlockIcons.OVERLAYS_ENERGY_OUT[this.mTier] }; + } + + @Override + public ITexture[] getBackActive(byte aColor) { + return new ITexture[] { super.getBackActive(aColor)[0], + TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_ACIDHAZARD) }; + } + + @Override + public ITexture[] getBottomActive(byte aColor) { + return new ITexture[] { super.getBottomActive(aColor)[0], + TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_ACIDHAZARD) }; + } + + @Override + public ITexture[] getTopActive(byte aColor) { + return new ITexture[] { super.getTopActive(aColor)[0], + TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_SOLID_STEEL), + TextureFactory + .of(new Textures.BlockIcons.CustomIcon("basicmachines/chemical_reactor/OVERLAY_FRONT_ACTIVE")), + TextureFactory.builder() + .addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/chemical_reactor/OVERLAY_FRONT_ACTIVE_GLOW")) + .glow() + .build() }; + } + + @Override + public ITexture[] getSidesActive(byte aColor) { + return new ITexture[] { super.getSidesActive(aColor)[0], + TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_ACIDHAZARD) }; + } + + @Override + public boolean isOutputFacing(ForgeDirection side) { + return side == this.getBaseMetaTileEntity() + .getFrontFacing(); + } + + @Override + public String[] getDescription() { + return new String[] { StatCollector.translateToLocal("tooltip.tile.acidgen.0.name"), + StatCollector.translateToLocal("tooltip.tile.acidgen.1.name"), + StatCollector.translateToLocal("tooltip.tile.tiereddsc.0.name") + " " + + EnumChatFormatting.YELLOW + + GTValues.V[this.mTier], + StatCollector.translateToLocal("tooltip.rotor.2.name") + " " + + EnumChatFormatting.YELLOW + + this.getEfficiency(), + StatCollector.translateToLocal("tooltip.tile.tiereddsc.2.name") + " " + + EnumChatFormatting.YELLOW + + this.maxAmperesOut(), + BWTooltipReference.ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS.get() }; + } +} diff --git a/src/main/java/bartworks/common/tileentities/tiered/MTEBioLab.java b/src/main/java/bartworks/common/tileentities/tiered/MTEBioLab.java new file mode 100644 index 0000000000..992c7188fa --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/tiered/MTEBioLab.java @@ -0,0 +1,405 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.tiered; + +import static gregtech.api.enums.Mods.Gendustry; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.StatCollector; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; + +import bartworks.API.recipe.BartWorksRecipeMaps; +import bartworks.common.items.ItemLabModule; +import bartworks.common.items.ItemLabParts; +import bartworks.common.loaders.BioCultureLoader; +import bartworks.common.loaders.BioItemList; +import bartworks.common.loaders.FluidLoader; +import bartworks.util.BWTooltipReference; +import bartworks.util.BWUtil; +import bartworks.util.BioCulture; +import bartworks.util.BioDNA; +import bartworks.util.BioData; +import bartworks.util.BioPlasmid; +import gregtech.api.enums.ItemList; +import gregtech.api.enums.Materials; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.implementations.MTEBasicMachine; +import gregtech.api.objects.XSTR; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTUtility; +import gregtech.common.items.behaviors.BehaviourDataOrb; + +public class MTEBioLab extends MTEBasicMachine { + + private static final int DNA_EXTRACTION_MODULE = 0; + private static final int PCR_THERMOCYCLE_MODULE = 1; + private static final int PLASMID_SYNTHESIS_MODULE = 2; + private static final int TRANSFORMATION_MODULE = 3; + private static final int CLONAL_CELLULAR_SYNTHESIS_MODULE = 4; + private static final int INCUBATION_MODULE = 5; + + public MTEBioLab(int aID, String aName, String aNameRegional, int aTier) { + super( + aID, + aName, + aNameRegional, + aTier, + 1, + (String) null, + 6, + 2, + TextureFactory.of( + TextureFactory + .of(new Textures.BlockIcons.CustomIcon("basicmachines/fluid_extractor/OVERLAY_SIDE_ACTIVE")), + TextureFactory.builder() + .addIcon( + new Textures.BlockIcons.CustomIcon("basicmachines/fluid_extractor/OVERLAY_SIDE_ACTIVE_GLOW")) + .glow() + .build()), + TextureFactory.of( + TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/fluid_extractor/OVERLAY_SIDE")), + TextureFactory.builder() + .addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/fluid_extractor/OVERLAY_SIDE_GLOW")) + .glow() + .build()), + TextureFactory.of( + TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/microwave/OVERLAY_FRONT_ACTIVE")), + TextureFactory.builder() + .addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/microwave/OVERLAY_FRONT_ACTIVE_GLOW")) + .glow() + .build()), + TextureFactory.of( + TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/microwave/OVERLAY_FRONT")), + TextureFactory.builder() + .addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/microwave/OVERLAY_FRONT_GLOW")) + .glow() + .build()), + TextureFactory.of( + TextureFactory + .of(new Textures.BlockIcons.CustomIcon("basicmachines/chemical_reactor/OVERLAY_FRONT_ACTIVE")), + TextureFactory.builder() + .addIcon( + new Textures.BlockIcons.CustomIcon("basicmachines/chemical_reactor/OVERLAY_FRONT_ACTIVE_GLOW")) + .glow() + .build() /* this is topactive */), + TextureFactory.of( + TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/chemical_reactor/OVERLAY_FRONT")), + TextureFactory.builder() + .addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/chemical_reactor/OVERLAY_FRONT_GLOW")) + .glow() + .build() /* this is top */), + TextureFactory.of( + TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/polarizer/OVERLAY_BOTTOM_ACTIVE")), + TextureFactory.builder() + .addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/polarizer/OVERLAY_BOTTOM_ACTIVE_GLOW")) + .glow() + .build()), + TextureFactory.of( + TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/polarizer/OVERLAY_BOTTOM")), + TextureFactory.builder() + .addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/polarizer/OVERLAY_BOTTOM_GLOW")) + .glow() + .build())); + } + + public MTEBioLab(String aName, int aTier, int aAmperage, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aAmperage, aDescription, aTextures, 6, 2); + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MTEBioLab(this.mName, this.mTier, this.mAmperage, this.mDescriptionArray, this.mTextures); + } + + @Override + public RecipeMap<?> getRecipeMap() { + return BartWorksRecipeMaps.bioLabRecipes; + } + + @Override + public int getCapacity() { + return this.mTier * 1000; + } + + @Override + public int checkRecipe(boolean skipOC) { + + int rTier = 3; + FluidStack dnaFluid = Gendustry.isModLoaded() ? FluidRegistry.getFluidStack("liquiddna", 1000) + : Materials.Biomass.getFluid(1000L); + + if (this.getSpecialSlot() != null && this.getSpecialSlot() + .getItem() instanceof ItemLabModule) { + int damage = this.getSpecialSlot() + .getItemDamage(); + switch (damage) { + case DNA_EXTRACTION_MODULE: + if (GTUtility.isStackValid(this.mInventory[this.getInputSlot()]) + && this.mInventory[this.getInputSlot()].getItem() instanceof ItemLabParts + && this.mInventory[this.getInputSlot()].getItemDamage() == 0 + && this.mInventory[this.getInputSlot()].getTagCompound() != null + && // checks if it is a Culture + GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 1]) + && this.mInventory[this.getInputSlot() + 1].getItem() instanceof ItemLabParts + && this.mInventory[this.getInputSlot() + 1].getItemDamage() == 1 + && this.mInventory[this.getInputSlot() + 1].getTagCompound() == null + && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 2]) + && this.mInventory[this.getInputSlot() + 2].getItem() instanceof ItemLabParts + && this.mInventory[this.getInputSlot() + 2].getItemDamage() == 3 + && GTUtility + .areStacksEqual(this.mInventory[this.getInputSlot() + 3], Materials.Ethanol.getCells(1)) + && this.mFluid != null + && this.mFluid.isFluidEqual(FluidRegistry.getFluidStack("ic2distilledwater", 1000)) + && this.mFluid.amount >= 1000) { + + NBTTagCompound DNABioDataTag = this.mInventory[this.getInputSlot()].getTagCompound() + .getCompoundTag("DNA"); + if (DNABioDataTag == null) return super.checkRecipe(skipOC); + BioData cultureDNABioData = BioData.getBioDataFromName( + this.mInventory[this.getInputSlot()].getTagCompound() + .getCompoundTag("DNA") + .getString("Name")); + if (cultureDNABioData == null) return super.checkRecipe(skipOC); + + if (this.mTier < rTier + cultureDNABioData.getTier()) + return MTEBasicMachine.FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS; + + for (int i = 0; i < 4; i++) { + if (this.mInventory[this.getInputSlot() + i] != null) + this.mInventory[this.getInputSlot() + i].stackSize--; + } + + this.mFluid.amount -= 1000; + + if (cultureDNABioData.getChance() > new XSTR().nextInt(10000)) { + this.mOutputItems[0] = BioItemList + .getDNASampleFlask(BioDNA.convertDataToDNA(cultureDNABioData)); + } + this.mOutputItems[1] = GTOreDictUnificator.get(OrePrefixes.cell, Materials.Empty, 1L); + this.calculateOverclockedNess( + BWUtil.getMachineVoltageFromTier(rTier + cultureDNABioData.getTier()), + 500); + + return MTEBasicMachine.FOUND_AND_SUCCESSFULLY_USED_RECIPE; + } + break; + case PCR_THERMOCYCLE_MODULE: { + if (GTUtility.isStackValid(this.mInventory[this.getInputSlot()]) + && this.mInventory[this.getInputSlot()].getItem() instanceof ItemLabParts + && this.mInventory[this.getInputSlot()].getItemDamage() == 1 + && this.mInventory[this.getInputSlot()].getTagCompound() != null + && // checks if it is a Culture + GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 3]) + && GTUtility + .areStacksEqual(this.mInventory[this.getInputSlot() + 3], ItemList.Tool_DataOrb.get(1L)) + && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 1]) + && GTUtility + .areStacksEqual(this.mInventory[this.getInputSlot() + 1], FluidLoader.BioLabFluidCells[0]) + && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 2]) + && GTUtility + .areStacksEqual(this.mInventory[this.getInputSlot() + 2], FluidLoader.BioLabFluidCells[3]) + && this.mFluid != null + && this.mFluid.isFluidEqual(dnaFluid) + && this.mFluid.amount >= 1000) { + NBTTagCompound DNABioDataTag = this.mInventory[this.getInputSlot()].getTagCompound(); + if (DNABioDataTag == null) return super.checkRecipe(skipOC); + BioData cultureDNABioData = BioData.getBioDataFromName(DNABioDataTag.getString("Name")); + if (cultureDNABioData == null) return super.checkRecipe(skipOC); + + if (this.mTier < 1 + rTier + cultureDNABioData.getTier()) + return MTEBasicMachine.FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS; + + for (int i = 0; i < 4; i++) { + if (this.mInventory[this.getInputSlot() + i] != null) + this.mInventory[this.getInputSlot() + i].stackSize--; + } + + this.mFluid.amount -= 1000; + + ItemStack Outp = ItemList.Tool_DataOrb.get(1L); + BehaviourDataOrb.setDataTitle(Outp, "DNA Sample"); + BehaviourDataOrb.setDataName(Outp, cultureDNABioData.getName()); + + if (cultureDNABioData.getChance() > new XSTR().nextInt(10000)) { + this.mOutputItems[0] = Outp; + } else this.mOutputItems[0] = ItemList.Tool_DataOrb.get(1L); + this.mOutputItems[1] = ItemList.Cell_Empty.get(2L); + + this.calculateOverclockedNess( + BWUtil.getMachineVoltageFromTier(1 + rTier + cultureDNABioData.getTier()), + 500); + + return MTEBasicMachine.FOUND_AND_SUCCESSFULLY_USED_RECIPE; + } + } + break; + case PLASMID_SYNTHESIS_MODULE: { + ItemStack inp2 = ItemList.Tool_DataOrb.get(1L); + BehaviourDataOrb.setDataTitle(inp2, "DNA Sample"); + BehaviourDataOrb.setDataName(inp2, BioCultureLoader.BIO_DATA_BETA_LACMATASE.getName()); + if (GTUtility.isStackValid(this.mInventory[this.getInputSlot()]) + && GTUtility + .areStacksEqual(FluidLoader.BioLabFluidCells[1], this.mInventory[this.getInputSlot()]) + && // checks + // if + // it + // is + // a + // Culture + GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 1]) + && GTUtility + .areStacksEqual(this.mInventory[this.getInputSlot() + 1], BioItemList.getPlasmidCell(null)) + && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 2]) + && GTUtility.areStacksEqual( + this.mInventory[this.getInputSlot() + 2], + ItemList.Tool_DataOrb.get(1L), + true) + && "DNA Sample".equals(BehaviourDataOrb.getDataTitle(this.mInventory[this.getInputSlot() + 2])) + && !BehaviourDataOrb.getDataName(this.mInventory[this.getInputSlot() + 2]) + .isEmpty() + && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 3]) + && GTUtility.areStacksEqual(this.mInventory[this.getInputSlot() + 3], inp2) + && this.mFluid != null + && this.mFluid.isFluidEqual(dnaFluid) + && this.mFluid.amount >= 1000) { + BioData cultureDNABioData = BioData + .getBioDataFromName(BehaviourDataOrb.getDataName(this.mInventory[this.getInputSlot() + 2])); + if (cultureDNABioData == null) return super.checkRecipe(skipOC); + if (this.mTier < 1 + rTier + cultureDNABioData.getTier()) + return MTEBasicMachine.FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS; + for (int i = 0; i < 2; i++) { + if (this.mInventory[this.getInputSlot() + i] != null) + this.mInventory[this.getInputSlot() + i].stackSize--; + } + this.mFluid.amount -= 1000; + if (cultureDNABioData.getChance() > new XSTR().nextInt(10000)) { + this.mOutputItems[0] = BioItemList + .getPlasmidCell(BioPlasmid.convertDataToPlasmid(cultureDNABioData)); + } + this.mOutputItems[1] = ItemList.Cell_Empty.get(1L); + this.calculateOverclockedNess( + BWUtil.getMachineVoltageFromTier(1 + rTier + cultureDNABioData.getTier()), + 500); + return MTEBasicMachine.FOUND_AND_SUCCESSFULLY_USED_RECIPE; + } + } + break; + case TRANSFORMATION_MODULE: { + if (GTUtility.isStackValid(this.mInventory[this.getInputSlot()]) + && GTUtility + .areStacksEqual(this.mInventory[this.getInputSlot()], BioItemList.getPetriDish(null), true) + && this.mInventory[this.getInputSlot()].getTagCompound() != null + && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 1]) + && GTUtility.areStacksEqual( + this.mInventory[this.getInputSlot() + 1], + BioItemList.getPlasmidCell(null), + true) + && this.mInventory[this.getInputSlot() + 1].getTagCompound() != null + && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 2]) + && GTUtility + .areStacksEqual(this.mInventory[this.getInputSlot() + 2], FluidLoader.BioLabFluidCells[2]) + && this.mFluid != null + && this.mFluid.isFluidEqual(FluidRegistry.getFluidStack("ic2distilledwater", 1000)) + && this.mFluid.amount >= 1000) { + BioData cultureDNABioData = BioData + .getBioDataFromNBTTag(this.mInventory[this.getInputSlot() + 1].getTagCompound()); + BioCulture bioCulture = BioCulture + .getBioCultureFromNBTTag(this.mInventory[this.getInputSlot()].getTagCompound()); + if (cultureDNABioData == null || bioCulture == null) return super.checkRecipe(skipOC); + if (this.mTier < 3 + rTier + cultureDNABioData.getTier()) + return MTEBasicMachine.FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS; + for (int i = 0; i < 3; i++) { + if (this.mInventory[this.getInputSlot() + i] != null) + this.mInventory[this.getInputSlot() + i].stackSize--; + } + this.mFluid.amount -= 1000; + bioCulture = bioCulture.setPlasmid(BioPlasmid.convertDataToPlasmid(cultureDNABioData)); + if (cultureDNABioData.getChance() > new XSTR().nextInt(10000)) { + this.mOutputItems[0] = BioItemList.getPetriDish(bioCulture); + } + this.mOutputItems[1] = ItemList.Cell_Empty.get(1L); + this.calculateOverclockedNess( + BWUtil.getMachineVoltageFromTier(3 + rTier + cultureDNABioData.getTier()), + 500); + return MTEBasicMachine.FOUND_AND_SUCCESSFULLY_USED_RECIPE; + } + } + break; + case CLONAL_CELLULAR_SYNTHESIS_MODULE: { + ItemStack Outp = ItemList.Tool_DataOrb.get(1L); + BehaviourDataOrb.setDataTitle(Outp, "DNA Sample"); + + if (GTUtility.isStackValid(this.mInventory[this.getInputSlot()]) + && GTUtility + .areStacksEqual(this.mInventory[this.getInputSlot()], BioItemList.getPetriDish(null)) + && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 1]) + && GTUtility.areStacksEqual(this.mInventory[this.getInputSlot() + 1], BioItemList.getOther(4)) + && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 2]) + && GTUtility.areStacksEqual( + this.mInventory[this.getInputSlot() + 2], + ItemList.Circuit_Chip_Stemcell.get(2L)) + && GTUtility.isStackValid(this.mInventory[this.getInputSlot() + 3]) + && GTUtility.areStacksEqual( + this.mInventory[this.getInputSlot() + 3], + ItemList.Tool_DataOrb.get(1L), + true) + && "DNA Sample".equals(BehaviourDataOrb.getDataTitle(this.mInventory[this.getInputSlot() + 3])) + && this.mFluid.isFluidEqual(dnaFluid) + && this.mFluid.amount >= 8000) { + + BioData cultureDNABioData = BioData + .getBioDataFromName(BehaviourDataOrb.getDataName(this.mInventory[this.getInputSlot() + 3])); + if (cultureDNABioData == null) return super.checkRecipe(skipOC); + if (this.mTier < 3 + rTier + cultureDNABioData.getTier()) + return MTEBasicMachine.FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS; + for (int i = 0; i < 3; i++) { + if (this.mInventory[this.getInputSlot() + i] != null) + this.mInventory[this.getInputSlot() + i].stackSize--; + } + this.mFluid.amount -= 8000; + if (cultureDNABioData.getChance() > new XSTR().nextInt(10000)) { + BioCulture out = BioCulture.getBioCulture(BioDNA.convertDataToDNA(cultureDNABioData)); + if (out == null) return MTEBasicMachine.DID_NOT_FIND_RECIPE; + out = out.setPlasmid(BioPlasmid.convertDataToPlasmid(cultureDNABioData)); + this.mOutputItems[0] = BioItemList.getPetriDish(out); + } + this.calculateOverclockedNess( + BWUtil.getMachineVoltageFromTier(3 + rTier + cultureDNABioData.getTier()), + 500); + return MTEBasicMachine.FOUND_AND_SUCCESSFULLY_USED_RECIPE; + } + } + break; + case INCUBATION_MODULE: + default: + break; + } + } + return super.checkRecipe(skipOC); + } + + @Override + public String[] getDescription() { + return new String[] { StatCollector.translateToLocal("tooltip.tile.biolab.0.name"), + BWTooltipReference.ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS.get() }; + } +} diff --git a/src/main/java/bartworks/common/tileentities/tiered/MTECompressedFluidHatch.java b/src/main/java/bartworks/common/tileentities/tiered/MTECompressedFluidHatch.java new file mode 100644 index 0000000000..89b21ae67e --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/tiered/MTECompressedFluidHatch.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.tiered; + +import net.minecraftforge.fluids.FluidStack; + +import com.gtnewhorizons.modularui.common.widget.FluidSlotWidget; + +import gregtech.api.enums.Materials; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.implementations.MTEHatchInput; +import gregtech.api.util.GTUtility; + +public class MTECompressedFluidHatch extends MTEHatchInput { + + public MTECompressedFluidHatch(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional, 0); + this.mDescriptionArray[1] = "Capacity: 100,000,000L"; + } + + public MTECompressedFluidHatch(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aDescription, aTextures); + } + + @Override + public int getCapacity() { + return 100_000_000; + } + + @Override + public boolean isFluidInputAllowed(FluidStack aFluid) { + return GTUtility.areFluidsEqual(aFluid, Materials.LiquidAir.getFluid(1)); + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTECompressedFluidHatch(this.mName, this.mTier, this.mDescriptionArray, this.mTextures); + } + + @Override + protected FluidSlotWidget createFluidSlot() { + return super.createFluidSlot().setFilter(f -> f == Materials.LiquidAir.mFluid); + } +} diff --git a/src/main/java/bartworks/common/tileentities/tiered/MTEDiode.java b/src/main/java/bartworks/common/tileentities/tiered/MTEDiode.java new file mode 100644 index 0000000000..ad3a39320f --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/tiered/MTEDiode.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.tiered; + +import static gregtech.api.enums.MetaTileEntityIDs.Diode12A_MAX; +import static gregtech.api.enums.MetaTileEntityIDs.Diode12A_ULV; +import static gregtech.api.enums.MetaTileEntityIDs.Diode16A_MAX; +import static gregtech.api.enums.MetaTileEntityIDs.Diode16A_ULV; +import static gregtech.api.enums.MetaTileEntityIDs.Diode2A_MAX; +import static gregtech.api.enums.MetaTileEntityIDs.Diode2A_ULV; +import static gregtech.api.enums.MetaTileEntityIDs.Diode4A_MAX; +import static gregtech.api.enums.MetaTileEntityIDs.Diode4A_ULV; +import static gregtech.api.enums.MetaTileEntityIDs.Diode8A_MAX; +import static gregtech.api.enums.MetaTileEntityIDs.Diode8A_ULV; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.util.ForgeDirection; + +import org.apache.commons.lang3.ArrayUtils; + +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.implementations.MTEBasicHull; +import gregtech.api.util.GTUtility; + +public class MTEDiode extends MTEBasicHull { + + private long maxAmps; + private long aAmps; + + public MTEDiode(int aID, String aName, String aNameRegional, int aTier) { + super(aID, aName, aNameRegional, aTier, StatCollector.translateToLocal("tooltip.tile.diode.0.name")); + this.maxAmps = this.getAmpsfromMeta(aID); + this.aAmps = this.maxAmps; + } + + public MTEDiode(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 0, aDescription, aTextures); + } + + @Override + public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) { + super.onFirstTick(aBaseMetaTileEntity); + if (this.maxAmps == 0 && !this.getBaseMetaTileEntity() + .getWorld().isRemote) { + this.maxAmps = this.getAmpsfromMeta( + this.getBaseMetaTileEntity() + .getMetaTileID()); + this.aAmps = this.maxAmps; + } + } + + @Override + public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) { + super.onScrewdriverRightClick(side, aPlayer, aX, aY, aZ); + + if (this.getBaseMetaTileEntity() + .getWorld().isRemote) return; + if (!aPlayer.isSneaking()) { + --this.aAmps; + if (this.aAmps < 0) this.aAmps = this.maxAmps; + } else { + ++this.aAmps; + if (this.aAmps > this.maxAmps) this.aAmps = 0; + } + GTUtility.sendChatToPlayer(aPlayer, "Max Amps: " + this.aAmps); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + aNBT.setLong("maxAmp", this.maxAmps); + aNBT.setLong("Amps", this.aAmps); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + this.maxAmps = aNBT.getLong("maxAmp"); + this.aAmps = aNBT.getLong("Amps"); + super.loadNBTData(aNBT); + } + + @Override + public long maxAmperesOut() { + return this.aAmps; + } + + @Override + public long maxAmperesIn() { + return this.aAmps; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEDiode(this.mName, this.mTier, this.mDescriptionArray, this.mTextures); + } + + private long getAmpsfromMeta(int meta) { + if (meta >= Diode2A_ULV.ID && meta <= Diode2A_MAX.ID) return 2L; + if (meta >= Diode4A_ULV.ID && meta <= Diode4A_MAX.ID) return 4L; + if (meta >= Diode8A_ULV.ID && meta <= Diode8A_MAX.ID) return 8L; + if (meta >= Diode12A_ULV.ID && meta <= Diode12A_MAX.ID) return 12L; + if (meta >= Diode16A_ULV.ID && meta <= Diode16A_MAX.ID) return 16L; + return 0L; + } + + @Override + public String[] getDescription() { + return ArrayUtils.addAll(this.mDescriptionArray); + } +} diff --git a/src/main/java/bartworks/common/tileentities/tiered/MTEEnergyDistributor.java b/src/main/java/bartworks/common/tileentities/tiered/MTEEnergyDistributor.java new file mode 100644 index 0000000000..d361047699 --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/tiered/MTEEnergyDistributor.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.tiered; + +import net.minecraft.util.StatCollector; + +import gregtech.api.enums.GTValues; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.implementations.MTETransformer; + +public class MTEEnergyDistributor extends MTETransformer { + + public MTEEnergyDistributor(int aID, String aName, String aNameRegional, int aTier) { + super(aID, aName, aNameRegional, aTier, null); + } + + public MTEEnergyDistributor(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aDescription, aTextures); + } + + public MTEEnergyDistributor(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aDescription, aTextures); + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEEnergyDistributor(this.mName, this.mTier, this.mDescriptionArray, this.mTextures); + } + + @Override + public long maxEUInput() { + return GTValues.V[this.mTier]; + } + + @Override + public long maxEUOutput() { + return GTValues.V[this.mTier]; + } + + @Override + public long maxAmperesOut() { + return 320; + } + + @Override + public long maxAmperesIn() { + return 320; + } + + @Override + public long maxEUStore() { + return 512L + GTValues.V[this.mTier] * 320L; + } + + @Override + public String[] getDescription() { + return new String[] { StatCollector.translateToLocal("tooltip.tile.energydistributor.0.name") }; + } +} diff --git a/src/main/java/bartworks/common/tileentities/tiered/MTEGiantOutputHatch.java b/src/main/java/bartworks/common/tileentities/tiered/MTEGiantOutputHatch.java new file mode 100644 index 0000000000..dc4b031f74 --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/tiered/MTEGiantOutputHatch.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.tiered; + +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.implementations.MTEHatchOutput; + +public class MTEGiantOutputHatch extends MTEHatchOutput { + + public MTEGiantOutputHatch(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional, 0); + this.mDescriptionArray[1] = "Capacity: 100000000L"; + } + + public MTEGiantOutputHatch(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aDescription, aTextures); + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEGiantOutputHatch(this.mName, this.mTier, this.mDescriptionArray, this.mTextures); + } + + @Override + public int getCapacity() { + return 100000000; + } +} diff --git a/src/main/java/bartworks/common/tileentities/tiered/MTEHumongousInputHatch.java b/src/main/java/bartworks/common/tileentities/tiered/MTEHumongousInputHatch.java new file mode 100644 index 0000000000..efe3614250 --- /dev/null +++ b/src/main/java/bartworks/common/tileentities/tiered/MTEHumongousInputHatch.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.common.tileentities.tiered; + +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.implementations.MTEHatchInput; + +public class MTEHumongousInputHatch extends MTEHatchInput { + + public MTEHumongousInputHatch(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional, 13); + this.mDescriptionArray[1] = "Capacity: 2,000,000,000L"; + } + + public MTEHumongousInputHatch(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aDescription, aTextures); + } + + @Override + public int getCapacity() { + return 2_000_000_000; + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEHumongousInputHatch(this.mName, this.mTier, this.mDescriptionArray, this.mTextures); + } +} |