aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/goodgenerator/blocks/tileEntity
diff options
context:
space:
mode:
authorSampsa <69092953+S4mpsa@users.noreply.github.com>2024-09-12 15:03:41 +0300
committerGitHub <noreply@github.com>2024-09-12 14:03:41 +0200
commitc2faa68ac8369db571e8136962b1cac5db206dd0 (patch)
treea2e6ab7379d32e13ca3a5a8de847e99957bfdf49 /src/main/java/goodgenerator/blocks/tileEntity
parent07cc2ec931b0e479026e78298a7bd926019c9334 (diff)
downloadGT5-Unofficial-c2faa68ac8369db571e8136962b1cac5db206dd0.tar.gz
GT5-Unofficial-c2faa68ac8369db571e8136962b1cac5db206dd0.tar.bz2
GT5-Unofficial-c2faa68ac8369db571e8136962b1cac5db206dd0.zip
Add Antimatter Power Generation (#3117)
Co-authored-by: BlueWeabo <ilia.iliev2005@gmail.com> Co-authored-by: Mary <33456283+FourIsTheNumber@users.noreply.github.com> Co-authored-by: BucketBrigade <138534411+CookieBrigade@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Martin Robertz <dream-master@gmx.net>
Diffstat (limited to 'src/main/java/goodgenerator/blocks/tileEntity')
-rw-r--r--src/main/java/goodgenerator/blocks/tileEntity/AntimatterForge.java978
-rw-r--r--src/main/java/goodgenerator/blocks/tileEntity/AntimatterGenerator.java572
-rw-r--r--src/main/java/goodgenerator/blocks/tileEntity/AntimatterOutputHatch.java74
-rw-r--r--src/main/java/goodgenerator/blocks/tileEntity/render/TileAntimatter.java130
4 files changed, 1754 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();
+ }
+
+}
diff --git a/src/main/java/goodgenerator/blocks/tileEntity/AntimatterGenerator.java b/src/main/java/goodgenerator/blocks/tileEntity/AntimatterGenerator.java
new file mode 100644
index 0000000000..89bb56acdd
--- /dev/null
+++ b/src/main/java/goodgenerator/blocks/tileEntity/AntimatterGenerator.java
@@ -0,0 +1,572 @@
+package goodgenerator.blocks.tileEntity;
+
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.lazy;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock;
+import static gregtech.api.enums.Textures.BlockIcons.*;
+import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY;
+import static gregtech.api.util.GTStructureUtility.buildHatchAdder;
+import static gregtech.api.util.GTStructureUtility.ofFrame;
+import static gregtech.common.misc.WirelessNetworkManager.addEUToGlobalEnergyMap;
+import static gregtech.common.misc.WirelessNetworkManager.strongCheckOrAddUser;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.UUID;
+
+import net.minecraft.block.Block;
+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.StatCollector;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.FluidStack;
+
+import com.gtnewhorizon.structurelib.alignment.constructable.IConstructable;
+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.api.drawable.IDrawable;
+import com.gtnewhorizons.modularui.api.drawable.UITexture;
+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.DynamicPositionedColumn;
+import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget;
+import com.gtnewhorizons.modularui.common.widget.SlotWidget;
+import com.gtnewhorizons.modularui.common.widget.TextWidget;
+
+import bartworks.common.loaders.ItemRegistry;
+import goodgenerator.blocks.structures.AntimatterStructures;
+import goodgenerator.loader.Loaders;
+import gregtech.api.GregTechAPI;
+import gregtech.api.enums.HatchElement;
+import gregtech.api.enums.Materials;
+import gregtech.api.enums.MaterialsUEVplus;
+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.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.GTUtility;
+import gregtech.api.util.HatchElementBuilder;
+import gregtech.api.util.MultiblockTooltipBuilder;
+import kekztech.client.gui.KTUITextures;
+import tectech.thing.metaTileEntity.hatch.MTEHatchDynamoTunnel;
+
+public class AntimatterGenerator extends MTEExtendedPowerMultiBlockBase
+ implements IConstructable, ISurvivalConstructable {
+
+ public static final String MAIN_NAME = "antimatterGenerator";
+ protected IStructureDefinition<AntimatterGenerator> multiDefinition = null;
+ protected int times = 1;
+ private UUID owner_uuid;
+ private boolean wirelessEnabled = false;
+ private boolean canUseWireless = true;
+ private long euCapacity = 0;
+ private long euLastCycle = 0;
+ private float annihilationEfficiency = 0f;
+
+ private static final ClassValue<IStructureDefinition<AntimatterGenerator>> STRUCTURE_DEFINITION = new ClassValue<IStructureDefinition<AntimatterGenerator>>() {
+
+ @Override
+ protected IStructureDefinition<AntimatterGenerator> computeValue(Class<?> type) {
+ return StructureDefinition.<AntimatterGenerator>builder()
+ .addShape(MAIN_NAME, AntimatterStructures.ANTIMATTER_GENERATOR)
+ .addElement('F', lazy(x -> ofFrame(Materials.Naquadria))) // Naquadria Frame Box
+ .addElement('D', lazy(x -> ofBlock(x.getCasingBlock(1), x.getCasingMeta(1)))) // Black Casing
+ .addElement('G', lazy(x -> ofBlock(x.getCoilBlock(1), x.getCoilMeta(1)))) // Annihilation Coil
+ .addElement('B', lazy(x -> ofBlock(x.getCoilBlock(2), x.getCoilMeta(2)))) // Containment Coil
+ .addElement('C', lazy(x -> ofBlock(x.getCasingBlock(2), x.getCasingMeta(2)))) // White Casing
+ .addElement('A', lazy(x -> ofBlock(x.getGlassBlock(), x.getGlassMeta()))) // Glass
+ .addElement('E', lazy(x -> ofBlock(GregTechAPI.sBlockCasings9, 1))) // Filter Casing
+ .addElement(
+ 'H',
+ lazy(
+ x -> HatchElementBuilder.<AntimatterGenerator>builder()
+ .anyOf(HatchElement.ExoticEnergy)
+ .adder(AntimatterGenerator::addLaserSource)
+ .casingIndex(x.textureIndex(2))
+ .dot(1)
+ .buildAndChain(x.getCasingBlock(2), x.getCasingMeta(2))))
+ .addElement(
+ 'I',
+ lazy(
+ x -> buildHatchAdder(AntimatterGenerator.class).atLeast(HatchElement.InputHatch)
+ .casingIndex(x.textureIndex(1))
+ .dot(2)
+ .buildAndChain(x.getCasingBlock(1), x.getCasingMeta(1))))
+ .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()));
+ };
+
+ private boolean addLaserSource(IGregTechTileEntity aBaseMetaTileEntity, int aBaseCasingIndex) {
+ IMetaTileEntity aMetaTileEntity = aBaseMetaTileEntity.getMetaTileEntity();
+ if (aMetaTileEntity == null) return false;
+ if (aMetaTileEntity instanceof MTEHatchDynamoTunnel tHatch) {
+ tHatch.updateTexture(aBaseCasingIndex);
+ return mExoticEnergyHatches.add(tHatch);
+ }
+ return false;
+ }
+
+ public AntimatterGenerator(String name) {
+ super(name);
+ }
+
+ public AntimatterGenerator(int id, String name, String nameRegional) {
+ super(id, name, nameRegional);
+ }
+
+ @Override
+ public boolean isCorrectMachinePart(ItemStack aStack) {
+ return true;
+ }
+
+ @Override
+ public RecipeMap<?> getRecipeMap() {
+ return null;
+ }
+
+ @Override
+ public CheckRecipeResult checkProcessing() {
+ startRecipeProcessing();
+ List<FluidStack> inputFluids = getStoredFluids();
+ long containedAntimatter = 0;
+ FluidStack catalystFluid = null;
+ int i = 0;
+
+ while (i < inputFluids.size()) {
+ FluidStack inputFluid = inputFluids.get(i);
+ if (inputFluid.isFluidEqual(MaterialsUEVplus.Antimatter.getFluid(1))) {
+ containedAntimatter += inputFluid.amount;
+ } else {
+ catalystFluid = inputFluid.copy();
+ }
+ // We annihilate everything, even if it was the wrong fluid
+ inputFluid.amount = 0;
+ i++;
+ }
+ // If i != 2, we iterated more than 2 times and have too many fluids.
+ if (i == 2 && containedAntimatter > 0 && catalystFluid != null) {
+ createEU(containedAntimatter, catalystFluid);
+ }
+
+ endRecipeProcessing();
+ return CheckRecipeResultRegistry.SUCCESSFUL;
+ }
+
+ // (Antimatter^(EXP) * 1e12 )/(Math.min((Antimatter/Matter),(Matter/Antimatter)))
+ public void createEU(long antimatter, FluidStack catalyst) {
+ Float modifier = null;
+
+ if (catalyst.isFluidEqual(Materials.Copper.getMolten(1L))) {
+ modifier = 1.0F;
+ } else if (catalyst.isFluidEqual(Materials.SuperconductorUIVBase.getMolten(1L))) {
+ modifier = 1.02F;
+ } else if (catalyst.isFluidEqual(Materials.SuperconductorUMVBase.getMolten(1L))) {
+ modifier = 1.03F;
+ } else if (catalyst.isFluidEqual(MaterialsUEVplus.BlackDwarfMatter.getMolten(1L))) {
+ modifier = 1.04F;
+ }
+ long catalystCount = catalyst.amount;
+ long generatedEU = 0;
+
+ if (modifier != null) {
+ float efficiency = Math
+ .min(((float) antimatter / (float) catalystCount), ((float) catalystCount / (float) antimatter));
+ this.annihilationEfficiency = efficiency;
+ generatedEU = (long) ((Math.pow(antimatter, modifier) * 1e12) * efficiency);
+ }
+
+ if (wirelessEnabled && modifier >= 1.03F) {
+ // Clamp the EU to the maximum of the hatches so wireless cannot bypass the limitations
+ generatedEU = Math.min(generatedEU, euCapacity);
+ this.euLastCycle = generatedEU;
+ addEUToGlobalEnergyMap(owner_uuid, generatedEU);
+ } else {
+ this.euLastCycle = generatedEU;
+ float invHatchCount = 1.0F / (float) mExoticEnergyHatches.size();
+ for (MTEHatch tHatch : getExoticEnergyHatches()) {
+ if (tHatch instanceof MTEHatchDynamoTunnel tLaserSource) {
+ tLaserSource.setEUVar(tLaserSource.getEUVar() + (long) (generatedEU * invHatchCount));
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) {
+ this.euCapacity = 0;
+ for (MTEHatch tHatch : getExoticEnergyHatches()) {
+ if (tHatch instanceof MTEHatchDynamoTunnel tLaserSource) {
+ this.euCapacity += tLaserSource.maxEUStore();
+ }
+ }
+ return checkPiece(MAIN_NAME, 17, 41, 0);
+ }
+
+ @Override
+ public int survivalConstruct(ItemStack stackSize, int elementBudget, ISurvivalBuildEnvironment env) {
+ if (mMachine) return -1;
+ return survivialBuildPiece(MAIN_NAME, stackSize, 17, 41, 0, elementBudget, env, false, true);
+ }
+
+ @Override
+ public void construct(ItemStack itemStack, boolean hintsOnly) {
+ buildPiece(MAIN_NAME, itemStack, hintsOnly, 17, 41, 0);
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound nbt) {
+ nbt.setBoolean("wirelessEnabled", wirelessEnabled);
+ super.saveNBTData(nbt);
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound nbt) {
+ wirelessEnabled = nbt.getBoolean("wirelessEnabled");
+ super.loadNBTData(nbt);
+ }
+
+ @Override
+ public int getMaxEfficiency(ItemStack aStack) {
+ return 10000;
+ }
+
+ @Override
+ public int getPollutionPerTick(ItemStack aStack) {
+ return 0;
+ }
+
+ @Override
+ public int getDamageToComponent(ItemStack aStack) {
+ return 0;
+ }
+
+ @Override
+ public boolean explodesOnComponentBreak(ItemStack aStack) {
+ return false;
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) {
+ return new AntimatterGenerator(this.MAIN_NAME);
+ }
+
+ @Override
+ public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) {
+ wirelessEnabled = !wirelessEnabled;
+ GTUtility.sendChatToPlayer(aPlayer, "Wireless network mode " + (wirelessEnabled ? "enabled." : "disabled."));
+ if (wirelessEnabled) {
+ GTUtility.sendChatToPlayer(aPlayer, "Wireless only works with UMV Superconductor Base or better.");
+ }
+ }
+
+ @Override
+ public void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
+ super.onPreTick(aBaseMetaTileEntity, aTick);
+
+ if (aBaseMetaTileEntity.isServerSide()) {
+
+ // On first tick find the player name and attempt to add them to the map.
+ if (aTick == 1) {
+
+ // UUID and username of the owner.
+ owner_uuid = aBaseMetaTileEntity.getOwnerUuid();
+
+ strongCheckOrAddUser(owner_uuid);
+ }
+ }
+ }
+
+ @Override
+ protected MultiblockTooltipBuilder createTooltip() {
+ final MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder();
+ tt.addMachineType("Antimatter Generator")
+ .addInfo("Annihilating antimatter like it's 2205!")
+ .addSeparator()
+ .addInfo("Generates energy by reacting Semi-Stable Antimatter with matter")
+ .addInfo("Annihilation uses an equal amount of antimatter and matter")
+ .addInfo(
+ "Consumes " + EnumChatFormatting.GOLD
+ + "all inputs"
+ + EnumChatFormatting.GRAY
+ + " every processing cycle")
+ .addInfo(
+ "Imbalance between antimatter and matter " + EnumChatFormatting.RED
+ + "will waste energy!"
+ + EnumChatFormatting.GRAY)
+ .addInfo(
+ "Any EU that does not fit in laser hatches will be " + EnumChatFormatting.RED
+ + "voided"
+ + EnumChatFormatting.GRAY)
+ .addSeparator()
+ .addInfo("Antimatter base energy value: 1,000,000,000 EU/L")
+ .addInfo("Energy production is exponentially increased depending on the matter used:")
+ .addInfo("Molten Copper: 1.00")
+ .addInfo("Molten SC UIV Base: 1.02")
+ .addInfo("Molten SC UMV Base: 1.03")
+ .addInfo("Molten Black Dwarf Matter: 1.04")
+ .addSeparator()
+ .addInfo("Enable wireless EU mode with screwdriver")
+ .addInfo("Wireless mode requires SC UMV Base or better")
+ .addInfo("Wireless mode uses hatch capacity limit")
+ .addDynamoHatch("1-9, Hint block with dot 4", 4)
+ .addInputHatch("1-6, Hint block with dot 1", 1)
+ .toolTipFinisher("Good Generator");
+ return tt;
+ }
+
+ protected boolean canUseWireless() {
+ return true;
+ }
+
+ @Override
+ public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) {
+ super.addUIWidgets(builder, buildContext);
+ builder.widget(new ButtonWidget().setOnClick((clickData, widget) -> {
+ if (!widget.isClient()) {
+ canUseWireless = canUseWireless();
+ }
+ if (canUseWireless) {
+ wirelessEnabled = !wirelessEnabled;
+ }
+ })
+ .setPlayClickSound(true)
+ .setBackground(() -> {
+ List<UITexture> ret = new ArrayList<>();
+ ret.add(GTUITextures.BUTTON_STANDARD);
+ if (canUseWireless) {
+ if (wirelessEnabled) {
+ ret.add(KTUITextures.OVERLAY_BUTTON_WIRELESS_ON);
+ } else {
+ ret.add(KTUITextures.OVERLAY_BUTTON_WIRELESS_OFF);
+ }
+ } else {
+ ret.add(KTUITextures.OVERLAY_BUTTON_WIRELESS_OFF_DISABLED);
+ }
+ return ret.toArray(new IDrawable[0]);
+ })
+ .setPos(80, 91)
+ .setSize(16, 16)
+ .addTooltip(StatCollector.translateToLocal("gui.kekztech_lapotronicenergyunit.wireless"))
+ .setTooltipShowUpDelay(TOOLTIP_DELAY))
+ .widget(new FakeSyncWidget.BooleanSyncer(() -> wirelessEnabled, val -> wirelessEnabled = val))
+ .widget(new FakeSyncWidget.BooleanSyncer(this::canUseWireless, val -> canUseWireless = val));
+ }
+
+ @Override
+ public String[] getInfoData() {
+ 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.AntimatterGenerator.0") + ": "
+ + EnumChatFormatting.GREEN
+ + GTUtility.formatNumbers(this.euLastCycle)
+ + EnumChatFormatting.RESET
+ + " EU",
+ StatCollector.translateToLocal("gui.AntimatterGenerator.1") + ": "
+ + EnumChatFormatting.AQUA
+ + GTUtility.formatNumbers(Math.ceil(this.annihilationEfficiency * 100))
+ + EnumChatFormatting.RESET
+ + " %" };
+ }
+
+ private long getEnergyProduced() {
+ return this.euLastCycle;
+ }
+
+ private float getEfficiency() {
+ return this.annihilationEfficiency;
+ }
+
+ protected long energyProducedCache;
+ protected float efficiencyCache;
+ 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.AntimatterGenerator.0") + ": "
+ + EnumChatFormatting.BLUE
+ + standardFormat.format(energyProducedCache)
+ + EnumChatFormatting.WHITE
+ + " EU")
+ .setDefaultColor(COLOR_TEXT_WHITE.get()))
+ .widget(new FakeSyncWidget.LongSyncer(this::getEnergyProduced, val -> energyProducedCache = val))
+ .widget(
+ new TextWidget()
+ .setStringSupplier(
+ () -> StatCollector.translateToLocal("gui.AntimatterGenerator.1") + ": "
+ + EnumChatFormatting.RED
+ + numberFormat.format(Math.ceil(efficiencyCache * 100))
+ + EnumChatFormatting.WHITE
+ + " %")
+ .setDefaultColor(COLOR_TEXT_WHITE.get()))
+ .widget(new FakeSyncWidget.FloatSyncer(this::getEfficiency, val -> efficiencyCache = val));
+ }
+
+ @Override
+ public IStructureDefinition<AntimatterGenerator> getStructureDefinition() {
+ return STRUCTURE_DEFINITION.get(getClass());
+ }
+
+ 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
+ @SuppressWarnings("ALL")
+ 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() };
+ }
+
+ public Block getCoilBlock(int type) {
+ switch (type) {
+ case 1:
+ return Loaders.antimatterAnnihilationMatrix;
+ case 2:
+ return Loaders.protomatterActivationCoil;
+ default:
+ return Loaders.antimatterAnnihilationMatrix;
+ }
+ }
+
+ public int getCoilMeta(int type) {
+ return 0;
+ }
+
+ 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) {
+ return 0;
+ }
+
+ public Block getFrameBlock() {
+ return Loaders.antimatterContainmentCasing;
+ }
+
+ public int getFrameMeta() {
+ return 0;
+ }
+
+ public Block getGlassBlock() {
+ return ItemRegistry.bw_realglas2;
+ }
+
+ public int getGlassMeta() {
+ 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;
+ }
+ }
+
+ @Override
+ public boolean getDefaultHasMaintenanceChecks() {
+ return false;
+ }
+
+}
diff --git a/src/main/java/goodgenerator/blocks/tileEntity/AntimatterOutputHatch.java b/src/main/java/goodgenerator/blocks/tileEntity/AntimatterOutputHatch.java
new file mode 100644
index 0000000000..f575e2f315
--- /dev/null
+++ b/src/main/java/goodgenerator/blocks/tileEntity/AntimatterOutputHatch.java
@@ -0,0 +1,74 @@
+package goodgenerator.blocks.tileEntity;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.FluidStack;
+
+import gregtech.api.enums.Materials;
+import gregtech.api.enums.MaterialsUEVplus;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.MetaTileEntity;
+import gregtech.api.metatileentity.implementations.MTEHatchOutput;
+
+public class AntimatterOutputHatch extends MTEHatchOutput {
+
+ private static final FluidStack ANTIMATTER = Materials.Antimatter.getFluid(1);
+
+ public AntimatterOutputHatch(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional, 11);
+ this.mDescriptionArray[1] = "Stores Antimatter";
+ this.mDescriptionArray[2] = "Antimatter can be inserted from any side";
+ this.mDescriptionArray[3] = "Capacity: 16,384,000L";
+ }
+
+ public AntimatterOutputHatch(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) {
+ super(aName, aTier, aDescription, aTextures);
+ setLockedFluidName(
+ MaterialsUEVplus.Antimatter.getFluid(1)
+ .getFluid()
+ .getName());
+ }
+
+ @Override
+ public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) {
+ return new AntimatterOutputHatch(this.mName, this.mTier, this.mDescriptionArray, this.mTextures);
+ }
+
+ @Override
+ public int getCapacity() {
+ return 16_384_000;
+ }
+
+ @Override
+ public boolean isFluidLocked() {
+ return true;
+ }
+
+ @Override
+ protected void onEmptyingContainerWhenEmpty() {
+ // Disable removing the lock
+ }
+
+ @Override
+ public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) {
+ if (!getBaseMetaTileEntity().getCoverInfoAtSide(side)
+ .isGUIClickable()) return;
+ if (aPlayer.isSneaking()) {
+ mMode = (byte) ((mMode + 9) % 10);
+ } else {
+ mMode = (byte) ((mMode + 1) % 10);
+ }
+ }
+
+ @Override
+ public boolean isLiquidInput(ForgeDirection side) {
+ return side != this.getBaseMetaTileEntity()
+ .getFrontFacing();
+ }
+
+ @Override
+ public boolean isLiquidOutput(ForgeDirection side) {
+ return side == getBaseMetaTileEntity().getFrontFacing();
+ }
+}
diff --git a/src/main/java/goodgenerator/blocks/tileEntity/render/TileAntimatter.java b/src/main/java/goodgenerator/blocks/tileEntity/render/TileAntimatter.java
new file mode 100644
index 0000000000..8e2027b36d
--- /dev/null
+++ b/src/main/java/goodgenerator/blocks/tileEntity/render/TileAntimatter.java
@@ -0,0 +1,130 @@
+
+package goodgenerator.blocks.tileEntity.render;
+
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.network.Packet;
+import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation;
+
+public class TileAntimatter extends TileEntity {
+
+ public boolean shouldRender = true;
+
+ // Antimatter Core settings
+ public static final float spikeR = 0.82f, spikeG = 0.92f, spikeB = 1f;
+ public static final float coreR = 0.43f, coreG = 0.40f, coreB = 1f;
+ public static final float maximalRadius = 9; // Includes core radius + spike length
+ // Due to being partially managed by a global timer, rotationSpeedMultiplier shouldn't change
+ // Otherwise it'll cause a snapping effect
+ public final float rotationSpeedMultiplier = 1;
+
+ public float coreScale = 1f;
+ public float coreScaleSnapshot = 1f;
+ public final float coreScaleTransitionTime = 2.5f;
+ public float timeSnapshot;
+ public float spikeFactor = 1f;
+
+ // Protomatter Settings
+ public static float protoSpiralMaxRadius = .5f;
+ public static final float protoR = 0.2f, protoG = 0.2f, protoB = 0.2f;
+ public float protomatterScale = .2f;
+ public boolean protomatterRender = false;
+ public float rotX = 0, rotY = 0, rotZ = 0;
+ public float rotationAngle = 0;
+
+ @Override
+ public void writeToNBT(NBTTagCompound compound) {
+ super.writeToNBT(compound);
+ compound.setFloat("coreScale", coreScale);
+ compound.setFloat("coreScaleSnapshot", coreScaleSnapshot);
+ compound.setFloat("currentTime", timeSnapshot);
+ compound.setFloat("spikeFactor", spikeFactor);
+ compound.setBoolean("protomatterRender", protomatterRender);
+
+ compound.setFloat("rotX", rotX);
+ compound.setFloat("rotY", rotY);
+ compound.setFloat("rotZ", rotZ);
+ compound.setFloat("rotationAngle", rotationAngle);
+ }
+
+ @Override
+ public void readFromNBT(NBTTagCompound compound) {
+ super.readFromNBT(compound);
+ coreScale = compound.getFloat("coreScale");
+ coreScaleSnapshot = compound.getFloat("coreScaleSnapshot");
+ timeSnapshot = compound.getFloat("currentTime");
+ spikeFactor = compound.getFloat("spikeFactor");
+ protomatterRender = compound.getBoolean("protomatterRender");
+
+ rotX = compound.getFloat("rotX");
+ rotY = compound.getFloat("rotY");
+ rotZ = compound.getFloat("rotZ");
+ rotationAngle = compound.getFloat("rotationAngle");
+ }
+
+ @Override
+ public Packet getDescriptionPacket() {
+ NBTTagCompound nbttagcompound = new NBTTagCompound();
+ writeToNBT(nbttagcompound);
+ return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 1, nbttagcompound);
+ }
+
+ @Override
+ public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) {
+ readFromNBT(pkt.func_148857_g());
+ worldObj.markBlockRangeForRenderUpdate(xCoord, yCoord, zCoord, xCoord, yCoord, zCoord);
+ }
+
+ @Override
+ public AxisAlignedBB getRenderBoundingBox() {
+ return AxisAlignedBB.getBoundingBox(
+ xCoord - maximalRadius - 1,
+ yCoord - maximalRadius - 1,
+ zCoord - maximalRadius - 1,
+ xCoord + maximalRadius + 1,
+ yCoord + maximalRadius + 1,
+ zCoord + maximalRadius + 1);
+ }
+
+ @Override
+ public double getMaxRenderDistanceSquared() {
+ return 65536;
+ }
+
+ public void setProtomatterRender(boolean flag) {
+ protomatterRender = flag;
+ worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
+ }
+
+ public float getSpiralRadius(float normalization) {
+ return Math.min(coreScale / 2.0f * normalization, protoSpiralMaxRadius);
+ }
+
+ public void setCoreSize(float diameter) {
+ coreScaleSnapshot = coreScale;
+ coreScale = diameter;
+ timeSnapshot = this.getWorldObj()
+ .getWorldInfo()
+ .getWorldTotalTime();
+ worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
+ }
+
+ public void setRotationFields(Rotation rotation, ForgeDirection direction) {
+ switch (rotation) {
+ case NORMAL -> rotationAngle = 0;
+ case CLOCKWISE -> rotationAngle = 90;
+ case COUNTER_CLOCKWISE -> rotationAngle = -90;
+ case UPSIDE_DOWN -> rotationAngle = 180;
+ }
+ rotX = direction.offsetX;
+ rotY = direction.offsetY;
+ rotZ = direction.offsetZ;
+ worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
+ }
+
+}