diff options
Diffstat (limited to 'src/main/java/goodgenerator/blocks/tileEntity/AntimatterForge.java')
-rw-r--r-- | src/main/java/goodgenerator/blocks/tileEntity/AntimatterForge.java | 978 |
1 files changed, 978 insertions, 0 deletions
diff --git a/src/main/java/goodgenerator/blocks/tileEntity/AntimatterForge.java b/src/main/java/goodgenerator/blocks/tileEntity/AntimatterForge.java new file mode 100644 index 0000000000..4bf48910e8 --- /dev/null +++ b/src/main/java/goodgenerator/blocks/tileEntity/AntimatterForge.java @@ -0,0 +1,978 @@ +package goodgenerator.blocks.tileEntity; + +import static com.gtnewhorizon.structurelib.structure.StructureUtility.*; +import static gregtech.api.enums.Textures.BlockIcons.*; +import static gregtech.api.util.GTStructureUtility.buildHatchAdder; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Random; + +import javax.annotation.Nonnull; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +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 net.minecraftforge.fluids.FluidStack; + +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.NumberFormatMUI; +import com.gtnewhorizons.modularui.common.widget.DynamicPositionedColumn; +import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; +import com.gtnewhorizons.modularui.common.widget.SlotWidget; +import com.gtnewhorizons.modularui.common.widget.TextWidget; + +import goodgenerator.blocks.structures.AntimatterStructures; +import goodgenerator.blocks.tileEntity.render.TileAntimatter; +import goodgenerator.items.GGMaterial; +import goodgenerator.loader.Loaders; +import gregtech.api.enums.HatchElement; +import gregtech.api.enums.Materials; +import gregtech.api.enums.MaterialsUEVplus; +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.interfaces.tileentity.IOverclockDescriptionProvider; +import gregtech.api.metatileentity.implementations.MTEExtendedPowerMultiBlockBase; +import gregtech.api.metatileentity.implementations.MTEHatch; +import gregtech.api.metatileentity.implementations.MTEHatchInput; +import gregtech.api.metatileentity.implementations.MTEHatchOutput; +import gregtech.api.objects.GTChunkManager; +import gregtech.api.objects.GTItemStack; +import gregtech.api.objects.overclockdescriber.OverclockDescriber; +import gregtech.api.recipe.check.CheckRecipeResult; +import gregtech.api.recipe.check.CheckRecipeResultRegistry; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.ExoticEnergyInputHelper; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; +import gregtech.api.util.HatchElementBuilder; +import gregtech.api.util.MultiblockTooltipBuilder; +import gregtech.api.util.shutdown.ShutDownReason; +import gregtech.api.util.shutdown.ShutDownReasonRegistry; +import gregtech.common.tileentities.machines.IDualInputHatch; + +public class AntimatterForge extends MTEExtendedPowerMultiBlockBase<AntimatterForge> + implements ISurvivalConstructable, IOverclockDescriptionProvider { + + private static final FluidStack[] magneticUpgrades = { Materials.TengamAttuned.getMolten(1L), + MaterialsUEVplus.Time.getMolten(1L) }; + private static final FluidStack[] gravityUpgrades = { MaterialsUEVplus.SpaceTime.getMolten(1L), + MaterialsUEVplus.Space.getMolten(1L), MaterialsUEVplus.Eternity.getMolten(1L) }; + private static final FluidStack[] containmentUpgrades = { GGMaterial.shirabon.getMolten(1), + MaterialsUEVplus.MagnetohydrodynamicallyConstrainedStarMatter.getMolten(1L) }; + private static final FluidStack[] activationUpgrades = { GGMaterial.naquadahBasedFuelMkVDepleted.getFluidOrGas(1), + GGMaterial.naquadahBasedFuelMkVIDepleted.getFluidOrGas(1) }; + + private static final int MAGNETIC_ID = 0; + private static final int GRAVITY_ID = 1; + private static final int CONTAINMENT_ID = 2; + private static final int ACTIVATION_ID = 3; + + private static final int BASE_CONSUMPTION = 10_000_000; + private static final int passiveBaseMult = 1000; + private static final int activeBaseMult = 10000; + + private static final float passiveBaseExp = 1.5f; + private static final float activeBaseExp = 1.5f; + private static final float coefficientBaseExp = 0.5f; + private static final float baseSkew = 0.2f; + + private float[] modifiers = { 0.0f, 0.0f, 0.0f, 0.0f }; + private FluidStack[] upgradeFluids = { null, null, null, null }; + private int[] fluidConsumptions = { 0, 0, 0, 0 }; + + public static final String MAIN_NAME = "antimatterForge"; + private int speed = 100; + private long rollingCost = 0L; + private boolean isLoadedChunk; + public GTRecipe mLastRecipe; + public int para; + private Random r = new Random(); + // Values for displaying cycle data + private long guiAntimatterAmount = 0; + private long guiAntimatterChange = 0; + private long guiPassiveEnergy = 0; + private long guiActiveEnergy = 0; + + private List<AntimatterOutputHatch> amOutputHatches = new ArrayList<>(16); + private static final ClassValue<IStructureDefinition<AntimatterForge>> STRUCTURE_DEFINITION = new ClassValue<IStructureDefinition<AntimatterForge>>() { + + @Override + protected IStructureDefinition<AntimatterForge> computeValue(Class<?> type) { + return StructureDefinition.<AntimatterForge>builder() + .addShape(MAIN_NAME, AntimatterStructures.ANTIMATTER_FORGE) + .addElement('A', lazy(x -> ofBlock(x.getFrameBlock(), x.getFrameMeta()))) + .addElement('B', lazy(x -> ofBlock(x.getCoilBlock(), x.getCoilMeta()))) + .addElement('C', lazy(x -> ofBlock(x.getCasingBlock(2), x.getCasingMeta(2)))) + .addElement('D', lazy(x -> ofBlock(x.getCasingBlock(1), x.getCasingMeta(1)))) + .addElement( + 'F', + lazy( + x -> HatchElementBuilder.<AntimatterForge>builder() + .anyOf(HatchElement.InputHatch) + .adder(AntimatterForge::addFluidIO) + .casingIndex(x.textureIndex(2)) + .dot(1) + .buildAndChain(x.getCasingBlock(2), x.getCasingMeta(2)))) + .addElement( + 'E', + lazy( + x -> buildHatchAdder(AntimatterForge.class).adder(AntimatterForge::addAntimatterHatch) + .hatchClass(AntimatterOutputHatch.class) + .casingIndex(x.textureIndex(1)) + .dot(3) + .build())) + .addElement( + 'H', + lazy( + x -> HatchElementBuilder.<AntimatterForge>builder() + .anyOf(HatchElement.Energy.or(HatchElement.ExoticEnergy)) + .adder(AntimatterForge::addEnergyInjector) + .casingIndex(x.textureIndex(2)) + .dot(4) + .buildAndChain(x.getCasingBlock(2), x.getCasingMeta(2)))) + .build(); + } + }; + + static { + Textures.BlockIcons.setCasingTextureForId( + 53, + TextureFactory.of( + TextureFactory.builder() + .addIcon(MACHINE_CASING_ANTIMATTER) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(MACHINE_CASING_ANTIMATTER_GLOW) + .extFacing() + .glow() + .build())); + } + + public AntimatterForge(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + public AntimatterForge(String aName) { + super(aName); + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity arg0) { + return new AntimatterForge(MAIN_NAME); + } + + @Override + protected MultiblockTooltipBuilder createTooltip() { + final MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder(); + tt.addMachineType("Antimatter Forge") + .addInfo(EnumChatFormatting.LIGHT_PURPLE + "Dimensions not included!" + EnumChatFormatting.GRAY) + .addInfo("Converts protomatter into antimatter") + .addInfo( + "Consumes 10 000 000 + (" + EnumChatFormatting.DARK_BLUE + + "Antimatter" + + EnumChatFormatting.GRAY + + " * " + + String.valueOf(this.passiveBaseMult) + + ")^" + + EnumChatFormatting.GREEN + + String.valueOf(this.passiveBaseExp) + + EnumChatFormatting.GRAY + + " EU/t passively. The consumption decays by 0.5% every tick when empty") + .addInfo( + "Uses (" + EnumChatFormatting.DARK_BLUE + + "Antimatter" + + EnumChatFormatting.GRAY + + " * " + + String.valueOf(this.activeBaseMult) + + ")^" + + EnumChatFormatting.DARK_PURPLE + + String.valueOf(this.activeBaseExp) + + EnumChatFormatting.GRAY + + " EU per operation to produce antimatter") + .addSeparator() + .addInfo("Every cycle, the lowest amount of antimatter in the 16 antimatter hatches is recorded") + .addInfo("Cycles every 5 seconds") + .addInfo( + "All hatches with more than the lowest amount will " + EnumChatFormatting.RED + + "lose half the difference!" + + EnumChatFormatting.GRAY) + .addInfo( + "If the machine runs out of energy or protomatter during a cycle, " + EnumChatFormatting.RED + + "10% of antimatter will be voided!" + + EnumChatFormatting.GRAY) + .addInfo( + "Produces (" + EnumChatFormatting.DARK_BLUE + + "Antimatter" + + EnumChatFormatting.GRAY + + "^" + + EnumChatFormatting.GOLD + + String.valueOf(this.coefficientBaseExp) + + EnumChatFormatting.GRAY + + ") * N(" + + EnumChatFormatting.AQUA + + String.valueOf(this.baseSkew) + + EnumChatFormatting.GRAY + + ", 1) of antimatter per cycle, consuming equal amounts of Protomatter") + .addInfo("The change can be negative! (N = Skewed Normal Distribution)") + .addSeparator() + .addInfo("Can be supplied with stabilization fluids to improve antimatter generation") + .addInfo( + EnumChatFormatting.GREEN + "Magnetic Stabilization" + + EnumChatFormatting.GRAY + + " (Uses " + + EnumChatFormatting.DARK_BLUE + + "Antimatter" + + EnumChatFormatting.GRAY + + "^0.5 per cycle)") + .addInfo( + "1. Molten Purified Tengam - Passive cost exponent " + EnumChatFormatting.GREEN + + "-0.15" + + EnumChatFormatting.GRAY) + .addInfo( + "2. Tachyon Rich Fluid - Passive cost exponent " + EnumChatFormatting.GREEN + + "-0.3" + + EnumChatFormatting.GRAY) + .addInfo( + EnumChatFormatting.DARK_PURPLE + "Gravity Stabilization" + + EnumChatFormatting.GRAY + + " (Uses " + + EnumChatFormatting.DARK_BLUE + + "Antimatter" + + EnumChatFormatting.GRAY + + "^0.5 per cycle)") + .addInfo( + "1. Molten Spacetime - Active cost exponent " + EnumChatFormatting.DARK_PURPLE + + "-0.05" + + EnumChatFormatting.GRAY) + .addInfo( + "2. Spatially Enlarged Fluid - Active cost exponent " + EnumChatFormatting.DARK_PURPLE + + "-0.10" + + EnumChatFormatting.GRAY) + .addInfo( + "3. Molten Eternity - Active cost exponent " + EnumChatFormatting.DARK_PURPLE + + "-0.15" + + EnumChatFormatting.GRAY) + .addInfo( + EnumChatFormatting.GOLD + "Containment Stabilization" + + EnumChatFormatting.GRAY + + " (Uses " + + EnumChatFormatting.DARK_BLUE + + "Antimatter" + + EnumChatFormatting.GRAY + + "^(2/7) per operation)") + .addInfo( + "1. Molten Shirabon - Production exponent " + EnumChatFormatting.GOLD + + "+0.05" + + EnumChatFormatting.GRAY) + .addInfo( + "2. Molten MHDCSM - Production exponent " + EnumChatFormatting.GOLD + "+0.10" + EnumChatFormatting.GRAY) + .addInfo( + EnumChatFormatting.AQUA + "Activation Stabilization" + + EnumChatFormatting.GRAY + + " (Uses " + + EnumChatFormatting.DARK_BLUE + + "Antimatter" + + EnumChatFormatting.GRAY + + "^(1/3) per operation)") + .addInfo( + "1. Depleted Naquadah Fuel Mk V - Distribution skew " + EnumChatFormatting.AQUA + + "+0.05" + + EnumChatFormatting.GRAY) + .addInfo( + "2. Depleted Naquadah Fuel Mk VI - Distribution skew " + EnumChatFormatting.AQUA + + "+0.10" + + EnumChatFormatting.GRAY) + .addSeparator() + .addEnergyHatch("1-9, Hint block with dot 4", 4) + .addInputHatch("1-6, Hint block with dot 1", 1) + .toolTipFinisher("Good Generator"); + return tt; + } + + @Override + public IStructureDefinition<AntimatterForge> getStructureDefinition() { + return STRUCTURE_DEFINITION.get(getClass()); + } + + public Block getCasingBlock(int type) { + switch (type) { + case 1: + return Loaders.magneticFluxCasing; + case 2: + return Loaders.gravityStabilizationCasing; + default: + return Loaders.magneticFluxCasing; + } + } + + public int getCasingMeta(int type) { + switch (type) { + case 1: + return 0; + case 2: + return 0; + default: + return 0; + } + } + + public Block getCoilBlock() { + return Loaders.protomatterActivationCoil; + } + + public int getCoilMeta() { + return 0; + } + + public Block getFrameBlock() { + return Loaders.antimatterContainmentCasing; + } + + public int getFrameMeta() { + return 0; + } + + public int textureIndex(int type) { + switch (type) { + case 1: + return (12 << 7) + 9; + case 2: + return (12 << 7) + 10; + default: + return (12 << 7) + 9; + } + } + + private static final ITexture textureOverlay = TextureFactory.of( + TextureFactory.builder() + .addIcon(OVERLAY_FUSION1) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FUSION1_GLOW) + .extFacing() + .glow() + .build()); + + public ITexture getTextureOverlay() { + return textureOverlay; + } + + @Override + public boolean allowCoverOnSide(ForgeDirection side, GTItemStack aStack) { + return side != getBaseMetaTileEntity().getFrontFacing(); + } + + @Override + public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) { + return checkPiece(MAIN_NAME, 26, 26, 4); + } + + @Override + public void construct(ItemStack itemStack, boolean b) { + buildPiece(MAIN_NAME, itemStack, b, 26, 26, 4); + } + + @Override + public int survivalConstruct(ItemStack stackSize, int elementBudget, ISurvivalBuildEnvironment env) { + if (mMachine) return -1; + int realBudget = elementBudget >= 200 ? elementBudget : Math.min(200, elementBudget * 5); + return survivialBuildPiece(MAIN_NAME, stackSize, 26, 26, 4, realBudget, env, false, true); + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing, + int colorIndex, boolean aActive, boolean aRedstone) { + if (side == facing) return new ITexture[] { TextureFactory.builder() + .addIcon(MACHINE_CASING_ANTIMATTER) + .extFacing() + .build(), getTextureOverlay() }; + if (aActive) return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(53) }; + return new ITexture[] { TextureFactory.builder() + .addIcon(MACHINE_CASING_ANTIMATTER) + .extFacing() + .build() }; + } + + @Override + public boolean isCorrectMachinePart(ItemStack aStack) { + return true; + } + + @Override + public void onMachineBlockUpdate() { + mUpdate = 100; + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onPostTick(aBaseMetaTileEntity, aTick); + if (aBaseMetaTileEntity.isServerSide()) { + FluidStack[] antimatterStored = new FluidStack[16]; + long totalAntimatterAmount = 0; + for (int i = 0; i < amOutputHatches.size(); i++) { + if (amOutputHatches.get(i) == null || !amOutputHatches.get(i) + .isValid() + || amOutputHatches.get(i) + .getFluid() == null) + continue; + antimatterStored[i] = amOutputHatches.get(i) + .getFluid() + .copy(); + totalAntimatterAmount += antimatterStored[i].amount; + } + drainEnergyInput(calculateEnergyContainmentCost(totalAntimatterAmount)); + + if ((this.mProgresstime >= this.mMaxProgresstime) && (!isAllowedToWork())) { + setProtoRender(false); + } + } + } + + private long calculateContainedAntimatter() { + long antimatterStored = 0; + for (int i = 0; i < amOutputHatches.size(); i++) { + if (amOutputHatches.get(i) == null || !amOutputHatches.get(i) + .isValid() + || amOutputHatches.get(i) + .getFluid() == null) + continue; + antimatterStored += amOutputHatches.get(i) + .getFluid().amount; + } + return antimatterStored; + } + + private void setModifiers(FluidStack inputFluid, float step, FluidStack[] upgradeFluids, int upgradeId) { + for (int tier = 1; tier <= upgradeFluids.length; tier++) { + if (inputFluid.isFluidEqual(upgradeFluids[tier - 1])) { + if (inputFluid.amount >= fluidConsumptions[upgradeId]) { + modifiers[upgradeId] = step * tier; + upgradeFluids[upgradeId] = inputFluid; + } + } + } + } + + @Override + public CheckRecipeResult checkProcessing() { + startRecipeProcessing(); + FluidStack[] antimatterStored = new FluidStack[16]; + long totalAntimatterAmount = 0; + long minAntimatterAmount = Long.MAX_VALUE; + // Calculate the total amount of antimatter in all 16 hatches and the minimum amount found in any individual + // hatch + for (int i = 0; i < amOutputHatches.size(); i++) { + if (amOutputHatches.get(i) == null || !amOutputHatches.get(i) + .isValid() + || amOutputHatches.get(i) + .getFluid() == null) + continue; + antimatterStored[i] = amOutputHatches.get(i) + .getFluid() + .copy(); + totalAntimatterAmount += antimatterStored[i].amount; + minAntimatterAmount = Math.min(minAntimatterAmount, antimatterStored[i].amount); + } + int ratioLosses = 0; + // Reduce the amount of antimatter in each hatch by half of the difference between the lowest amount and current + // hatch contents + for (int i = 0; i < amOutputHatches.size(); i++) { + if (amOutputHatches.get(i) == null || !amOutputHatches.get(i) + .isValid() + || amOutputHatches.get(i) + .getFluid() == null) + continue; + FluidStack fluid = amOutputHatches.get(i) + .getFluid() + .copy(); + ratioLosses -= amOutputHatches.get(i) + .drain((int) ((fluid.amount - minAntimatterAmount) * 0.5), true).amount; + } + + // Check for upgrade fluids + long containedProtomatter = 0; + + fluidConsumptions[MAGNETIC_ID] = (int) Math.ceil(Math.pow(totalAntimatterAmount, 0.5)); + fluidConsumptions[GRAVITY_ID] = (int) Math.ceil(Math.pow(totalAntimatterAmount, 0.5)); + fluidConsumptions[CONTAINMENT_ID] = (int) Math.ceil(Math.pow(totalAntimatterAmount, 2 / 7)); + fluidConsumptions[ACTIVATION_ID] = (int) Math.ceil(Math.pow(totalAntimatterAmount, 1 / 3)); + + for (int i = 0; i < modifiers.length; i++) { + modifiers[i] = 0.0f; + upgradeFluids[i] = null; + } + + List<FluidStack> inputFluids = getStoredFluids(); + for (int i = 0; i < inputFluids.size(); i++) { + FluidStack inputFluid = inputFluids.get(i); + setModifiers(inputFluid, -0.15f, magneticUpgrades, MAGNETIC_ID); + setModifiers(inputFluid, -0.05f, gravityUpgrades, GRAVITY_ID); + setModifiers(inputFluid, 0.05f, containmentUpgrades, CONTAINMENT_ID); + setModifiers(inputFluid, 0.05f, activationUpgrades, ACTIVATION_ID); + } + + long energyCost = calculateEnergyCost(totalAntimatterAmount); + + // If we run out of energy, reduce contained antimatter by 10% + if (!drainEnergyInput(energyCost)) { + decimateAntimatter(); + stopMachine(ShutDownReasonRegistry.POWER_LOSS); + endRecipeProcessing(); + setProtoRender(false); + return CheckRecipeResultRegistry.insufficientPower(energyCost); + } + + // Drain upgrade fluids + for (int i = 0; i < upgradeFluids.length; i++) { + FluidStack upgradeFluid = upgradeFluids[i]; + if (upgradeFluid != null) { + for (FluidStack inputFluid : inputFluids.toArray(new FluidStack[0])) { + if (inputFluid.isFluidEqual(upgradeFluid)) { + inputFluid.amount -= fluidConsumptions[i]; + } + } + } + } + + int antimatterChange = distributeAntimatterToHatch( + amOutputHatches, + totalAntimatterAmount, + containedProtomatter); + + // We didn't have enough protomatter, reduce antimatter by 10% and stop the machine. + if (!this.depleteInput(MaterialsUEVplus.Protomatter.getFluid((long) Math.abs(antimatterChange)))) { + decimateAntimatter(); + stopMachine(ShutDownReasonRegistry.outOfFluid(MaterialsUEVplus.Protomatter.getFluid(1L))); + endRecipeProcessing(); + setProtoRender(false); + return CheckRecipeResultRegistry.NO_FUEL_FOUND; + } + + this.guiAntimatterChange = ratioLosses + antimatterChange; + this.guiAntimatterAmount = calculateContainedAntimatter(); + + updateAntimatterSize(this.guiAntimatterAmount); + setProtoRender(true); + + mEfficiency = (10000 - (getIdealStatus() - getRepairStatus()) * 1000); + mEfficiencyIncrease = 10000; + mMaxProgresstime = speed; + + endRecipeProcessing(); + return CheckRecipeResultRegistry.SUCCESSFUL; + } + + /* + * How much passive energy is drained every tick + * Base containment cost: 10M EU/t + * The containment cost ramps up by the amount of antimatter each tick, up to 1000 times + * If the current cost is more than 1000 times the amount of antimatter, or + * if no antimatter is in the hatches, the value will decay by 1% every tick + */ + private long calculateEnergyContainmentCost(long antimatterAmount) { + if (antimatterAmount == 0) { + rollingCost *= 0.995; + if (rollingCost < 100) rollingCost = 0; + } else if (rollingCost < antimatterAmount * 1000) { + rollingCost += antimatterAmount; + } else { + rollingCost *= 0.995; + } + long value = BASE_CONSUMPTION + (long) Math.pow(rollingCost, 1.5 + modifiers[MAGNETIC_ID]); + this.guiPassiveEnergy = value; + return value; + } + + // How much energy is consumed when machine does one operation + // Base formula: (Antimatter * 10000) ^ (1.5) + private long calculateEnergyCost(long antimatterAmount) { + long value = (long) Math.pow(antimatterAmount * activeBaseMult, activeBaseExp + modifiers[GRAVITY_ID]); + this.guiActiveEnergy = value; + return value; + } + + private void decimateAntimatter() { + for (int i = 0; i < amOutputHatches.size(); i++) { + if (amOutputHatches.get(i) == null || !amOutputHatches.get(i) + .isValid() + || amOutputHatches.get(i) + .getFluid() == null) + continue; + FluidStack fluid = amOutputHatches.get(i) + .getFluid() + .copy(); + amOutputHatches.get(i) + .drain((int) Math.floor(fluid.amount * 0.1), true); + } + } + + private int distributeAntimatterToHatch(List<AntimatterOutputHatch> hatches, long totalAntimatterAmount, + long protomatterAmount) { + double coeff = Math.pow((totalAntimatterAmount), 0.5 + modifiers[CONTAINMENT_ID]); + int difference = 0; + + for (AntimatterOutputHatch hatch : hatches) { + // Skewed normal distribution multiplied by coefficient from antimatter amount + // We round up so you are guaranteed to be antimatter positive on the first run (reduces startup RNG) + int change = (int) (Math.ceil((r.nextGaussian() + baseSkew + modifiers[ACTIVATION_ID]) * (coeff / 16))); + difference += change; + if (change >= 0) { + hatch.fill(MaterialsUEVplus.Antimatter.getFluid((long) (change)), true); + } else { + hatch.drain(-change, true); + } + } + return difference; + } + + @Override + public void clearHatches() { + super.clearHatches(); + amOutputHatches.clear(); + } + + @Override + public void onRemoval() { + if (this.isLoadedChunk) GTChunkManager.releaseTicket((TileEntity) getBaseMetaTileEntity()); + super.onRemoval(); + } + + public int getChunkX() { + return getBaseMetaTileEntity().getXCoord() >> 4; + } + + public int getChunkZ() { + return getBaseMetaTileEntity().getZCoord() >> 4; + } + + private boolean addEnergyInjector(IGregTechTileEntity aBaseMetaTileEntity, int aBaseCasingIndex) { + IMetaTileEntity aMetaTileEntity = aBaseMetaTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null) return false; + if (aMetaTileEntity instanceof MTEHatch hatch && ExoticEnergyInputHelper.isExoticEnergyInput(aMetaTileEntity)) { + hatch.updateTexture(aBaseCasingIndex); + hatch.updateCraftingIcon(this.getMachineCraftingIcon()); + return mExoticEnergyHatches.add(hatch); + } + return false; + } + + private boolean addFluidIO(IGregTechTileEntity aBaseMetaTileEntity, int aBaseCasingIndex) { + IMetaTileEntity aMetaTileEntity = aBaseMetaTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null) return false; + if (aMetaTileEntity instanceof MTEHatch hatch) { + hatch.updateTexture(aBaseCasingIndex); + hatch.updateCraftingIcon(this.getMachineCraftingIcon()); + } + if (aMetaTileEntity instanceof MTEHatchInput tInput) { + tInput.mRecipeMap = getRecipeMap(); + return mInputHatches.add(tInput); + } + if (aMetaTileEntity instanceof AntimatterOutputHatch tAntimatter) { + return amOutputHatches.add(tAntimatter); + } + if (aMetaTileEntity instanceof MTEHatchOutput tOutput) { + return mOutputHatches.add(tOutput); + } + if (aMetaTileEntity instanceof IDualInputHatch tInput) { + tInput.updateCraftingIcon(this.getMachineCraftingIcon()); + return mDualInputHatches.add(tInput); + } + return false; + } + + private boolean addAntimatterHatch(IGregTechTileEntity aBaseMetaTileEntity, int aBaseCasingIndex) { + IMetaTileEntity aMetaTileEntity = aBaseMetaTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null) return false; + if (aMetaTileEntity instanceof MTEHatch hatch) { + hatch.updateTexture(aBaseCasingIndex); + hatch.updateCraftingIcon(this.getMachineCraftingIcon()); + } + if (aMetaTileEntity instanceof AntimatterOutputHatch tAntimatter) { + return amOutputHatches.add(tAntimatter); + } + + return false; + } + + @Override + public int getMaxEfficiency(ItemStack aStack) { + return 10000; + } + + @Override + public int getDamageToComponent(ItemStack aStack) { + return 0; + } + + @Override + public boolean explodesOnComponentBreak(ItemStack aStack) { + return false; + } + + @Override + public OverclockDescriber getOverclockDescriber() { + return null; + } + + @Override + public String[] getInfoData() { + IGregTechTileEntity baseMetaTileEntity = getBaseMetaTileEntity(); + + long storedEnergy = 0; + long maxEnergy = 0; + + for (MTEHatch tHatch : mExoticEnergyHatches) { + storedEnergy += tHatch.getBaseMetaTileEntity() + .getStoredEU(); + maxEnergy += tHatch.getBaseMetaTileEntity() + .getEUCapacity(); + } + + return new String[] { EnumChatFormatting.BLUE + "Antimatter Forge " + EnumChatFormatting.GRAY, + StatCollector.translateToLocal("GT5U.multiblock.Progress") + ": " + + EnumChatFormatting.GREEN + + GTUtility.formatNumbers(mProgresstime) + + EnumChatFormatting.RESET + + "t / " + + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(mMaxProgresstime) + + EnumChatFormatting.RESET + + "t", + StatCollector.translateToLocal("GT5U.multiblock.energy") + ": " + + EnumChatFormatting.GREEN + + GTUtility.formatNumbers(storedEnergy) + + EnumChatFormatting.RESET + + " EU / " + + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(maxEnergy) + + EnumChatFormatting.RESET + + " EU", + StatCollector.translateToLocal("gui.AntimatterForge.0") + ": " + + EnumChatFormatting.BLUE + + GTUtility.formatNumbers(this.guiAntimatterAmount) + + EnumChatFormatting.RESET + + " L", + StatCollector.translateToLocal("gui.AntimatterForge.1") + ": " + + EnumChatFormatting.RED + + GTUtility.formatNumbers(this.guiPassiveEnergy) + + EnumChatFormatting.RESET + + " EU/t", + StatCollector.translateToLocal("gui.AntimatterForge.2") + ": " + + EnumChatFormatting.LIGHT_PURPLE + + GTUtility.formatNumbers(this.guiActiveEnergy) + + EnumChatFormatting.RESET + + " EU/t", + StatCollector.translateToLocal("gui.AntimatterForge.3") + ": " + + EnumChatFormatting.AQUA + + GTUtility.formatNumbers(this.guiAntimatterChange) + + EnumChatFormatting.RESET + + " EU/t" }; + } + + private long getAntimatterAmount() { + return this.guiAntimatterAmount; + } + + private long getPassiveConsumption() { + return this.guiPassiveEnergy; + } + + private long getActiveConsumption() { + return this.guiActiveEnergy; + } + + private long getAntimatterChange() { + return this.guiAntimatterChange; + } + + protected long antimatterAmountCache; + protected long passiveCostCache; + protected long activeCostCache; + protected long antimatterChangeCache; + protected static final NumberFormatMUI numberFormat = new NumberFormatMUI(); + + protected static DecimalFormat standardFormat; + + static { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US); + dfs.setExponentSeparator("e"); + standardFormat = new DecimalFormat("0.00E0", dfs); + } + + @Override + protected void drawTexts(DynamicPositionedColumn screenElements, SlotWidget inventorySlot) { + super.drawTexts(screenElements, inventorySlot); + + screenElements + .widget( + new TextWidget() + .setStringSupplier( + () -> StatCollector.translateToLocal("gui.AntimatterForge.0") + ": " + + EnumChatFormatting.BLUE + + numberFormat.format(antimatterAmountCache) + + EnumChatFormatting.WHITE + + " L") + .setDefaultColor(COLOR_TEXT_WHITE.get())) + .widget(new FakeSyncWidget.LongSyncer(this::getAntimatterAmount, val -> antimatterAmountCache = val)) + .widget( + new TextWidget() + .setStringSupplier( + () -> StatCollector.translateToLocal("gui.AntimatterForge.1") + ": " + + EnumChatFormatting.RED + + standardFormat.format(passiveCostCache) + + EnumChatFormatting.WHITE + + " EU/t") + .setDefaultColor(COLOR_TEXT_WHITE.get())) + .widget(new FakeSyncWidget.LongSyncer(this::getPassiveConsumption, val -> passiveCostCache = val)) + .widget( + new TextWidget() + .setStringSupplier( + () -> StatCollector.translateToLocal("gui.AntimatterForge.2") + ": " + + EnumChatFormatting.LIGHT_PURPLE + + standardFormat.format(activeCostCache) + + EnumChatFormatting.WHITE + + " EU") + .setDefaultColor(COLOR_TEXT_WHITE.get())) + .widget(new FakeSyncWidget.LongSyncer(this::getActiveConsumption, val -> activeCostCache = val)) + .widget( + new TextWidget() + .setStringSupplier( + () -> StatCollector.translateToLocal("gui.AntimatterForge.3") + ": " + + EnumChatFormatting.AQUA + + numberFormat.format(antimatterChangeCache) + + EnumChatFormatting.WHITE + + " L") + .setDefaultColor(COLOR_TEXT_WHITE.get())) + .widget(new FakeSyncWidget.LongSyncer(this::getAntimatterChange, val -> antimatterChangeCache = val)); + } + + @Override + public boolean getDefaultHasMaintenanceChecks() { + return false; + } + + @Override + public void stopMachine(@Nonnull ShutDownReason reason) { + super.stopMachine(reason); + setProtoRender(false); + } + + @Override + public void onBlockDestroyed() { + super.onBlockDestroyed(); + destroyAntimatterRender(); + } + + public void updateAntimatterSize(float antimatterAmount) { + TileAntimatter render = forceGetAntimatterRender(); + + if (antimatterAmount < 0) { + setProtoRender(false); + render.setCoreSize(0); + return; + } + + float size = (float) Math.pow(antimatterAmount, 0.17); + render.setCoreSize(size); + } + + public void setProtoRender(boolean flag) { + TileAntimatter render = forceGetAntimatterRender(); + render.setProtomatterRender(flag); + if (flag) render.setRotationFields(getRotation(), getDirection()); + } + + public TileAntimatter getAntimatterRender() { + IGregTechTileEntity gregTechTileEntity = this.getBaseMetaTileEntity(); + World world = gregTechTileEntity.getWorld(); + + if (world == null) { + return null; + } + + int x = gregTechTileEntity.getXCoord(); + int y = gregTechTileEntity.getYCoord(); + int z = gregTechTileEntity.getZCoord(); + + double xOffset = 16 * getExtendedFacing().getRelativeBackInWorld().offsetX; + double zOffset = 16 * getExtendedFacing().getRelativeBackInWorld().offsetZ; + double yOffset = 16 * getExtendedFacing().getRelativeBackInWorld().offsetY; + + int wX = (int) (x + xOffset); + int wY = (int) (y + yOffset); + int wZ = (int) (z + zOffset); + + return (TileAntimatter) world.getTileEntity(wX, wY, wZ); + } + + public void destroyAntimatterRender() { + IGregTechTileEntity gregTechTileEntity = this.getBaseMetaTileEntity(); + World world = gregTechTileEntity.getWorld(); + + if (world == null) { + return; + } + + int x = gregTechTileEntity.getXCoord(); + int y = gregTechTileEntity.getYCoord(); + int z = gregTechTileEntity.getZCoord(); + + int xOffset = 16 * getExtendedFacing().getRelativeBackInWorld().offsetX; + int yOffset = 16 * getExtendedFacing().getRelativeBackInWorld().offsetY; + int zOffset = 16 * getExtendedFacing().getRelativeBackInWorld().offsetZ; + + int xTarget = x + xOffset; + int yTarget = y + yOffset; + int zTarget = z + zOffset; + + world.setBlock(xTarget, yTarget, zTarget, Blocks.air); + } + + public void createAntimatterRender() { + IGregTechTileEntity gregTechTileEntity = this.getBaseMetaTileEntity(); + World world = gregTechTileEntity.getWorld(); + + if (world == null) { + return; + } + + int x = gregTechTileEntity.getXCoord(); + int y = gregTechTileEntity.getYCoord(); + int z = gregTechTileEntity.getZCoord(); + + int xOffset = 16 * getExtendedFacing().getRelativeBackInWorld().offsetX; + int yOffset = 16 * getExtendedFacing().getRelativeBackInWorld().offsetY; + int zOffset = 16 * getExtendedFacing().getRelativeBackInWorld().offsetZ; + + int wX = x + xOffset; + int wY = y + yOffset; + int wZ = z + zOffset; + + world.setBlock(wX, wY, wZ, Blocks.air); + world.setBlock(wX, wY, wZ, Loaders.antimatterRenderBlock); + } + + public TileAntimatter forceGetAntimatterRender() { + TileAntimatter render = getAntimatterRender(); + if (render != null) return render; + else createAntimatterRender(); + return getAntimatterRender(); + } + +} |