aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/gregtech/api')
-rw-r--r--src/main/java/gregtech/api/GregTech_API.java13
-rw-r--r--src/main/java/gregtech/api/damagesources/GT_DamageSources.java19
-rw-r--r--src/main/java/gregtech/api/enums/GT_Values.java4
-rw-r--r--src/main/java/gregtech/api/enums/HeatingCoilLevel.java14
-rw-r--r--src/main/java/gregtech/api/enums/ItemList.java15
-rw-r--r--src/main/java/gregtech/api/enums/Materials.java10
-rw-r--r--src/main/java/gregtech/api/enums/OrePrefixes.java30
-rw-r--r--src/main/java/gregtech/api/graphs/GenerateNodeMap.java68
-rw-r--r--src/main/java/gregtech/api/graphs/GenerateNodeMapPower.java2
-rw-r--r--src/main/java/gregtech/api/graphs/Node.java10
-rw-r--r--src/main/java/gregtech/api/graphs/NodeList.java12
-rw-r--r--src/main/java/gregtech/api/graphs/PowerNodes.java44
-rw-r--r--src/main/java/gregtech/api/graphs/consumers/ConsumerNode.java4
-rw-r--r--src/main/java/gregtech/api/graphs/consumers/EmptyPowerConsumer.java4
-rw-r--r--src/main/java/gregtech/api/graphs/consumers/NodeEnergyReceiver.java4
-rw-r--r--src/main/java/gregtech/api/graphs/consumers/NodeEnergySink.java4
-rw-r--r--src/main/java/gregtech/api/graphs/consumers/NodeGTBaseMetaTile.java4
-rw-r--r--src/main/java/gregtech/api/graphs/paths/PowerNodePath.java4
-rw-r--r--src/main/java/gregtech/api/gui/GT_Container.java8
-rw-r--r--src/main/java/gregtech/api/gui/GT_Container_BasicMachine.java150
-rw-r--r--src/main/java/gregtech/api/gui/GT_Container_BasicTank.java223
-rw-r--r--src/main/java/gregtech/api/gui/GT_GUIContainerMetaTile_Machine.java7
-rw-r--r--src/main/java/gregtech/api/gui/GT_GUIContainer_BasicMachine.java18
-rw-r--r--src/main/java/gregtech/api/gui/GT_GUICover.java7
-rw-r--r--src/main/java/gregtech/api/interfaces/ITextureBuilder.java8
-rw-r--r--src/main/java/gregtech/api/items/GT_MetaGenerated_Tool.java3
-rw-r--r--src/main/java/gregtech/api/items/GT_RadioactiveCellIC_Item.java3
-rw-r--r--src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java66
-rw-r--r--src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java143
-rw-r--r--src/main/java/gregtech/api/metatileentity/MetaPipeEntity.java25
-rw-r--r--src/main/java/gregtech/api/metatileentity/MetaTileEntity.java18
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java27
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Fluid.java8
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Item.java10
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicGenerator.java52
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java16
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicTank.java2
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Buffer.java20
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_CubicMultiBlockBase.java110
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_EnhancedMultiBlockBase.java185
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Input.java4
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_InputBus.java32
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Output.java10
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_OutputBus.java34
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java43
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Transformer.java2
-rw-r--r--src/main/java/gregtech/api/net/GT_Packet_WirelessRedstoneCover.java95
-rw-r--r--src/main/java/gregtech/api/objects/CollectorUtils.java29
-rw-r--r--src/main/java/gregtech/api/objects/iterators/MergedIterator.java30
-rw-r--r--src/main/java/gregtech/api/threads/GT_Runnable_Cable_Update.java6
-rw-r--r--src/main/java/gregtech/api/util/GT_BaseCrop.java10
-rw-r--r--src/main/java/gregtech/api/util/GT_CoverBehavior.java5
-rw-r--r--src/main/java/gregtech/api/util/GT_FoodStat.java4
-rw-r--r--src/main/java/gregtech/api/util/GT_ModHandler.java82
-rw-r--r--src/main/java/gregtech/api/util/GT_Multiblock_Tooltip_Builder.java202
-rw-r--r--src/main/java/gregtech/api/util/GT_OreDictUnificator.java9
-rw-r--r--src/main/java/gregtech/api/util/GT_Recipe.java91
-rw-r--r--src/main/java/gregtech/api/util/GT_RecipeRegistrator.java163
-rw-r--r--src/main/java/gregtech/api/util/GT_SpawnEventHandler.java4
-rw-r--r--src/main/java/gregtech/api/util/GT_StructureUtility.java183
-rw-r--r--src/main/java/gregtech/api/util/GT_Utility.java246
-rw-r--r--src/main/java/gregtech/api/util/IGT_HatchAdder.java15
-rw-r--r--src/main/java/gregtech/api/util/LightingHelper.java1
-rw-r--r--src/main/java/gregtech/api/util/extensions/ArrayExt.java80
-rw-r--r--src/main/java/gregtech/api/util/extensions/IteratorExt.java12
65 files changed, 2009 insertions, 757 deletions
diff --git a/src/main/java/gregtech/api/GregTech_API.java b/src/main/java/gregtech/api/GregTech_API.java
index ba7e3ab43e..2b9e9297e3 100644
--- a/src/main/java/gregtech/api/GregTech_API.java
+++ b/src/main/java/gregtech/api/GregTech_API.java
@@ -277,6 +277,7 @@ public class GregTech_API {
sMultiThreadedSounds = false,
sDoShowAllItemsInCreative = false,
sColoredGUI = true,
+ sMachineMetalGUI = false,
sConstantEnergy = true,
sMachineExplosions = true,
sMachineFlammable = true,
@@ -426,7 +427,7 @@ public class GregTech_API {
* @param aMeta the Metadata of the Blocks as Bitmask! -1 or ~0 for all Metavalues
*/
public static boolean registerMachineBlock(Block aBlock, int aMeta) {
- if (GT_Utility.isBlockInvalid(aBlock))
+ if (aBlock == null)
return false;
if (GregTech_API.sThaumcraftCompat != null)
GregTech_API.sThaumcraftCompat.registerPortholeBlacklistedBlock(aBlock);
@@ -438,7 +439,7 @@ public class GregTech_API {
* Like above but with boolean Parameters instead of a BitMask
*/
public static boolean registerMachineBlock(Block aBlock, boolean... aMeta) {
- if (GT_Utility.isBlockInvalid(aBlock) || aMeta == null || aMeta.length == 0)
+ if (aBlock == null || aMeta == null || aMeta.length == 0)
return false;
if (GregTech_API.sThaumcraftCompat != null)
GregTech_API.sThaumcraftCompat.registerPortholeBlacklistedBlock(aBlock);
@@ -452,9 +453,11 @@ public class GregTech_API {
* if this Block is a Machine Update Conducting Block
*/
public static boolean isMachineBlock(Block aBlock, int aMeta) {
- if (GT_Utility.isBlockInvalid(aBlock))
- return false;
- return (sMachineIDs.containsKey(aBlock) && (sMachineIDs.get(aBlock) & B[aMeta]) != 0);
+ if (aBlock != null) {
+ Integer id = sMachineIDs.get(aBlock);
+ return id != null && (id & B[aMeta]) != 0;
+ }
+ return false;
}
/**
diff --git a/src/main/java/gregtech/api/damagesources/GT_DamageSources.java b/src/main/java/gregtech/api/damagesources/GT_DamageSources.java
index fd13b9cfee..45f3fd5323 100644
--- a/src/main/java/gregtech/api/damagesources/GT_DamageSources.java
+++ b/src/main/java/gregtech/api/damagesources/GT_DamageSources.java
@@ -1,8 +1,11 @@
package gregtech.api.damagesources;
import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.item.ItemStack;
import net.minecraft.util.*;
+import javax.annotation.Nullable;
+
public class GT_DamageSources {
public static DamageSource getElectricDamage() {
return ic2.api.info.Info.DMG_ELECTRIC;
@@ -33,7 +36,7 @@ public class GT_DamageSources {
}
private static class DamageSourceCombat extends EntityDamageSource {
- private IChatComponent mDeathMessage;
+ private final IChatComponent mDeathMessage;
public DamageSourceCombat(String aType, EntityLivingBase aPlayer, IChatComponent aDeathMessage) {
super(aType, aPlayer);
@@ -70,6 +73,20 @@ public class GT_DamageSources {
}
}
+ public static class DamageSourceHotItem extends DamageSourceHeat {
+ @Nullable
+ private final ItemStack stack;
+
+ public DamageSourceHotItem(@Nullable ItemStack cause) {
+ this.stack = cause;
+ }
+
+ @Nullable
+ public ItemStack getDamagingStack() {
+ return stack;
+ }
+ }
+
public static class DamageSourceExploding extends DamageSource {
public DamageSourceExploding() {
super("exploded");
diff --git a/src/main/java/gregtech/api/enums/GT_Values.java b/src/main/java/gregtech/api/enums/GT_Values.java
index 7152663c42..0c484d05e0 100644
--- a/src/main/java/gregtech/api/enums/GT_Values.java
+++ b/src/main/java/gregtech/api/enums/GT_Values.java
@@ -302,4 +302,8 @@ public class GT_Values {
public static boolean hideAssLineRecipes = false;
public static boolean updateFluidDisplayItems = true;
public static final int STEAM_PER_WATER = 160;
+ /**
+ * If true, then digital chest with AE2 storage bus will be accessible only through AE2
+ */
+ public static boolean disableDigitalChestsExternalAccess = false;
}
diff --git a/src/main/java/gregtech/api/enums/HeatingCoilLevel.java b/src/main/java/gregtech/api/enums/HeatingCoilLevel.java
index d4446e31d0..06ceedff53 100644
--- a/src/main/java/gregtech/api/enums/HeatingCoilLevel.java
+++ b/src/main/java/gregtech/api/enums/HeatingCoilLevel.java
@@ -23,6 +23,8 @@ public enum HeatingCoilLevel {
MAX,
;
+ private static final HeatingCoilLevel[] VALUES = values();
+
/**
* @return the Coils Tier Name
*/
@@ -61,9 +63,17 @@ public enum HeatingCoilLevel {
}
public static HeatingCoilLevel getFromTier(byte tier){
- if (tier < 0 || tier > HeatingCoilLevel.values().length -1)
+ if (tier < 0 || tier > getMaxTier())
return HeatingCoilLevel.None;
- return HeatingCoilLevel.values()[tier+2];
+ return VALUES[tier+2];
+ }
+
+ public static int size() {
+ return VALUES.length;
+ }
+
+ public static int getMaxTier() {
+ return VALUES.length - 1 - 2;
}
}
diff --git a/src/main/java/gregtech/api/enums/ItemList.java b/src/main/java/gregtech/api/enums/ItemList.java
index 5d6de01493..862985faca 100644
--- a/src/main/java/gregtech/api/enums/ItemList.java
+++ b/src/main/java/gregtech/api/enums/ItemList.java
@@ -1571,6 +1571,8 @@ public enum ItemList implements IItemContainer {
FluidRegulator_ZPM,
FluidRegulator_UV,
FluidFilter,
+ ItemFilter_Export,
+ ItemFilter_Import,
CuringOven,
Machine_Multi_Assemblyline,
Machine_Multi_DieselEngine,
@@ -2024,11 +2026,11 @@ public enum ItemList implements IItemContainer {
}
if (tCamelCasedDisplayNameBuilder.length() == 0) {
// CamelCased DisplayName is empty, so use hash of aDisplayName
- tCamelCasedDisplayNameBuilder.append(((Long) (long)aDisplayName.hashCode()).toString());
+ tCamelCasedDisplayNameBuilder.append(((Long) (long) aDisplayName.hashCode()));
}
// Construct a translation key from UnlocalizedName and CamelCased DisplayName
- final String tKey = rStack.getUnlocalizedName() + ".with." + tCamelCasedDisplayNameBuilder.toString() + ".name";
+ final String tKey = rStack.getUnlocalizedName() + ".with." + tCamelCasedDisplayNameBuilder + ".name";
rStack.setStackDisplayName(GT_LanguageManager.addStringLocalization(tKey, aDisplayName));
return GT_Utility.copyAmount(aAmount, rStack);
@@ -2069,4 +2071,13 @@ public enum ItemList implements IItemContainer {
GT_OreDictUnificator.registerOre(tOreName, getWildcard(1));
return this;
}
+
+ /**
+ * Returns the internal stack.
+ * This method is unsafe. It's here only for quick operations.
+ * DON'T CHANGE THE RETURNED VALUE!
+ */
+ public ItemStack getInternalStack_unsafe() {
+ return mStack;
+ }
}
diff --git a/src/main/java/gregtech/api/enums/Materials.java b/src/main/java/gregtech/api/enums/Materials.java
index 1bb38f7621..9075a0a013 100644
--- a/src/main/java/gregtech/api/enums/Materials.java
+++ b/src/main/java/gregtech/api/enums/Materials.java
@@ -508,15 +508,15 @@ public class Materials implements IColorModulationContainer, ISubTagContainer {
public static Materials EnrichedNaquadria = new MaterialBuilder(601, TextureSet.SET_FLUID , "Enriched Naquadria").setName("EnrichedNaquadria").addCell().addFluid().setRGB(52, 52, 52).setColor(Dyes.dyeBlack).constructMaterial();
public static Materials ReinforceGlass = new MaterialBuilder(602, TextureSet.SET_FLUID , "Molten Reinforced Glass").setName("ReinforcedGlass").addCell().addFluid().setRGB(192, 245, 254).setColor(Dyes.dyeWhite).setLiquidTemperature(2000).constructMaterial();
- public static Materials BioMediumRaw = new MaterialBuilder(603, TextureSet.SET_FLUID , "Raw Bio Medium").setName("BioMediumRaw").addCell().addFluid().setRGB(97, 147, 46).setColor(Dyes.dyeLime).constructMaterial();
- public static Materials BioMediumSterilized = new MaterialBuilder(604, TextureSet.SET_FLUID , "Sterilized Bio Medium").setName("BiohMediumSterilized").addCell().addFluid().setRGB(162, 253, 53).setColor(Dyes.dyeLime).constructMaterial();
+ public static Materials BioMediumRaw = new MaterialBuilder(603, TextureSet.SET_FLUID , "Raw Bio Catalyst Medium").setName("BioMediumRaw").addCell().addFluid().setRGB(97, 147, 46).setColor(Dyes.dyeLime).constructMaterial();
+ public static Materials BioMediumSterilized = new MaterialBuilder(604, TextureSet.SET_FLUID , "Sterilized Bio Catalyst Medium").setName("BiohMediumSterilized").addCell().addFluid().setRGB(162, 253, 53).setColor(Dyes.dyeLime).constructMaterial();
public static Materials Chlorobenzene = new MaterialBuilder(605, TextureSet.SET_FLUID , "Chlorobenzene").addCell().addFluid().setRGB(0, 50, 65).setColor(Dyes.dyeGray).setMaterialList(new MaterialStack(Carbon, 6), new MaterialStack(Hydrogen, 5), new MaterialStack(Chlorine, 1)).addElectrolyzerRecipe().constructMaterial();
public static Materials DilutedHydrochloricAcid = new MaterialBuilder(606, TextureSet.SET_FLUID , "Diluted Hydrochloric Acid").setName("DilutedHydrochloricAcid_GT5U").addCell().addFluid().setRGB(153, 167, 163).setColor(Dyes.dyeLightGray).setMaterialList(new MaterialStack(Hydrogen, 1), new MaterialStack(Chlorine, 1)).constructMaterial();
public static Materials Pyrochlore = new MaterialBuilder(607, TextureSet.SET_METALLIC , "Pyrochlore").addDustItems().addOreItems().setRGB(43, 17, 0).setColor(Dyes.dyeBlack).setMaterialList(new MaterialStack(Calcium, 2), new MaterialStack(Niobium, 2), new MaterialStack(Oxygen, 7)).addElectrolyzerRecipe().constructMaterial();
- public static Materials GrowthMediumRaw = new MaterialBuilder(608, TextureSet.SET_FLUID , "Raw Growth Medium").setName("GrowthMediumRaw").addCell().addFluid().setRGB(211, 141, 95).setColor(Dyes.dyeOrange).constructMaterial();
- public static Materials GrowthMediumSterilized = new MaterialBuilder(609, TextureSet.SET_FLUID , "Sterilized Growth Medium").setName("GrowthMediumSterilized").addCell().addFluid().setRGB(222, 170, 135).setColor(Dyes.dyeOrange).constructMaterial();
+ public static Materials GrowthMediumRaw = new MaterialBuilder(608, TextureSet.SET_FLUID , "Raw Growth Catalyst Medium").setName("GrowthMediumRaw").addCell().addFluid().setRGB(211, 141, 95).setColor(Dyes.dyeOrange).constructMaterial();
+ public static Materials GrowthMediumSterilized = new MaterialBuilder(609, TextureSet.SET_FLUID , "Growth Catalyst Medium").setName("GrowthMediumSterilized").addCell().addFluid().setRGB(222, 170, 135).setColor(Dyes.dyeOrange).constructMaterial();
public static Materials FerriteMixture = new MaterialBuilder(612, TextureSet.SET_METALLIC , "Ferrite Mixture").addDustItems().setRGB(180, 180, 180).setColor(Dyes.dyeGray).setMaterialList(new MaterialStack(Nickel, 1), new MaterialStack(Zinc, 1), new MaterialStack(Iron, 4)).constructMaterial();
public static Materials NickelZincFerrite = new MaterialBuilder(613, TextureSet.SET_ROUGH , "Nickel-Zinc Ferrite").addDustItems().addMetalItems().addToolHeadItems().addGearItems().setToolSpeed(3.0f).setDurability(32).setRGB(60, 60, 60).setColor(Dyes.dyeBlack).setBlastFurnaceRequired(true).setBlastFurnaceTemp(1500).setMaterialList(new MaterialStack(Nickel, 1), new MaterialStack(Zinc, 1), new MaterialStack(Iron, 4), new MaterialStack(Oxygen, 8)).constructMaterial();
@@ -2068,7 +2068,7 @@ public class Materials implements IColorModulationContainer, ISubTagContainer {
//SuperconductorUV .add(SubTag.NO_SMASHING, SubTag.NO_SMELTING);
SuperconductorUHV.add(SubTag.NO_SMASHING, SubTag.NO_SMELTING);
- Blaze.add(SubTag.MAGICAL, SubTag.NO_SMELTING, SubTag.SMELTING_TO_FLUID, SubTag.MORTAR_GRINDABLE, SubTag.UNBURNABLE, SubTag.BURNING);
+ Blaze.add(SubTag.MAGICAL, SubTag.SMELTING_TO_FLUID, SubTag.MORTAR_GRINDABLE, SubTag.UNBURNABLE, SubTag.BURNING);
FierySteel.add(SubTag.MAGICAL, SubTag.UNBURNABLE, SubTag.BURNING);
// ElvenElementium .add(SubTag.MAGICAL);
DarkThaumium.add(SubTag.MAGICAL);
diff --git a/src/main/java/gregtech/api/enums/OrePrefixes.java b/src/main/java/gregtech/api/enums/OrePrefixes.java
index ba91886c99..606d12c832 100644
--- a/src/main/java/gregtech/api/enums/OrePrefixes.java
+++ b/src/main/java/gregtech/api/enums/OrePrefixes.java
@@ -1,6 +1,7 @@
package gregtech.api.enums;
import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
import gregtech.api.GregTech_API;
import gregtech.api.enums.TC_Aspects.TC_AspectStack;
import gregtech.api.interfaces.ICondition;
@@ -102,6 +103,7 @@ public enum OrePrefixes {
cellMolten("Cells of Molten stuff", "Molten ", " Cell", true, true, true, true, false, false, false, true, false, false, 0, M * 1, 64, 31), // Hot Cell full of molten stuff, which can be used in the Plasma Generator.
cell("Cells", "", " Cell", true, true, true, true, false, false, true, true, false, false, B[4] | B[8], M * 1, 64, 30), // Regular Gas/Fluid Cell. Introduced by Calclavia
bucket("Buckets", "", " Bucket", true, true, true, true, false, false, true, false, false, false, B[4] | B[8], M * 1, 16, -1), // A vanilla Iron Bucket filled with the Material.
+ bucketClay("Clay Buckets", "", " Clay Bucket", true, true, true, true, false, false, true, false, false, false, B[4] | B[8], M * 1, 16, -1), // An Iguana Tweaks Clay Bucket filled with the Material.
bottle("Bottles", "", " Bottle", true, true, true, true, false, false, false, false, false, false, B[4] | B[8], -1, 16, -1), // Glass Bottle containing a Fluid.
capsule("Capsules", "", " Capsule", false, true, true, true, false, false, false, false, false, false, B[4] | B[8], M * 1, 16, -1),
crystal("Crystals", "", " Crystal", false, true, false, false, false, false, true, false, false, false, B[2], M * 1, 64, -1),
@@ -318,8 +320,22 @@ public enum OrePrefixes {
bars("Bars", "", "", false, false, false, false, false, false, false, false, false, false, 0, -1, 64, -1),
bar("Bars", "", "", false, false, false, false, false, false, false, false, false, false, 0, -1, 64, -1),
toolHeadMallet("Mallet Heads", "", " Mallet Head", true, true, false, false, false, false, true, true, false, false, B[6], M * 6, 16, 127), // Reverse Head consisting out of 6 Ingots.
- handleMallet("Mallet Handle", "", " Handle", true, true, false, false, false, false, true, true, false, false, B[1] | B[2], M / 2, 64, 126); // Reverse Stick made of half an Ingot. Introduced by Eloraam
-
+ handleMallet("Mallet Handle", "", " Handle", true, true, false, false, false, false, true, true, false, false, B[1] | B[2], M / 2, 64, 126), // Reverse Stick made of half an Ingot. Introduced by Eloraam
+
+ // Cracked fluids
+ cellHydroCracked1("Cells", "Lightly Hydro-Cracked ", " Cell", true, true, true, true, false, false, false, true, false, false, 0, M * 1, 64, 30),
+ cellHydroCracked2("Cells", "Moderately Hydro-Cracked ", " Cell", true, true, true, true, false, false, false, true, false, false, 0, M * 1, 64, 30),
+ cellHydroCracked3("Cells", "Severely Hydro-Cracked ", " Cell", true, true, true, true, false, false, false, true, false, false, 0, M * 1, 64, 30),
+ cellSteamCracked1("Cells", "Lightly Steam-Cracked ", " Cell", true, true, true, true, false, false, false, true, false, false, 0, M * 1, 64, 30),
+ cellSteamCracked2("Cells", "Moderately Steam-Cracked ", " Cell", true, true, true, true, false, false, false, true, false, false, 0, M * 1, 64, 30),
+ cellSteamCracked3("Cells", "Severely Steam-Cracked ", " Cell", true, true, true, true, false, false, false, true, false, false, 0, M * 1, 64, 30);
+
+ public static final ImmutableList<OrePrefixes> CELL_TYPES =
+ ImmutableList.of(
+ cell, cellMolten, cellPlasma,
+ cellHydroCracked1, cellHydroCracked2, cellHydroCracked3,
+ cellSteamCracked1, cellSteamCracked2, cellSteamCracked3);
+
public static volatile int VERSION = 509;
static {
@@ -413,6 +429,10 @@ public enum OrePrefixes {
bucket.mNotGeneratedItems.add(Materials.Lava);
bucket.mNotGeneratedItems.add(Materials.Milk);
bucket.mNotGeneratedItems.add(Materials.Water);
+ bucketClay.mNotGeneratedItems.add(Materials.Empty);
+ bucketClay.mNotGeneratedItems.add(Materials.Lava);
+ bucketClay.mNotGeneratedItems.add(Materials.Milk);
+ bucketClay.mNotGeneratedItems.add(Materials.Water);
bottle.mNotGeneratedItems.add(Materials.Empty);
bottle.mNotGeneratedItems.add(Materials.Water);
bottle.mNotGeneratedItems.add(Materials.Milk);
@@ -522,9 +542,8 @@ public enum OrePrefixes {
cableGt02.mSecondaryMaterial = new MaterialStack(Materials.Rubber, plate.mMaterialAmount);
cableGt01.mSecondaryMaterial = new MaterialStack(Materials.Rubber, plate.mMaterialAmount);
bucket.mSecondaryMaterial = new MaterialStack(Materials.Iron, ingot.mMaterialAmount * 3);
- cell.mSecondaryMaterial = new MaterialStack(Materials.Tin, plate.mMaterialAmount * 2);
- cellPlasma.mSecondaryMaterial = new MaterialStack(Materials.Tin, plate.mMaterialAmount * 2);
- cellMolten.mSecondaryMaterial = new MaterialStack(Materials.Tin, plate.mMaterialAmount * 2);
+ bucketClay.mSecondaryMaterial = new MaterialStack(Materials.Clay, dust.mMaterialAmount * 5);
+ CELL_TYPES.forEach(prefix -> prefix.mSecondaryMaterial = new MaterialStack(Materials.Tin, plate.mMaterialAmount * 2));
oreRedgranite.mSecondaryMaterial = new MaterialStack(Materials.GraniteRed, dust.mMaterialAmount);
oreBlackgranite.mSecondaryMaterial = new MaterialStack(Materials.GraniteBlack, dust.mMaterialAmount);
oreNetherrack.mSecondaryMaterial = new MaterialStack(Materials.Netherrack, dust.mMaterialAmount);
@@ -977,7 +996,6 @@ public enum OrePrefixes {
return mLocalizedMaterialPre + OrePrefixes.gem.getDefaultLocalNameFormatForItem(aMaterial);
case crateGtPlate:
return mLocalizedMaterialPre + OrePrefixes.plate.getDefaultLocalNameFormatForItem(aMaterial);
- case cellMolten:
}
switch (aMaterial.mName) {
case "Glass":
diff --git a/src/main/java/gregtech/api/graphs/GenerateNodeMap.java b/src/main/java/gregtech/api/graphs/GenerateNodeMap.java
index 60a820cdd1..98c8215fc7 100644
--- a/src/main/java/gregtech/api/graphs/GenerateNodeMap.java
+++ b/src/main/java/gregtech/api/graphs/GenerateNodeMap.java
@@ -13,7 +13,7 @@ import static gregtech.api.util.GT_Utility.getOppositeSide;
//generates the node map
abstract public class GenerateNodeMap {
- //clearign the node map to make sure it is gone on reset
+ //clearing the node map to make sure it is gone on reset
public static void clearNodeMap(Node aNode,int aReturnNodeValue) {
if (aNode.mTileEntity instanceof BaseMetaPipeEntity) {
BaseMetaPipeEntity tPipe = (BaseMetaPipeEntity) aNode.mTileEntity;
@@ -25,21 +25,21 @@ abstract public class GenerateNodeMap {
}
}
for (int i = 0;i<6;i++) {
- NodePath tPath = aNode.mNodePats[i];
+ NodePath tPath = aNode.mNodePaths[i];
if (tPath != null) {
tPath.clearPath();
- aNode.mNodePats[i] = null;
+ aNode.mNodePaths[i] = null;
}
- Node tNextNode = aNode.mNeigbourNodes[i];
+ Node tNextNode = aNode.mNeighbourNodes[i];
if (tNextNode == null) continue;
if (tNextNode.mNodeValue != aReturnNodeValue)
clearNodeMap(tNextNode,aNode.mNodeValue);
- aNode.mNeigbourNodes[i] = null;
+ aNode.mNeighbourNodes[i] = null;
}
}
//gets the next node
- protected void generateNextNode(BaseMetaPipeEntity aPipe, Node aPipeNode, byte aInvalidSide, int aNextNodeVale,
+ protected void generateNextNode(BaseMetaPipeEntity aPipe, Node aPipeNode, byte aInvalidSide, int aNextNodeValue,
ArrayList<ConsumerNode> tConsumers, HashSet<Node> tNodeMap) {
MetaPipeEntity tMetaPipe = (MetaPipeEntity) aPipe.getMetaTileEntity();
for (byte i = 0;i<6;i++) {
@@ -51,20 +51,20 @@ abstract public class GenerateNodeMap {
ArrayList<MetaPipeEntity> tNewPipes = new ArrayList<MetaPipeEntity>();
Pair nextTileEntity = getNextValidTileEntity(tNextTileEntity,tNewPipes,i,tNodeMap);
if (nextTileEntity != null) {
- Node tNextNode = generateNode(nextTileEntity.mTileEntity,aPipeNode,aNextNodeVale+1,tNewPipes,
+ Node tNextNode = generateNode(nextTileEntity.mTileEntity,aPipeNode,aNextNodeValue+1,tNewPipes,
nextTileEntity.mSide,tConsumers,tNodeMap);
if (tNextNode != null) {
- aNextNodeVale = tNextNode.mHigestNodeValue;
- aPipeNode.mHigestNodeValue = tNextNode.mHigestNodeValue;
- aPipeNode.mNeigbourNodes[i] = tNextNode;
- aPipeNode.mNodePats[i] = aPipeNode.mReturnPath;
+ aNextNodeValue = tNextNode.mHighestNodeValue;
+ aPipeNode.mHighestNodeValue = tNextNode.mHighestNodeValue;
+ aPipeNode.mNeighbourNodes[i] = tNextNode;
+ aPipeNode.mNodePaths[i] = aPipeNode.mReturnPath;
}
}
}
}
- //on a valid tilentity create a new node
- protected Node generateNode(TileEntity aTileEntity, Node aPreviousNode, int aNextNodeVale, ArrayList<MetaPipeEntity> aPipes,
+ //on a valid tile entity create a new node
+ protected Node generateNode(TileEntity aTileEntity, Node aPreviousNode, int aNextNodeValue, ArrayList<MetaPipeEntity> aPipes,
int aSide, ArrayList<ConsumerNode> aConsumers, HashSet<Node> aNodeMap) {
if (aTileEntity.isInvalid()) return null;
byte tSideOp = getOppositeSide(aSide);
@@ -73,36 +73,36 @@ abstract public class GenerateNodeMap {
if (isPipe(aTileEntity)){
BaseMetaPipeEntity tPipe = (BaseMetaPipeEntity) aTileEntity;
MetaPipeEntity tMetaPipe = (MetaPipeEntity) tPipe.getMetaTileEntity();
- int tConections = getNumberOfConections(tMetaPipe);
+ int tConnections = getNumberOfConnections(tMetaPipe);
Node tPipeNode;
- if (tConections == 1) {
- tPipeNode = getEmptyNode(aNextNodeVale,tSideOp,aTileEntity,aConsumers);
+ if (tConnections == 1) {
+ tPipeNode = getEmptyNode(aNextNodeValue,tSideOp,aTileEntity,aConsumers);
if (tPipeNode == null) return null;
} else {
- tPipeNode = getPipeNode(aNextNodeVale,tSideOp,aTileEntity,aConsumers);
+ tPipeNode = getPipeNode(aNextNodeValue,tSideOp,aTileEntity,aConsumers);
}
tPipe.setNode(tPipeNode);
aNodeMap.add(tPipeNode);
tPipeNode.mSelfPath = getNewPath(new MetaPipeEntity[]{tMetaPipe});
tThisNode = tPipeNode;
if (tInvalidSide>-1) {
- tPipeNode.mNeigbourNodes[tInvalidSide] = aPreviousNode;
- tPipeNode.mNodePats[tInvalidSide] = getNewPath(aPipes.toArray(new MetaPipeEntity[0]));
- aPreviousNode.mReturnPath = tPipeNode.mNodePats[tInvalidSide];
+ tPipeNode.mNeighbourNodes[tInvalidSide] = aPreviousNode;
+ tPipeNode.mNodePaths[tInvalidSide] = getNewPath(aPipes.toArray(new MetaPipeEntity[0]));
+ aPreviousNode.mReturnPath = tPipeNode.mNodePaths[tInvalidSide];
}
- if (tConections > 1)
- generateNextNode(tPipe,tPipeNode,tInvalidSide,aNextNodeVale,aConsumers,aNodeMap);
- } else if (addConsumer(aTileEntity,tSideOp,aNextNodeVale,aConsumers)) {
+ if (tConnections > 1)
+ generateNextNode(tPipe,tPipeNode,tInvalidSide,aNextNodeValue,aConsumers,aNodeMap);
+ } else if (addConsumer(aTileEntity,tSideOp,aNextNodeValue,aConsumers)) {
ConsumerNode tConsumeNode = aConsumers.get(aConsumers.size()-1);
- tConsumeNode.mNeigbourNodes[tSideOp] = aPreviousNode;
- tConsumeNode.mNodePats[tSideOp] = getNewPath(aPipes.toArray(new MetaPipeEntity[0]));
- aPreviousNode.mReturnPath = tConsumeNode.mNodePats[tSideOp];
+ tConsumeNode.mNeighbourNodes[tSideOp] = aPreviousNode;
+ tConsumeNode.mNodePaths[tSideOp] = getNewPath(aPipes.toArray(new MetaPipeEntity[0]));
+ aPreviousNode.mReturnPath = tConsumeNode.mNodePaths[tSideOp];
tThisNode = tConsumeNode;
}
return tThisNode;
}
- //go over the pipes until we see a valid tileentity that needs a node
+ //go over the pipes until we see a valid tile entity that needs a node
protected Pair getNextValidTileEntity(TileEntity aTileEntity, ArrayList<MetaPipeEntity> aPipes, byte aSide, HashSet<Node> aNodeMap) {
if (isPipe(aTileEntity)) {
BaseMetaPipeEntity tPipe = (BaseMetaPipeEntity) aTileEntity;
@@ -112,8 +112,8 @@ abstract public class GenerateNodeMap {
if (aNodeMap.contains(tNode))
return null;
}
- int tConections = getNumberOfConections(tMetaPipe);
- if (tConections == 2) {
+ int tConnections = getNumberOfConnections(tMetaPipe);
+ if (tConnections == 2) {
byte tSideOp = getOppositeSide(aSide);
for (byte i = 0;i<6;i++) {
if (i == tSideOp || !(tMetaPipe.isConnectedAtSide(i))) continue;
@@ -144,16 +144,16 @@ abstract public class GenerateNodeMap {
}
}
- //if check if the tileentity is the correct pipe
+ //if check if the tile entity is the correct pipe
protected boolean isPipe(TileEntity aTileEntity) {
return aTileEntity instanceof BaseMetaPipeEntity;
}
- //checks if the tileentity is a consumer and add to the list
+ //checks if the tile entity is a consumer and add to the list
abstract protected boolean addConsumer(TileEntity aTileEntity, byte aSide, int aNodeValue, ArrayList<ConsumerNode> aConsumers);
//get correct pathClass that you need for your node network
protected abstract NodePath getNewPath(MetaPipeEntity[] aPipes);
- //used for if you need to use death ends for somthing
+ //used for if you need to use death ends for something
//can be null
protected Node getEmptyNode(int aNodeValue, byte aSide, TileEntity aTileEntity, ArrayList<ConsumerNode> aConsumers) {
return null;
@@ -163,8 +163,8 @@ abstract public class GenerateNodeMap {
return new Node(aNodeValue,aTileEntity,aConsumers);
}
- //get how many conections the pipe have
- private static int getNumberOfConections(MetaPipeEntity aPipe) {
+ //get how many connections the pipe have
+ private static int getNumberOfConnections(MetaPipeEntity aPipe) {
int tCons = 0;
for (int i = 0; i < 6; i++) {
if (aPipe.isConnectedAtSide(i)) tCons++;
diff --git a/src/main/java/gregtech/api/graphs/GenerateNodeMapPower.java b/src/main/java/gregtech/api/graphs/GenerateNodeMapPower.java
index ec5c984bc0..76a24e8802 100644
--- a/src/main/java/gregtech/api/graphs/GenerateNodeMapPower.java
+++ b/src/main/java/gregtech/api/graphs/GenerateNodeMapPower.java
@@ -17,7 +17,7 @@ import net.minecraftforge.common.util.ForgeDirection;
import java.util.ArrayList;
import java.util.HashSet;
-//node map generator for power distrubution
+//node map generator for power distribution
public class GenerateNodeMapPower extends GenerateNodeMap {
public GenerateNodeMapPower(BaseMetaPipeEntity aTileEntity) {
generateNode(aTileEntity,null,1,null,
diff --git a/src/main/java/gregtech/api/graphs/Node.java b/src/main/java/gregtech/api/graphs/Node.java
index fed599881c..258915e473 100644
--- a/src/main/java/gregtech/api/graphs/Node.java
+++ b/src/main/java/gregtech/api/graphs/Node.java
@@ -12,8 +12,8 @@ public class Node {
this.mNodeValue = aNodeValue;
this.mTileEntity = aTileEntity;
this.mConsumers = aConsumers;
- mHigestNodeValue = aNodeValue;
- //you dont want to generate map multiple times in the same tick
+ mHighestNodeValue = aNodeValue;
+ //you don't want to generate map multiple times in the same tick
mCreationTime = MinecraftServer.getServer().getTickCounter();
}
@@ -23,8 +23,8 @@ public class Node {
public ArrayList<ConsumerNode> mConsumers;
public int mNodeValue;
public final TileEntity mTileEntity;
- public Node[] mNeigbourNodes = new Node[6];
- public NodePath[] mNodePats = new NodePath[6];
+ public Node[] mNeighbourNodes = new Node[6];
+ public NodePath[] mNodePaths = new NodePath[6];
public NodePath mReturnPath;
- public int mHigestNodeValue;
+ public int mHighestNodeValue;
}
diff --git a/src/main/java/gregtech/api/graphs/NodeList.java b/src/main/java/gregtech/api/graphs/NodeList.java
index 702e8446c0..36ebbc4f6f 100644
--- a/src/main/java/gregtech/api/graphs/NodeList.java
+++ b/src/main/java/gregtech/api/graphs/NodeList.java
@@ -1,23 +1,23 @@
package gregtech.api.graphs;
-//keep track on wich node is being looked for accrouse the recursif functions
+//keep track on which node is being looked for across the recursive functions
public class NodeList {
Node[] mNodes;
- int mConter = 0;
+ int mCounter = 0;
public NodeList(Node[] mNodes) {
this.mNodes = mNodes;
}
Node getNextNode() {
- if (++mConter < mNodes.length)
- return mNodes[mConter];
+ if (++mCounter < mNodes.length)
+ return mNodes[mCounter];
else
return null;
}
Node getNode() {
- if (mConter < mNodes.length)
- return mNodes[mConter];
+ if (mCounter < mNodes.length)
+ return mNodes[mCounter];
else
return null;
}
diff --git a/src/main/java/gregtech/api/graphs/PowerNodes.java b/src/main/java/gregtech/api/graphs/PowerNodes.java
index 39844bdd17..411d690cca 100644
--- a/src/main/java/gregtech/api/graphs/PowerNodes.java
+++ b/src/main/java/gregtech/api/graphs/PowerNodes.java
@@ -12,9 +12,9 @@ import gregtech.api.graphs.paths.PowerNodePath;
* this network only includes nodes that have a higher value then it self so it does not know the highest known value that
* the return node knows
*
- * with these rules we can know what a node contains the target node in its network as long the target node has a value
- * more or equal then the node we are looking but is less or equal then the highest value that node knows
- * this way we don't have to go over the entire network too look for it
+ * with these rules we can know for the target node to be in the network of a node, the target node must have a value no
+ * less than the node we are looking and no greater than the highest value that node knows
+ * this way we don't have to go over the entire network to look for it
*
* we also hold a list of all consumers so we can check before looking if that consumer actually needs power
* and only look for nodes that actually need power
@@ -27,11 +27,11 @@ public class PowerNodes {
ConsumerNode tConsumer =(ConsumerNode) aConsumers.getNode();
int tLoopProtection = 0;
while (tConsumer != null) {
- int tTagetNodeValue = tConsumer.mNodeValue;
+ int tTargetNodeValue = tConsumer.mNodeValue;
//if the target node has a value less then the current node
- if (tTagetNodeValue < aCurrentNode.mNodeValue || tTagetNodeValue > aCurrentNode.mHigestNodeValue) {
+ if (tTargetNodeValue < aCurrentNode.mNodeValue || tTargetNodeValue > aCurrentNode.mHighestNodeValue) {
for (int j = 0;j<6;j++) {
- Node tNextNode = aCurrentNode.mNeigbourNodes[j];
+ Node tNextNode = aCurrentNode.mNeighbourNodes[j];
if (tNextNode != null && tNextNode.mNodeValue < aCurrentNode.mNodeValue) {
if (tNextNode.mNodeValue == tConsumer.mNodeValue) {
tAmpsUsed += processNodeInject(aCurrentNode,tConsumer,j,aMaxAmps-tAmpsUsed,aVoltage,false);
@@ -46,16 +46,16 @@ public class PowerNodes {
}
}
} else {
- //if the target node has a node value greater then current node vale
+ //if the target node has a node value greater then current node value
for (int side = 5;side>-1;side--) {
- Node tNextNode = aCurrentNode.mNeigbourNodes[side];
+ Node tNextNode = aCurrentNode.mNeighbourNodes[side];
if (tNextNode == null) continue;
- if (tNextNode.mNodeValue > aCurrentNode.mNodeValue && tNextNode.mNodeValue < tTagetNodeValue) {
+ if (tNextNode.mNodeValue > aCurrentNode.mNodeValue && tNextNode.mNodeValue < tTargetNodeValue) {
if (tNextNode == aPreviousNode) return tAmpsUsed;
tAmpsUsed += processNextNodeAbove(aCurrentNode,tNextNode,aConsumers,side,aMaxAmps-tAmpsUsed,aVoltage);
tConsumer =(ConsumerNode) aConsumers.getNode();
break;
- } else if (tNextNode.mNodeValue == tTagetNodeValue) {
+ } else if (tNextNode.mNodeValue == tTargetNodeValue) {
tAmpsUsed += processNodeInject(aCurrentNode,tConsumer,side,aMaxAmps-tAmpsUsed,aVoltage,true);
tConsumer =(ConsumerNode) aConsumers.getNextNode();
break;
@@ -66,32 +66,32 @@ public class PowerNodes {
return tAmpsUsed;
}
if (tLoopProtection++ > 20) {
- throw new NullPointerException("infinit loop in powering nodes ");
+ throw new NullPointerException("infinite loop in powering nodes ");
}
}
return tAmpsUsed;
}
- //checking if target node is next to it ot has a higer value then current node value
- //thse functions are difrent to eayer go down or up the stack
+ //checking if target node is next to it or has a higher value then current node value
+ //these functions are different to either go down or up the stack
protected static int powerNodeAbove(Node aCurrentNode, Node aPreviousNode, NodeList aConsumers, int aVoltage, int aMaxAmps) {
int tAmpsUsed = 0;
int tLoopProtection = 0;
ConsumerNode tConsumer =(ConsumerNode) aConsumers.getNode();
while (tConsumer != null) {
- int tTagetNodeValue = tConsumer.mNodeValue;
- if (tTagetNodeValue > aCurrentNode.mHigestNodeValue || tTagetNodeValue < aCurrentNode.mNodeValue) {
+ int tTargetNodeValue = tConsumer.mNodeValue;
+ if (tTargetNodeValue > aCurrentNode.mHighestNodeValue || tTargetNodeValue < aCurrentNode.mNodeValue) {
return tAmpsUsed;
} else {
for (int side = 5;side>-1;side--) {
- Node tNextNode = aCurrentNode.mNeigbourNodes[side];
+ Node tNextNode = aCurrentNode.mNeighbourNodes[side];
if (tNextNode == null) continue;
- if (tNextNode.mNodeValue > aCurrentNode.mNodeValue && tNextNode.mNodeValue < tTagetNodeValue) {
+ if (tNextNode.mNodeValue > aCurrentNode.mNodeValue && tNextNode.mNodeValue < tTargetNodeValue) {
if (tNextNode == aPreviousNode) return tAmpsUsed;
tAmpsUsed += processNextNodeAbove(aCurrentNode,tNextNode,aConsumers,side,aMaxAmps-tAmpsUsed,aVoltage);
tConsumer =(ConsumerNode) aConsumers.getNode();
break;
- } else if (tNextNode.mNodeValue == tTagetNodeValue) {
+ } else if (tNextNode.mNodeValue == tTargetNodeValue) {
tAmpsUsed += processNodeInject(aCurrentNode,tConsumer,side,aMaxAmps-tAmpsUsed,aVoltage,true);
tConsumer =(ConsumerNode) aConsumers.getNextNode();
break;
@@ -102,14 +102,14 @@ public class PowerNodes {
return tAmpsUsed;
}
if (tLoopProtection++ > 20) {
- throw new NullPointerException("infinit loop in powering nodes ");
+ throw new NullPointerException("infinite loop in powering nodes ");
}
}
return tAmpsUsed;
}
protected static int processNextNode(Node aCurrentNode, Node aNextNode, NodeList aConsumers, int aSide, int aMaxAmps, int aVoltage) {
- PowerNodePath tPath = (PowerNodePath)aCurrentNode.mNodePats[aSide];
+ PowerNodePath tPath = (PowerNodePath)aCurrentNode.mNodePaths[aSide];
PowerNodePath tSelfPath = (PowerNodePath) aCurrentNode.mSelfPath;
int tVoltLoss = 0;
if (tSelfPath != null) {
@@ -126,7 +126,7 @@ public class PowerNodes {
}
protected static int processNextNodeAbove(Node aCurrentNode, Node aNextNode, NodeList aConsumers, int aSide, int aMaxAmps, int aVoltage) {
- PowerNodePath tPath = (PowerNodePath)aCurrentNode.mNodePats[aSide];
+ PowerNodePath tPath = (PowerNodePath)aCurrentNode.mNodePaths[aSide];
PowerNodePath tSelfPath = (PowerNodePath) aCurrentNode.mSelfPath;
int tVoltLoss = 0;
if (tSelfPath != null) {
@@ -144,7 +144,7 @@ public class PowerNodes {
protected static int processNodeInject(Node aCurrentNode, ConsumerNode aConsumer, int aSide,int aMaxAmps, int aVoltage,
boolean isUp) {
- PowerNodePath tPath = (PowerNodePath)aCurrentNode.mNodePats[aSide];
+ PowerNodePath tPath = (PowerNodePath)aCurrentNode.mNodePaths[aSide];
PowerNodePath tSelfPath = (PowerNodePath) aCurrentNode.mSelfPath;
int tVoltLoss = 0;
if (tSelfPath != null) {
diff --git a/src/main/java/gregtech/api/graphs/consumers/ConsumerNode.java b/src/main/java/gregtech/api/graphs/consumers/ConsumerNode.java
index d2be4d94f1..87376008c4 100644
--- a/src/main/java/gregtech/api/graphs/consumers/ConsumerNode.java
+++ b/src/main/java/gregtech/api/graphs/consumers/ConsumerNode.java
@@ -5,7 +5,7 @@ import net.minecraft.tileentity.TileEntity;
import java.util.ArrayList;
-//node atached to a tileentity that can consume stuff from the network
+//node attached to a tile entity that can consume stuff from the network
public class ConsumerNode extends Node {
public byte mSide;
public ConsumerNode(int aNodeValue, TileEntity aTileEntity, byte aSide, ArrayList<ConsumerNode> aConsumers) {
@@ -17,7 +17,7 @@ public class ConsumerNode extends Node {
return !mTileEntity.isInvalid();
}
- public int injectEnergy(int aVoltage, int aMaxApms) {
+ public int injectEnergy(int aVoltage, int aMaxAmps) {
return 0;
}
}
diff --git a/src/main/java/gregtech/api/graphs/consumers/EmptyPowerConsumer.java b/src/main/java/gregtech/api/graphs/consumers/EmptyPowerConsumer.java
index 47e3bca144..da3d0a757b 100644
--- a/src/main/java/gregtech/api/graphs/consumers/EmptyPowerConsumer.java
+++ b/src/main/java/gregtech/api/graphs/consumers/EmptyPowerConsumer.java
@@ -6,7 +6,7 @@ import net.minecraft.tileentity.TileEntity;
import java.util.ArrayList;
-//this is here to aply voltage to death ends
+//this is here to apply voltage to death ends
public class EmptyPowerConsumer extends ConsumerNode{
public EmptyPowerConsumer(int aNodeValue, TileEntity aTileEntity, byte aSide, ArrayList<ConsumerNode> aConsumers) {
super(aNodeValue, aTileEntity, aSide, aConsumers);
@@ -18,7 +18,7 @@ public class EmptyPowerConsumer extends ConsumerNode{
}
@Override
- public int injectEnergy(int aVoltage, int aMaxApms) {
+ public int injectEnergy(int aVoltage, int aMaxAmps) {
BaseMetaPipeEntity tPipe = (BaseMetaPipeEntity) mTileEntity;
PowerNodePath tPath =(PowerNodePath) tPipe.getNodePath();
tPath.applyVoltage(aVoltage,true);
diff --git a/src/main/java/gregtech/api/graphs/consumers/NodeEnergyReceiver.java b/src/main/java/gregtech/api/graphs/consumers/NodeEnergyReceiver.java
index 099c7617f0..a24c4acbcd 100644
--- a/src/main/java/gregtech/api/graphs/consumers/NodeEnergyReceiver.java
+++ b/src/main/java/gregtech/api/graphs/consumers/NodeEnergyReceiver.java
@@ -23,7 +23,7 @@ public class NodeEnergyReceiver extends ConsumerNode {
}
@Override
- public int injectEnergy(int aVoltage, int aMaxApms) {
+ public int injectEnergy(int aVoltage, int aMaxAmps) {
ForgeDirection tDirection = ForgeDirection.getOrientation(mSide);
int rfOut = GT_Utility.safeInt(aVoltage * GregTech_API.mEUtoRF / 100);
int ampsUsed = 0;
@@ -43,7 +43,7 @@ public class NodeEnergyReceiver extends ConsumerNode {
return 0;
}
- //copyed from IEnergyConnected
+ //copied from IEnergyConnected
private void explode(int aRfOut) {
if (aRfOut > 32L * GregTech_API.mEUtoRF / 100L) {
int aExplosionPower = aRfOut;
diff --git a/src/main/java/gregtech/api/graphs/consumers/NodeEnergySink.java b/src/main/java/gregtech/api/graphs/consumers/NodeEnergySink.java
index db9f383492..3f93c62010 100644
--- a/src/main/java/gregtech/api/graphs/consumers/NodeEnergySink.java
+++ b/src/main/java/gregtech/api/graphs/consumers/NodeEnergySink.java
@@ -18,9 +18,9 @@ public class NodeEnergySink extends ConsumerNode {
}
@Override
- public int injectEnergy(int aVoltage, int aMaxApms) {
+ public int injectEnergy(int aVoltage, int aMaxAmps) {
int tUsedAmps = 0;
- while (aMaxApms > tUsedAmps && ((IEnergySink) mTileEntity).getDemandedEnergy() > 0 &&
+ while (aMaxAmps > tUsedAmps && ((IEnergySink) mTileEntity).getDemandedEnergy() > 0 &&
((IEnergySink) mTileEntity).injectEnergy(ForgeDirection.getOrientation(mSide), aVoltage, aVoltage) < aVoltage)
tUsedAmps++;
return tUsedAmps;
diff --git a/src/main/java/gregtech/api/graphs/consumers/NodeGTBaseMetaTile.java b/src/main/java/gregtech/api/graphs/consumers/NodeGTBaseMetaTile.java
index dbcc3c3b62..5c54ee16f9 100644
--- a/src/main/java/gregtech/api/graphs/consumers/NodeGTBaseMetaTile.java
+++ b/src/main/java/gregtech/api/graphs/consumers/NodeGTBaseMetaTile.java
@@ -11,8 +11,8 @@ public class NodeGTBaseMetaTile extends ConsumerNode {
}
@Override
- public int injectEnergy(int aVoltage, int aMaxApms) {
- return (int)((IEnergyConnected) mTileEntity).injectEnergyUnits(mSide,aVoltage, aMaxApms);
+ public int injectEnergy(int aVoltage, int aMaxAmps) {
+ return (int)((IEnergyConnected) mTileEntity).injectEnergyUnits(mSide,aVoltage, aMaxAmps);
}
@Override
diff --git a/src/main/java/gregtech/api/graphs/paths/PowerNodePath.java b/src/main/java/gregtech/api/graphs/paths/PowerNodePath.java
index 5cad66d7f4..df6f2671e4 100644
--- a/src/main/java/gregtech/api/graphs/paths/PowerNodePath.java
+++ b/src/main/java/gregtech/api/graphs/paths/PowerNodePath.java
@@ -6,7 +6,7 @@ import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Cable;
import net.minecraft.server.MinecraftServer;
//path for cables
-//al calculations like ams and voltage hapens here
+//all calculations like amp and voltage happens here
public class PowerNodePath extends NodePath {
int mMaxAmps;
int mAmps = 0;
@@ -63,7 +63,7 @@ public class PowerNodePath extends NodePath {
}
//if no amps pass trough for more then 0.5 second reduce them to minimize wrong results
- //but still allow the player to see if activity is hapening
+ //but still allow the player to see if activity is happening
public int getAmps() {
int tTime = MinecraftServer.getServer().getTickCounter() - 10;
if (mTick < tTime) {
diff --git a/src/main/java/gregtech/api/gui/GT_Container.java b/src/main/java/gregtech/api/gui/GT_Container.java
index 608c6015d5..e00759bf24 100644
--- a/src/main/java/gregtech/api/gui/GT_Container.java
+++ b/src/main/java/gregtech/api/gui/GT_Container.java
@@ -142,7 +142,7 @@ public class GT_Container extends Container {
if (aSlot != null && aSlot.canTakeStack(aPlayer)) {
tTempStack = this.transferStackInSlot(aPlayer, aSlotIndex);
if (tTempStack != null) {
- rStack = GT_Utility.copy(tTempStack);
+ rStack = GT_Utility.copyOrNull(tTempStack);
if (aSlot.getStack() != null && aSlot.getStack().getItem() == tTempStack.getItem()) {
slotClick(aSlotIndex, aMouseclick, aShifthold, aPlayer);
}
@@ -157,7 +157,7 @@ public class GT_Container extends Container {
tTempStack = aSlot.getStack();
ItemStack var13 = aPlayerInventory.getItemStack();
if (tTempStack != null) {
- rStack = GT_Utility.copy(tTempStack);
+ rStack = GT_Utility.copyOrNull(tTempStack);
}
if (tTempStack == null) {
if (var13 != null && aSlot.isItemValid(var13)) {
@@ -253,7 +253,7 @@ public class GT_Container extends Container {
} else if (aShifthold == 3 && aPlayer.capabilities.isCreativeMode && aPlayerInventory.getItemStack() == null && aSlotIndex >= 0) {
aSlot = (Slot) this.inventorySlots.get(aSlotIndex);
if (aSlot != null && aSlot.getHasStack()) {
- tTempStack = GT_Utility.copy(aSlot.getStack());
+ tTempStack = GT_Utility.copyOrNull(aSlot.getStack());
tTempStack.stackSize = tTempStack.getMaxStackSize();
aPlayerInventory.setItemStack(tTempStack);
}
@@ -271,7 +271,7 @@ public class GT_Container extends Container {
//null checks and checks if the item can be stacked (maxStackSize > 1)
if (getSlotCount() > 0 && slotObject != null && slotObject.getHasStack() && !(slotObject instanceof GT_Slot_Holo)) {
ItemStack stackInSlot = slotObject.getStack();
- stack = GT_Utility.copy(stackInSlot);
+ stack = GT_Utility.copyOrNull(stackInSlot);
//TileEntity -> Player
if (aSlotIndex < getAllSlotCount()) {
diff --git a/src/main/java/gregtech/api/gui/GT_Container_BasicMachine.java b/src/main/java/gregtech/api/gui/GT_Container_BasicMachine.java
index 28fd2983f4..5d2a9321c4 100644
--- a/src/main/java/gregtech/api/gui/GT_Container_BasicMachine.java
+++ b/src/main/java/gregtech/api/gui/GT_Container_BasicMachine.java
@@ -4,6 +4,7 @@ import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachine;
+import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicTank;
import gregtech.api.util.GT_Utility;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
@@ -11,7 +12,6 @@ import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
-import net.minecraftforge.fluids.IFluidContainerItem;
import static gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachine.OTHER_SLOT_COUNT;
@@ -195,154 +195,22 @@ public class GT_Container_BasicMachine extends GT_Container_BasicTank {
if (mTileEntity.getMetaTileEntity() == null) return null;
machine.mItemTransfer = !machine.mItemTransfer;
return null;
- case 2:
- if (aMouseclick > 1)
- return null;
- tResultStack = pickupFluid(machine.getDrainableStack(), aPlayer, aMouseclick == 0);
- if (machine.getDrainableStack() != null && machine.getDrainableStack().amount == 0)
- machine.setDrainableStack(null);
- return tResultStack;
default:
- if (aSlotIndex == OTHER_SLOT_COUNT + 1 + machine.mInputSlotCount + machine.mOutputItems.length) {
- if (aMouseclick > 1)
- return null;
- // input fluid slot
- ItemStack tStackHeld = aPlayer.inventory.getItemStack();
- ItemStack tStackSizedOne = GT_Utility.copyAmount(1, tStackHeld);
- if (tStackSizedOne == null || tStackHeld.stackSize == 0) return null;
- FluidStack tInputFluid = machine.getFillableStack();
- FluidStack tFluidHeld = GT_Utility.getFluidForFilledItem(tStackSizedOne, true);
- if (tFluidHeld != null && tFluidHeld.amount <= 0)
- tFluidHeld = null;
- if (tInputFluid == null) {
- if (tFluidHeld == null)
- // both null -> no op
- return null;
- return fillFluid(machine, aPlayer, tFluidHeld, aMouseclick == 0);
- } else {
- if (tFluidHeld != null && tInputFluid.amount < machine.getCapacity()) {
- // both nonnull and have space left for filling.
- // actually both pickup and fill is reasonable, but I'll go with fill here
- return fillFluid(machine, aPlayer, tFluidHeld, aMouseclick == 0);
- } else {
- tResultStack = pickupFluid(tInputFluid, aPlayer, aMouseclick == 0);
- if (tInputFluid.amount == 0)
- machine.setFillableStack(null);
- return tResultStack;
- }
+ if (aSlotIndex == OTHER_SLOT_COUNT + 1 + machine.mInputSlotCount + machine.mOutputItems.length && aMouseclick < 2) {
+ if (mTileEntity.isClientSide()) {
+ // see parent class slotClick for an explanation on why doing this
+ GT_MetaTileEntity_BasicTank tTank = (GT_MetaTileEntity_BasicTank) mTileEntity.getMetaTileEntity();
+ tTank.setFillableStack(GT_Utility.getFluidFromDisplayStack(tTank.getStackInSlot(2)));
}
+ GT_MetaTileEntity_BasicTank tTank = (GT_MetaTileEntity_BasicTank) mTileEntity.getMetaTileEntity();
+ IFluidAccess tFillableAccess = IFluidAccess.from(tTank, true);
+ return handleFluidSlotClick(tFillableAccess, aPlayer, aMouseclick == 0, true, true);
} else {
return super.slotClick(aSlotIndex, aMouseclick, aShifthold, aPlayer);
}
}
}
- private ItemStack pickupFluid(FluidStack aTankStack, EntityPlayer aPlayer, boolean aProcessFullStack) {
- if (aTankStack == null) return null;
- ItemStack tStackHeld = aPlayer.inventory.getItemStack();
- ItemStack tStackSizedOne = GT_Utility.copyAmount(1, tStackHeld);
- if (tStackSizedOne == null || tStackHeld.stackSize == 0) return null;
- int tOriginalFluidAmount = aTankStack.amount;
- ItemStack tFilled = GT_Utility.fillFluidContainer(aTankStack, tStackSizedOne, true, false);
- if (tFilled == null && tStackSizedOne.getItem() instanceof IFluidContainerItem) {
- IFluidContainerItem tContainerItem = (IFluidContainerItem) tStackSizedOne.getItem();
- int tFilledAmount = tContainerItem.fill(tStackSizedOne, aTankStack, true);
- if (tFilledAmount > 0) {
- tFilled = tStackSizedOne;
- aTankStack.amount -= tFilledAmount;
- }
- }
- if (tFilled != null) {
- if (aProcessFullStack) {
- int tFilledAmount = tOriginalFluidAmount - aTankStack.amount;
- /*
- work out how many more items we can fill
- one cell is already used, so account for that
- the round down behavior will left over a fraction of a cell worth of fluid
- the user then get to decide what to do with it
- it will not be too fancy if it spills out partially filled cells
- */
- int tAdditionalParallel = Math.min(tStackHeld.stackSize - 1, aTankStack.amount / tFilledAmount);
- aTankStack.amount -= tFilledAmount * tAdditionalParallel;
- tFilled.stackSize += tAdditionalParallel;
- }
- replaceCursorItemStack(aPlayer, tFilled);
- }
- return tFilled;
- }
-
- private ItemStack fillFluid(GT_MetaTileEntity_BasicMachine aMachine, EntityPlayer aPlayer, FluidStack aFluidHeld, boolean aProcessFullStack) {
- // we are not using aMachine.fill() here any more, so we need to check for fluid type here ourselves
- if (aMachine.getFillableStack() != null && !aMachine.getFillableStack().isFluidEqual(aFluidHeld))
- return null;
- ItemStack tStackHeld = aPlayer.inventory.getItemStack();
- ItemStack tStackSizedOne = GT_Utility.copyAmount(1, tStackHeld);
- if (tStackSizedOne == null)
- return null;
-
- int tFreeSpace = aMachine.getCapacity() - (aMachine.getFillableStack() != null ? aMachine.getFillableStack().amount : 0);
- if (tFreeSpace <= 0)
- // no space left
- return null;
-
- // find out how much fluid can be taken
- // some cells cannot be partially filled
- ItemStack tStackEmptied = null;
- int tAmountTaken = 0;
- if (tFreeSpace >= aFluidHeld.amount) {
- // fully accepted - try take it from item now
- // IFluidContainerItem is intentionally not checked here. it will be checked later
- tStackEmptied = GT_Utility.getContainerForFilledItem(tStackSizedOne, false);
- tAmountTaken = aFluidHeld.amount;
- }
- if (tStackEmptied == null && tStackSizedOne.getItem() instanceof IFluidContainerItem) {
- // either partially accepted, or is IFluidContainerItem
- IFluidContainerItem container = (IFluidContainerItem) tStackSizedOne.getItem();
- FluidStack tDrained = container.drain(tStackSizedOne, tFreeSpace, true);
- if (tDrained != null && tDrained.amount > 0) {
- // something is actually drained - change the cell and drop it to player
- tStackEmptied = tStackSizedOne;
- tAmountTaken = tDrained.amount;
- }
- }
- if (tStackEmptied == null)
- // somehow the cell refuse to give out that amount of fluid, no op then
- return null;
-
- // find out how many fill can we do
- // same round down behavior as above
- // however here the fluid stack is not changed at all, so the exact code will slightly differ
- int tParallel = aProcessFullStack ? Math.min(tFreeSpace / tAmountTaken, tStackHeld.stackSize) : 1;
- if (aMachine.getFillableStack() == null) {
- FluidStack tNewFillableStack = aFluidHeld.copy();
- tNewFillableStack.amount = tAmountTaken * tParallel;
- aMachine.setFillableStack(tNewFillableStack);
- } else {
- aMachine.getFillableStack().amount += tAmountTaken * tParallel;
- }
- tStackEmptied.stackSize = tParallel;
- replaceCursorItemStack(aPlayer, tStackEmptied);
- return tStackEmptied;
- }
-
- private void replaceCursorItemStack(EntityPlayer aPlayer, ItemStack tStackResult) {
- int tStackResultMaxStackSize = tStackResult.getMaxStackSize();
- while (tStackResult.stackSize > tStackResultMaxStackSize) {
- aPlayer.inventory.getItemStack().stackSize -= tStackResultMaxStackSize;
- GT_Utility.addItemToPlayerInventory(aPlayer, tStackResult.splitStack(tStackResultMaxStackSize));
- }
- if (aPlayer.inventory.getItemStack().stackSize == tStackResult.stackSize) {
- // every cell is mutated. it could just stay on the cursor.
- aPlayer.inventory.setItemStack(tStackResult);
- } else {
- // some cells not mutated. The mutated cells must go into the inventory
- // or drop into the world if there isn't enough space.
- ItemStack tStackHeld = aPlayer.inventory.getItemStack();
- tStackHeld.stackSize -= tStackResult.stackSize;
- GT_Utility.addItemToPlayerInventory(aPlayer, tStackResult);
- }
- }
-
@Override
public void detectAndSendChanges() {
super.detectAndSendChanges();
diff --git a/src/main/java/gregtech/api/gui/GT_Container_BasicTank.java b/src/main/java/gregtech/api/gui/GT_Container_BasicTank.java
index c80874eef4..477e52d103 100644
--- a/src/main/java/gregtech/api/gui/GT_Container_BasicTank.java
+++ b/src/main/java/gregtech/api/gui/GT_Container_BasicTank.java
@@ -4,9 +4,15 @@ import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicTank;
+import gregtech.api.util.GT_Utility;
+import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.Slot;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.ChatComponentText;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.IFluidContainerItem;
/**
* NEVER INCLUDE THIS FILE IN YOUR MOD!!!
@@ -29,6 +35,186 @@ public class GT_Container_BasicTank extends GT_ContainerMetaTile_Machine {
}
@Override
+ public ItemStack slotClick(int aSlotIndex, int aMouseclick, int aShifthold, EntityPlayer aPlayer) {
+ if (aSlotIndex == 2 && aMouseclick < 2) {
+ if (mTileEntity.isClientSide()) {
+ /*
+ * While a logical client don't really need to process fluid cells upon click (it could have just wait
+ * for server side to send the result), doing so would result in every fluid interaction having a
+ * noticeable delay between clicking and changes happening even on single player.
+ * I'd imagine this delay to get only more severe when playing MP over ethernet, which would have much more latency
+ * than a memory connection
+ */
+ GT_MetaTileEntity_BasicTank tTank = (GT_MetaTileEntity_BasicTank) mTileEntity.getMetaTileEntity();
+ tTank.setDrainableStack(GT_Utility.getFluidFromDisplayStack(tTank.getStackInSlot(2)));
+ }
+ GT_MetaTileEntity_BasicTank tTank = (GT_MetaTileEntity_BasicTank) mTileEntity.getMetaTileEntity();
+ IFluidAccess tDrainableAccess = IFluidAccess.from(tTank, false);
+ return handleFluidSlotClick(tDrainableAccess, aPlayer, aMouseclick == 0, true, !tTank.isDrainableStackSeparate());
+ }
+ return super.slotClick(aSlotIndex, aMouseclick, aShifthold, aPlayer);
+ }
+
+ /**
+ * Expected to be called on client side only. Load fluid stacks from fluid display items as they were not sent
+ * over the network.
+ * Override this if you have more than one fluid display stack. This implementation will set drainable stack according to items
+ * in slot indexed 2.
+ *
+ */
+ protected void syncFluidFromFluidDisplayItems() {
+ GT_MetaTileEntity_BasicTank tTank = (GT_MetaTileEntity_BasicTank) mTileEntity.getMetaTileEntity();
+ tTank.setDrainableStack(GT_Utility.getFluidFromDisplayStack(tTank.getStackInSlot(2)));
+ }
+
+ protected static ItemStack handleFluidSlotClick(IFluidAccess aFluidAccess, EntityPlayer aPlayer, boolean aProcessFullStack, boolean aCanDrain, boolean aCanFill) {
+ ItemStack tStackHeld = aPlayer.inventory.getItemStack();
+ ItemStack tStackSizedOne = GT_Utility.copyAmount(1, tStackHeld);
+ if (tStackSizedOne == null || tStackHeld.stackSize == 0) return null;
+ FluidStack tInputFluid = aFluidAccess.get();
+ FluidStack tFluidHeld = GT_Utility.getFluidForFilledItem(tStackSizedOne, true);
+ if (tFluidHeld != null && tFluidHeld.amount <= 0)
+ tFluidHeld = null;
+ if (tInputFluid == null) {
+ // tank empty, consider fill only from now on
+ if (!aCanFill)
+ // cannot fill and nothing to take, bail out
+ return null;
+ if (tFluidHeld == null)
+ // no fluid to fill
+ return null;
+ return fillFluid(aFluidAccess, aPlayer, tFluidHeld, aProcessFullStack);
+ }
+ // tank not empty, both action possible
+ if (tFluidHeld != null && tInputFluid.amount < aFluidAccess.getCapacity()) {
+ // both nonnull and have space left for filling.
+ if (aCanFill)
+ // actually both pickup and fill is reasonable, but I'll go with fill here
+ return fillFluid(aFluidAccess, aPlayer, tFluidHeld, aProcessFullStack);
+ if (!aCanDrain)
+ // cannot take AND cannot fill, why make this call then?
+ return null;
+ // the slot does not allow filling, so try take some
+ return drainFluid(aFluidAccess.get(), aPlayer, aProcessFullStack);
+ } else {
+ // cannot fill and there is something to take
+ if (!aCanDrain)
+ // but the slot does not allow taking, so bail out
+ return null;
+ ItemStack tResultStack = drainFluid(tInputFluid, aPlayer, aProcessFullStack);
+ if (tInputFluid.amount == 0)
+ aFluidAccess.set(null);
+ return tResultStack;
+ }
+ }
+
+ protected static ItemStack drainFluid(FluidStack aTankStack, EntityPlayer aPlayer, boolean aProcessFullStack) {
+ if (aTankStack == null) return null;
+ ItemStack tStackHeld = aPlayer.inventory.getItemStack();
+ ItemStack tStackSizedOne = GT_Utility.copyAmount(1, tStackHeld);
+ if (tStackSizedOne == null || tStackHeld.stackSize == 0) return null;
+ int tOriginalFluidAmount = aTankStack.amount;
+ ItemStack tFilled = GT_Utility.fillFluidContainer(aTankStack, tStackSizedOne, true, false);
+ if (tFilled == null && tStackSizedOne.getItem() instanceof IFluidContainerItem) {
+ IFluidContainerItem tContainerItem = (IFluidContainerItem) tStackSizedOne.getItem();
+ int tFilledAmount = tContainerItem.fill(tStackSizedOne, aTankStack, true);
+ if (tFilledAmount > 0) {
+ tFilled = tStackSizedOne;
+ aTankStack.amount -= tFilledAmount;
+ }
+ }
+ if (tFilled != null) {
+ if (aProcessFullStack) {
+ int tFilledAmount = tOriginalFluidAmount - aTankStack.amount;
+ /*
+ work out how many more items we can fill
+ one cell is already used, so account for that
+ the round down behavior will left over a fraction of a cell worth of fluid
+ the user then get to decide what to do with it
+ it will not be too fancy if it spills out partially filled cells
+ */
+ int tAdditionalParallel = Math.min(tStackHeld.stackSize - 1, aTankStack.amount / tFilledAmount);
+ aTankStack.amount -= tFilledAmount * tAdditionalParallel;
+ tFilled.stackSize += tAdditionalParallel;
+ }
+ replaceCursorItemStack(aPlayer, tFilled);
+ }
+ return tFilled;
+ }
+
+ protected static ItemStack fillFluid(IFluidAccess aFluidAccess, EntityPlayer aPlayer, FluidStack aFluidHeld, boolean aProcessFullStack) {
+ // we are not using aMachine.fill() here any more, so we need to check for fluid type here ourselves
+ if (aFluidAccess.get() != null && !aFluidAccess.get().isFluidEqual(aFluidHeld))
+ return null;
+ ItemStack tStackHeld = aPlayer.inventory.getItemStack();
+ ItemStack tStackSizedOne = GT_Utility.copyAmount(1, tStackHeld);
+ if (tStackSizedOne == null)
+ return null;
+
+ int tFreeSpace = aFluidAccess.getCapacity() - (aFluidAccess.get() != null ? aFluidAccess.get().amount : 0);
+ if (tFreeSpace <= 0)
+ // no space left
+ return null;
+
+ // find out how much fluid can be taken
+ // some cells cannot be partially filled
+ ItemStack tStackEmptied = null;
+ int tAmountTaken = 0;
+ if (tFreeSpace >= aFluidHeld.amount) {
+ // fully accepted - try take it from item now
+ // IFluidContainerItem is intentionally not checked here. it will be checked later
+ tStackEmptied = GT_Utility.getContainerForFilledItem(tStackSizedOne, false);
+ tAmountTaken = aFluidHeld.amount;
+ }
+ if (tStackEmptied == null && tStackSizedOne.getItem() instanceof IFluidContainerItem) {
+ // either partially accepted, or is IFluidContainerItem
+ IFluidContainerItem container = (IFluidContainerItem) tStackSizedOne.getItem();
+ FluidStack tDrained = container.drain(tStackSizedOne, tFreeSpace, true);
+ if (tDrained != null && tDrained.amount > 0) {
+ // something is actually drained - change the cell and drop it to player
+ tStackEmptied = tStackSizedOne;
+ tAmountTaken = tDrained.amount;
+ }
+ }
+ if (tStackEmptied == null)
+ // somehow the cell refuse to give out that amount of fluid, no op then
+ return null;
+
+ // find out how many fill can we do
+ // same round down behavior as above
+ // however here the fluid stack is not changed at all, so the exact code will slightly differ
+ int tParallel = aProcessFullStack ? Math.min(tFreeSpace / tAmountTaken, tStackHeld.stackSize) : 1;
+ if (aFluidAccess.get() == null) {
+ FluidStack tNewFillableStack = aFluidHeld.copy();
+ tNewFillableStack.amount = tAmountTaken * tParallel;
+ aFluidAccess.set(tNewFillableStack);
+ } else {
+ aFluidAccess.get().amount += tAmountTaken * tParallel;
+ }
+ tStackEmptied.stackSize = tParallel;
+ replaceCursorItemStack(aPlayer, tStackEmptied);
+ return tStackEmptied;
+ }
+
+ private static void replaceCursorItemStack(EntityPlayer aPlayer, ItemStack tStackResult) {
+ int tStackResultMaxStackSize = tStackResult.getMaxStackSize();
+ while (tStackResult.stackSize > tStackResultMaxStackSize) {
+ aPlayer.inventory.getItemStack().stackSize -= tStackResultMaxStackSize;
+ GT_Utility.addItemToPlayerInventory(aPlayer, tStackResult.splitStack(tStackResultMaxStackSize));
+ }
+ if (aPlayer.inventory.getItemStack().stackSize == tStackResult.stackSize) {
+ // every cell is mutated. it could just stay on the cursor.
+ aPlayer.inventory.setItemStack(tStackResult);
+ } else {
+ // some cells not mutated. The mutated cells must go into the inventory
+ // or drop into the world if there isn't enough space.
+ ItemStack tStackHeld = aPlayer.inventory.getItemStack();
+ tStackHeld.stackSize -= tStackResult.stackSize;
+ GT_Utility.addItemToPlayerInventory(aPlayer, tStackResult);
+ }
+ }
+
+ @Override
public void detectAndSendChanges() {
super.detectAndSendChanges();
if (mTileEntity.isClientSide() || mTileEntity.getMetaTileEntity() == null) return;
@@ -66,4 +252,41 @@ public class GT_Container_BasicTank extends GT_ContainerMetaTile_Machine {
public int getShiftClickSlotCount() {
return 1;
}
+
+ protected interface IFluidAccess {
+ void set(FluidStack stack);
+ FluidStack get();
+ int getCapacity();
+ static IFluidAccess from(GT_MetaTileEntity_BasicTank aTank, boolean aIsFillableStack) {
+ return new BasicTankFluidAccess(aTank, aIsFillableStack);
+ }
+ }
+
+ static class BasicTankFluidAccess implements IFluidAccess {
+ private final GT_MetaTileEntity_BasicTank mTank;
+ private final boolean mIsFillableStack;
+
+ public BasicTankFluidAccess(GT_MetaTileEntity_BasicTank aTank, boolean aIsFillableStack) {
+ this.mTank = aTank;
+ this.mIsFillableStack = aIsFillableStack;
+ }
+
+ @Override
+ public void set(FluidStack stack) {
+ if (mIsFillableStack)
+ mTank.setFillableStack(stack);
+ else
+ mTank.setDrainableStack(stack);
+ }
+
+ @Override
+ public FluidStack get() {
+ return mIsFillableStack ? mTank.getFillableStack() : mTank.getDrainableStack();
+ }
+
+ @Override
+ public int getCapacity() {
+ return mTank.getCapacity();
+ }
+ }
}
diff --git a/src/main/java/gregtech/api/gui/GT_GUIContainerMetaTile_Machine.java b/src/main/java/gregtech/api/gui/GT_GUIContainerMetaTile_Machine.java
index a54aa2e526..7fd4f9f0b2 100644
--- a/src/main/java/gregtech/api/gui/GT_GUIContainerMetaTile_Machine.java
+++ b/src/main/java/gregtech/api/gui/GT_GUIContainerMetaTile_Machine.java
@@ -27,7 +27,9 @@ public class GT_GUIContainerMetaTile_Machine extends GT_GUIContainer {
@Override
protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) {
super.drawGuiContainerBackgroundLayer(par1, par2, par3);
- if (GregTech_API.sColoredGUI && mContainer != null && mContainer.mTileEntity != null) {
+ if (GregTech_API.sMachineMetalGUI) {
+ GL11.glColor3ub((byte) Dyes.MACHINE_METAL.mRGBa[0], (byte) Dyes.MACHINE_METAL.mRGBa[1], (byte) Dyes.MACHINE_METAL.mRGBa[2]);
+ } else if (GregTech_API.sColoredGUI && mContainer != null && mContainer.mTileEntity != null) {
byte colorByte = mContainer.mTileEntity.getColorization();
Dyes color;
if (colorByte != -1)
@@ -35,7 +37,8 @@ public class GT_GUIContainerMetaTile_Machine extends GT_GUIContainer {
else
color = Dyes.MACHINE_METAL;
GL11.glColor3ub((byte) color.mRGBa[0], (byte) color.mRGBa[1], (byte) color.mRGBa[2]);
- } else
+ } else {
GL11.glColor3ub((byte) 255, (byte) 255, (byte) 255);
+ }
}
}
diff --git a/src/main/java/gregtech/api/gui/GT_GUIContainer_BasicMachine.java b/src/main/java/gregtech/api/gui/GT_GUIContainer_BasicMachine.java
index a27ee175ef..bd28bb11e9 100644
--- a/src/main/java/gregtech/api/gui/GT_GUIContainer_BasicMachine.java
+++ b/src/main/java/gregtech/api/gui/GT_GUIContainer_BasicMachine.java
@@ -1,6 +1,7 @@
package gregtech.api.gui;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachine_Bronze;
import net.minecraft.entity.player.InventoryPlayer;
import java.util.ArrayList;
@@ -23,6 +24,8 @@ public class GT_GUIContainer_BasicMachine extends GT_GUIContainerMetaTile_Machin
public final byte
mProgressBarDirection,
mProgressBarAmount;
+ public final boolean
+ mRenderAutoOutputSlots;
public GT_GUIContainer_BasicMachine(InventoryPlayer aInventoryPlayer, IGregTechTileEntity aTileEntity, String aName, String aTextureFile, String aNEI) {
this(aInventoryPlayer, aTileEntity, aName, aTextureFile, aNEI, (byte) 0, (byte) 1);
@@ -34,12 +37,15 @@ public class GT_GUIContainer_BasicMachine extends GT_GUIContainerMetaTile_Machin
mProgressBarAmount = (byte) Math.max(1, aProgressBarAmount);
mName = aName;
mNEI = aNEI;
+ mRenderAutoOutputSlots = !(aTileEntity.getMetaTileEntity() instanceof GT_MetaTileEntity_BasicMachine_Bronze);
}
@Override
public void drawScreen(int par1, int par2, float par3) {
super.drawScreen(par1, par2, par3);
- drawTooltip(par1, par2);
+ if (mRenderAutoOutputSlots){
+ drawTooltip(par1, par2);
+ }
}
@Override
@@ -72,10 +78,12 @@ public class GT_GUIContainer_BasicMachine extends GT_GUIContainerMetaTile_Machin
int y = (height - ySize) / 2;
drawTexturedModalRect(x, y, 0, 0, xSize, ySize);
if (mContainer != null) {
- if (((GT_Container_BasicMachine) mContainer).mFluidTransfer)
- drawTexturedModalRect(x + 7, y + 62, 176, 18, 18, 18);
- if (((GT_Container_BasicMachine) mContainer).mItemTransfer)
- drawTexturedModalRect(x + 25, y + 62, 176, 36, 18, 18);
+ if (mRenderAutoOutputSlots){
+ if (((GT_Container_BasicMachine) mContainer).mFluidTransfer)
+ drawTexturedModalRect(x + 7, y + 62, 176, 18, 18, 18);
+ if (((GT_Container_BasicMachine) mContainer).mItemTransfer)
+ drawTexturedModalRect(x + 25, y + 62, 176, 36, 18, 18);
+ }
if (((GT_Container_BasicMachine) mContainer).mStuttering)
drawTexturedModalRect(x + 79, y + 44, 176, 54, 18, 18);
diff --git a/src/main/java/gregtech/api/gui/GT_GUICover.java b/src/main/java/gregtech/api/gui/GT_GUICover.java
index 1e51cf0758..2e9d082ebf 100644
--- a/src/main/java/gregtech/api/gui/GT_GUICover.java
+++ b/src/main/java/gregtech/api/gui/GT_GUICover.java
@@ -252,10 +252,17 @@ public abstract class GT_GUICover extends GuiScreen implements GT_IToolTipRender
textBox.setFocused(textBox.equals(boxToFocus) && textBox.isEnabled());
}
}
+
+ /**
+ * Given textbox's value might have changed.
+ */
public void applyTextBox(GT_GuiIntegerTextBox box) {
}
+ /**
+ * Reset the given textbox to the last valid value, <b>NOT</b> 0.
+ */
public void resetTextBox(GT_GuiIntegerTextBox box) {
}
diff --git a/src/main/java/gregtech/api/interfaces/ITextureBuilder.java b/src/main/java/gregtech/api/interfaces/ITextureBuilder.java
index 8a4d715ccb..d72b538243 100644
--- a/src/main/java/gregtech/api/interfaces/ITextureBuilder.java
+++ b/src/main/java/gregtech/api/interfaces/ITextureBuilder.java
@@ -1,5 +1,6 @@
package gregtech.api.interfaces;
+import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing;
import gregtech.api.render.TextureFactory;
import net.minecraft.block.Block;
import net.minecraftforge.common.util.ForgeDirection;
@@ -64,6 +65,13 @@ public interface ITextureBuilder {
ITextureBuilder stdOrient();
/**
+ * Texture will orientate from block's {@link ExtendedFacing}
+ *
+ * @return {@link ITextureBuilder} for chaining
+ */
+ ITextureBuilder extFacing();
+
+ /**
* Texture always render with full brightness to glow in the dark
*
* @return {@link ITextureBuilder} for chaining
diff --git a/src/main/java/gregtech/api/items/GT_MetaGenerated_Tool.java b/src/main/java/gregtech/api/items/GT_MetaGenerated_Tool.java
index 65e9dfcc39..82f19351a5 100644
--- a/src/main/java/gregtech/api/items/GT_MetaGenerated_Tool.java
+++ b/src/main/java/gregtech/api/items/GT_MetaGenerated_Tool.java
@@ -47,6 +47,7 @@ import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.world.BlockEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
@@ -645,7 +646,7 @@ public abstract class GT_MetaGenerated_Tool extends GT_MetaBase_Item implements
return false;
}
Materials aMaterial = getPrimaryMaterial(aStack);
- ConcurrentHashMap<Integer, Integer> tMap = new ConcurrentHashMap<Integer, Integer>(), tResult = new ConcurrentHashMap<Integer, Integer>();
+ HashMap<Integer, Integer> tMap = new HashMap<>(), tResult = new HashMap<>();
if (aMaterial.mEnchantmentTools != null) {
tMap.put(aMaterial.mEnchantmentTools.effectId, (int) aMaterial.mEnchantmentToolsLevel);
if (aMaterial.mEnchantmentTools == Enchantment.fortune)
diff --git a/src/main/java/gregtech/api/items/GT_RadioactiveCellIC_Item.java b/src/main/java/gregtech/api/items/GT_RadioactiveCellIC_Item.java
index e24ed04539..7950672ec2 100644
--- a/src/main/java/gregtech/api/items/GT_RadioactiveCellIC_Item.java
+++ b/src/main/java/gregtech/api/items/GT_RadioactiveCellIC_Item.java
@@ -2,6 +2,7 @@ package gregtech.api.items;
import gregtech.api.GregTech_API;
+import gregtech.api.util.GT_Utility;
import ic2.api.reactor.IReactor;
import ic2.api.reactor.IReactorComponent;
import ic2.core.IC2Potion;
@@ -153,7 +154,7 @@ public class GT_RadioactiveCellIC_Item extends GT_RadioactiveCell_Item implement
public void onUpdate(ItemStack stack, World world, Entity entity, int slotIndex, boolean isCurrentItem) {
if (this.sRadiation > 0 && (entity instanceof EntityLivingBase)) {
EntityLivingBase entityLiving = (EntityLivingBase) entity;
- if (!GregTech_API.mIC2Classic&&!ItemArmorHazmat.hasCompleteHazmat(entityLiving)) {
+ if (!GregTech_API.mIC2Classic&&!GT_Utility.isWearingFullRadioHazmat(entityLiving)) {
IC2Potion.radiation.applyTo(entityLiving, sRadiation * 20, sRadiation * 10);
}
}
diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java
index 39cbee3aa9..c2465c1a53 100644
--- a/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java
@@ -1,13 +1,5 @@
package gregtech.api.metatileentity;
-import static gregtech.GT_Mod.GT_FML_LOGGER;
-import static gregtech.api.enums.GT_Values.NW;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.UUID;
-
import gregtech.GT_Mod;
import gregtech.api.GregTech_API;
import gregtech.api.enums.Textures;
@@ -19,13 +11,10 @@ import gregtech.api.interfaces.metatileentity.IConnectable;
import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.interfaces.tileentity.IPipeRenderedTileEntity;
+import gregtech.api.metatileentity.BaseMetaTileEntity.ClientEvents;
import gregtech.api.net.GT_Packet_TileEntity;
import gregtech.api.objects.GT_ItemStack;
-import gregtech.api.util.GT_CoverBehavior;
-import gregtech.api.util.GT_Log;
-import gregtech.api.util.GT_ModHandler;
-import gregtech.api.util.GT_OreDictUnificator;
-import gregtech.api.util.GT_Utility;
+import gregtech.api.util.*;
import gregtech.common.GT_Client;
import gregtech.common.covers.GT_Cover_Fluidfilter;
import net.minecraft.block.Block;
@@ -41,11 +30,15 @@ import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
-import net.minecraftforge.fluids.Fluid;
-import net.minecraftforge.fluids.FluidRegistry;
-import net.minecraftforge.fluids.FluidStack;
-import net.minecraftforge.fluids.FluidTankInfo;
-import net.minecraftforge.fluids.IFluidHandler;
+import net.minecraftforge.fluids.*;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+import static gregtech.GT_Mod.GT_FML_LOGGER;
+import static gregtech.api.enums.GT_Values.NW;
/**
* NEVER INCLUDE THIS FILE IN YOUR MOD!!!
@@ -57,9 +50,11 @@ public class BaseMetaPipeEntity extends BaseTileEntity implements IGregTechTileE
public byte mConnections = IConnectable.NO_CONNECTION;
protected MetaPipeEntity mMetaTileEntity;
private byte[] mSidedRedstone = new byte[]{0, 0, 0, 0, 0, 0};
- private int[] mCoverSides = new int[]{0, 0, 0, 0, 0, 0}, mCoverData = new int[]{0, 0, 0, 0, 0, 0}, mTimeStatistics = new int[GregTech_API.TICKS_FOR_LAG_AVERAGING];
+ private int[] mCoverSides = new int[]{0, 0, 0, 0, 0, 0};
+ private int[] mCoverData = new int[]{0, 0, 0, 0, 0, 0};
+ private final int[] mTimeStatistics = new int[GregTech_API.TICKS_FOR_LAG_AVERAGING];
private boolean mInventoryChanged = false, mWorkUpdate = false, mWorks = true, mNeedsUpdate = true, mNeedsBlockUpdate = true, mSendClientData = false;
- private boolean mCheckConnections = false;
+ private final boolean mCheckConnections = false;
private byte mColor = 0, oColor = 0, mStrongRedstone = 0, oStrongRedstone = 0, oRedstoneData = 63, oTextureData = 0, oUpdateData = 0, mLagWarningCount = 0;
private int oX = 0, oY = 0, oZ = 0, mTimeStatisticsIndex = 0;
private short mID = 0;
@@ -279,18 +274,19 @@ public class BaseMetaPipeEntity extends BaseTileEntity implements IGregTechTileE
GT_CoverBehavior tCover = getCoverBehaviorAtSide(i);
int tCoverTickRate = tCover.getTickRate(i, getCoverIDAtSide(i), mCoverData[i], this);
if (tCoverTickRate > 0 && mTickTimer % tCoverTickRate == 0) {
- mCoverData[i] = tCover.doCoverThings(i, getInputRedstoneSignal(i), getCoverIDAtSide(i), mCoverData[i], this, mTickTimer);
+ byte tRedstone = tCover.isRedstoneSensitive(i, getCoverIDAtSide(i), mCoverData[i], this, mTickTimer) ? getInputRedstoneSignal(i) : 0;
+ mCoverData[i] = tCover.doCoverThings(i, tRedstone, getCoverIDAtSide(i), mCoverData[i], this, mTickTimer);
if (!hasValidMetaTileEntity()) return;
}
}
- byte oldConections = mConnections;
- // Mask-out Connection direction bits to keep only Foam related connections
+ byte oldConnections = mConnections;
+ // Mask-out connection direction bits to keep only Foam related connections
mConnections = (byte) (mMetaTileEntity.mConnections | (mConnections & ~IConnectable.CONNECTED_ALL));
// If foam not hardened, tries roll chance to harden
if ((mConnections & IConnectable.HAS_FOAM) == IConnectable.HAS_FRESHFOAM && getRandomNumber(1000) == 0) {
mConnections = (byte) ((mConnections & ~IConnectable.HAS_FRESHFOAM) | IConnectable.HAS_HARDENEDFOAM);
}
- if (mTickTimer > 12 && oldConections != mConnections)
+ if (mTickTimer > 12 && oldConnections != mConnections)
GregTech_API.causeCableUpdate(worldObj,xCoord,yCoord,zCoord);
}
case 8:
@@ -330,12 +326,15 @@ public class BaseMetaPipeEntity extends BaseTileEntity implements IGregTechTileE
}
if (mTickTimer > 10) {
- if (mConnections != oTextureData) sendBlockEvent((byte) 0, oTextureData = mConnections);
+ if (mConnections != oTextureData)
+ sendBlockEvent(ClientEvents.CHANGE_COMMON_DATA, oTextureData = mConnections);
byte tData = mMetaTileEntity.getUpdateData();
- if (tData != oUpdateData) sendBlockEvent((byte) 1, oUpdateData = tData);
- if (mColor != oColor) sendBlockEvent((byte) 2, oColor = mColor);
+ if (tData != oUpdateData)
+ sendBlockEvent(ClientEvents.CHANGE_CUSTOM_DATA, oUpdateData = tData);
+ if (mColor != oColor) sendBlockEvent(ClientEvents.CHANGE_COLOR, oColor = mColor);
tData = (byte) (((mSidedRedstone[0] > 0) ? 1 : 0) | ((mSidedRedstone[1] > 0) ? 2 : 0) | ((mSidedRedstone[2] > 0) ? 4 : 0) | ((mSidedRedstone[3] > 0) ? 8 : 0) | ((mSidedRedstone[4] > 0) ? 16 : 0) | ((mSidedRedstone[5] > 0) ? 32 : 0));
- if (tData != oRedstoneData) sendBlockEvent((byte) 3, oRedstoneData = tData);
+ if (tData != oRedstoneData)
+ sendBlockEvent(ClientEvents.CHANGE_REDSTONE_OUTPUT, oRedstoneData = tData);
}
if (mNeedsBlockUpdate) {
@@ -653,7 +652,7 @@ public class BaseMetaPipeEntity extends BaseTileEntity implements IGregTechTileE
@Override
public boolean increaseProgress(int aProgressAmountInTicks) {
- return canAccessData() ? mMetaTileEntity.increaseProgress(aProgressAmountInTicks) != aProgressAmountInTicks : false;
+ return canAccessData() && mMetaTileEntity.increaseProgress(aProgressAmountInTicks) != aProgressAmountInTicks;
}
@Override
@@ -1324,15 +1323,12 @@ public class BaseMetaPipeEntity extends BaseTileEntity implements IGregTechTileE
if (tTileEntity != null && !mMetaTileEntity.isConnectedAtSide((byte) aSide.ordinal()))
return false;
- if(isFill && mMetaTileEntity.isLiquidInput((byte) aSide.ordinal())
+ if (isFill && mMetaTileEntity.isLiquidInput((byte) aSide.ordinal())
&& getCoverBehaviorAtSide((byte) aSide.ordinal()).letsFluidIn((byte) aSide.ordinal(), getCoverIDAtSide((byte) aSide.ordinal()), getCoverDataAtSide((byte) aSide.ordinal()), aFluid, this))
return true;
- if (!isFill && mMetaTileEntity.isLiquidOutput((byte) aSide.ordinal())
- && getCoverBehaviorAtSide((byte) aSide.ordinal()).letsFluidOut((byte) aSide.ordinal(), getCoverIDAtSide((byte) aSide.ordinal()), getCoverDataAtSide((byte) aSide.ordinal()),aFluid, this))
- return true;
-
- return false;
+ return !isFill && mMetaTileEntity.isLiquidOutput((byte) aSide.ordinal())
+ && getCoverBehaviorAtSide((byte) aSide.ordinal()).letsFluidOut((byte) aSide.ordinal(), getCoverIDAtSide((byte) aSide.ordinal()), getCoverDataAtSide((byte) aSide.ordinal()), aFluid, this);
}
@Override
diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java
index 341e7d5714..397d03e0df 100644
--- a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java
@@ -8,6 +8,12 @@ import appeng.me.helpers.AENetworkProxy;
import appeng.me.helpers.IGridProxyable;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
+import com.gtnewhorizon.structurelib.alignment.IAlignment;
+import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits;
+import com.gtnewhorizon.structurelib.alignment.IAlignmentProvider;
+import com.gtnewhorizon.structurelib.alignment.constructable.IConstructable;
+import com.gtnewhorizon.structurelib.alignment.constructable.IConstructableProvider;
+import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing;
import cpw.mods.fml.common.Optional;
import gregtech.GT_Mod;
import gregtech.api.GregTech_API;
@@ -25,11 +31,7 @@ import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachin
import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch;
import gregtech.api.net.GT_Packet_TileEntity;
import gregtech.api.objects.GT_ItemStack;
-import gregtech.api.util.GT_CoverBehavior;
-import gregtech.api.util.GT_Log;
-import gregtech.api.util.GT_ModHandler;
-import gregtech.api.util.GT_OreDictUnificator;
-import gregtech.api.util.GT_Utility;
+import gregtech.api.util.*;
import gregtech.common.GT_Client;
import gregtech.common.GT_Pollution;
import ic2.api.Direction;
@@ -54,6 +56,7 @@ import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
+import javax.annotation.Nullable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
@@ -71,20 +74,23 @@ import static gregtech.api.objects.XSTR.XSTR_INSTANCE;
* This is the main TileEntity for EVERYTHING.
*/
@Optional.InterfaceList(value = {
- @Optional.Interface(iface = "appeng.api.networking.security.IActionHost", modid = "appliedenergistics2", striprefs = true),
- @Optional.Interface(iface = "appeng.me.helpers.IGridProxyable", modid = "appliedenergistics2", striprefs = true)})
-public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileEntity, IActionHost, IGridProxyable {
+ @Optional.Interface(iface = "appeng.api.networking.security.IActionHost", modid = "appliedenergistics2", striprefs = true),
+ @Optional.Interface(iface = "appeng.me.helpers.IGridProxyable", modid = "appliedenergistics2", striprefs = true)})
+public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileEntity, IActionHost, IGridProxyable, IAlignmentProvider, IConstructableProvider {
private final GT_CoverBehavior[] mCoverBehaviors = new GT_CoverBehavior[]{GregTech_API.sNoBehavior, GregTech_API.sNoBehavior, GregTech_API.sNoBehavior, GregTech_API.sNoBehavior, GregTech_API.sNoBehavior, GregTech_API.sNoBehavior};
protected MetaTileEntity mMetaTileEntity;
protected long mStoredEnergy = 0, mStoredSteam = 0;
protected int mAverageEUInputIndex = 0, mAverageEUOutputIndex = 0;
protected boolean mReleaseEnergy = false;
protected long[] mAverageEUInput = new long[]{0, 0, 0, 0, 0}, mAverageEUOutput = new long[]{0, 0, 0, 0, 0};
- private boolean[] mActiveEUInputs = new boolean[]{false, false, false, false, false, false}, mActiveEUOutputs = new boolean[]{false, false, false, false, false, false};
+ private final boolean[] mActiveEUInputs = new boolean[]{false, false, false, false, false, false};
+ private final boolean[] mActiveEUOutputs = new boolean[]{false, false, false, false, false, false};
private byte[] mSidedRedstone = new byte[]{15, 15, 15, 15, 15, 15};
- private int[] mCoverSides = new int[]{0, 0, 0, 0, 0, 0}, mCoverData = new int[]{0, 0, 0, 0, 0, 0}, mTimeStatistics = new int[GregTech_API.TICKS_FOR_LAG_AVERAGING];
+ private int[] mCoverSides = new int[]{0, 0, 0, 0, 0, 0};
+ private int[] mCoverData = new int[]{0, 0, 0, 0, 0, 0};
+ private final int[] mTimeStatistics = new int[GregTech_API.TICKS_FOR_LAG_AVERAGING];
private boolean mHasEnoughEnergy = true, mRunningThroughTick = false, mInputDisabled = false, mOutputDisabled = false, mMuffler = false, mLockUpgrade = false, mActive = false, mRedstone = false, mWorkUpdate = false, mSteamConverter = false, mInventoryChanged = false, mWorks = true, mNeedsUpdate = true, mNeedsBlockUpdate = true, mSendClientData = false, oRedstone = false;
- private byte mColor = 0, oColor = 0, oStrongRedstone = 0, mStrongRedstone = 0, oRedstoneData = 63, oTextureData = 0, oUpdateData = 0, oTexturePage=0, oLightValueClient = -1, oLightValue = -1, mLightValue = 0, mOtherUpgrades = 0, mFacing = 0, oFacing = 0, mWorkData = 0;
+ private byte mColor = 0, oColor = 0, oStrongRedstone = 0, mStrongRedstone = 0, oRedstoneData = 63, oTextureData = 0, oUpdateData = 0, oTexturePage = 0, oLightValueClient = -1, oLightValue = -1, mLightValue = 0, mOtherUpgrades = 0, mFacing = 0, oFacing = 0, mWorkData = 0;
private int mDisplayErrorCode = 0, oX = 0, oY = 0, oZ = 0, mTimeStatisticsIndex = 0, mLagWarningCount = 0;
private short mID = 0;
public long mTickTimer = 0;
@@ -377,7 +383,8 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
GT_CoverBehavior tCover = getCoverBehaviorAtSide(i);
int tCoverTickRate = tCover.getTickRate(i, getCoverIDAtSide(i), mCoverData[i], this);
if (tCoverTickRate > 0 && mTickTimer % tCoverTickRate == 0) {
- mCoverData[i] = tCover.doCoverThings(i, getInputRedstoneSignal(i), getCoverIDAtSide(i), mCoverData[i], this, mTickTimer);
+ byte tRedstone = tCover.isRedstoneSensitive(i, getCoverIDAtSide(i), mCoverData[i], this, mTickTimer) ? getInputRedstoneSignal(i) : 0;
+ mCoverData[i] = tCover.doCoverThings(i, tRedstone, getCoverIDAtSide(i), mCoverData[i], this, mTickTimer);
if (!hasValidMetaTileEntity()) {
mRunningThroughTick = false;
return;
@@ -485,7 +492,7 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
if (GregTech_API.sMachineRainExplosions && worldObj.isRaining() && getBiome().rainfall > 0) {
if (getRandomNumber(10) == 0) {
try{
- GT_Mod.instance.achievements.issueAchievement(this.getWorldObj().getPlayerEntityByName(mOwnerName), "badweather");
+ GT_Mod.achievements.issueAchievement(this.getWorldObj().getPlayerEntityByName(mOwnerName), "badweather");
}catch(Exception e){
}
@@ -501,9 +508,9 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
return;
}
if (GregTech_API.sMachineThunderExplosions && worldObj.isThundering() && getBiome().rainfall > 0 && getRandomNumber(3) == 0) {
- try{
- GT_Mod.instance.achievements.issueAchievement(this.getWorldObj().getPlayerEntityByName(mOwnerName), "badweather");
- }catch(Exception e){
+ try {
+ GT_Mod.achievements.issueAchievement(this.getWorldObj().getPlayerEntityByName(mOwnerName), "badweather");
+ }catch(Exception e){
}
GT_Log.exp.println("Machine at: "+ this.getXCoord()+" | "+ this.getYCoord()+" | "+ this.getZCoord()+" DIMID: " +this.worldObj.provider.dimensionId + " explosion due to Thunderstorm!");
@@ -596,17 +603,21 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
if (mTickTimer > 10) {
byte tData = (byte) ((mFacing & 7) | (mActive ? 8 : 0) | (mRedstone ? 16 : 0) | (mLockUpgrade ? 32 : 0)| (mWorks ? 64 : 0));
- if (tData != oTextureData) sendBlockEvent((byte) 0, oTextureData = tData);
+ if (tData != oTextureData)
+ sendBlockEvent(ClientEvents.CHANGE_COMMON_DATA, oTextureData = tData);
tData = mMetaTileEntity.getUpdateData();
- if (tData != oUpdateData) sendBlockEvent((byte) 1, oUpdateData = tData);
- if(mMetaTileEntity instanceof GT_MetaTileEntity_Hatch) {
+ if (tData != oUpdateData)
+ sendBlockEvent(ClientEvents.CHANGE_CUSTOM_DATA, oUpdateData = tData);
+ if (mMetaTileEntity instanceof GT_MetaTileEntity_Hatch) {
tData = ((GT_MetaTileEntity_Hatch) mMetaTileEntity).getTexturePage();
- if (tData != oTexturePage) sendBlockEvent((byte) 1, (byte)((oTexturePage = tData)|0x80));//set last bit as a flag for page
+ if (tData != oTexturePage)
+ sendBlockEvent(ClientEvents.CHANGE_CUSTOM_DATA, (byte) ((oTexturePage = tData) | 0x80));//set last bit as a flag for page
}
- if (mColor != oColor) sendBlockEvent((byte) 2, oColor = mColor);
+ if (mColor != oColor) sendBlockEvent(ClientEvents.CHANGE_COLOR, oColor = mColor);
tData = (byte) (((mSidedRedstone[0] > 0) ? 1 : 0) | ((mSidedRedstone[1] > 0) ? 2 : 0) | ((mSidedRedstone[2] > 0) ? 4 : 0) | ((mSidedRedstone[3] > 0) ? 8 : 0) | ((mSidedRedstone[4] > 0) ? 16 : 0) | ((mSidedRedstone[5] > 0) ? 32 : 0));
- if (tData != oRedstoneData) sendBlockEvent((byte) 3, oRedstoneData = tData);
+ if (tData != oRedstoneData)
+ sendBlockEvent(ClientEvents.CHANGE_REDSTONE_OUTPUT, oRedstoneData = tData);
if (mLightValue != oLightValue) {
worldObj.setLightValue(EnumSkyBlock.Block, xCoord, yCoord, zCoord, mLightValue);
worldObj.updateLightByType(EnumSkyBlock.Block, xCoord, yCoord, zCoord);
@@ -617,7 +628,7 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
worldObj.updateLightByType(EnumSkyBlock.Block, xCoord, yCoord, zCoord + 1);
worldObj.updateLightByType(EnumSkyBlock.Block, xCoord, yCoord, zCoord - 1);
issueTextureUpdate();
- sendBlockEvent((byte) 7, oLightValue = mLightValue);
+ sendBlockEvent(ClientEvents.CHANGE_LIGHT, oLightValue = mLightValue);
}
}
@@ -669,11 +680,11 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
for (byte i = 0; i < 6; i++) mCoverBehaviors[i] = GregTech_API.getCoverBehavior(mCoverSides[i]);
- receiveClientEvent(0, aTextureData);
- receiveClientEvent(1, aUpdateData & 0x7F);
- receiveClientEvent(1, aTexturePage | 0x80);
- receiveClientEvent(2, aColorData);
- receiveClientEvent(3, aRedstoneData);
+ receiveClientEvent(ClientEvents.CHANGE_COMMON_DATA, aTextureData);
+ receiveClientEvent(ClientEvents.CHANGE_CUSTOM_DATA, aUpdateData & 0x7F);
+ receiveClientEvent(ClientEvents.CHANGE_CUSTOM_DATA, aTexturePage | 0x80);
+ receiveClientEvent(ClientEvents.CHANGE_COLOR, aColorData);
+ receiveClientEvent(ClientEvents.CHANGE_REDSTONE_OUTPUT, aRedstoneData);
}
@Deprecated
@@ -693,11 +704,22 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
for (byte i = 0; i < 6; i++) mCoverBehaviors[i] = GregTech_API.getCoverBehavior(mCoverSides[i]);
- receiveClientEvent(0, aTextureData);
- receiveClientEvent(1, aUpdateData & 0x7F);
- receiveClientEvent(1, 0x80);
- receiveClientEvent(2, aColorData);
- receiveClientEvent(3, aRedstoneData);
+ receiveClientEvent(ClientEvents.CHANGE_COMMON_DATA, aTextureData);
+ receiveClientEvent(ClientEvents.CHANGE_CUSTOM_DATA, aUpdateData & 0x7F);
+ receiveClientEvent(ClientEvents.CHANGE_CUSTOM_DATA, 0x80);
+ receiveClientEvent(ClientEvents.CHANGE_COLOR, aColorData);
+ receiveClientEvent(ClientEvents.CHANGE_REDSTONE_OUTPUT, aRedstoneData);
+ }
+
+ public static class ClientEvents {
+ public static final byte CHANGE_COMMON_DATA = 0;
+ public static final byte CHANGE_CUSTOM_DATA = 1;
+ public static final byte CHANGE_COLOR = 2;
+ public static final byte CHANGE_REDSTONE_OUTPUT = 3;
+ public static final byte DO_SOUND = 4;
+ public static final byte START_SOUND_LOOP = 5;
+ public static final byte STOP_SOUND_LOOP = 6;
+ public static final byte CHANGE_LIGHT = 7;
}
@Override
@@ -716,14 +738,14 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
if (isClientSide()) {
issueTextureUpdate();
switch (aEventID) {
- case 0:
+ case ClientEvents.CHANGE_COMMON_DATA:
mFacing = (byte) (aValue & 7);
mActive = ((aValue & 8) != 0);
mRedstone = ((aValue & 16) != 0);
//mLockUpgrade = ((aValue&32) != 0);
mWorks = ((aValue & 64) != 0);
break;
- case 1:
+ case ClientEvents.CHANGE_CUSTOM_DATA:
if (hasValidMetaTileEntity()) {
if ((aValue & 0x80) == 0) //Is texture index
mMetaTileEntity.onValueUpdate((byte) (aValue & 0x7F));
@@ -731,11 +753,11 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
((GT_MetaTileEntity_Hatch) mMetaTileEntity).onTexturePageUpdate((byte) (aValue & 0x7F));
}
break;
- case 2:
+ case ClientEvents.CHANGE_COLOR:
if (aValue > 16 || aValue < 0) aValue = 0;
mColor = (byte) aValue;
break;
- case 3:
+ case ClientEvents.CHANGE_REDSTONE_OUTPUT:
mSidedRedstone[0] = (byte) ((aValue & 1) == 1 ? 15 : 0);
mSidedRedstone[1] = (byte) ((aValue & 2) == 2 ? 15 : 0);
mSidedRedstone[2] = (byte) ((aValue & 4) == 4 ? 15 : 0);
@@ -743,19 +765,19 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
mSidedRedstone[4] = (byte) ((aValue & 16) == 16 ? 15 : 0);
mSidedRedstone[5] = (byte) ((aValue & 32) == 32 ? 15 : 0);
break;
- case 4:
+ case ClientEvents.DO_SOUND:
if (hasValidMetaTileEntity() && mTickTimer > 20)
mMetaTileEntity.doSound((byte) aValue, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5);
break;
- case 5:
+ case ClientEvents.START_SOUND_LOOP:
if (hasValidMetaTileEntity() && mTickTimer > 20)
mMetaTileEntity.startSoundLoop((byte) aValue, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5);
break;
- case 6:
+ case ClientEvents.STOP_SOUND_LOOP:
if (hasValidMetaTileEntity() && mTickTimer > 20)
mMetaTileEntity.stopSoundLoop((byte) aValue, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5);
break;
- case 7:
+ case ClientEvents.CHANGE_LIGHT:
mLightValue = (byte) aValue;
break;
}
@@ -1006,7 +1028,7 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
@Override
public boolean increaseProgress(int aProgressAmountInTicks) {
- return canAccessData() ? mMetaTileEntity.increaseProgress(aProgressAmountInTicks) != aProgressAmountInTicks : false;
+ return canAccessData() && mMetaTileEntity.increaseProgress(aProgressAmountInTicks) != aProgressAmountInTicks;
}
@Override
@@ -1306,8 +1328,8 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
if ((mOwnerName.length() == 0) && isServerSide()) {
setOwnerName(aPlayer.getDisplayName());
setOwnerUuid(aPlayer.getUniqueID());
- } else if (privateAccess() && !aPlayer.getDisplayName().equals("Player") && !mOwnerName.equals("Player") && !mOwnerName.equals(aPlayer.getDisplayName()))
- return false;
+ } else
+ return !privateAccess() || aPlayer.getDisplayName().equals("Player") || mOwnerName.equals("Player") || mOwnerName.equals(aPlayer.getDisplayName());
return true;
}
@@ -1318,10 +1340,10 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
public void doEnergyExplosion() {
if (getUniversalEnergyCapacity() > 0 && getUniversalEnergyStored() >= getUniversalEnergyCapacity() / 5) {
- GT_Log.exp.println("Energy Explosion, injected "+getUniversalEnergyStored()+"EU >= "+Double.toString((getUniversalEnergyCapacity() / 5D))+"Capacity of the Machine!");
+ GT_Log.exp.println("Energy Explosion, injected " + getUniversalEnergyStored() + "EU >= " + getUniversalEnergyCapacity() / 5D + "Capacity of the Machine!");
doExplosion(oOutput * (getUniversalEnergyStored() >= getUniversalEnergyCapacity() ? 4 : getUniversalEnergyStored() >= getUniversalEnergyCapacity() / 2 ? 2 : 1));
- GT_Mod.instance.achievements.issueAchievement(this.getWorldObj().getPlayerEntityByName(mOwnerName), "electricproblems");
+ GT_Mod.achievements.issueAchievement(this.getWorldObj().getPlayerEntityByName(mOwnerName), "electricproblems");
}
}
@@ -2367,4 +2389,33 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
public void setShutdownStatus(boolean newStatus) {
mWasShutdown = newStatus;
}
+
+ @Override
+ public IAlignment getAlignment() {
+ return getMetaTileEntity() instanceof IAlignmentProvider ? ((IAlignmentProvider) getMetaTileEntity()).getAlignment() : new BasicAlignment();
+ }
+
+ @Nullable
+ @Override
+ public IConstructable getConstructable() {
+ return getMetaTileEntity() instanceof IConstructable ? (IConstructable) getMetaTileEntity() : null;
+ }
+
+ private class BasicAlignment implements IAlignment {
+
+ @Override
+ public ExtendedFacing getExtendedFacing() {
+ return ExtendedFacing.of(ForgeDirection.getOrientation(getFrontFacing()));
+ }
+
+ @Override
+ public void setExtendedFacing(ExtendedFacing alignment) {
+ setFrontFacing((byte) Math.min(alignment.getDirection().ordinal(), ForgeDirection.UNKNOWN.ordinal() - 1));
+ }
+
+ @Override
+ public IAlignmentLimits getAlignmentLimits() {
+ return (direction, rotation, flip) -> rotation.isNotRotated() && flip.isNotFlipped();
+ }
+ }
}
diff --git a/src/main/java/gregtech/api/metatileentity/MetaPipeEntity.java b/src/main/java/gregtech/api/metatileentity/MetaPipeEntity.java
index 601b6fb4f9..99e018ecdf 100644
--- a/src/main/java/gregtech/api/metatileentity/MetaPipeEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/MetaPipeEntity.java
@@ -8,12 +8,9 @@ import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
import gregtech.api.interfaces.tileentity.IColoredTileEntity;
import gregtech.api.interfaces.tileentity.ICoverable;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.BaseMetaTileEntity.ClientEvents;
import gregtech.api.objects.GT_ItemStack;
-import gregtech.api.util.GT_Config;
-import gregtech.api.util.GT_CoverBehavior;
-import gregtech.api.util.GT_LanguageManager;
-import gregtech.api.util.GT_Utility;
-import gregtech.api.util.WorldSpawnedEventBuilder;
+import gregtech.api.util.*;
import gregtech.common.GT_Client;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
@@ -181,10 +178,7 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable {
if (difference > 1.05 && difference < 1.4) {
aSide = 5;
}
- boolean tCovered = false;
- if (aSide < 6 && mBaseMetaTileEntity.getCoverIDAtSide(aSide) > 0) {
- tCovered = true;
- }
+ boolean tCovered = aSide < 6 && mBaseMetaTileEntity.getCoverIDAtSide(aSide) > 0;
if(isConnectedAtSide(aSide)){
tCovered = true;
}
@@ -305,17 +299,20 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable {
@Override
public final void sendSound(byte aIndex) {
- if (!getBaseMetaTileEntity().hasMufflerUpgrade()) getBaseMetaTileEntity().sendBlockEvent((byte) 4, aIndex);
+ if (!getBaseMetaTileEntity().hasMufflerUpgrade())
+ getBaseMetaTileEntity().sendBlockEvent(ClientEvents.DO_SOUND, aIndex);
}
@Override
public final void sendLoopStart(byte aIndex) {
- if (!getBaseMetaTileEntity().hasMufflerUpgrade()) getBaseMetaTileEntity().sendBlockEvent((byte) 5, aIndex);
+ if (!getBaseMetaTileEntity().hasMufflerUpgrade())
+ getBaseMetaTileEntity().sendBlockEvent(ClientEvents.START_SOUND_LOOP, aIndex);
}
@Override
public final void sendLoopEnd(byte aIndex) {
- if (!getBaseMetaTileEntity().hasMufflerUpgrade()) getBaseMetaTileEntity().sendBlockEvent((byte) 6, aIndex);
+ if (!getBaseMetaTileEntity().hasMufflerUpgrade())
+ getBaseMetaTileEntity().sendBlockEvent(ClientEvents.STOP_SOUND_LOOP, aIndex);
}
@Override
@@ -503,7 +500,7 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable {
@Override
public ItemStack decrStackSize(int aIndex, int aAmount) {
- ItemStack tStack = getStackInSlot(aIndex), rStack = GT_Utility.copy(tStack);
+ ItemStack tStack = getStackInSlot(aIndex), rStack = GT_Utility.copyOrNull(tStack);
if (tStack != null) {
if (tStack.stackSize <= aAmount) {
if (setStackToZeroInsteadOfNull(aIndex)) tStack.stackSize = 0;
@@ -769,7 +766,7 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable {
if (tTileEntity instanceof IColoredTileEntity) {
if (getBaseMetaTileEntity().getColorization() >= 0) {
byte tColor = ((IColoredTileEntity) tTileEntity).getColorization();
- if (tColor >= 0 && tColor != getBaseMetaTileEntity().getColorization()) return false;
+ return tColor < 0 || tColor == getBaseMetaTileEntity().getColorization();
}
}
diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
index 87eee3e6ac..e1a8d65149 100644
--- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
@@ -8,13 +8,10 @@ import cpw.mods.fml.relauncher.SideOnly;
import gregtech.api.GregTech_API;
import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.BaseMetaTileEntity.ClientEvents;
import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Cable;
import gregtech.api.objects.GT_ItemStack;
-import gregtech.api.util.GT_Config;
-import gregtech.api.util.GT_LanguageManager;
-import gregtech.api.util.GT_Log;
-import gregtech.api.util.GT_ModHandler;
-import gregtech.api.util.GT_Utility;
+import gregtech.api.util.*;
import gregtech.common.GT_Client;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
@@ -276,18 +273,21 @@ public abstract class MetaTileEntity implements IMetaTileEntity {
@Override
public final void sendSound(byte aIndex) {
- if (!getBaseMetaTileEntity().hasMufflerUpgrade()) getBaseMetaTileEntity().sendBlockEvent((byte) 4, aIndex);
+ if (!getBaseMetaTileEntity().hasMufflerUpgrade())
+ getBaseMetaTileEntity().sendBlockEvent(ClientEvents.DO_SOUND, aIndex);
}
@Override
public final void sendLoopStart(byte aIndex) {
- if (!getBaseMetaTileEntity().hasMufflerUpgrade()) getBaseMetaTileEntity().sendBlockEvent((byte) 5, aIndex);
+ if (!getBaseMetaTileEntity().hasMufflerUpgrade())
+ getBaseMetaTileEntity().sendBlockEvent(ClientEvents.START_SOUND_LOOP, aIndex);
mSoundRequests++;
}
@Override
public final void sendLoopEnd(byte aIndex) {
- if (!getBaseMetaTileEntity().hasMufflerUpgrade()) getBaseMetaTileEntity().sendBlockEvent((byte) 6, aIndex);
+ if (!getBaseMetaTileEntity().hasMufflerUpgrade())
+ getBaseMetaTileEntity().sendBlockEvent(ClientEvents.STOP_SOUND_LOOP, aIndex);
}
/**
@@ -696,7 +696,7 @@ public abstract class MetaTileEntity implements IMetaTileEntity {
@Override
public ItemStack decrStackSize(int aIndex, int aAmount) {
- ItemStack tStack = getStackInSlot(aIndex), rStack = GT_Utility.copy(tStack);
+ ItemStack tStack = getStackInSlot(aIndex), rStack = GT_Utility.copyOrNull(tStack);
if (tStack != null) {
if (tStack.stackSize <= aAmount) {
if (setStackToZeroInsteadOfNull(aIndex)) tStack.stackSize = 0;
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java
index de008abcab..439cacff91 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java
@@ -329,9 +329,9 @@ public class GT_MetaPipeEntity_Cable extends MetaPipeEntity implements IMetaTile
@Override
public String[] getDescription() {
return new String[]{
- "Max Voltage: %%%" + EnumChatFormatting.GREEN + mVoltage + " (" + VN[GT_Utility.getTier(mVoltage)] + ")" + EnumChatFormatting.GRAY,
- "Max Amperage: %%%" + EnumChatFormatting.YELLOW + mAmperage + EnumChatFormatting.GRAY,
- "Loss/Meter/Ampere: %%%" + EnumChatFormatting.RED + mCableLossPerMeter + EnumChatFormatting.GRAY + "%%% EU-Volt"
+ "Max Voltage: %%%" + EnumChatFormatting.GREEN + GT_Utility.formatNumbers(mVoltage) + " (" + VN[GT_Utility.getTier(mVoltage)] + ")" + EnumChatFormatting.GRAY,
+ "Max Amperage: %%%" + EnumChatFormatting.YELLOW + GT_Utility.formatNumbers(mAmperage) + EnumChatFormatting.GRAY,
+ "Loss/Meter/Ampere: %%%" + EnumChatFormatting.RED + GT_Utility.formatNumbers(mCableLossPerMeter) + EnumChatFormatting.GRAY + "%%% EU-Volt"
};
}
@@ -371,18 +371,19 @@ public class GT_MetaPipeEntity_Cable extends MetaPipeEntity implements IMetaTile
}
return new String[]{
//EnumChatFormatting.BLUE + mName + EnumChatFormatting.RESET,
- "Heat: "+
- EnumChatFormatting.RED+ mOverheat +EnumChatFormatting.RESET+" / "+EnumChatFormatting.YELLOW+ mMaxOverheat + EnumChatFormatting.RESET,
+ "Heat: " +
+ EnumChatFormatting.RED + GT_Utility.formatNumbers(mOverheat) + EnumChatFormatting.RESET + " / " +
+ EnumChatFormatting.YELLOW + GT_Utility.formatNumbers(mMaxOverheat) + EnumChatFormatting.RESET,
"Max Load (1t):",
- EnumChatFormatting.GREEN + Integer.toString(amps) + EnumChatFormatting.RESET +" A / "+
- EnumChatFormatting.YELLOW + mAmperage + EnumChatFormatting.RESET +" A",
+ EnumChatFormatting.GREEN + GT_Utility.formatNumbers(amps) + EnumChatFormatting.RESET + " A / " +
+ EnumChatFormatting.YELLOW + GT_Utility.formatNumbers(mAmperage) + EnumChatFormatting.RESET + " A",
"Max EU/p (1t):",
- EnumChatFormatting.GREEN + Long.toString(volts) + EnumChatFormatting.RESET +" EU / "+
- EnumChatFormatting.YELLOW + mVoltage + EnumChatFormatting.RESET +" EU",
- "Max Load (20t): "+
- EnumChatFormatting.GREEN + mTransferredAmperageLast20OK + EnumChatFormatting.RESET +" A",
- "Max EU/p (20t): "+
- EnumChatFormatting.GREEN + mTransferredVoltageLast20OK + EnumChatFormatting.RESET +" EU"
+ EnumChatFormatting.GREEN + GT_Utility.formatNumbers(volts) + EnumChatFormatting.RESET + " EU / " +
+ EnumChatFormatting.YELLOW + GT_Utility.formatNumbers(mVoltage) + EnumChatFormatting.RESET + " EU",
+ "Max Load (20t): " +
+ EnumChatFormatting.GREEN + GT_Utility.formatNumbers(mTransferredAmperageLast20OK) + EnumChatFormatting.RESET + " A",
+ "Max EU/p (20t): " +
+ EnumChatFormatting.GREEN + GT_Utility.formatNumbers(mTransferredVoltageLast20OK) + EnumChatFormatting.RESET + " EU"
};
}
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Fluid.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Fluid.java
index 59c1e91543..128f6fa916 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Fluid.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Fluid.java
@@ -642,13 +642,13 @@ public class GT_MetaPipeEntity_Fluid extends MetaPipeEntity {
public String[] getDescription() {
if (mPipeAmount == 1) {
return new String[]{
- EnumChatFormatting.BLUE + "Fluid Capacity: %%%" + (mCapacity * 20) + "%%% L/sec" + EnumChatFormatting.GRAY,
- EnumChatFormatting.RED + "Heat Limit: %%%" + mHeatResistance + "%%% K" + EnumChatFormatting.GRAY
+ EnumChatFormatting.BLUE + "Fluid Capacity: %%%" + GT_Utility.formatNumbers(mCapacity * 20) + "%%% L/sec" + EnumChatFormatting.GRAY,
+ EnumChatFormatting.RED + "Heat Limit: %%%" + GT_Utility.formatNumbers(mHeatResistance) + "%%% K" + EnumChatFormatting.GRAY
};
} else {
return new String[]{
- EnumChatFormatting.BLUE + "Fluid Capacity: %%%" + (mCapacity * 20) + "%%% L/sec" + EnumChatFormatting.GRAY,
- EnumChatFormatting.RED + "Heat Limit: %%%" + mHeatResistance + "%%% K" + EnumChatFormatting.GRAY,
+ EnumChatFormatting.BLUE + "Fluid Capacity: %%%" + GT_Utility.formatNumbers(mCapacity * 20) + "%%% L/sec" + EnumChatFormatting.GRAY,
+ EnumChatFormatting.RED + "Heat Limit: %%%" + GT_Utility.formatNumbers(mHeatResistance) + "%%% K" + EnumChatFormatting.GRAY,
EnumChatFormatting.AQUA + "Pipe Amount: %%%" + mPipeAmount + EnumChatFormatting.GRAY
};
}
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Item.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Item.java
index e24aebc064..edec79fe65 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Item.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Item.java
@@ -29,8 +29,8 @@ import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
import static gregtech.api.enums.Textures.BlockIcons.PIPE_RESTRICTOR;
@@ -174,7 +174,7 @@ public class GT_MetaPipeEntity_Item extends MetaPipeEntity implements IMetaTileE
for (boolean temp = true; temp && !isInventoryEmpty() && pipeCapacityCheck(); ) {
temp = false;
tPipeList.clear();
- for (IMetaTileEntityItemPipe tTileEntity : GT_Utility.sortMapByValuesAcending(IMetaTileEntityItemPipe.Util.scanPipes(this, new ConcurrentHashMap<IMetaTileEntityItemPipe, Long>(), 0, false, false)).keySet()) {
+ for (IMetaTileEntityItemPipe tTileEntity : GT_Utility.sortMapByValuesAcending(IMetaTileEntityItemPipe.Util.scanPipes(this, new HashMap<>(), 0, false, false)).keySet()) {
if (temp) break;
tPipeList.add(tTileEntity);
while (!temp && !isInventoryEmpty() && tTileEntity.sendItemStack(aBaseMetaTileEntity))
@@ -345,11 +345,11 @@ public class GT_MetaPipeEntity_Item extends MetaPipeEntity implements IMetaTileE
@Override
public String[] getDescription() {
if (mTickTime == 20)
- return new String[]{"Item Capacity: %%%" + getMaxPipeCapacity() + "%%% Stacks/sec", "Routing Value: %%%" + mStepSize};
+ return new String[]{"Item Capacity: %%%" + getMaxPipeCapacity() + "%%% Stacks/sec", "Routing Value: %%%" + GT_Utility.formatNumbers(mStepSize)};
else if (mTickTime % 20 == 0)
- return new String[]{"Item Capacity: %%%" + getMaxPipeCapacity() + "%%% Stacks/%%%" + (mTickTime / 20) + "%%% sec", "Routing Value: %%%" + mStepSize};
+ return new String[]{"Item Capacity: %%%" + getMaxPipeCapacity() + "%%% Stacks/%%%" + (mTickTime / 20) + "%%% sec", "Routing Value: %%%" + GT_Utility.formatNumbers(mStepSize)};
else
- return new String[]{"Item Capacity: %%%" + getMaxPipeCapacity() + "%%% Stacks/%%%" + mTickTime + "%%% ticks", "Routing Value: %%%" + mStepSize};
+ return new String[]{"Item Capacity: %%%" + getMaxPipeCapacity() + "%%% Stacks/%%%" + mTickTime + "%%% ticks", "Routing Value: %%%" + GT_Utility.formatNumbers(mStepSize)};
}
private boolean isInventoryEmpty() {
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicGenerator.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicGenerator.java
index ccc0fc0af4..57f7073e24 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicGenerator.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicGenerator.java
@@ -18,8 +18,6 @@ import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidContainerItem;
import net.minecraftforge.fluids.IFluidHandler;
-import java.util.Collection;
-
import static gregtech.api.enums.GT_Values.V;
public abstract class GT_MetaTileEntity_BasicGenerator extends GT_MetaTileEntity_BasicTank {
@@ -154,7 +152,7 @@ public abstract class GT_MetaTileEntity_BasicGenerator extends GT_MetaTileEntity
@Override
public long maxEUStore() {
- return Math.max(getEUVar(), V[mTier] * 40L + getMinimumStoredEU());
+ return Math.max(getEUVar(), V[mTier] * 80L + getMinimumStoredEU());
}
@Override
@@ -247,16 +245,17 @@ public abstract class GT_MetaTileEntity_BasicGenerator extends GT_MetaTileEntity
public boolean solidFuelOverride(ItemStack stack) {
//this could be used for a coal generator for example aswell...
ItemData association = GT_OreDictUnificator.getAssociation(stack);
- //if it is a gregtech Item, make sure its not a VOLUMETRIC_FLASK, cell, motlen cell or plasma cell, else do vanilla checks
- return association != null ? !OrePrefixes.cell.equals(association.mPrefix) &&
- !OrePrefixes.cellMolten.equals(association.mPrefix) &&
- !OrePrefixes.cellPlasma.equals(association.mPrefix) &&
- !GT_Utility.areStacksEqual(ItemList.VOLUMETRIC_FLASK.get(1L), stack, true) :
- stack != null && //when the stack is null its not a solid
- stack.getItem() != null && //when the item in the stack is null its not a solid
- !(stack.getItem() instanceof IFluidContainerItem) && //when the item is a fluid container its not a solid...
- !(stack.getItem() instanceof IFluidHandler) && //when the item is a fluid handler its not a solid...
- !stack.getItem().getUnlocalizedName().contains("bucket"); //since we cant really check for buckets...
+ //if it is a gregtech Item, make sure its not a VOLUMETRIC_FLASK or any type of cell, else do vanilla checks
+ if (association != null) {
+ return !OrePrefixes.CELL_TYPES.contains(association.mPrefix) &&
+ !GT_Utility.areStacksEqual(ItemList.VOLUMETRIC_FLASK.get(1L), stack, true);
+ } else {
+ return stack != null && //when the stack is null its not a solid
+ stack.getItem() != null && //when the item in the stack is null its not a solid
+ !(stack.getItem() instanceof IFluidContainerItem) && //when the item is a fluid container its not a solid...
+ !(stack.getItem() instanceof IFluidHandler) && //when the item is a fluid handler its not a solid...
+ !stack.getItem().getUnlocalizedName().contains("bucket"); //since we cant really check for buckets...
+ }
}
public abstract int getPollution();
@@ -271,19 +270,18 @@ public abstract class GT_MetaTileEntity_BasicGenerator extends GT_MetaTileEntity
public int getFuelValue(FluidStack aLiquid) {
//System.out.println("Fluid stack check");
- if (aLiquid == null || getRecipes() == null) return 0;
- FluidStack tLiquid;
- Collection<GT_Recipe> tRecipeList = getRecipes().mRecipeList;
- if (tRecipeList != null) for (GT_Recipe tFuel : tRecipeList)
- if ((tLiquid = GT_Utility.getFluidForFilledItem(tFuel.getRepresentativeInput(0), true)) != null)
- if (aLiquid.isFluidEqual(tLiquid)){
- long val=(long)tFuel.mSpecialValue * getEfficiency() * consumedFluidPerOperation(tLiquid) / 100;
- if(val> Integer.MAX_VALUE){
- throw new ArithmeticException("Integer LOOPBACK!");
- }
- return (int) val;
- }
- return 0;
+ GT_Recipe_Map tRecipes = getRecipes();
+ if (aLiquid == null || !(tRecipes instanceof GT_Recipe.GT_Recipe_Map_Fuel)) return 0;
+ GT_Recipe.GT_Recipe_Map_Fuel tFuels = (GT_Recipe.GT_Recipe_Map_Fuel) tRecipes;
+ GT_Recipe tFuel = tFuels.findFuel(aLiquid);
+ if (tFuel == null) {
+ return 0;
+ }
+ long val=(long)tFuel.mSpecialValue * getEfficiency() * consumedFluidPerOperation(aLiquid) / 100;
+ if(val> Integer.MAX_VALUE){
+ throw new ArithmeticException("Integer LOOPBACK!");
+ }
+ return (int) val;
}
public int getFuelValue(ItemStack aStack) {
@@ -303,7 +301,7 @@ public abstract class GT_MetaTileEntity_BasicGenerator extends GT_MetaTileEntity
public ItemStack getEmptyContainer(ItemStack aStack) {
if (GT_Utility.isStackInvalid(aStack) || getRecipes() == null) return null;
GT_Recipe tFuel = getRecipes().findRecipe(getBaseMetaTileEntity(), false, Long.MAX_VALUE, null, aStack);
- if (tFuel != null) return GT_Utility.copy(tFuel.getOutput(0));
+ if (tFuel != null) return GT_Utility.copyOrNull(tFuel.getOutput(0));
return GT_Utility.getContainerItem(aStack, true);
}
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java
index 834344d2d2..7c15137691 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java
@@ -549,7 +549,7 @@ public abstract class GT_MetaTileEntity_BasicMachine extends GT_MetaTileEntity_B
for (int i = getInputSlot(), j = i + mInputSlotCount; i < j; i++)
if (mInventory[i] != null && mInventory[i].stackSize <= 0) mInventory[i] = null;
for (int i = 0; i < mOutputItems.length; i++) {
- mOutputItems[i] = GT_Utility.copy(mOutputItems[i]);
+ mOutputItems[i] = GT_Utility.copyOrNull(mOutputItems[i]);
if (mOutputItems[i] != null && mOutputItems[i].stackSize > 64)
mOutputItems[i].stackSize = 64;
mOutputItems[i] = GT_OreDictUnificator.get(true, mOutputItems[i]);
@@ -594,7 +594,7 @@ public abstract class GT_MetaTileEntity_BasicMachine extends GT_MetaTileEntity_B
if (ItemList.Display_Fluid.isStackEqual(mInventory[tDisplayStackSlot], true, true))
mInventory[tDisplayStackSlot] = null;
} else {
- mInventory[tDisplayStackSlot] = GT_Utility.getFluidDisplayStack(getFillableStack(), displaysStackSize());
+ mInventory[tDisplayStackSlot] = GT_Utility.getFluidDisplayStack(getFillableStack(), true, !displaysStackSize());
}
}
}
@@ -792,14 +792,14 @@ public abstract class GT_MetaTileEntity_BasicMachine extends GT_MetaTileEntity_B
return new String[]{
EnumChatFormatting.BLUE + mNEIName + EnumChatFormatting.RESET,
"Progress:",
- EnumChatFormatting.GREEN + Integer.toString(mProgresstime/20) + EnumChatFormatting.RESET +" s / "+
- EnumChatFormatting.YELLOW + mMaxProgresstime / 20 + EnumChatFormatting.RESET +" s",
+ EnumChatFormatting.GREEN + GT_Utility.formatNumbers((mProgresstime/20)) + EnumChatFormatting.RESET +" s / " +
+ EnumChatFormatting.YELLOW + GT_Utility.formatNumbers(mMaxProgresstime / 20) + EnumChatFormatting.RESET + " s",
"Stored Energy:",
- EnumChatFormatting.GREEN + Long.toString(getBaseMetaTileEntity().getStoredEU()) + EnumChatFormatting.RESET +" EU / "+
- EnumChatFormatting.YELLOW + getBaseMetaTileEntity().getEUCapacity() + EnumChatFormatting.RESET +" EU",
+ EnumChatFormatting.GREEN + GT_Utility.formatNumbers(getBaseMetaTileEntity().getStoredEU()) + EnumChatFormatting.RESET + " EU / " +
+ EnumChatFormatting.YELLOW + GT_Utility.formatNumbers(getBaseMetaTileEntity().getEUCapacity()) + EnumChatFormatting.RESET + " EU",
"Probably uses: " +
- EnumChatFormatting.RED + mEUt + EnumChatFormatting.RESET + " EU/t at " +
- EnumChatFormatting.RED + (mEUt == 0 ? 0 : mAmperage) + EnumChatFormatting.RESET +" A"
+ EnumChatFormatting.RED + GT_Utility.formatNumbers(mEUt) + EnumChatFormatting.RESET + " EU/t at " +
+ EnumChatFormatting.RED + GT_Utility.formatNumbers(mEUt == 0 ? 0 : mAmperage) + EnumChatFormatting.RESET +" A"
};
}
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicTank.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicTank.java
index 6a65eaf5d8..7b99d78009 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicTank.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicTank.java
@@ -198,7 +198,7 @@ public abstract class GT_MetaTileEntity_BasicTank extends GT_MetaTileEntity_Tier
if (ItemList.Display_Fluid.isStackEqual(mInventory[getStackDisplaySlot()], true, true))
mInventory[getStackDisplaySlot()] = null;
} else {
- mInventory[getStackDisplaySlot()] = GT_Utility.getFluidDisplayStack(getDisplayedFluid(), displaysStackSize());
+ mInventory[getStackDisplaySlot()] = GT_Utility.getFluidDisplayStack(getDisplayedFluid(), true, !displaysStackSize());
}
}
}
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Buffer.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Buffer.java
index 7f9e21ff65..d5741f599d 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Buffer.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Buffer.java
@@ -329,11 +329,19 @@ public abstract class GT_MetaTileEntity_Buffer extends GT_MetaTileEntity_TieredM
}
protected void fillStacksIntoFirstSlots() {
- if (bSortStacks) {
- for (int i = 0; i < mInventory.length; i++)
- for (int j = i + 1; j < mInventory.length; j++)
- if (mInventory[j] != null && (mInventory[i] == null || GT_Utility.areStacksEqual(mInventory[i], mInventory[j])))
- GT_Utility.moveStackFromSlotAToSlotB(getBaseMetaTileEntity(), getBaseMetaTileEntity(), j, i, (byte) 64, (byte) 1, (byte) 64, (byte) 1);
+ for (int i = 0; i < mInventory.length - 1; i++) {
+ if (!isValidSlot(i)) {
+ continue;
+ }
+
+ for (int j = i + 1; j < mInventory.length; j++) {
+ if (!isValidSlot(j)) {
+ continue;
+ }
+
+ if (mInventory[j] != null && (mInventory[i] == null || GT_Utility.areStacksEqual(mInventory[i], mInventory[j])))
+ GT_Utility.moveStackFromSlotAToSlotB(getBaseMetaTileEntity(), getBaseMetaTileEntity(), j, i, (byte) 64, (byte) 1, (byte) 64, (byte) 1);
+ }
}
}
@@ -342,7 +350,7 @@ public abstract class GT_MetaTileEntity_Buffer extends GT_MetaTileEntity_TieredM
if (aPlayer.isSneaking()) {
// I was so proud of all this but I literally just copied code from OutputBus
bSortStacks = !bSortStacks;
- GT_Utility.sendChatToPlayer(aPlayer, trans("200", "Sort mode: " + (bSortStacks ? "Disabled" : "Enabled")));
+ GT_Utility.sendChatToPlayer(aPlayer, trans("200", "Sort mode: " + (bSortStacks ? "Enabled" : "Disabled")));
return true;
}
return super.onSolderingToolRightClick(aSide,aWrenchingSide,aPlayer,aX,aY,aZ);
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_CubicMultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_CubicMultiBlockBase.java
new file mode 100644
index 0000000000..3854a96cda
--- /dev/null
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_CubicMultiBlockBase.java
@@ -0,0 +1,110 @@
+package gregtech.api.metatileentity.implementations;
+
+import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
+import com.gtnewhorizon.structurelib.structure.IStructureElement;
+import com.gtnewhorizon.structurelib.structure.StructureDefinition;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import net.minecraft.item.ItemStack;
+
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.lazy;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.onElementPass;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose;
+import static gregtech.api.util.GT_StructureUtility.ofHatchAdder;
+
+/**
+ * A simple 3x3x3 hollow cubic multiblock, that can be arbitrarily rotated, made of a single type of machine casing and accepts hatches everywhere.
+ * Controller will be placed in front center of the structure.
+ * <p>
+ * Note: You cannot use different casing for the same Class. Make a new subclass for it. You also should not change the casing
+ * dynamically, i.e. it should be a dumb method returning some sort of constant.
+ * <p>
+ * Implementation tips:
+ * 1. To restrict hatches, override {@link #addDynamoToMachineList(IGregTechTileEntity, int)} and its cousins instead of overriding the whole
+ * {@link #getStructureDefinition()} or change {@link #checkHatches(IGregTechTileEntity, ItemStack)}. The former is a total overkill, while the later cannot
+ * stop the structure check early.
+ * 2. To limit rotation, override {@link #getInitialAlignmentLimits()}
+ *
+ * @param <T>
+ */
+public abstract class GT_MetaTileEntity_CubicMultiBlockBase<T extends GT_MetaTileEntity_CubicMultiBlockBase<T>> extends GT_MetaTileEntity_EnhancedMultiBlockBase<T> {
+ protected static final String STRUCTURE_PIECE_MAIN = "main";
+ protected static final ClassValue<IStructureDefinition<GT_MetaTileEntity_CubicMultiBlockBase<?>>> STRUCTURE_DEFINITION = new ClassValue<IStructureDefinition<GT_MetaTileEntity_CubicMultiBlockBase<?>>>() {
+ @Override
+ protected IStructureDefinition<GT_MetaTileEntity_CubicMultiBlockBase<?>> computeValue(Class<?> type) {
+ return StructureDefinition.<GT_MetaTileEntity_CubicMultiBlockBase<?>>builder()
+ .addShape(STRUCTURE_PIECE_MAIN, transpose(new String[][]{
+ {"hhh", "hhh", "hhh"},
+ {"h~h", "h-h", "hhh"},
+ {"hhh", "hhh", "hhh"},
+ }))
+ .addElement('h', ofChain(
+ lazy(t -> ofHatchAdder(GT_MetaTileEntity_CubicMultiBlockBase::addToMachineList, t.getHatchTextureIndex(), 1)),
+ onElementPass(
+ GT_MetaTileEntity_CubicMultiBlockBase::onCorrectCasingAdded,
+ lazy(GT_MetaTileEntity_CubicMultiBlockBase::getCasingElement)
+ )
+ ))
+ .build();
+ }
+ };
+ private int mCasingAmount = 0;
+
+ protected GT_MetaTileEntity_CubicMultiBlockBase(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ }
+
+ protected GT_MetaTileEntity_CubicMultiBlockBase(String aName) {
+ super(aName);
+ }
+
+ /**
+ * Create a simple 3x3x3 hollow cubic structure made of a single type of machine casing and accepts hatches everywhere.
+ * <p>
+ * The created definition contains a single piece named {@link #STRUCTURE_PIECE_MAIN}.
+ */
+ @Override
+ @SuppressWarnings("unchecked")
+ public IStructureDefinition<T> getStructureDefinition() {
+ return (IStructureDefinition<T>) STRUCTURE_DEFINITION.get(getClass());
+ }
+
+ @Override
+ public void construct(ItemStack aStack, boolean aHintsOnly) {
+ buildPiece(STRUCTURE_PIECE_MAIN, aStack, aHintsOnly, 1, 1, 0);
+ }
+
+ @Override
+ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) {
+ mCasingAmount = 0;
+ return checkPiece(STRUCTURE_PIECE_MAIN, 1, 1, 0) &&
+ mCasingAmount >= getRequiredCasingCount() &&
+ checkHatches(aBaseMetaTileEntity, aStack);
+ }
+
+ /**
+ * Called by {@link #checkMachine(IGregTechTileEntity, ItemStack)} to check if all required hatches are present.
+ * <p>
+ * Default implementation requires EXACTLY ONE maintenance hatch to be present, and ignore all other conditions.
+ *
+ * @param aBaseMetaTileEntity the tile entity of self
+ * @param aStack The item stack inside the controller
+ * @return true if the test passes, false otherwise
+ */
+ protected boolean checkHatches(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) {
+ return mMaintenanceHatches.size() == 1;
+ }
+
+ protected abstract IStructureElement<GT_MetaTileEntity_CubicMultiBlockBase<?>> getCasingElement();
+
+ /**
+ * The hatch's texture index.
+ */
+ protected abstract int getHatchTextureIndex();
+
+ protected abstract int getRequiredCasingCount();
+
+ protected void onCorrectCasingAdded() {
+ mCasingAmount++;
+ }
+}
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_EnhancedMultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_EnhancedMultiBlockBase.java
new file mode 100644
index 0000000000..cc2513f5c2
--- /dev/null
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_EnhancedMultiBlockBase.java
@@ -0,0 +1,185 @@
+package gregtech.api.metatileentity.implementations;
+
+import com.gtnewhorizon.structurelib.StructureLibAPI;
+import com.gtnewhorizon.structurelib.alignment.IAlignment;
+import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits;
+import com.gtnewhorizon.structurelib.alignment.IAlignmentProvider;
+import com.gtnewhorizon.structurelib.alignment.constructable.IConstructable;
+import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing;
+import com.gtnewhorizon.structurelib.alignment.enumerable.Flip;
+import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation;
+import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
+import cpw.mods.fml.common.network.NetworkRegistry;
+import gregtech.api.GregTech_API;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.util.GT_Multiblock_Tooltip_Builder;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraftforge.common.util.ForgeDirection;
+import org.lwjgl.input.Keyboard;
+
+import java.util.concurrent.atomic.AtomicReferenceArray;
+
+/**
+ * Enhanced multiblock base class, featuring following improvement over {@link GT_MetaTileEntity_MultiBlockBase}
+ * <p>
+ * 1. TecTech style declarative structure check utilizing StructureLib.
+ * 2. Arbitrarily rotating the whole structure, if allowed to.
+ *
+ * @param <T> type of this
+ */
+public abstract class GT_MetaTileEntity_EnhancedMultiBlockBase<T extends GT_MetaTileEntity_EnhancedMultiBlockBase<T>> extends GT_MetaTileEntity_MultiBlockBase implements IAlignment, IConstructable {
+ private static final AtomicReferenceArray<GT_Multiblock_Tooltip_Builder> tooltips = new AtomicReferenceArray<>(GregTech_API.METATILEENTITIES.length);
+ private ExtendedFacing mExtendedFacing = ExtendedFacing.DEFAULT;
+ private IAlignmentLimits mLimits = getInitialAlignmentLimits();
+
+ protected GT_MetaTileEntity_EnhancedMultiBlockBase(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ }
+
+ protected GT_MetaTileEntity_EnhancedMultiBlockBase(String aName) {
+ super(aName);
+ }
+
+ @Override
+ public ExtendedFacing getExtendedFacing() {
+ return mExtendedFacing;
+ }
+
+ @Override
+ public void setExtendedFacing(ExtendedFacing newExtendedFacing) {
+ if (mExtendedFacing != newExtendedFacing) {
+ stopMachine();
+ mExtendedFacing = newExtendedFacing;
+ IGregTechTileEntity base = getBaseMetaTileEntity();
+ mMachine = false;
+ mUpdate = 100;
+ if (getBaseMetaTileEntity().isServerSide()) {
+ StructureLibAPI.sendAlignment((IAlignmentProvider) base,
+ new NetworkRegistry.TargetPoint(base.getWorld().provider.dimensionId,
+ base.getXCoord(), base.getYCoord(), base.getZCoord(), 512));
+ } else {
+ base.issueTextureUpdate();
+ }
+ }
+ }
+
+ @Override
+ public final boolean isFacingValid(byte aFacing) {
+ return canSetToDirectionAny(ForgeDirection.getOrientation(aFacing));
+ }
+
+ @Override
+ public boolean onWrenchRightClick(byte aSide, byte aWrenchingSide, EntityPlayer aPlayer, float aX, float aY, float aZ) {
+ if (aWrenchingSide != getBaseMetaTileEntity().getFrontFacing())
+ return super.onWrenchRightClick(aSide, aWrenchingSide, aPlayer, aX, aY, aZ);
+ if (aPlayer.isSneaking()) {
+ // we won't be allowing horizontal flips, as it can be perfectly emulated by rotating twice and flipping horizontally
+ // allowing an extra round of flip make it hard to draw meaningful flip markers in GT_Proxy#drawGrid
+ toolSetFlip(getFlip().isHorizontallyFlipped() ? Flip.NONE : Flip.HORIZONTAL);
+ } else {
+ toolSetRotation(null);
+ }
+ return true;
+ }
+
+ @Override
+ public void onFacingChange() {
+ toolSetDirection(ForgeDirection.getOrientation(getBaseMetaTileEntity().getFrontFacing()));
+ }
+
+ @Override
+ public IAlignmentLimits getAlignmentLimits() {
+ return mLimits;
+ }
+
+ protected void setAlignmentLimits(IAlignmentLimits mLimits) {
+ this.mLimits = mLimits;
+ }
+
+ /**
+ * Due to limitation of Java type system, you might need to do an unchecked cast.
+ * HOWEVER, the returned IStructureDefinition is expected to be evaluated against current instance only, and should
+ * not be used against other instances, even for those of the same class.
+ */
+ public abstract IStructureDefinition<T> getStructureDefinition();
+
+ protected abstract GT_Multiblock_Tooltip_Builder createTooltip();
+
+ @Override
+ public String[] getDescription() {
+ if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) {
+ return getTooltip().getStructureInformation();
+ } else {
+ return getTooltip().getInformation();
+ }
+ }
+
+ protected GT_Multiblock_Tooltip_Builder getTooltip() {
+ int tId = getBaseMetaTileEntity().getMetaTileID();
+ GT_Multiblock_Tooltip_Builder tooltip = tooltips.get(tId);
+ if (tooltip == null) {
+ tooltip = createTooltip();
+ tooltips.set(tId, tooltip);
+ }
+ return tooltip;
+ }
+
+ @Override
+ public String[] getStructureDescription(ItemStack stackSize) {
+ return getTooltip().getStructureHint();
+ }
+
+ protected IAlignmentLimits getInitialAlignmentLimits() {
+ return (d, r, f) -> !f.isVerticallyFliped();
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ super.saveNBTData(aNBT);
+ aNBT.setByte("eRotation", (byte) mExtendedFacing.getRotation().getIndex());
+ aNBT.setByte("eFlip", (byte) mExtendedFacing.getFlip().getIndex());
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ super.loadNBTData(aNBT);
+ mExtendedFacing = ExtendedFacing.of(ForgeDirection.getOrientation(getBaseMetaTileEntity().getFrontFacing()),
+ Rotation.byIndex(aNBT.getByte("eRotation")),
+ Flip.byIndex(aNBT.getByte("eFlip")));
+ }
+
+ @SuppressWarnings("unchecked")
+ private IStructureDefinition<GT_MetaTileEntity_EnhancedMultiBlockBase<T>> getCastedStructureDefinition() {
+ return (IStructureDefinition<GT_MetaTileEntity_EnhancedMultiBlockBase<T>>) getStructureDefinition();
+ }
+
+ /**
+ * Explanation of the world coordinate these offset means:
+ *
+ * Imagine you stand in front of the controller, with controller facing towards you not rotated or flipped.
+ *
+ * The horizontalOffset would be the number of blocks on the left side of the controller, not counting controller itself.
+ * The verticalOffset would be the number of blocks on the top side of the controller, not counting controller itself.
+ * The depthOffset would be the number of blocks between you and controller, not counting controller itself.
+ *
+ * All these offsets can be negative.
+ */
+ protected final boolean checkPiece(String piece, int horizontalOffset, int verticalOffset, int depthOffset) {
+ IGregTechTileEntity tTile = getBaseMetaTileEntity();
+ return getCastedStructureDefinition().check(this, piece, tTile.getWorld(), getExtendedFacing(), tTile.getXCoord(), tTile.getYCoord(), tTile.getZCoord(), horizontalOffset, verticalOffset, depthOffset, !mMachine);
+ }
+
+ protected final boolean buildPiece(String piece, ItemStack trigger, boolean hintOnly, int horizontalOffset, int verticalOffset, int depthOffset) {
+ IGregTechTileEntity tTile = getBaseMetaTileEntity();
+ return getCastedStructureDefinition().buildOrHints(this, trigger, piece, tTile.getWorld(), getExtendedFacing(), tTile.getXCoord(), tTile.getYCoord(), tTile.getZCoord(), horizontalOffset, verticalOffset, depthOffset, hintOnly);
+ }
+
+ @Override
+ public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) {
+ super.onFirstTick(aBaseMetaTileEntity);
+ if (aBaseMetaTileEntity.isClientSide())
+ StructureLibAPI.queryAlignment((IAlignmentProvider) aBaseMetaTileEntity);
+ }
+}
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Input.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Input.java
index e37d2160a2..fd7eb0fc94 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Input.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Input.java
@@ -16,7 +16,9 @@ public class GT_MetaTileEntity_Hatch_Input extends GT_MetaTileEntity_Hatch {
public GT_Recipe_Map mRecipeMap = null;
public GT_MetaTileEntity_Hatch_Input(int aID, String aName, String aNameRegional, int aTier) {
- super(aID, aName, aNameRegional, aTier, 3, new String[]{"Fluid Input for Multiblocks", "Capacity: " + (8000+8000*(aTier*(aTier+1)>>1)) + "L"});
+ super(aID, aName, aNameRegional, aTier, 3, new String[]{
+ "Fluid Input for Multiblocks",
+ "Capacity: " + GT_Utility.formatNumbers(8000+8000*(aTier*(aTier+1)>>1)) + "L"});
}
public GT_MetaTileEntity_Hatch_Input(String aName, int aTier, String aDescription, ITexture[][][] aTextures) {
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_InputBus.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_InputBus.java
index ebda3cccbc..cfb4d33150 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_InputBus.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_InputBus.java
@@ -1,14 +1,7 @@
package gregtech.api.metatileentity.implementations;
import gregtech.GT_Mod;
-import gregtech.api.gui.GT_Container_1by1;
-import gregtech.api.gui.GT_Container_2by2;
-import gregtech.api.gui.GT_Container_3by3;
-import gregtech.api.gui.GT_Container_4by4;
-import gregtech.api.gui.GT_GUIContainer_1by1;
-import gregtech.api.gui.GT_GUIContainer_2by2;
-import gregtech.api.gui.GT_GUIContainer_3by3;
-import gregtech.api.gui.GT_GUIContainer_4by4;
+import gregtech.api.gui.*;
import gregtech.api.interfaces.ITexture;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.metatileentity.MetaTileEntity;
@@ -17,6 +10,7 @@ import gregtech.api.util.GT_ClientPreference;
import gregtech.api.util.GT_LanguageManager;
import gregtech.api.util.GT_Recipe.GT_Recipe_Map;
import gregtech.api.util.GT_Utility;
+import gregtech.api.util.extensions.ArrayExt;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
@@ -30,19 +24,29 @@ public class GT_MetaTileEntity_Hatch_InputBus extends GT_MetaTileEntity_Hatch {
public boolean disableSort;
public boolean disableFilter = false;
- public GT_MetaTileEntity_Hatch_InputBus(int aID, String aName, String aNameRegional, int aTier) {
- super(aID, aName, aNameRegional, aTier, getSlots(aTier), new String[]{
+ public GT_MetaTileEntity_Hatch_InputBus(int id, String name, String nameRegional, int tier) {
+ this(id, name, nameRegional, tier, getSlots(tier));
+ }
+
+ public GT_MetaTileEntity_Hatch_InputBus(int id, String name, String nameRegional, int tier, int slots) {
+ super(id, name, nameRegional, tier, slots, ArrayExt.of(
"Item Input for Multiblocks",
"Shift + right click with screwdriver to turn Sort mode on/off",
- "Capacity: " + getSlots(aTier) + " stack" + (getSlots(aTier) >= 2 ? "s" : "")});
+ "Capacity: " + slots + " stack" + (slots >= 2 ? "s" : "")));
}
+ @Deprecated
+ // having too many constructors is bad, don't be so lazy, use GT_MetaTileEntity_Hatch_InputBus(String, int, String[], ITexture[][][])
public GT_MetaTileEntity_Hatch_InputBus(String aName, int aTier, String aDescription, ITexture[][][] aTextures) {
- super(aName, aTier, aTier < 1 ? 1 : aTier == 1 ? 4 : aTier == 2 ? 9 : 16, aDescription, aTextures);
+ this(aName, aTier, ArrayExt.of(aDescription), aTextures);
}
public GT_MetaTileEntity_Hatch_InputBus(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) {
- super(aName, aTier, aTier < 1 ? 1 : aTier == 1 ? 4 : aTier == 2 ? 9 : 16, aDescription, aTextures);
+ this(aName, aTier, getSlots(aTier), aDescription, aTextures);
+ }
+
+ public GT_MetaTileEntity_Hatch_InputBus(String aName, int aTier, int aSlots, String[] aDescription, ITexture[][][] aTextures) {
+ super(aName, aTier, aSlots, aDescription, aTextures);
}
@Override
@@ -176,7 +180,7 @@ public class GT_MetaTileEntity_Hatch_InputBus extends GT_MetaTileEntity_Hatch {
GT_Utility.sendChatToPlayer(aPlayer, trans("200", "Sort mode: " + (disableSort ? "Disabled" : "Enabled")));
} else {
disableFilter = !disableFilter;
- GT_Utility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("GT5U.hatch.disableFilter."+disableFilter));
+ GT_Utility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("GT5U.hatch.disableFilter." + disableFilter));
}
}
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Output.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Output.java
index 9965b88a17..bb23452220 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Output.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Output.java
@@ -27,7 +27,7 @@ public class GT_MetaTileEntity_Hatch_Output extends GT_MetaTileEntity_Hatch {
public GT_MetaTileEntity_Hatch_Output(int aID, String aName, String aNameRegional, int aTier) {
super(aID, aName, aNameRegional, aTier, 3, new String[]{
"Fluid Output for Multiblocks",
- "Capacity: " + (8000+8000*(aTier*(aTier+1)>>1)) + "L",
+ "Capacity: " + GT_Utility.formatNumbers(8000+8000*(aTier*(aTier+1)>>1)) + "L",
"Right click with screwdriver to restrict output",
"Can be restricted to put out Items and/or Steam/No Steam/1 specific Fluid",
"Restricted Output Hatches are given priority for Multiblock Fluid output"});
@@ -315,11 +315,11 @@ public class GT_MetaTileEntity_Hatch_Output extends GT_MetaTileEntity_Hatch {
@Override
public String[] getInfoData() {
return new String[]{
- EnumChatFormatting.BLUE + "Output Hatch"+ EnumChatFormatting.RESET,
+ EnumChatFormatting.BLUE + "Output Hatch" + EnumChatFormatting.RESET,
"Stored Fluid:",
- EnumChatFormatting.GOLD + (mFluid == null ? "No Fluid" : mFluid.getLocalizedName())+ EnumChatFormatting.RESET,
- EnumChatFormatting.GREEN + Integer.toString(mFluid == null ? 0 : mFluid.amount) + " L"+ EnumChatFormatting.RESET+" "+
- EnumChatFormatting.YELLOW+ getCapacity() + " L"+ EnumChatFormatting.RESET,
+ EnumChatFormatting.GOLD + (mFluid == null ? "No Fluid" : mFluid.getLocalizedName()) + EnumChatFormatting.RESET,
+ EnumChatFormatting.GREEN + GT_Utility.formatNumbers(mFluid == null ? 0 : mFluid.amount) + " L" + EnumChatFormatting.RESET + " " +
+ EnumChatFormatting.YELLOW + GT_Utility.formatNumbers(getCapacity()) + " L"+ EnumChatFormatting.RESET,
lockedFluidName == null ? "Not Locked" : ("Locked to " + StatCollector.translateToLocal(getLockedFluidName()))
};
}
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_OutputBus.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_OutputBus.java
index 7c8efb88e0..f997f5f489 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_OutputBus.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_OutputBus.java
@@ -1,18 +1,12 @@
package gregtech.api.metatileentity.implementations;
-import gregtech.api.gui.GT_Container_1by1;
-import gregtech.api.gui.GT_Container_2by2;
-import gregtech.api.gui.GT_Container_3by3;
-import gregtech.api.gui.GT_Container_4by4;
-import gregtech.api.gui.GT_GUIContainer_1by1;
-import gregtech.api.gui.GT_GUIContainer_2by2;
-import gregtech.api.gui.GT_GUIContainer_3by3;
-import gregtech.api.gui.GT_GUIContainer_4by4;
+import gregtech.api.gui.*;
import gregtech.api.interfaces.ITexture;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.metatileentity.MetaTileEntity;
import gregtech.api.render.TextureFactory;
import gregtech.api.util.GT_Utility;
+import gregtech.api.util.extensions.ArrayExt;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.IInventory;
@@ -23,8 +17,13 @@ import static gregtech.api.util.GT_Utility.moveMultipleItemStacks;
public class GT_MetaTileEntity_Hatch_OutputBus extends GT_MetaTileEntity_Hatch {
public GT_MetaTileEntity_Hatch_OutputBus(int aID, String aName, String aNameRegional, int aTier) {
- super(aID, aName, aNameRegional, aTier, getSlots(aTier), new String[]{"Item Output for Multiblocks",
- "Capacity: " + getSlots(aTier) + " stack" + (getSlots(aTier) >= 2 ? "s" : "")});
+ this(aID, aName, aNameRegional, aTier, getSlots(aTier));
+ }
+
+ public GT_MetaTileEntity_Hatch_OutputBus(int id, String name, String nameRegional, int tier, int slots) {
+ super(id, name, nameRegional, tier, slots, ArrayExt.of(
+ "Item Output for Multiblocks",
+ "Capacity: " + getSlots(tier) + " stack" + (getSlots(tier) >= 2 ? "s" : "")));
}
public GT_MetaTileEntity_Hatch_OutputBus(int aID, String aName, String aNameRegional, int aTier, String[] aDescription) {
@@ -35,16 +34,18 @@ public class GT_MetaTileEntity_Hatch_OutputBus extends GT_MetaTileEntity_Hatch {
super(aID, aName, aNameRegional, aTier, inventorySize, aDescription);
}
+ @Deprecated
+ // having too many constructors is bad, don't be so lazy, use GT_MetaTileEntity_Hatch_OutputBus(String, int, String[], ITexture[][][])
public GT_MetaTileEntity_Hatch_OutputBus(String aName, int aTier, String aDescription, ITexture[][][] aTextures) {
- super(aName, aTier, aTier < 1 ? 1 : aTier == 1 ? 4 : aTier == 2 ? 9 : 16, aDescription, aTextures);
+ this(aName, aTier, getSlots(aTier), ArrayExt.of(aDescription), aTextures);
}
public GT_MetaTileEntity_Hatch_OutputBus(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) {
- super(aName, aTier, aTier < 1 ? 1 : aTier == 1 ? 4 : aTier == 2 ? 9 : 16, aDescription, aTextures);
+ super(aName, aTier, getSlots(aTier), aDescription, aTextures);
}
- public GT_MetaTileEntity_Hatch_OutputBus(String aName, int aTier, String[] aDescription, int inventorySize, ITexture[][][] aTextures) {
- super(aName, aTier, inventorySize, aDescription, aTextures);
+ public GT_MetaTileEntity_Hatch_OutputBus(String name, int tier, int slots, String[] description, ITexture[][][] textures) {
+ super(name, tier, slots, description, textures);
}
@Override
@@ -126,7 +127,7 @@ public class GT_MetaTileEntity_Hatch_OutputBus extends GT_MetaTileEntity_Hatch {
* @return true if stack is fully accepted. false is stack is partially accepted or nothing is accepted
*/
public boolean storeAll(ItemStack aStack) {
- for (int i = 0, mInventoryLength = mInventory.length; i < mInventoryLength; i++) {
+ for (int i = 0, mInventoryLength = mInventory.length; i < mInventoryLength && aStack.stackSize > 0; i++) {
ItemStack tSlot = mInventory[i];
if (GT_Utility.isStackInvalid(tSlot)) {
if (aStack.stackSize <= getInventoryStackLimit()) {
@@ -170,7 +171,8 @@ public class GT_MetaTileEntity_Hatch_OutputBus extends GT_MetaTileEntity_Hatch {
IInventory tTileEntity =aBaseMetaTileEntity.getIInventoryAtSide(aBaseMetaTileEntity.getFrontFacing());
if(tTileEntity!=null){
moveMultipleItemStacks(aBaseMetaTileEntity,tTileEntity,aBaseMetaTileEntity.getFrontFacing(),aBaseMetaTileEntity.getBackFacing(),null,false,(byte)64,(byte)1,(byte)64,(byte)1,mInventory.length);
-
+ for (int i = 0; i < mInventory.length; i++)
+ if (mInventory[i] != null && mInventory[i].stackSize <= 0) mInventory[i] = null;
// GT_Utility.moveOneItemStack(aBaseMetaTileEntity, tTileEntity,
// aBaseMetaTileEntity.getFrontFacing(), aBaseMetaTileEntity.getBackFacing(),
// null, false, (byte) 64, (byte) 1, (byte)( 64 * aBaseMetaTileEntity.getSizeInventory()), (byte) 1);
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java
index 193b9d482c..0a1b2e8b02 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java
@@ -26,6 +26,7 @@ import net.minecraftforge.fluids.FluidStack;
import org.lwjgl.input.Keyboard;
import java.util.ArrayList;
+import java.util.List;
import static gregtech.api.enums.GT_Values.V;
import static gregtech.api.enums.GT_Values.VN;
@@ -676,8 +677,8 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity {
return false;
}
- private boolean dumpFluid(FluidStack copiedFluidStack, boolean restrictiveHatchesOnly){
- for (GT_MetaTileEntity_Hatch_Output tHatch : mOutputHatches) {
+ protected static boolean dumpFluid(List<GT_MetaTileEntity_Hatch_Output> aOutputHatches, FluidStack copiedFluidStack, boolean restrictiveHatchesOnly){
+ for (GT_MetaTileEntity_Hatch_Output tHatch : aOutputHatches) {
if (!isValidMetaTileEntity(tHatch) || (restrictiveHatchesOnly && tHatch.mMode == 0)) {
continue;
}
@@ -709,8 +710,8 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity {
public boolean addOutput(FluidStack aLiquid) {
if (aLiquid == null) return false;
FluidStack copiedFluidStack = aLiquid.copy();
- if (!dumpFluid(copiedFluidStack, true)){
- dumpFluid(copiedFluidStack, false);
+ if (!dumpFluid(mOutputHatches, copiedFluidStack, true)){
+ dumpFluid(mOutputHatches, copiedFluidStack, false);
}
return false;
}
@@ -741,7 +742,7 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity {
public boolean addOutput(ItemStack aStack) {
if (GT_Utility.isStackInvalid(aStack)) return false;
- aStack = GT_Utility.copy(aStack);
+ aStack = GT_Utility.copyOrNull(aStack);
for (GT_MetaTileEntity_Hatch_OutputBus tHatch : mOutputBusses) {
if (isValidMetaTileEntity(tHatch) && tHatch.storeAll(aStack)) {
return true;
@@ -973,20 +974,24 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity {
}
return new String[]{
- /* 1*/ StatCollector.translateToLocal("GT5U.multiblock.Progress")+": " + EnumChatFormatting.GREEN + Integer.toString(mProgresstime/20) + EnumChatFormatting.RESET +" s / "
- + EnumChatFormatting.YELLOW + Integer.toString(mMaxProgresstime/20) + EnumChatFormatting.RESET +" s",
- /* 2*/ StatCollector.translateToLocal("GT5U.multiblock.energy")+": " +
- EnumChatFormatting.GREEN + Long.toString(storedEnergy) + EnumChatFormatting.RESET +" EU / "+
- EnumChatFormatting.YELLOW + Long.toString(maxEnergy) + EnumChatFormatting.RESET +" EU",
- /* 3*/ StatCollector.translateToLocal("GT5U.multiblock.usage")+": "+ EnumChatFormatting.RED + Integer.toString(-mEUt) + EnumChatFormatting.RESET + " EU/t",
- /* 4*/ StatCollector.translateToLocal("GT5U.multiblock.mei")+": "+
- EnumChatFormatting.YELLOW+Long.toString(getMaxInputVoltage())+EnumChatFormatting.RESET+ " EU/t(*2A) "+StatCollector.translateToLocal("GT5U.machines.tier")+": "+
- EnumChatFormatting.YELLOW+VN[GT_Utility.getTier(getMaxInputVoltage())]+ EnumChatFormatting.RESET,
- /* 5*/ StatCollector.translateToLocal("GT5U.multiblock.problems")+": "+
- EnumChatFormatting.RED+ (getIdealStatus() - getRepairStatus())+EnumChatFormatting.RESET+
- " "+StatCollector.translateToLocal("GT5U.multiblock.efficiency")+": "+
- EnumChatFormatting.YELLOW+Float.toString(mEfficiency / 100.0F)+EnumChatFormatting.RESET + " %",
- /* 6*/ StatCollector.translateToLocal("GT5U.multiblock.pollution")+": "+ EnumChatFormatting.GREEN + mPollutionReduction+ EnumChatFormatting.RESET+" %"
+ /* 1*/ StatCollector.translateToLocal("GT5U.multiblock.Progress") + ": " +
+ EnumChatFormatting.GREEN + GT_Utility.formatNumbers(mProgresstime/20) + EnumChatFormatting.RESET + " s / " +
+ EnumChatFormatting.YELLOW + GT_Utility.formatNumbers(mMaxProgresstime/20) + EnumChatFormatting.RESET + " s",
+ /* 2*/ StatCollector.translateToLocal("GT5U.multiblock.energy") + ": " +
+ EnumChatFormatting.GREEN + GT_Utility.formatNumbers(storedEnergy) + EnumChatFormatting.RESET + " EU / " +
+ EnumChatFormatting.YELLOW + GT_Utility.formatNumbers(maxEnergy) + EnumChatFormatting.RESET + " EU",
+ /* 3*/ StatCollector.translateToLocal("GT5U.multiblock.usage") + ": " +
+ EnumChatFormatting.RED + GT_Utility.formatNumbers(-mEUt) + EnumChatFormatting.RESET + " EU/t",
+ /* 4*/ StatCollector.translateToLocal("GT5U.multiblock.mei") + ": " +
+ EnumChatFormatting.YELLOW + GT_Utility.formatNumbers(getMaxInputVoltage()) + EnumChatFormatting.RESET + " EU/t(*2A) " +
+ StatCollector.translateToLocal("GT5U.machines.tier") + ": " +
+ EnumChatFormatting.YELLOW + VN[GT_Utility.getTier(getMaxInputVoltage())] + EnumChatFormatting.RESET,
+ /* 5*/ StatCollector.translateToLocal("GT5U.multiblock.problems") + ": " +
+ EnumChatFormatting.RED + (getIdealStatus() - getRepairStatus()) + EnumChatFormatting.RESET + " " +
+ StatCollector.translateToLocal("GT5U.multiblock.efficiency") + ": " +
+ EnumChatFormatting.YELLOW + Float.toString(mEfficiency / 100.0F) + EnumChatFormatting.RESET + " %",
+ /* 6*/ StatCollector.translateToLocal("GT5U.multiblock.pollution") + ": " +
+ EnumChatFormatting.GREEN + mPollutionReduction + EnumChatFormatting.RESET + " %"
};
}
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Transformer.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Transformer.java
index 5cc4245bc8..8e8cc6de76 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Transformer.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Transformer.java
@@ -115,7 +115,7 @@ public class GT_MetaTileEntity_Transformer extends GT_MetaTileEntity_TieredMachi
@Override
public long maxEUStore() {
- return Math.max(512L, 1L << (mTier + 1)) + V[mTier + 1] * 2L;
+ return Math.max(512L, 1L << (mTier + 2)) + V[mTier + 1] * 4L;
}
@Override
diff --git a/src/main/java/gregtech/api/net/GT_Packet_WirelessRedstoneCover.java b/src/main/java/gregtech/api/net/GT_Packet_WirelessRedstoneCover.java
new file mode 100644
index 0000000000..3ce0b48821
--- /dev/null
+++ b/src/main/java/gregtech/api/net/GT_Packet_WirelessRedstoneCover.java
@@ -0,0 +1,95 @@
+package gregtech.api.net;
+
+import com.google.common.io.ByteArrayDataInput;
+import gregtech.api.interfaces.tileentity.ICoverable;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import io.netty.buffer.ByteBuf;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.network.INetHandler;
+import net.minecraft.network.NetHandlerPlayServer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.IBlockAccess;
+import net.minecraft.world.World;
+import net.minecraftforge.common.DimensionManager;
+
+public class GT_Packet_WirelessRedstoneCover extends GT_Packet_TileEntityCover {
+ private static final int PRIVATE_MASK = 0xFFFE0000;
+ private static final int PUBLIC_MASK = 0x0000FFFF;
+ private static final int CHECKBOX_MASK = 0x00010000;
+
+ private EntityPlayerMP mPlayer;
+ private int mPublicChannel;
+ private int mCheckBoxValue;
+
+ public GT_Packet_WirelessRedstoneCover() {
+ super();
+ }
+
+ public GT_Packet_WirelessRedstoneCover(int mX, short mY, int mZ, byte coverSide, int coverID, int dimID, int publicChannel, int checkBoxValue) {
+ super(mX, mY, mZ, coverSide, coverID, 0, dimID);
+ mPublicChannel = publicChannel;
+ mCheckBoxValue = checkBoxValue;
+ }
+
+ public GT_Packet_WirelessRedstoneCover(byte coverSide, int coverID, ICoverable tile, int publicChannel, int checkBoxValue) {
+ super(coverSide, coverID, 0, tile);
+ mPublicChannel = publicChannel;
+ mCheckBoxValue = checkBoxValue;
+ }
+
+ @Override
+ public byte getPacketID() {
+ return 10;
+ }
+
+ @Override
+ public void setINetHandler(INetHandler aHandler) {
+ if (aHandler instanceof NetHandlerPlayServer) {
+ mPlayer = ((NetHandlerPlayServer) aHandler).playerEntity;
+ }
+ }
+
+ @Override
+ public void encode(ByteBuf aOut) {
+ aOut.writeInt(mX);
+ aOut.writeShort(mY);
+ aOut.writeInt(mZ);
+
+ aOut.writeByte(side);
+ aOut.writeInt(coverID);
+
+ aOut.writeInt(dimID);
+
+ aOut.writeInt(mPublicChannel);
+ aOut.writeInt(mCheckBoxValue);
+ }
+
+ @Override
+ public GT_Packet_New decode(ByteArrayDataInput aData) {
+ return new GT_Packet_WirelessRedstoneCover(
+ aData.readInt(),
+ aData.readShort(),
+ aData.readInt(),
+
+ aData.readByte(),
+ aData.readInt(),
+
+ aData.readInt(),
+
+ aData.readInt(),
+ aData.readInt());
+ }
+
+ @Override
+ public void process(IBlockAccess aWorld) {
+ World world = DimensionManager.getWorld(dimID);
+ if (world != null && world.blockExists(mX, mY, mZ)) {
+ TileEntity tile = world.getTileEntity(mX, mY, mZ);
+ if (tile instanceof IGregTechTileEntity && !((IGregTechTileEntity) tile).isDead()) {
+ int tPrivateChannel = (mCheckBoxValue > 0) ? mPlayer.getUniqueID().hashCode() & PRIVATE_MASK : 0;
+ int tCoverData = tPrivateChannel | (mCheckBoxValue & CHECKBOX_MASK) | (mPublicChannel & PUBLIC_MASK);
+ ((IGregTechTileEntity) tile).receiveCoverData(side, coverID, tCoverData);
+ }
+ }
+ }
+}
diff --git a/src/main/java/gregtech/api/objects/CollectorUtils.java b/src/main/java/gregtech/api/objects/CollectorUtils.java
new file mode 100644
index 0000000000..3f89ad0773
--- /dev/null
+++ b/src/main/java/gregtech/api/objects/CollectorUtils.java
@@ -0,0 +1,29 @@
+package gregtech.api.objects;
+
+import java.util.Map;
+import java.util.function.BiFunction;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+
+public class CollectorUtils {
+ /**
+ * Returns a merge function, suitable for use in
+ * {@link Map#merge(Object, Object, BiFunction) Map.merge()} or
+ * {@link Collectors#toMap(Function, Function, BinaryOperator) toMap()}, which always
+ * throws {@code IllegalStateException}. This can be used to enforce the
+ * assumption that the elements being collected are distinct.
+ *
+ * @param <T> the type of input arguments to the merge function
+ * @return a merge function which always throw {@code IllegalStateException}
+ */
+ public static <T> BinaryOperator<T> throwingMerger() {
+ return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); };
+ }
+
+ public static <K, V, E extends Map.Entry<K, V>, M extends Map<K, V>> Collector<E, ?, M> entriesToMap(Supplier<M> mapSupplier) {
+ return Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, CollectorUtils.throwingMerger(), mapSupplier);
+ }
+}
diff --git a/src/main/java/gregtech/api/objects/iterators/MergedIterator.java b/src/main/java/gregtech/api/objects/iterators/MergedIterator.java
new file mode 100644
index 0000000000..77fac8d22f
--- /dev/null
+++ b/src/main/java/gregtech/api/objects/iterators/MergedIterator.java
@@ -0,0 +1,30 @@
+package gregtech.api.objects.iterators;
+
+import java.util.Iterator;
+
+public class MergedIterator<T> implements Iterator<T> {
+ private final Iterator<T>[] inners;
+ private int current;
+
+ @SafeVarargs
+ public MergedIterator(Iterator<T>... iterators) {
+ inners = iterators;
+ current = 0;
+ }
+
+ public boolean hasNext() {
+ while (current < inners.length && !inners[current].hasNext()) {
+ current++;
+ }
+
+ return current < inners.length;
+ }
+
+ public T next() {
+ while (current < inners.length && !inners[current].hasNext()) {
+ current++;
+ }
+
+ return inners[current].next();
+ }
+}
diff --git a/src/main/java/gregtech/api/threads/GT_Runnable_Cable_Update.java b/src/main/java/gregtech/api/threads/GT_Runnable_Cable_Update.java
index 6bc42e9cc8..7093184533 100644
--- a/src/main/java/gregtech/api/threads/GT_Runnable_Cable_Update.java
+++ b/src/main/java/gregtech/api/threads/GT_Runnable_Cable_Update.java
@@ -21,18 +21,16 @@ public class GT_Runnable_Cable_Update extends GT_Runnable_MachineBlockUpdate {
}
}
-
@Override
public void run() {
try {
while (!tQueue.isEmpty()) {
final ChunkCoordinates aCoords = tQueue.poll();
final TileEntity tTileEntity;
- final boolean isMachineBlock;
GT_Proxy.TICK_LOCK.lock();
try {
- //we dont want to go over cables that are in unloaded chuncks
+ //we dont want to go over cables that are in unloaded chunks
//keeping the lock just to make sure no CME happens
if (world.blockExists(aCoords.posX, aCoords.posY, aCoords.posZ)) {
tTileEntity = world.getTileEntity(aCoords.posX, aCoords.posY, aCoords.posZ);
@@ -48,7 +46,7 @@ public class GT_Runnable_Cable_Update extends GT_Runnable_MachineBlockUpdate {
((IMachineBlockUpdateable) tTileEntity).onMachineBlockUpdate();
// Now see if we should add the nearby blocks to the queue:
- //only add blocks wich the cable is conected too
+ // only add blocks the cable is connected to
if (tTileEntity instanceof BaseMetaPipeEntity &&
((BaseMetaPipeEntity) tTileEntity).getMetaTileEntity() instanceof GT_MetaPipeEntity_Cable)
{
diff --git a/src/main/java/gregtech/api/util/GT_BaseCrop.java b/src/main/java/gregtech/api/util/GT_BaseCrop.java
index c06bf82b89..97f8db0547 100644
--- a/src/main/java/gregtech/api/util/GT_BaseCrop.java
+++ b/src/main/java/gregtech/api/util/GT_BaseCrop.java
@@ -68,7 +68,7 @@ public class GT_BaseCrop extends CropCard implements ICropCardInfo {
aID = GT_Config.addIDConfig(ConfigCategories.IDs.crops, mName.replaceAll(" ", "_"), aID);
if (aDiscoveredBy != null && !aDiscoveredBy.equals(E)) mDiscoveredBy = aDiscoveredBy;
if (aDrop != null && aID > 0 && aID < 256) {
- mDrop = GT_Utility.copy(aDrop);
+ mDrop = GT_Utility.copyOrNull(aDrop);
mSpecialDrops = aSpecialDrops;
mTier = Math.max(1, aTier);
mMaxSize = Math.max(3, aMaxSize);
@@ -177,9 +177,9 @@ public class GT_BaseCrop extends CropCard implements ICropCardInfo {
public ItemStack getGain(ICropTile aCrop) {
int tDrop = 0;
if (mSpecialDrops != null && (tDrop = java.util.concurrent.ThreadLocalRandom.current().nextInt(0, (mSpecialDrops.length*2) + 2)) < mSpecialDrops.length && mSpecialDrops[tDrop] != null) {
- return GT_Utility.copy(mSpecialDrops[tDrop]);
+ return GT_Utility.copyOrNull(mSpecialDrops[tDrop]);
}
- return GT_Utility.copy(mDrop);
+ return GT_Utility.copyOrNull(mDrop);
}
@Override
@@ -247,9 +247,9 @@ public class GT_BaseCrop extends CropCard implements ICropCardInfo {
@Override
public ItemStack getDisplayItem() {
if (mSpecialDrops != null && mSpecialDrops[mSpecialDrops.length - 1] != null) {
- return GT_Utility.copy(mSpecialDrops[mSpecialDrops.length - 1]);
+ return GT_Utility.copyOrNull(mSpecialDrops[mSpecialDrops.length - 1]);
}
- return GT_Utility.copy(mDrop);
+ return GT_Utility.copyOrNull(mDrop);
}
}
diff --git a/src/main/java/gregtech/api/util/GT_CoverBehavior.java b/src/main/java/gregtech/api/util/GT_CoverBehavior.java
index 08092cd31e..14c8cc1308 100644
--- a/src/main/java/gregtech/api/util/GT_CoverBehavior.java
+++ b/src/main/java/gregtech/api/util/GT_CoverBehavior.java
@@ -18,6 +18,10 @@ public abstract class GT_CoverBehavior {
public EntityPlayer lastPlayer = null;
+ public boolean isRedstoneSensitive(byte aSide, int aCoverID, int aCoverVariable, ICoverable aTileEntity, long aTimer) {
+ return true;
+ }
+
/**
* Called by updateEntity inside the covered TileEntity. aCoverVariable is the Value you returned last time.
*/
@@ -57,6 +61,7 @@ public abstract class GT_CoverBehavior {
*/
public boolean onCoverShiftRightclick(byte aSide, int aCoverID, int aCoverVariable, ICoverable aTileEntity, EntityPlayer aPlayer) {
if(hasCoverGUI() && aPlayer instanceof EntityPlayerMP) {
+ lastPlayer = aPlayer;
GT_Values.NW.sendToPlayer(new GT_Packet_TileEntityCoverGUI(aSide, aCoverID, aCoverVariable, aTileEntity, (EntityPlayerMP) aPlayer), (EntityPlayerMP) aPlayer);
return true;
}
diff --git a/src/main/java/gregtech/api/util/GT_FoodStat.java b/src/main/java/gregtech/api/util/GT_FoodStat.java
index ce89881a5b..193977476a 100644
--- a/src/main/java/gregtech/api/util/GT_FoodStat.java
+++ b/src/main/java/gregtech/api/util/GT_FoodStat.java
@@ -36,7 +36,7 @@ public class GT_FoodStat implements IFoodStat {
mSaturation = aSaturation;
mAction = aAction == null ? EnumAction.eat : aAction;
mPotionEffects = aPotionEffects;
- mEmptyContainer = GT_Utility.copy(aEmptyContainer);
+ mEmptyContainer = GT_Utility.copyOrNull(aEmptyContainer);
mInvisibleParticles = aInvisibleParticles;
mAlwaysEdible = aAlwaysEdible;
mIsRotten = aIsRotten;
@@ -65,7 +65,7 @@ public class GT_FoodStat implements IFoodStat {
@Override
public void onEaten(GT_MetaBase_Item aItem, ItemStack aStack, EntityPlayer aPlayer) {
aStack.stackSize--;
- ItemStack tStack = GT_OreDictUnificator.get(GT_Utility.copy(mEmptyContainer));
+ ItemStack tStack = GT_OreDictUnificator.get(GT_Utility.copyOrNull(mEmptyContainer));
if (tStack != null && !aPlayer.inventory.addItemStackToInventory(tStack))
aPlayer.dropPlayerItemWithRandomChoice(tStack, true);
diff --git a/src/main/java/gregtech/api/util/GT_ModHandler.java b/src/main/java/gregtech/api/util/GT_ModHandler.java
index f82b0ecb7e..a910723069 100644
--- a/src/main/java/gregtech/api/util/GT_ModHandler.java
+++ b/src/main/java/gregtech/api/util/GT_ModHandler.java
@@ -383,14 +383,14 @@ public class GT_ModHandler {
}
/**
- * Gets an Item from RailCraft
+ * Gets an Item from the specified mod
*/
public static ItemStack getModItem(String aModID, String aItem, long aAmount) {
return getModItem(aModID, aItem, aAmount, null);
}
/**
- * Gets an Item from RailCraft, and returns a Replacement Item if not possible
+ * Gets an Item from the specified mod, and returns a Replacement Item if not possible
*/
public static ItemStack getModItem(String aModID, String aItem, long aAmount, ItemStack aReplacement) {
if (GT_Utility.isStringInvalid(aItem) || !GregTech_API.sPreloadStarted) return null;
@@ -398,7 +398,7 @@ public class GT_ModHandler {
}
/**
- * Gets an Item from RailCraft, but the Damage Value can be specified
+ * Gets an Item from the specified mod, but the Damage Value can be specified
*/
public static ItemStack getModItem(String aModID, String aItem, long aAmount, int aMeta) {
ItemStack rStack = getModItem(aModID, aItem, aAmount);
@@ -408,7 +408,7 @@ public class GT_ModHandler {
}
/**
- * Gets an Item from RailCraft, but the Damage Value can be specified, and returns a Replacement Item with the same Damage if not possible
+ * Gets an Item from the specified mod, but the Damage Value can be specified, and returns a Replacement Item with the same Damage if not possible
*/
public static ItemStack getModItem(String aModID, String aItem, long aAmount, int aMeta, ItemStack aReplacement) {
ItemStack rStack = getModItem(aModID, aItem, aAmount, aReplacement);
@@ -460,8 +460,8 @@ public class GT_ModHandler {
aChance = (float) GregTech_API.sRecipeFile.get(ConfigCategories.Machines.scrapboxdrops, aOutput, aChance);
if (aChance <= 0) return false;
try {
- GT_Utility.callMethod(GT_Utility.getFieldContent("ic2.api.recipe.Recipes", "scrapboxDrops", true, true), "addDrop", true, false, true, GT_Utility.copy(aOutput), aChance);
- GT_Utility.callMethod(GT_Utility.getFieldContent("ic2.api.recipe.Recipes", "scrapboxDrops", true, true), "addRecipe", true, true, false, GT_Utility.copy(aOutput), aChance);
+ GT_Utility.callMethod(GT_Utility.getFieldContent("ic2.api.recipe.Recipes", "scrapboxDrops", true, true), "addDrop", true, false, true, GT_Utility.copyOrNull(aOutput), aChance);
+ GT_Utility.callMethod(GT_Utility.getFieldContent("ic2.api.recipe.Recipes", "scrapboxDrops", true, true), "addRecipe", true, true, false, GT_Utility.copyOrNull(aOutput), aChance);
} catch (Throwable e) {/*Do nothing*/}
return true;
}
@@ -484,7 +484,7 @@ public class GT_ModHandler {
aOutput = GT_OreDictUnificator.get(true, aOutput);
if (aInput == null || aOutput == null || GT_Utility.getContainerItem(aInput, false) != null) return false;
if (!GregTech_API.sRecipeFile.get(ConfigCategories.Machines.smelting, aInput, true)) return false;
- FurnaceRecipes.smelting().func_151394_a(aInput, GT_Utility.copy(aOutput), 0.0F);
+ FurnaceRecipes.smelting().func_151394_a(aInput, GT_Utility.copyOrNull(aOutput), 0.0F);
return true;
}
@@ -562,8 +562,8 @@ public class GT_ModHandler {
aOutput = GT_OreDictUnificator.get(true, aOutput);
if (aInput == null || aOutput == null || aTime <= 0) return false;
if (!GregTech_API.sRecipeFile.get(ConfigCategories.Machines.rcblastfurnace, aInput, true)) return false;
- aInput = GT_Utility.copy(aInput);
- aOutput = GT_Utility.copy(aOutput);
+ aInput = GT_Utility.copyOrNull(aInput);
+ aOutput = GT_Utility.copyOrNull(aOutput);
try {
mods.railcraft.api.crafting.RailcraftCraftingManager.blastFurnace.addRecipe(aInput, true, false, aTime, aOutput);
} catch (Throwable e) {
@@ -614,28 +614,28 @@ public class GT_ModHandler {
if (Materials.Wood.contains(aOutput1)) {
if (aEnableTEMachineRecipes && GregTech_API.sRecipeFile.get(ConfigCategories.Machines.pulverization, aInput, true)) {
if (aOutput2 == null)
- ThermalExpansion.addSawmillRecipe(32000, GT_Utility.copy(aInput), GT_Utility.copy(aOutput1));
+ ThermalExpansion.addSawmillRecipe(32000, GT_Utility.copyOrNull(aInput), GT_Utility.copyOrNull(aOutput1));
else
- ThermalExpansion.addSawmillRecipe(32000, GT_Utility.copy(aInput), GT_Utility.copy(aOutput1), GT_Utility.copy(aOutput2), aChance2 <= 0 ? 10 : aChance2);
+ ThermalExpansion.addSawmillRecipe(32000, GT_Utility.copyOrNull(aInput), GT_Utility.copyOrNull(aOutput1), GT_Utility.copyOrNull(aOutput2), aChance2 <= 0 ? 10 : aChance2);
}
} else {
if (GregTech_API.sRecipeFile.get(ConfigCategories.Machines.rockcrushing, aInput, true)) {
try {
if (GT_Utility.getBlockFromStack(aInput) != Blocks.obsidian && GT_Utility.getBlockFromStack(aInput) != Blocks.gravel) {
mods.railcraft.api.crafting.IRockCrusherRecipe tRecipe = mods.railcraft.api.crafting.RailcraftCraftingManager.rockCrusher.createNewRecipe(GT_Utility.copyAmount(1, aInput), aInput.getItemDamage() != W, false);
- tRecipe.addOutput(GT_Utility.copy(aOutput1), 1.0F / aInput.stackSize);
+ tRecipe.addOutput(GT_Utility.copyOrNull(aOutput1), 1.0F / aInput.stackSize);
if (aOutput2 != null)
- tRecipe.addOutput(GT_Utility.copy(aOutput2), (0.01F * (aChance2 <= 0 ? 10 : aChance2)) / aInput.stackSize);
+ tRecipe.addOutput(GT_Utility.copyOrNull(aOutput2), (0.01F * (aChance2 <= 0 ? 10 : aChance2)) / aInput.stackSize);
if (aOutput3 != null)
- tRecipe.addOutput(GT_Utility.copy(aOutput3), (0.01F * (aChance3 <= 0 ? 10 : aChance3)) / aInput.stackSize);
+ tRecipe.addOutput(GT_Utility.copyOrNull(aOutput3), (0.01F * (aChance3 <= 0 ? 10 : aChance3)) / aInput.stackSize);
}
} catch (Throwable e) {/*Do nothing*/}
}
if (aEnableTEMachineRecipes && GregTech_API.sRecipeFile.get(ConfigCategories.Machines.pulverization, aInput, true)) {
if (aOutput2 == null)
- ThermalExpansion.addPulverizerRecipe(32000, GT_Utility.copy(aInput), GT_Utility.copy(aOutput1));
+ ThermalExpansion.addPulverizerRecipe(32000, GT_Utility.copyOrNull(aInput), GT_Utility.copyOrNull(aOutput1));
else
- ThermalExpansion.addPulverizerRecipe(32000, GT_Utility.copy(aInput), GT_Utility.copy(aOutput1), GT_Utility.copy(aOutput2), aChance2 <= 0 ? 10 : aChance2);
+ ThermalExpansion.addPulverizerRecipe(32000, GT_Utility.copyOrNull(aInput), GT_Utility.copyOrNull(aOutput1), GT_Utility.copyOrNull(aOutput2), aChance2 <= 0 ? 10 : aChance2);
}
}
}
@@ -702,7 +702,7 @@ public class GT_ModHandler {
if (!GT_Mod.gregtechproxy.mTEMachineRecipes && !GregTech_API.sRecipeFile.get(ConfigCategories.Machines.inductionsmelter, aInput2 == null ? aInput1 : aOutput1, true))
return false;
try {
- ThermalExpansion.addSmelterRecipe(aEnergy * 10, GT_Utility.copy(aInput1), aInput2 == null ? new ItemStack(Blocks.sand, 1, 0) : aInput2, aOutput1, aOutput2, aChance);
+ ThermalExpansion.addSmelterRecipe(aEnergy * 10, GT_Utility.copyOrNull(aInput1), aInput2 == null ? new ItemStack(Blocks.sand, 1, 0) : aInput2, aOutput1, aOutput2, aChance);
} catch (Throwable e) {/*Do nothing*/}
return true;
}
@@ -713,7 +713,7 @@ public class GT_ModHandler {
public static boolean addOreToIngotSmeltingRecipe(ItemStack aInput, ItemStack aOutput) {
aOutput = GT_OreDictUnificator.get(true, aOutput);
if (aInput == null || aOutput == null) return false;
- FurnaceRecipes.smelting().func_151394_a(aInput, GT_Utility.copy(aOutput), 0.0F);
+ FurnaceRecipes.smelting().func_151394_a(aInput, GT_Utility.copyOrNull(aOutput), 0.0F);
return true;
}
@@ -847,9 +847,9 @@ public class GT_ModHandler {
aResult = GT_OreDictUnificator.get(true, aResult);
if (aResult == null || aRecipe == null || aResult.stackSize <= 0) return false;
try {
- mods.railcraft.api.crafting.RailcraftCraftingManager.rollingMachine.getRecipeList().add(new ShapedOreRecipe(GT_Utility.copy(aResult), aRecipe));
+ mods.railcraft.api.crafting.RailcraftCraftingManager.rollingMachine.getRecipeList().add(new ShapedOreRecipe(GT_Utility.copyOrNull(aResult), aRecipe));
} catch (Throwable e) {
- return addCraftingRecipe(GT_Utility.copy(aResult), aRecipe);
+ return addCraftingRecipe(GT_Utility.copyOrNull(aResult), aRecipe);
}
return true;
}
@@ -1084,8 +1084,9 @@ public class GT_ModHandler {
Character chr = (Character) aRecipe[idx];
Object in = aRecipe[idx + 1];
if (in instanceof ItemStack) {
- tItemStackMap.put(chr, GT_Utility.copy(in));
- tItemDataMap.put(chr, GT_OreDictUnificator.getItemData((ItemStack) in));
+ ItemStack is = (ItemStack) in;
+ tItemStackMap.put(chr, GT_Utility.copyOrNull(is));
+ tItemDataMap.put(chr, GT_OreDictUnificator.getItemData(is));
} else if (in instanceof ItemData) {
String tString = in.toString();
switch (tString) {
@@ -1184,9 +1185,9 @@ public class GT_ModHandler {
if (tThereWasARecipe || !aOnlyAddIfThereIsAnyRecipeOutputtingThis) {
if (sBufferCraftingRecipes && aBuffered)
- sBufferRecipeList.add(new GT_Shaped_Recipe(GT_Utility.copy(aResult), aDismantleable, aRemovable, aKeepNBT, aEnchantmentsAdded, aEnchantmentLevelsAdded, aRecipe).setMirrored(aMirrored));
+ sBufferRecipeList.add(new GT_Shaped_Recipe(GT_Utility.copyOrNull(aResult), aDismantleable, aRemovable, aKeepNBT, aEnchantmentsAdded, aEnchantmentLevelsAdded, aRecipe).setMirrored(aMirrored));
else
- GameRegistry.addRecipe(new GT_Shaped_Recipe(GT_Utility.copy(aResult), aDismantleable, aRemovable, aKeepNBT, aEnchantmentsAdded, aEnchantmentLevelsAdded, aRecipe).setMirrored(aMirrored));
+ GameRegistry.addRecipe(new GT_Shaped_Recipe(GT_Utility.copyOrNull(aResult), aDismantleable, aRemovable, aKeepNBT, aEnchantmentsAdded, aEnchantmentLevelsAdded, aRecipe).setMirrored(aMirrored));
}
return true;
}
@@ -1260,9 +1261,9 @@ public class GT_ModHandler {
GT_Utility.updateItemStack(aResult);
if (sBufferCraftingRecipes && aBuffered)
- sBufferRecipeList.add(new GT_Shapeless_Recipe(GT_Utility.copy(aResult), aDismantleable, aRemovable, aKeepNBT, aEnchantmentsAdded, aEnchantmentLevelsAdded, aRecipe));
+ sBufferRecipeList.add(new GT_Shapeless_Recipe(GT_Utility.copyOrNull(aResult), aDismantleable, aRemovable, aKeepNBT, aEnchantmentsAdded, aEnchantmentLevelsAdded, aRecipe));
else
- GameRegistry.addRecipe(new GT_Shapeless_Recipe(GT_Utility.copy(aResult), aDismantleable, aRemovable, aKeepNBT, aEnchantmentsAdded, aEnchantmentLevelsAdded, aRecipe));
+ GameRegistry.addRecipe(new GT_Shapeless_Recipe(GT_Utility.copyOrNull(aResult), aDismantleable, aRemovable, aKeepNBT, aEnchantmentsAdded, aEnchantmentLevelsAdded, aRecipe));
return true;
}
@@ -1531,7 +1532,7 @@ public class GT_ModHandler {
throw new GT_ItsNotMyFaultException("Seems another Mod added a Crafting Recipe with null Output. Tell the Developer of said Mod to fix that.");
} else {
if (aUncopiedStack) return tOutput;
- return GT_Utility.copy(tOutput);
+ return GT_Utility.copyOrNull(tOutput);
}
}
}
@@ -1679,7 +1680,7 @@ public class GT_ModHandler {
if (tRecipe instanceof ShapelessRecipes) continue;
if (tRecipe instanceof ShapelessOreRecipe) continue;
if (tRecipe instanceof IGT_CraftingRecipe) continue;
- rList.add(GT_Utility.copy(tOutput));
+ rList.add(GT_Utility.copyOrNull(tOutput));
aList.remove(i--);
}
}
@@ -1691,7 +1692,7 @@ public class GT_ModHandler {
*/
@Deprecated
public static ItemStack getMaceratorOutput(ItemStack aInput, boolean aRemoveInput, ItemStack aOutputSlot) {
- return GT_Utility.copy(getMachineOutput(aInput, getMaceratorRecipeList(), aRemoveInput, new NBTTagCompound(), aOutputSlot)[0]);
+ return GT_Utility.copyOrNull(getMachineOutput(aInput, getMaceratorRecipeList(), aRemoveInput, new NBTTagCompound(), aOutputSlot)[0]);
}
/**
@@ -1699,7 +1700,7 @@ public class GT_ModHandler {
*/
@Deprecated
public static ItemStack getExtractorOutput(ItemStack aInput, boolean aRemoveInput, ItemStack aOutputSlot) {
- return GT_Utility.copy(getMachineOutput(aInput, getExtractorRecipeList(), aRemoveInput, new NBTTagCompound(), aOutputSlot)[0]);
+ return GT_Utility.copyOrNull(getMachineOutput(aInput, getExtractorRecipeList(), aRemoveInput, new NBTTagCompound(), aOutputSlot)[0]);
}
/**
@@ -1707,7 +1708,7 @@ public class GT_ModHandler {
*/
@Deprecated
public static ItemStack getCompressorOutput(ItemStack aInput, boolean aRemoveInput, ItemStack aOutputSlot) {
- return GT_Utility.copy(getMachineOutput(aInput, getCompressorRecipeList(), aRemoveInput, new NBTTagCompound(), aOutputSlot)[0]);
+ return GT_Utility.copyOrNull(getMachineOutput(aInput, getCompressorRecipeList(), aRemoveInput, new NBTTagCompound(), aOutputSlot)[0]);
}
/**
@@ -1748,7 +1749,7 @@ public class GT_ModHandler {
for (byte i = 0; i < aOutputSlots.length && i < tList.length; i++) {
if (tList[i] != null) {
if (aOutputSlots[i] == null || (GT_Utility.areStacksEqual(tList[i], aOutputSlots[i]) && tList[i].stackSize + aOutputSlots[i].stackSize <= aOutputSlots[i].getMaxStackSize())) {
- rList[i] = GT_Utility.copy(tList[i]);
+ rList[i] = GT_Utility.copyOrNull(tList[i]);
} else {
return new ItemStack[aOutputSlots.length];
}
@@ -2007,7 +2008,22 @@ public class GT_ModHandler {
public static int getCapsuleCellContainerCount(ItemStack aStack) {
if (aStack == null) return 0;
- return GT_Utility.areStacksEqual(GT_Utility.getContainerForFilledItem(aStack, true), ItemList.Cell_Empty.get(1)) || OrePrefixes.cell.contains(aStack) || OrePrefixes.cellMolten.contains(aStack) || OrePrefixes.cellPlasma.contains(aStack) || GT_Utility.areStacksEqual(aStack, getIC2Item("waterCell", 1, W)) ? 1 : 0;
+
+ if (GT_Utility.areStacksEqual(GT_Utility.getContainerForFilledItem(aStack, true), ItemList.Cell_Empty.get(1))) {
+ return 1;
+ }
+
+ if (GT_Utility.areStacksEqual(aStack, getIC2Item("waterCell", 1, W))) {
+ return 1;
+ }
+
+ for (OrePrefixes cellType : OrePrefixes.CELL_TYPES) {
+ if (cellType.contains(aStack)) {
+ return 1;
+ }
+ }
+
+ return 0;
}
public static class RecipeBits {
diff --git a/src/main/java/gregtech/api/util/GT_Multiblock_Tooltip_Builder.java b/src/main/java/gregtech/api/util/GT_Multiblock_Tooltip_Builder.java
index e30fe5d606..3071cb95a3 100644
--- a/src/main/java/gregtech/api/util/GT_Multiblock_Tooltip_Builder.java
+++ b/src/main/java/gregtech/api/util/GT_Multiblock_Tooltip_Builder.java
@@ -1,11 +1,19 @@
package gregtech.api.util;
-import java.util.LinkedList;
-import java.util.List;
-
+import com.google.common.collect.Multimaps;
+import com.google.common.collect.SetMultimap;
+import com.gtnewhorizon.structurelib.StructureLibAPI;
+import gregtech.api.enums.Materials;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.StatCollector;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
/**
* This makes it easier to build multi tooltips, with a standardized format. <br>
* Info section order should be:<br>
@@ -32,12 +40,16 @@ import net.minecraft.util.StatCollector;
public class GT_Multiblock_Tooltip_Builder {
private static final String TAB = " ";
private static final String COLON = ": ";
-
+ private static final String SEPARATOR = ", ";
+
private final List<String> iLines;
private final List<String> sLines;
-
+ private final List<String> hLines;
+ private final SetMultimap<Integer, String> hBlocks;
+
private String[] iArray;
private String[] sArray;
+ private String[] hArray;
//Localized tooltips
private static final String TT_machineType = StatCollector.translateToLocal("GT5U.MBTT.MachineType");
@@ -58,11 +70,17 @@ public class GT_Multiblock_Tooltip_Builder {
private static final String TT_pps = StatCollector.translateToLocal("GT5U.MBTT.PPS");
private static final String TT_hold = StatCollector.translateToLocal("GT5U.MBTT.Hold");
private static final String TT_todisplay = StatCollector.translateToLocal("GT5U.MBTT.Display");
+ private static final String TT_structurehint = StatCollector.translateToLocal("GT5U.MBTT.StructureHint");
private static final String TT_mod = StatCollector.translateToLocal("GT5U.MBTT.Mod");
+ private static final String TT_air = StatCollector.translateToLocal("GT5U.MBTT.Air");
+ private static final String[] TT_dots = IntStream.range(0, 16).mapToObj(i -> StatCollector.translateToLocal("structurelib.blockhint." + i + ".name")).toArray(String[]::new);
public GT_Multiblock_Tooltip_Builder() {
iLines = new LinkedList<>();
sLines = new LinkedList<>();
+ hLines = new LinkedList<>();
+ hBlocks = Multimaps.newSetMultimap(new HashMap<>(), HashSet::new);
+ hBlocks.put(StructureLibAPI.HINT_BLOCK_META_AIR, TT_air);
}
/**
@@ -103,11 +121,10 @@ public class GT_Multiblock_Tooltip_Builder {
}
/**
- * Add a line telling you what the machine type is. Usually, this will be the name of a SB version.<br>
- * Machine Type: machine
+ * Add a line telling how much this machine pollutes.
*
- * @param machine
- * Name of the machine type
+ * @param pollution
+ * Amount of pollution per second when active
*
* @return Instance this method was called on.
*/
@@ -307,7 +324,136 @@ public class GT_Multiblock_Tooltip_Builder {
sLines.add(TAB + TT_outputhatch + COLON + info);
return this;
}
-
+
+ /**
+ * Use this method to add a structural part that isn't covered by the other methods.<br>
+ * (indent)name: info
+ * @param name
+ * Name of the hatch or other component.
+ * @param info
+ * Positional information.
+ * @param dots
+ * The valid locations for this part when asked to display hints
+ * @return Instance this method was called on.
+ */
+ public GT_Multiblock_Tooltip_Builder addOtherStructurePart(String name, String info, int... dots) {
+ sLines.add(TAB + name + COLON + info);
+ for (int dot : dots) hBlocks.put(dot, name);
+ return this;
+ }
+
+ /**
+ * Add a line of information about the structure:<br>
+ * (indent)Maintenance Hatch: info
+ *
+ * @param info Positional information.
+ * @param dots The valid locations for this part when asked to display hints
+ * @return Instance this method was called on.
+ */
+ public GT_Multiblock_Tooltip_Builder addMaintenanceHatch(String info, int... dots) {
+ sLines.add(TAB + TT_maintenancehatch + COLON + info);
+ for (int dot : dots) hBlocks.put(dot, TT_maintenancehatch);
+ return this;
+ }
+
+ /**
+ * Add a line of information about the structure:<br>
+ * (indent)Muffler Hatch: info
+ *
+ * @param info Location where the hatch goes
+ * @param dots The valid locations for this part when asked to display hints
+ * @return Instance this method was called on.
+ */
+ public GT_Multiblock_Tooltip_Builder addMufflerHatch(String info, int... dots) {
+ sLines.add(TAB + TT_mufflerhatch + COLON + info);
+ for (int dot : dots) hBlocks.put(dot, TT_mufflerhatch);
+ return this;
+ }
+
+ /**
+ * Add a line of information about the structure:<br>
+ * (indent)Energy Hatch: info
+ *
+ * @param info Positional information.
+ * @param dots The valid locations for this part when asked to display hints
+ * @return Instance this method was called on.
+ */
+ public GT_Multiblock_Tooltip_Builder addEnergyHatch(String info, int... dots) {
+ sLines.add(TAB + TT_energyhatch + COLON + info);
+ for (int dot : dots) hBlocks.put(dot, TT_energyhatch);
+ return this;
+ }
+
+ /**
+ * Add a line of information about the structure:<br>
+ * (indent)Dynamo Hatch: info
+ *
+ * @param info Positional information.
+ * @param dots The valid locations for this part when asked to display hints
+ * @return Instance this method was called on.
+ */
+ public GT_Multiblock_Tooltip_Builder addDynamoHatch(String info, int... dots) {
+ sLines.add(TAB + TT_dynamohatch + COLON + info);
+ for (int dot : dots) hBlocks.put(dot, TT_dynamohatch);
+ return this;
+ }
+
+ /**
+ * Add a line of information about the structure:<br>
+ * (indent)Input Bus: info
+ *
+ * @param info Location where the bus goes
+ * @param dots The valid locations for this part when asked to display hints
+ * @return Instance this method was called on.
+ */
+ public GT_Multiblock_Tooltip_Builder addInputBus(String info, int... dots) {
+ sLines.add(TAB + TT_inputbus + COLON + info);
+ for (int dot : dots) hBlocks.put(dot, TT_inputbus);
+ return this;
+ }
+
+ /**
+ * Add a line of information about the structure:<br>
+ * (indent)Input Hatch: info
+ *
+ * @param info Location where the hatch goes
+ * @param dots The valid locations for this part when asked to display hints
+ * @return Instance this method was called on.
+ */
+ public GT_Multiblock_Tooltip_Builder addInputHatch(String info, int... dots) {
+ sLines.add(TAB + TT_inputhatch + COLON + info);
+ for (int dot : dots) hBlocks.put(dot, TT_inputhatch);
+ return this;
+ }
+
+ /**
+ * Add a line of information about the structure:<br>
+ * (indent)Output Bus: info
+ *
+ * @param info Location where the bus goes
+ * @param dots The valid locations for this part when asked to display hints
+ * @return Instance this method was called on.
+ */
+ public GT_Multiblock_Tooltip_Builder addOutputBus(String info, int... dots) {
+ sLines.add(TAB + TT_outputbus + COLON + info);
+ for (int dot : dots) hBlocks.put(dot, TT_outputbus);
+ return this;
+ }
+
+ /**
+ * Add a line of information about the structure:<br>
+ * (indent)Output Hatch: info
+ *
+ * @param info Location where the bus goes
+ * @param dots The valid locations for this part when asked to display hints
+ * @return Instance this method was called on.
+ */
+ public GT_Multiblock_Tooltip_Builder addOutputHatch(String info, int... dots) {
+ sLines.add(TAB + TT_outputhatch + COLON + info);
+ for (int dot : dots) hBlocks.put(dot, TT_outputhatch);
+ return this;
+ }
+
/**
* Use this method to add non-standard structural info.<br>
* (indent)info
@@ -319,6 +465,30 @@ public class GT_Multiblock_Tooltip_Builder {
sLines.add(TAB + info);
return this;
}
+
+ /**
+ * Use this method to add non-standard structural hint. This info will appear before the standard structural hint.
+ * @param info
+ * The line to be added. This should be an entry into minecraft's localization system.
+ * @return Instance this method was called on.
+ */
+ public GT_Multiblock_Tooltip_Builder addStructureHint(String info) {
+ hLines.add(StatCollector.translateToLocal(info));
+ return this;
+ }
+
+ /**
+ * Use this method to add an entry to standard structural hint without creating a corresponding line in structure information
+ * @param name
+ * The name of block This should be an entry into minecraft's localization system.
+ * @param dots
+ * Possible locations of this block
+ * @return Instance this method was called on.
+ */
+ public GT_Multiblock_Tooltip_Builder addStructureHint(String name, int... dots) {
+ for (int dot : dots) hBlocks.put(dot, StatCollector.translateToLocal(name));
+ return this;
+ }
/**
* Call at the very end.<br>
@@ -331,10 +501,11 @@ public class GT_Multiblock_Tooltip_Builder {
public void toolTipFinisher(String mod) {
iLines.add(TT_hold + " " + EnumChatFormatting.BOLD + "[LSHIFT]" + EnumChatFormatting.RESET + EnumChatFormatting.GRAY + " " + TT_todisplay);
iLines.add(TT_mod + COLON + EnumChatFormatting.GREEN + mod + EnumChatFormatting.GRAY);
- iArray = new String[iLines.size()];
- sArray = new String[sLines.size()];
- iLines.toArray(iArray);
- sLines.toArray(sArray);
+ hLines.add(TT_structurehint);
+ iArray = iLines.toArray(new String[0]);
+ sArray = sLines.toArray(new String[0]);
+ // e.getKey() - 1 because 1 dot is meta 0.
+ hArray = Stream.concat(hLines.stream(), hBlocks.asMap().entrySet().stream().map(e -> TT_dots[e.getKey() - 1] + COLON + String.join(SEPARATOR, e.getValue()))).toArray(String[]::new);
}
public String[] getInformation() {
@@ -345,4 +516,7 @@ public class GT_Multiblock_Tooltip_Builder {
return sArray;
}
+ public String[] getStructureHint() {
+ return hArray;
+ }
}
diff --git a/src/main/java/gregtech/api/util/GT_OreDictUnificator.java b/src/main/java/gregtech/api/util/GT_OreDictUnificator.java
index 4a5ca9070b..54ef5b2866 100644
--- a/src/main/java/gregtech/api/util/GT_OreDictUnificator.java
+++ b/src/main/java/gregtech/api/util/GT_OreDictUnificator.java
@@ -123,7 +123,7 @@ public class GT_OreDictUnificator {
}
public static ItemStack[] setStackArray(boolean aUseBlackList, ItemStack... aStacks) {
- for (int i = 0; i < aStacks.length; i++) aStacks[i] = get(aUseBlackList, GT_Utility.copy(aStacks[i]));
+ for (int i = 0; i < aStacks.length; i++) aStacks[i] = get(aUseBlackList, GT_Utility.copyOrNull(aStacks[i]));
return aStacks;
}
@@ -155,15 +155,15 @@ public class GT_OreDictUnificator {
ItemData tPrefixMaterial = getAssociation(aStack);
ItemStack rStack = null;
if (tPrefixMaterial == null || !tPrefixMaterial.hasValidPrefixMaterialData() || (aUseBlackList && tPrefixMaterial.mBlackListed))
- return GT_Utility.copy(aStack);
+ return GT_Utility.copyOrNull(aStack);
if (aUseBlackList && !GregTech_API.sUnificationEntriesRegistered && isBlacklisted(aStack)) {
tPrefixMaterial.mBlackListed = true;
- return GT_Utility.copy(aStack);
+ return GT_Utility.copyOrNull(aStack);
}
if (tPrefixMaterial.mUnificationTarget == null)
tPrefixMaterial.mUnificationTarget = sName2StackMap.get(tPrefixMaterial.toString());
rStack = tPrefixMaterial.mUnificationTarget;
- if (GT_Utility.isStackInvalid(rStack)) return GT_Utility.copy(aStack);
+ if (GT_Utility.isStackInvalid(rStack)) return GT_Utility.copyOrNull(aStack);
assert rStack != null;
rStack.setTagCompound(aStack.getTagCompound());
return GT_Utility.copyAmount(aStack.stackSize, rStack);
@@ -448,7 +448,6 @@ public class GT_OreDictUnificator {
public static ItemStack getIngotOrDust(MaterialStack aMaterial) {
ItemStack rStack = getIngot(aMaterial);
- if(aMaterial!=null&&aMaterial.mMaterial!=null&&(aMaterial.mMaterial==Materials.Naquadah||aMaterial.mMaterial==Materials.NaquadahEnriched))rStack = getDust(aMaterial);
if (rStack == null) rStack = getDust(aMaterial);
return rStack;
}
diff --git a/src/main/java/gregtech/api/util/GT_Recipe.java b/src/main/java/gregtech/api/util/GT_Recipe.java
index aa54b55277..4059c6cd92 100644
--- a/src/main/java/gregtech/api/util/GT_Recipe.java
+++ b/src/main/java/gregtech/api/util/GT_Recipe.java
@@ -9,6 +9,7 @@ import gregtech.api.objects.GT_FluidStack;
import gregtech.api.objects.GT_ItemStack;
import gregtech.api.objects.ItemData;
import gregtech.api.objects.MaterialStack;
+import gregtech.api.util.extensions.ArrayExt;
import gregtech.common.tileentities.machines.basic.GT_MetaTileEntity_Replicator;
import gregtech.nei.GT_NEI_DefaultHandler.FixedPositionedStack;
import ic2.core.Ic2Items;
@@ -96,7 +97,8 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
mEnabled = aRecipe.mEnabled;
mHidden = aRecipe.mHidden;
}
- protected GT_Recipe(boolean aOptimize, ItemStack[] aInputs, ItemStack[] aOutputs, Object aSpecialItems, int[] aChances, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, int aSpecialValue) {
+
+ public GT_Recipe(boolean aOptimize, ItemStack[] aInputs, ItemStack[] aOutputs, Object aSpecialItems, int[] aChances, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, int aSpecialValue) {
if (aInputs == null)
aInputs = new ItemStack[0];
if (aOutputs == null)
@@ -110,10 +112,10 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
if (aChances.length < aOutputs.length)
aChances = Arrays.copyOf(aChances, aOutputs.length);
- aInputs = GT_Utility.getArrayListWithoutTrailingNulls(aInputs).toArray(new ItemStack[0]);
- aOutputs = GT_Utility.getArrayListWithoutTrailingNulls(aOutputs).toArray(new ItemStack[0]);
- aFluidInputs = GT_Utility.getArrayListWithoutNulls(aFluidInputs).toArray(new FluidStack[0]);
- aFluidOutputs = GT_Utility.getArrayListWithoutNulls(aFluidOutputs).toArray(new FluidStack[0]);
+ aInputs = ArrayExt.withoutTrailingNulls(aInputs, ItemStack[]::new);
+ aOutputs = ArrayExt.withoutTrailingNulls(aOutputs, ItemStack[]::new);
+ aFluidInputs = ArrayExt.withoutNulls(aFluidInputs, FluidStack[]::new);
+ aFluidOutputs = ArrayExt.withoutNulls(aFluidOutputs, FluidStack[]::new);
GT_OreDictUnificator.setStackArray(true, aInputs);
GT_OreDictUnificator.setStackArray(true, aOutputs);
@@ -196,6 +198,11 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
this(aInput1, aOutput1, null, null, null, aFuelValue, aType);
}
+ private static FluidStack[] tryGetFluidInputsFromCells(ItemStack aInput) {
+ FluidStack tFluid = GT_Utility.getFluidForFilledItem(aInput, true);
+ return tFluid == null ? null : new FluidStack[] {tFluid};
+ }
+
// aSpecialValue = EU per Liter! If there is no Liquid for this Object, then it gets multiplied with 1000!
public GT_Recipe(ItemStack aInput1, ItemStack aOutput1, ItemStack aOutput2, ItemStack aOutput3, ItemStack aOutput4, int aSpecialValue, int aType) {
this(true, new ItemStack[]{aInput1}, new ItemStack[]{aOutput1, aOutput2, aOutput3, aOutput4}, null, null, null, null, 0, 0, Math.max(1, aSpecialValue));
@@ -312,12 +319,12 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
public ItemStack getRepresentativeInput(int aIndex) {
if (aIndex < 0 || aIndex >= mInputs.length) return null;
- return GT_Utility.copy(mInputs[aIndex]);
+ return GT_Utility.copyOrNull(mInputs[aIndex]);
}
public ItemStack getOutput(int aIndex) {
if (aIndex < 0 || aIndex >= mOutputs.length) return null;
- return GT_Utility.copy(mOutputs[aIndex]);
+ return GT_Utility.copyOrNull(mOutputs[aIndex]);
}
public int getOutputChance(int aIndex) {
@@ -365,6 +372,8 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
public static boolean GTppRecipeHelper;
public boolean isRecipeInputEqual(boolean aDecreaseStacksizeBySuccess, boolean aDontCheckStackSizes, FluidStack[] aFluidInputs, ItemStack... aInputs) {
+
+ if (mInputs.length > 0 && aInputs == null) return false;
if (mFluidInputs.length > 0 && aFluidInputs == null) return false;
int amt;
for (FluidStack tFluid : mFluidInputs)
@@ -386,15 +395,18 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
if (temp) return false;
}
- if (mInputs.length > 0 && aInputs == null) return false;
-
+ HashSet<Integer> isVisited = new HashSet<>();
+
for (ItemStack tStack : mInputs) {
ItemStack unified_tStack = GT_OreDictUnificator.get_nocopy(true, tStack);
if (unified_tStack != null) {
amt = tStack.stackSize;
boolean temp = true;
+ int it = 0;
for (ItemStack aStack : aInputs) {
- if (GT_OreDictUnificator.isInputStackEqual(aStack, unified_tStack)) {
+ it ++;
+ if (GT_OreDictUnificator.isInputStackEqual(aStack, unified_tStack) && !isVisited.contains(it)) {
+ isVisited.add(it);
if (GTppRecipeHelper) {//remove once the fix is out
if (GT_Utility.areStacksEqual(aStack, Ic2Items.FluidCell.copy(), true) || GT_Utility.areStacksEqual(aStack, ItemList.Tool_DataStick.get(1L), true) || GT_Utility.areStacksEqual(aStack, ItemList.Tool_DataOrb.get(1L), true)) {
if (!GT_Utility.areStacksEqual(aStack, tStack, false))
@@ -561,6 +573,8 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
public static final GT_Recipe_Map sRecyclerRecipes = new GT_Recipe_Map_Recycler(new HashSet<>(0), "ic.recipe.recycler", "Recycler", "ic2.recycler", RES_PATH_GUI + "basicmachines/Recycler", 1, 1, 1, 0, 1, E, 1, E, true, false);
public static final GT_Recipe_Map sFurnaceRecipes = new GT_Recipe_Map_Furnace(new HashSet<>(0), "mc.recipe.furnace", "Furnace", "smelting", RES_PATH_GUI + "basicmachines/E_Furnace", 1, 1, 1, 0, 1, E, 1, E, true, false);
public static final GT_Recipe_Map sMicrowaveRecipes = new GT_Recipe_Map_Microwave(new HashSet<>(0), "gt.recipe.microwave", "Microwave", "smelting", RES_PATH_GUI + "basicmachines/E_Furnace", 1, 1, 1, 0, 1, E, 1, E, true, false);
+
+ /** Set {@code aSpecialValue = -100} to bypass the disassembler tier check and default recipe duration. */
public static final GT_Recipe_Map sDisassemblerRecipes = new GT_Recipe_Map(new HashSet<>(250), "gt.recipe.disassembler", "Disassembler", null, RES_PATH_GUI + "basicmachines/Disassembler", 1, 9, 1, 0, 1, E, 1, E, true, false);
public static final GT_Recipe_Map sScannerFakeRecipes = new GT_Recipe_Map(new HashSet<>(300), "gt.recipe.scanner", "Scanner", null, RES_PATH_GUI + "basicmachines/Scanner", 1, 1, 1, 0, 1, E, 1, E, true, true);
public static final GT_Recipe_Map sRockBreakerFakeRecipes = new GT_Recipe_Map(new HashSet<>(200), "gt.recipe.rockbreaker", "Rock Breaker", null, RES_PATH_GUI + "basicmachines/RockBreaker", 1, 1, 0, 0, 1, E, 1, E, true, true);
@@ -971,6 +985,7 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
* Just a Recipe Map with Utility specifically for Fuels.
*/
public static class GT_Recipe_Map_Fuel extends GT_Recipe_Map {
+ private final Map<String, GT_Recipe> mRecipesByFluidInput = new HashMap<>();
public GT_Recipe_Map_Fuel(Collection<GT_Recipe> aRecipeList, String aUnlocalizedName, String aLocalName, String aNEIName, String aNEIGUIPath, int aUsualInputCount, int aUsualOutputCount, int aMinimalInputItems, int aMinimalInputFluids, int aAmperage, String aNEISpecialValuePre, int aNEISpecialValueMultiplier, String aNEISpecialValuePost, boolean aShowVoltageAmperageInNEI, boolean aNEIAllowed) {
super(aRecipeList, aUnlocalizedName, aLocalName, aNEIName, aNEIGUIPath, aUsualInputCount, aUsualOutputCount, aMinimalInputItems, aMinimalInputFluids, aAmperage, aNEISpecialValuePre, aNEISpecialValueMultiplier, aNEISpecialValuePost, aShowVoltageAmperageInNEI, aNEIAllowed);
}
@@ -994,6 +1009,24 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
public GT_Recipe addFuel(ItemStack aInput, ItemStack aOutput, FluidStack aFluidInput, FluidStack aFluidOutput, int aChance, int aFuelValueInEU) {
return addRecipe(true, new ItemStack[]{aInput}, new ItemStack[]{aOutput}, null, new int[]{aChance}, new FluidStack[]{aFluidInput}, new FluidStack[]{aFluidOutput}, 0, 0, aFuelValueInEU);
}
+
+ @Override
+ public GT_Recipe add(GT_Recipe aRecipe) {
+ aRecipe = super.add(aRecipe);
+ if (aRecipe.mInputs != null && GT_Utility.getNonnullElementCount(aRecipe.mInputs) == 1 &&
+ (aRecipe.mFluidInputs == null || GT_Utility.getNonnullElementCount(aRecipe.mFluidInputs) == 0)) {
+ FluidStack tFluid = GT_Utility.getFluidForFilledItem(aRecipe.mInputs[0], true);
+ if (tFluid != null) {
+ tFluid.amount = 0;
+ mRecipesByFluidInput.put(tFluid.getUnlocalizedName(), aRecipe);
+ }
+ }
+ return aRecipe;
+ }
+
+ public GT_Recipe findFuel(FluidStack aFluidInput) {
+ return mRecipesByFluidInput.get(aFluidInput.getUnlocalizedName());
+ }
}
/**
@@ -1215,7 +1248,7 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated, long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, ItemStack... aInputs) {
if (aInputs == null || aInputs.length <= 0 || aInputs[0] == null) return null;
if (aRecipe != null && aRecipe.isRecipeInputEqual(false, true, aFluids, aInputs)) return aRecipe;
- ItemStack tComparedInput = GT_Utility.copy(aInputs[0]);
+ ItemStack tComparedInput = GT_Utility.copyOrNull(aInputs[0]);
ItemStack[] tOutputItems = GT_ModHandler.getMachineOutput(tComparedInput, ic2.api.recipe.Recipes.compressor.getRecipes(), true, new NBTTagCompound(), null, null, null);
return GT_Utility.arrayContainsNonNull(tOutputItems) ? new GT_Recipe(false, new ItemStack[]{GT_Utility.copyAmount(aInputs[0].stackSize - tComparedInput.stackSize, aInputs[0])}, tOutputItems, null, null, null, null, 400, 2, 0) : null;
}
@@ -1238,7 +1271,7 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated, long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, ItemStack... aInputs) {
if (aInputs == null || aInputs.length <= 0 || aInputs[0] == null) return null;
if (aRecipe != null && aRecipe.isRecipeInputEqual(false, true, aFluids, aInputs)) return aRecipe;
- ItemStack tComparedInput = GT_Utility.copy(aInputs[0]);
+ ItemStack tComparedInput = GT_Utility.copyOrNull(aInputs[0]);
ItemStack[] tOutputItems = GT_ModHandler.getMachineOutput(tComparedInput, ic2.api.recipe.Recipes.extractor.getRecipes(), true, new NBTTagCompound(), null, null, null);
return GT_Utility.arrayContainsNonNull(tOutputItems) ? new GT_Recipe(false, new ItemStack[]{GT_Utility.copyAmount(aInputs[0].stackSize - tComparedInput.stackSize, aInputs[0])}, tOutputItems, null, null, null, null, 400, 2, 0) : null;
}
@@ -1261,7 +1294,7 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated, long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, ItemStack... aInputs) {
if (aInputs == null || aInputs.length <= 0 || aInputs[0] == null) return null;
if (aRecipe != null && aRecipe.isRecipeInputEqual(false, true, aFluids, aInputs)) return aRecipe;
- ItemStack tComparedInput = GT_Utility.copy(aInputs[0]);
+ ItemStack tComparedInput = GT_Utility.copyOrNull(aInputs[0]);
ItemStack[] tOutputItems = GT_ModHandler.getMachineOutput(tComparedInput, ic2.api.recipe.Recipes.centrifuge.getRecipes(), true, new NBTTagCompound(), null, null, null);
return GT_Utility.arrayContainsNonNull(tOutputItems) ? new GT_Recipe(false, new ItemStack[]{GT_Utility.copyAmount(aInputs[0].stackSize - tComparedInput.stackSize, aInputs[0])}, tOutputItems, null, null, null, null, 400, 48, 0) : null;
}
@@ -1285,7 +1318,7 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
if (aInputs == null || aInputs.length <= 0 || aInputs[0] == null || aFluids == null || aFluids.length < 1 || !GT_ModHandler.isWater(aFluids[0]))
return null;
if (aRecipe != null && aRecipe.isRecipeInputEqual(false, true, aFluids, aInputs)) return aRecipe;
- ItemStack tComparedInput = GT_Utility.copy(aInputs[0]);
+ ItemStack tComparedInput = GT_Utility.copyOrNull(aInputs[0]);
NBTTagCompound aRecipeMetaData = new NBTTagCompound();
ItemStack[] tOutputItems = GT_ModHandler.getMachineOutput(tComparedInput, ic2.api.recipe.Recipes.oreWashing.getRecipes(), true, aRecipeMetaData, null, null, null);
return GT_Utility.arrayContainsNonNull(tOutputItems) ? new GT_Recipe(false, new ItemStack[]{GT_Utility.copyAmount(aInputs[0].stackSize - tComparedInput.stackSize, aInputs[0])}, tOutputItems, null, null, new FluidStack[]{new FluidStack(aFluids[0].getFluid(), ((NBTTagCompound) aRecipeMetaData.getTag("return")).getInteger("amount"))}, null, 400, 16, 0) : null;
@@ -1334,7 +1367,7 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
if (D1) GT_Log.err.println("Railcraft Not loaded");
} catch (NullPointerException e) {/**/}
- ItemStack tComparedInput = GT_Utility.copy(aInputs[0]);
+ ItemStack tComparedInput = GT_Utility.copyOrNull(aInputs[0]);
ItemStack[] tOutputItems = GT_ModHandler.getMachineOutput(tComparedInput, ic2.api.recipe.Recipes.macerator.getRecipes(), true, new NBTTagCompound(), null, null, null);
return GT_Utility.arrayContainsNonNull(tOutputItems) ? new GT_Recipe(false, new ItemStack[]{GT_Utility.copyAmount(aInputs[0].stackSize - tComparedInput.stackSize, aInputs[0])}, tOutputItems, null, null, null, null, 400, 2, 0) : null;
}
@@ -1597,12 +1630,12 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
}
}
-
- public static class GT_Recipe_Map_LargeChemicalReactor extends GT_Recipe_Map{
- private static int TOTAL_INPUT_COUNT = 6;
- private static int OUTPUT_COUNT = 2;
- private static int FLUID_OUTPUT_COUNT = 4;
-
+
+ public static class GT_Recipe_Map_LargeChemicalReactor extends GT_Recipe_Map {
+ private static final int TOTAL_INPUT_COUNT = 6;
+ private static final int OUTPUT_COUNT = 2;
+ private static final int FLUID_OUTPUT_COUNT = 4;
+
public GT_Recipe_Map_LargeChemicalReactor() {
super(new HashSet<>(1000), "gt.recipe.largechemicalreactor", "Large Chemical Reactor", null, RES_PATH_GUI + "basicmachines/Default", 2, OUTPUT_COUNT, 0, 0, 1, E, 1, E, true, true);
}
@@ -1618,7 +1651,7 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
if (aInputs == null) {
aInputs = new ItemStack[0];
} else {
- aInputs = GT_Utility.getArrayListWithoutTrailingNulls(aInputs).toArray(new ItemStack[0]);
+ aInputs = ArrayExt.withoutTrailingNulls(aInputs, ItemStack[]::new);
}
for (ItemStack input : aInputs) {
@@ -1658,7 +1691,7 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
if (aOutputs == null) {
aOutputs = new ItemStack[0];
} else {
- aOutputs = GT_Utility.getArrayListWithoutTrailingNulls(aOutputs).toArray(new ItemStack[0]);
+ aOutputs = ArrayExt.withoutTrailingNulls(aOutputs, ItemStack[]::new);
}
for (ItemStack output : aOutputs) {
@@ -1704,9 +1737,9 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
for (int i = 0; i < itemLimit; i++, j++) {
if (this.mInputs == null || (this.mInputs[i] == null && (i == 0 && itemLimit == 1))) {
if (this.mOutputs != null && this.mOutputs.length > 0 && this.mOutputs[0] != null)
- GT_Log.out.println("recipe " + this.toString() + " Output 0:" + this.mOutputs[0].getDisplayName() + " has errored!");
+ GT_Log.out.println("recipe " + this + " Output 0:" + this.mOutputs[0].getDisplayName() + " has errored!");
else
- GT_Log.out.println("recipe " + this.toString() + " has errored!");
+ GT_Log.out.println("recipe " + this + " has errored!");
new Exception("Recipe Fixme").printStackTrace(GT_Log.out);
}
@@ -1721,9 +1754,9 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
for (int i = 0; i < fluidLimit; i++, j++) {
if (this.mFluidInputs == null || this.mFluidInputs[i] == null) {
if (this.mOutputs != null && this.mOutputs.length > 0 && this.mOutputs[0] != null)
- GT_Log.out.println("recipe " + this.toString() + " Output 0:" + this.mOutputs[0].getDisplayName() + " has errored!");
+ GT_Log.out.println("recipe " + this + " Output 0:" + this.mOutputs[0].getDisplayName() + " has errored!");
else
- GT_Log.out.println("recipe " + this.toString() + " has errored!");
+ GT_Log.out.println("recipe " + this + " has errored!");
new Exception("Recipe Fixme").printStackTrace(GT_Log.out);
}
@@ -1823,13 +1856,13 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
if (mOreDictAlt[aIndex] != null && mOreDictAlt[aIndex].length > 0) {
ItemStack[] rStacks = new ItemStack[mOreDictAlt[aIndex].length];
for (int i = 0; i < mOreDictAlt[aIndex].length; i++) {
- rStacks[i] = GT_Utility.copy(mOreDictAlt[aIndex][i]);
+ rStacks[i] = GT_Utility.copyOrNull(mOreDictAlt[aIndex][i]);
}
return rStacks;
}
}
if (aIndex >= mInputs.length) return null;
- return GT_Utility.copy(mInputs[aIndex]);
+ return GT_Utility.copyOrNull(mInputs[aIndex]);
}
}
diff --git a/src/main/java/gregtech/api/util/GT_RecipeRegistrator.java b/src/main/java/gregtech/api/util/GT_RecipeRegistrator.java
index cbaea6af3a..34cf7ca80e 100644
--- a/src/main/java/gregtech/api/util/GT_RecipeRegistrator.java
+++ b/src/main/java/gregtech/api/util/GT_RecipeRegistrator.java
@@ -1,5 +1,6 @@
package gregtech.api.util;
+import com.google.common.base.Stopwatch;
import gregtech.GT_Mod;
import gregtech.api.GregTech_API;
import gregtech.api.enums.*;
@@ -28,52 +29,52 @@ public class GT_RecipeRegistrator {
public static final List<Materials> sRodMaterialList = new ArrayList<Materials>();
private static final ItemStack sMt1 = new ItemStack(Blocks.dirt, 1, 0), sMt2 = new ItemStack(Blocks.dirt, 1, 0);
private static final String s_H = "h", s_F = "f", s_I = "I", s_P = "P", s_R = "R";
- private static final ItemStack[][]
- sShapes1 = new ItemStack[][]{
- {sMt1, null, sMt1, sMt1, sMt1, sMt1, null, sMt1, null},
- {sMt1, null, sMt1, sMt1, null, sMt1, sMt1, sMt1, sMt1},
- {null, sMt1, null, sMt1, sMt1, sMt1, sMt1, null, sMt1},
- {sMt1, sMt1, sMt1, sMt1, null, sMt1, null, null, null},
- {sMt1, null, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1},
- {sMt1, sMt1, sMt1, sMt1, null, sMt1, sMt1, null, sMt1},
- {null, null, null, sMt1, null, sMt1, sMt1, null, sMt1},
- {null, sMt1, null, null, sMt1, null, null, sMt2, null},
- {sMt1, sMt1, sMt1, null, sMt2, null, null, sMt2, null},
- {null, sMt1, null, null, sMt2, null, null, sMt2, null},
- {sMt1, sMt1, null, sMt1, sMt2, null, null, sMt2, null},
- {null, sMt1, sMt1, null, sMt2, sMt1, null, sMt2, null},
- {sMt1, sMt1, null, null, sMt2, null, null, sMt2, null},
- {null, sMt1, sMt1, null, sMt2, null, null, sMt2, null},
- {null, sMt1, null, sMt1, null, null, null, sMt1, sMt2},
- {null, sMt1, null, null, null, sMt1, sMt2, sMt1, null},
- {null, sMt1, null, sMt1, null, sMt1, null, null, sMt2},
- {null, sMt1, null, sMt1, null, sMt1, sMt2, null, null},
- {null, sMt2, null, null, sMt1, null, null, sMt1, null},
- {null, sMt2, null, null, sMt2, null, sMt1, sMt1, sMt1},
- {null, sMt2, null, null, sMt2, null, null, sMt1, null},
- {null, sMt2, null, sMt1, sMt2, null, sMt1, sMt1, null},
- {null, sMt2, null, null, sMt2, sMt1, null, sMt1, sMt1},
- {null, sMt2, null, null, sMt2, null, sMt1, sMt1, null},
- {sMt1, null, null, null, sMt2, null, null, null, sMt2},
- {null, null, sMt1, null, sMt2, null, sMt2, null, null},
- {sMt1, null, null, null, sMt2, null, null, null, null},
- {null, null, sMt1, null, sMt2, null, null, null, null},
- {sMt1, sMt2, null, null, null, null, null, null, null},
- {sMt2, sMt1, null, null, null, null, null, null, null},
- {sMt1, null, null, sMt2, null, null, null, null, null},
- {sMt2, null, null, sMt1, null, null, null, null, null},
- {sMt1, sMt1, sMt1, sMt1, sMt1, sMt1, null, sMt2, null},
- {sMt1, sMt1, null, sMt1, sMt1, sMt2, sMt1, sMt1, null},
- {null, sMt1, sMt1, sMt2, sMt1, sMt1, null, sMt1, sMt1},
- {null, sMt2, null, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1},
- {sMt1, sMt1, sMt1, sMt1, sMt2, sMt1, null, sMt2, null},
- {sMt1, sMt1, null, sMt1, sMt2, sMt2, sMt1, sMt1, null},
- {null, sMt1, sMt1, sMt2, sMt2, sMt1, null, sMt1, sMt1},
- {null, sMt2, null, sMt1, sMt2, sMt1, sMt1, sMt1, sMt1},
- {sMt1, null, null, null, sMt1, null, null, null, null},
- {null, sMt1, null, sMt1, null, null, null, null, null},
- {sMt1, sMt1, null, sMt2, null, sMt1, sMt2, null, null},
- {null, sMt1, sMt1, sMt1, null, sMt2, null, null, sMt2}
+ private static final RecipeShape[]
+ sShapes = new RecipeShape[]{
+ new RecipeShape(sMt1, null, sMt1, sMt1, sMt1, sMt1, null, sMt1, null),
+ new RecipeShape(sMt1, null, sMt1, sMt1, null, sMt1, sMt1, sMt1, sMt1),
+ new RecipeShape(null, sMt1, null, sMt1, sMt1, sMt1, sMt1, null, sMt1),
+ new RecipeShape(sMt1, sMt1, sMt1, sMt1, null, sMt1, null, null, null),
+ new RecipeShape(sMt1, null, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1),
+ new RecipeShape(sMt1, sMt1, sMt1, sMt1, null, sMt1, sMt1, null, sMt1),
+ new RecipeShape(null, null, null, sMt1, null, sMt1, sMt1, null, sMt1),
+ new RecipeShape(null, sMt1, null, null, sMt1, null, null, sMt2, null),
+ new RecipeShape(sMt1, sMt1, sMt1, null, sMt2, null, null, sMt2, null),
+ new RecipeShape(null, sMt1, null, null, sMt2, null, null, sMt2, null),
+ new RecipeShape(sMt1, sMt1, null, sMt1, sMt2, null, null, sMt2, null),
+ new RecipeShape(null, sMt1, sMt1, null, sMt2, sMt1, null, sMt2, null),
+ new RecipeShape(sMt1, sMt1, null, null, sMt2, null, null, sMt2, null),
+ new RecipeShape(null, sMt1, sMt1, null, sMt2, null, null, sMt2, null),
+ new RecipeShape(null, sMt1, null, sMt1, null, null, null, sMt1, sMt2),
+ new RecipeShape(null, sMt1, null, null, null, sMt1, sMt2, sMt1, null),
+ new RecipeShape(null, sMt1, null, sMt1, null, sMt1, null, null, sMt2),
+ new RecipeShape(null, sMt1, null, sMt1, null, sMt1, sMt2, null, null),
+ new RecipeShape(null, sMt2, null, null, sMt1, null, null, sMt1, null),
+ new RecipeShape(null, sMt2, null, null, sMt2, null, sMt1, sMt1, sMt1),
+ new RecipeShape(null, sMt2, null, null, sMt2, null, null, sMt1, null),
+ new RecipeShape(null, sMt2, null, sMt1, sMt2, null, sMt1, sMt1, null),
+ new RecipeShape(null, sMt2, null, null, sMt2, sMt1, null, sMt1, sMt1),
+ new RecipeShape(null, sMt2, null, null, sMt2, null, sMt1, sMt1, null),
+ new RecipeShape(sMt1, null, null, null, sMt2, null, null, null, sMt2),
+ new RecipeShape(null, null, sMt1, null, sMt2, null, sMt2, null, null),
+ new RecipeShape(sMt1, null, null, null, sMt2, null, null, null, null),
+ new RecipeShape(null, null, sMt1, null, sMt2, null, null, null, null),
+ new RecipeShape(sMt1, sMt2, null, null, null, null, null, null, null),
+ new RecipeShape(sMt2, sMt1, null, null, null, null, null, null, null),
+ new RecipeShape(sMt1, null, null, sMt2, null, null, null, null, null),
+ new RecipeShape(sMt2, null, null, sMt1, null, null, null, null, null),
+ new RecipeShape(sMt1, sMt1, sMt1, sMt1, sMt1, sMt1, null, sMt2, null),
+ new RecipeShape(sMt1, sMt1, null, sMt1, sMt1, sMt2, sMt1, sMt1, null),
+ new RecipeShape(null, sMt1, sMt1, sMt2, sMt1, sMt1, null, sMt1, sMt1),
+ new RecipeShape(null, sMt2, null, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1),
+ new RecipeShape(sMt1, sMt1, sMt1, sMt1, sMt2, sMt1, null, sMt2, null),
+ new RecipeShape(sMt1, sMt1, null, sMt1, sMt2, sMt2, sMt1, sMt1, null),
+ new RecipeShape(null, sMt1, sMt1, sMt2, sMt2, sMt1, null, sMt1, sMt1),
+ new RecipeShape(null, sMt2, null, sMt1, sMt2, sMt1, sMt1, sMt1, sMt1),
+ new RecipeShape(sMt1, null, null, null, sMt1, null, null, null, null),
+ new RecipeShape(null, sMt1, null, sMt1, null, null, null, null, null),
+ new RecipeShape(sMt1, sMt1, null, sMt2, null, sMt1, sMt2, null, null),
+ new RecipeShape(null, sMt1, sMt1, sMt1, null, sMt2, null, null, sMt2)
};
private static final String[][] sShapesA = new String[][]{
null,
@@ -260,14 +261,15 @@ public class GT_RecipeRegistrator {
long tAmount = 0;
for (MaterialStack tMaterial : aData.getAllMaterialStacks())
tAmount += tMaterial.mAmount * tMaterial.mMaterial.getMass();
- boolean tHide = (aData.mMaterial.mMaterial != Materials.Iron)&&(GT_Mod.gregtechproxy.mHideRecyclingRecipes);
+ boolean tHide = (aData.mMaterial.mMaterial != Materials.Iron) && (GT_Mod.gregtechproxy.mHideRecyclingRecipes);
RA.addPulveriserRecipe(aStack, new ItemStack[]{GT_OreDictUnificator.getDust(aData.mMaterial), GT_OreDictUnificator.getDust(aData.getByProduct(0)), GT_OreDictUnificator.getDust(aData.getByProduct(1)), GT_OreDictUnificator.getDust(aData.getByProduct(2))}, null, aData.mMaterial.mMaterial==Materials.Marble ? 1 : (int) Math.max(16, tAmount / M), 4, tHide);
- if (aAllowHammer) for (MaterialStack tMaterial : aData.getAllMaterialStacks())
- if (tMaterial.mMaterial.contains(SubTag.CRYSTAL) && !tMaterial.mMaterial.contains(SubTag.METAL) && tMaterial.mMaterial != Materials.Glass) {
- if (RA.addForgeHammerRecipe(GT_Utility.copyAmount(1, aStack), GT_OreDictUnificator.getDust(aData.mMaterial), 200, 30))
- break;
- }
+ if (aAllowHammer)
+ for (MaterialStack tMaterial : aData.getAllMaterialStacks())
+ if (tMaterial.mMaterial.contains(SubTag.CRYSTAL) && !tMaterial.mMaterial.contains(SubTag.METAL) && tMaterial.mMaterial != Materials.Glass) {
+ if (RA.addForgeHammerRecipe(GT_Utility.copyAmount(1, aStack), GT_OreDictUnificator.getDust(aData.mMaterial), 200, 30))
+ break;
+ }
ItemStack tDust = GT_OreDictUnificator.getDust(aData.mMaterial);
if (tDust != null && GT_ModHandler.addPulverisationRecipe(GT_Utility.copyAmount(1, aStack), tDust, GT_OreDictUnificator.getDust(aData.getByProduct(0)), 100, GT_OreDictUnificator.getDust(aData.getByProduct(1)), 100, true)) {
if (GregTech_API.sThaumcraftCompat != null)
@@ -306,10 +308,7 @@ public class GT_RecipeRegistrator {
*/
public static synchronized void registerUsagesForMaterials(String aPlate, boolean aRecipeReplacing, ItemStack... aMats) {
for (ItemStack aMat : aMats) {
- if (aMat == null)
- continue;
-
- aMat = GT_Utility.copy(aMat);
+ aMat = GT_Utility.copyOrNull(aMat);
if (aMat == null)
continue;
@@ -326,20 +325,17 @@ public class GT_RecipeRegistrator {
sMt2.stackSize = 1;
Items.feather.setDamage(sMt2, 0);
- for (ItemStack[] tRecipe : sShapes1) {
- int tAmount1 = 0;
- for (ItemStack tMat : tRecipe) {
- if (tMat == sMt1) tAmount1++;
- }
- if (aItemData != null && aItemData.hasValidPrefixMaterialData())
- for (ItemStack tCrafted : GT_ModHandler.getRecipeOutputsBuffered(tRecipe)) {
- GT_OreDictUnificator.addItemData(tCrafted, new ItemData(aItemData.mMaterial.mMaterial, aItemData.mMaterial.mAmount * tAmount1));
-// GT_Log.out.println("###################################################################################");
-// GT_Log.out.println("registerUsagesForMaterials used aPlate: "+aPlate);
-// GT_Log.out.println("registerUsagesForMaterials used aPlate: "+aMat.getUnlocalizedName());
-// GT_Log.out.println("registerUsagesForMaterials used aPlate: "+aMat.getDisplayName());
-// GT_Log.out.println("###################################################################################");
+ if(aItemData != null && aItemData.hasValidPrefixMaterialData()) {
+ for (RecipeShape tRecipe : sShapes) {
+ for (ItemStack tCrafted : GT_ModHandler.getRecipeOutputsBuffered(tRecipe.shape)) {
+ GT_OreDictUnificator.addItemData(tCrafted, new ItemData(aItemData.mMaterial.mMaterial, aItemData.mMaterial.mAmount * tRecipe.amount1));
+ // GT_Log.out.println("###################################################################################");
+ // GT_Log.out.println("registerUsagesForMaterials used aPlate: "+aPlate);
+ // GT_Log.out.println("registerUsagesForMaterials used aPlate: "+aMat.getUnlocalizedName());
+ // GT_Log.out.println("registerUsagesForMaterials used aPlate: "+aMat.getDisplayName());
+ // GT_Log.out.println("###################################################################################");
}
+ }
}
registerStickStuff(aPlate, aItemData, aRecipeReplacing);
}
@@ -354,22 +350,17 @@ public class GT_RecipeRegistrator {
sMt2.stackSize = 1;
Items.feather.setDamage(sMt2, Items.feather.getDamage(tMt2));
- for (int i = 0; i < sShapes1.length; i++) {
- ItemStack[] tRecipe = sShapes1[i];
+ for (int i = 0; i < sShapes.length; i++) {
+ RecipeShape tRecipe = sShapes[i];
- int tAmount1 = 0, tAmount2 = 0;
- for (ItemStack tMat : tRecipe) {
- if (tMat == sMt1) tAmount1++;
- if (tMat == sMt2) tAmount2++;
- }
- for (ItemStack tCrafted : GT_ModHandler.getVanillyToolRecipeOutputs(tRecipe)) {
+ for (ItemStack tCrafted : GT_ModHandler.getVanillyToolRecipeOutputs(tRecipe.shape)) {
if (aItemData != null && aItemData.hasValidPrefixMaterialData())
- GT_OreDictUnificator.addItemData(tCrafted, new ItemData(aItemData.mMaterial.mMaterial, aItemData.mMaterial.mAmount * tAmount1, new MaterialStack(tMaterial, OrePrefixes.stick.mMaterialAmount * tAmount2)));
+ GT_OreDictUnificator.addItemData(tCrafted, new ItemData(aItemData.mMaterial.mMaterial, aItemData.mMaterial.mAmount * tRecipe.amount1, new MaterialStack(tMaterial, OrePrefixes.stick.mMaterialAmount * tRecipe.amount2)));
if (aRecipeReplacing && aPlate != null && sShapesA[i] != null && sShapesA[i].length > 1) {
assert aItemData != null;
if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.recipereplacements, aItemData.mMaterial.mMaterial + "." + sShapesA[i][0], true)) {
- if (null != (tStack = GT_ModHandler.removeRecipe(tRecipe))) {
+ if (null != (tStack = GT_ModHandler.removeRecipe(tRecipe.shape))) {
// GT_Log.out.println("###################################################################################");
// GT_Log.out.println("registerStickStuff used aPlate: "+aPlate);
// GT_Log.out.println("###################################################################################");
@@ -397,4 +388,18 @@ public class GT_RecipeRegistrator {
return Arrays.stream(VANILLA_MATS).anyMatch(mat -> mat == materials);
}
+ private static class RecipeShape {
+ private final ItemStack[] shape;
+ private int amount1;
+ private int amount2;
+
+ public RecipeShape(ItemStack... shape) {
+ this.shape = shape;
+
+ for (ItemStack stack : shape) {
+ if(stack == sMt1) this.amount1++;
+ if(stack == sMt2) this.amount2++;
+ }
+ }
+ }
}
diff --git a/src/main/java/gregtech/api/util/GT_SpawnEventHandler.java b/src/main/java/gregtech/api/util/GT_SpawnEventHandler.java
index 9063b1f7c9..0e29950dbd 100644
--- a/src/main/java/gregtech/api/util/GT_SpawnEventHandler.java
+++ b/src/main/java/gregtech/api/util/GT_SpawnEventHandler.java
@@ -9,12 +9,12 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.living.LivingSpawnEvent.CheckSpawn;
-import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
public class GT_SpawnEventHandler {
- public static volatile List<int[]> mobReps = new ArrayList();
+ public static volatile List<int[]> mobReps = new CopyOnWriteArrayList<>();
public GT_SpawnEventHandler() {
MinecraftForge.EVENT_BUS.register(this);
diff --git a/src/main/java/gregtech/api/util/GT_StructureUtility.java b/src/main/java/gregtech/api/util/GT_StructureUtility.java
new file mode 100644
index 0000000000..a627da4fd6
--- /dev/null
+++ b/src/main/java/gregtech/api/util/GT_StructureUtility.java
@@ -0,0 +1,183 @@
+package gregtech.api.util;
+
+import com.gtnewhorizon.structurelib.StructureLibAPI;
+import com.gtnewhorizon.structurelib.structure.IStructureElement;
+import com.gtnewhorizon.structurelib.structure.IStructureElementNoPlacement;
+import gregtech.api.GregTech_API;
+import gregtech.api.enums.HeatingCoilLevel;
+import gregtech.api.enums.Materials;
+import gregtech.api.enums.OrePrefixes;
+import gregtech.api.interfaces.IHeatingCoil;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.BaseMetaPipeEntity;
+import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Frame;
+import gregtech.common.blocks.GT_Block_Casings5;
+import net.minecraft.block.Block;
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemBlock;
+import net.minecraft.item.ItemStack;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.IIcon;
+import net.minecraft.world.World;
+
+import java.util.Arrays;
+import java.util.function.BiConsumer;
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+
+public class GT_StructureUtility {
+ private GT_StructureUtility() {
+ throw new AssertionError("Not instantiable");
+ }
+
+ public static <T> IStructureElementNoPlacement<T> ofHatchAdder(IGT_HatchAdder<T> aHatchAdder, int aTextureIndex, int aDots) {
+ return ofHatchAdder(aHatchAdder, aTextureIndex, StructureLibAPI.getBlockHint(), aDots - 1);
+ }
+
+ public static <T> IStructureElement<T> ofFrame(Materials aFrameMaterial) {
+ if (aFrameMaterial == null) throw new IllegalArgumentException();
+ return new IStructureElement<T>() {
+
+ private IIcon[] mIcons;
+
+ @Override
+ public boolean check(T t, World world, int x, int y, int z) {
+ TileEntity tBase = world.getTileEntity(x, y, z);
+ if (tBase instanceof BaseMetaPipeEntity) {
+ BaseMetaPipeEntity tPipeBase = (BaseMetaPipeEntity) tBase;
+ if (tPipeBase.isInvalidTileEntity()) return false;
+ if (tPipeBase.getMetaTileEntity() instanceof GT_MetaPipeEntity_Frame)
+ return aFrameMaterial == ((GT_MetaPipeEntity_Frame) tPipeBase.getMetaTileEntity()).mMaterial;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
+ if (mIcons == null) {
+ mIcons = new IIcon[6];
+ Arrays.fill(mIcons, aFrameMaterial.mIconSet.mTextures[OrePrefixes.frameGt.mTextureIndex].getIcon());
+ }
+ StructureLibAPI.hintParticleTinted(world, x, y, z, mIcons, aFrameMaterial.mRGBa);
+ return true;
+ }
+
+ @Override
+ public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
+ ItemStack tFrameStack = GT_OreDictUnificator.get(OrePrefixes.frameGt, aFrameMaterial, 1);
+ if (tFrameStack.getItem() instanceof ItemBlock) {
+ ItemBlock tFrameStackItem = (ItemBlock) tFrameStack.getItem();
+ return tFrameStackItem.placeBlockAt(tFrameStack, null, world, x, y, z, 6, 0, 0, 0, Items.feather.getDamage(tFrameStack));
+ }
+ return false;
+ }
+ };
+ }
+
+ public static <T> IStructureElementNoPlacement<T> ofHatchAdder(IGT_HatchAdder<T> aHatchAdder, int aTextureIndex, Block aHintBlock, int aHintMeta) {
+ if (aHatchAdder == null || aHintBlock == null) {
+ throw new IllegalArgumentException();
+ }
+ return new IStructureElementNoPlacement<T>() {
+ @Override
+ public boolean check(T t, World world, int x, int y, int z) {
+ TileEntity tileEntity = world.getTileEntity(x, y, z);
+ return tileEntity instanceof IGregTechTileEntity && aHatchAdder.apply(t, (IGregTechTileEntity) tileEntity, (short) aTextureIndex);
+ }
+
+ @Override
+ public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
+ StructureLibAPI.hintParticle(world, x, y, z, aHintBlock, aHintMeta);
+ return true;
+ }
+ };
+ }
+
+ public static <T> IStructureElement<T> ofHatchAdderOptional(IGT_HatchAdder<T> aHatchAdder, int textureIndex, int dots, Block placeCasing, int placeCasingMeta) {
+ return ofHatchAdderOptional(aHatchAdder, textureIndex, StructureLibAPI.getBlockHint(), dots - 1, placeCasing, placeCasingMeta);
+ }
+
+ public static <T> IStructureElement<T> ofHatchAdderOptional(IGT_HatchAdder<T> aHatchAdder, int aTextureIndex, Block aHintBlock, int hintMeta, Block placeCasing, int placeCasingMeta) {
+ if (aHatchAdder == null || aHintBlock == null) {
+ throw new IllegalArgumentException();
+ }
+ return new IStructureElement<T>() {
+ @Override
+ public boolean check(T t, World world, int x, int y, int z) {
+ TileEntity tileEntity = world.getTileEntity(x, y, z);
+ Block worldBlock = world.getBlock(x, y, z);
+ return (tileEntity instanceof IGregTechTileEntity &&
+ aHatchAdder.apply(t, (IGregTechTileEntity) tileEntity, (short) aTextureIndex)) ||
+ (worldBlock == placeCasing && worldBlock.getDamageValue(world, x, y, z) == placeCasingMeta);
+ }
+
+ @Override
+ public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
+ StructureLibAPI.hintParticle(world, x, y, z, aHintBlock, hintMeta);
+ return true;
+ }
+
+ @Override
+ public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
+ world.setBlock(x, y, z, placeCasing, placeCasingMeta, 2);
+ return true;
+ }
+ };
+ }
+
+ /**
+ * Assume all coils accepted.
+ * @see #ofCoil(BiPredicate, Function)
+ */
+ public static <T> IStructureElement<T> ofCoil(BiConsumer<T, HeatingCoilLevel> aHeatingCoilSetter, Function<T, HeatingCoilLevel> aHeatingCoilGetter) {
+ return ofCoil((t, l) -> {
+ aHeatingCoilSetter.accept(t, l);
+ return true;
+ }, aHeatingCoilGetter);
+ }
+
+ /**
+ * Heating coil structure element.
+ * @param aHeatingCoilSetter Notify the controller of this new coil.
+ * Got called exactly once per coil.
+ * Might be called less times if structure test fails.
+ * If the setter returns false then it assumes the coil is rejected.
+ * @param aHeatingCoilGetter Get the current heating level. Null means no coil recorded yet.
+ */
+ public static <T> IStructureElement<T> ofCoil(BiPredicate<T, HeatingCoilLevel> aHeatingCoilSetter, Function<T, HeatingCoilLevel> aHeatingCoilGetter) {
+ if (aHeatingCoilSetter == null || aHeatingCoilGetter == null) {
+ throw new IllegalArgumentException();
+ }
+ return new IStructureElement<T>() {
+ @Override
+ public boolean check(T t, World world, int x, int y, int z) {
+ Block block = world.getBlock(x, y, z);
+ if (!(block instanceof IHeatingCoil))
+ return false;
+ HeatingCoilLevel existingLevel = aHeatingCoilGetter.apply(t),
+ newLevel = ((IHeatingCoil) block).getCoilHeat(world.getBlockMetadata(x, y, z));
+ if (existingLevel == null || existingLevel == HeatingCoilLevel.None) {
+ return aHeatingCoilSetter.test(t, newLevel);
+ } else {
+ return newLevel == existingLevel;
+ }
+ }
+
+ @Override
+ public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
+ StructureLibAPI.hintParticle(world, x, y, z, GregTech_API.sBlockCasings5, getMeta(trigger));
+ return true;
+ }
+
+ private int getMeta(ItemStack trigger) {
+ // -4 to skip unimplemented tiers
+ return GT_Block_Casings5.getMetaFromCoilHeat(HeatingCoilLevel.getFromTier((byte) Math.min(HeatingCoilLevel.getMaxTier() - 4, Math.max(0, trigger.stackSize - 1))));
+ }
+
+ @Override
+ public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
+ return world.setBlock(x, y, z, GregTech_API.sBlockCasings5, getMeta(trigger), 3);
+ }
+ };
+ }
+}
diff --git a/src/main/java/gregtech/api/util/GT_Utility.java b/src/main/java/gregtech/api/util/GT_Utility.java
index e9a9d6a436..be5f978d6e 100644
--- a/src/main/java/gregtech/api/util/GT_Utility.java
+++ b/src/main/java/gregtech/api/util/GT_Utility.java
@@ -3,36 +3,30 @@ package gregtech.api.util;
import cofh.api.transport.IItemDuct;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
+import com.gtnewhorizon.structurelib.alignment.IAlignment;
+import com.gtnewhorizon.structurelib.alignment.IAlignmentProvider;
import com.mojang.authlib.GameProfile;
import cpw.mods.fml.common.FMLCommonHandler;
import gregtech.api.GregTech_API;
import gregtech.api.damagesources.GT_DamageSources;
+import gregtech.api.damagesources.GT_DamageSources.DamageSourceHotItem;
import gregtech.api.enchants.Enchantment_Radioactivity;
-import gregtech.api.enums.GT_Values;
-import gregtech.api.enums.ItemList;
-import gregtech.api.enums.Materials;
-import gregtech.api.enums.OrePrefixes;
-import gregtech.api.enums.SubTag;
-import gregtech.api.enums.Textures;
-import gregtech.api.enums.ToolDictNames;
+import gregtech.api.enums.*;
import gregtech.api.events.BlockScanningEvent;
import gregtech.api.interfaces.IBlockContainer;
import gregtech.api.interfaces.IDebugableBlock;
import gregtech.api.interfaces.IProjectileItem;
import gregtech.api.interfaces.ITexture;
-import gregtech.api.interfaces.tileentity.IBasicEnergyContainer;
-import gregtech.api.interfaces.tileentity.ICoverable;
-import gregtech.api.interfaces.tileentity.IGregTechDeviceInformation;
-import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
-import gregtech.api.interfaces.tileentity.IMachineProgress;
-import gregtech.api.interfaces.tileentity.IUpgradableMachine;
+import gregtech.api.interfaces.tileentity.*;
import gregtech.api.items.GT_EnergyArmor_Item;
import gregtech.api.items.GT_Generic_Item;
import gregtech.api.items.GT_MetaGenerated_Tool;
import gregtech.api.net.GT_Packet_Sound;
+import gregtech.api.objects.CollectorUtils;
import gregtech.api.objects.GT_ItemStack;
import gregtech.api.objects.ItemData;
import gregtech.api.threads.GT_Runnable_Sound;
+import gregtech.api.util.extensions.ArrayExt;
import gregtech.common.GT_Proxy;
import ic2.api.recipe.IRecipeInput;
import ic2.api.recipe.RecipeInputItemStack;
@@ -41,11 +35,7 @@ import ic2.api.recipe.RecipeOutput;
import net.minecraft.block.Block;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
-import net.minecraft.entity.Entity;
-import net.minecraft.entity.EntityList;
-import net.minecraft.entity.EntityLiving;
-import net.minecraft.entity.EntityLivingBase;
-import net.minecraft.entity.EnumCreatureAttribute;
+import net.minecraft.entity.*;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
@@ -67,10 +57,7 @@ import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityChest;
-import net.minecraft.util.AxisAlignedBB;
-import net.minecraft.util.ChatComponentText;
-import net.minecraft.util.EnumChatFormatting;
-import net.minecraft.util.MathHelper;
+import net.minecraft.util.*;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.DimensionManager;
@@ -81,47 +68,22 @@ import net.minecraftforge.common.util.FakePlayerFactory;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.event.ForgeEventFactory;
import net.minecraftforge.event.world.BlockEvent;
-import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.*;
import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData;
-import net.minecraftforge.fluids.FluidRegistry;
-import net.minecraftforge.fluids.FluidStack;
-import net.minecraftforge.fluids.FluidTankInfo;
-import net.minecraftforge.fluids.IFluidContainerItem;
-import net.minecraftforge.fluids.IFluidHandler;
import net.minecraftforge.oredict.OreDictionary;
+import javax.annotation.Nullable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
-import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
+import java.util.*;
import java.util.Map.Entry;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.UUID;
+import java.util.function.IntFunction;
import static gregtech.GT_Mod.GT_FML_LOGGER;
-import static gregtech.api.enums.GT_Values.D1;
-import static gregtech.api.enums.GT_Values.DW;
-import static gregtech.api.enums.GT_Values.E;
-import static gregtech.api.enums.GT_Values.GT;
-import static gregtech.api.enums.GT_Values.L;
-import static gregtech.api.enums.GT_Values.M;
-import static gregtech.api.enums.GT_Values.NW;
-import static gregtech.api.enums.GT_Values.V;
-import static gregtech.api.enums.GT_Values.W;
+import static gregtech.api.enums.GT_Values.*;
import static gregtech.common.GT_Proxy.GTPOLLUTION;
import static gregtech.common.GT_UndergroundOil.undergroundOilReadInformation;
@@ -131,6 +93,9 @@ import static gregtech.common.GT_UndergroundOil.undergroundOilReadInformation;
* Just a few Utility Functions I use.
*/
public class GT_Utility {
+ /** Formats a number with group separator and at most 2 fraction digits. */
+ private static final DecimalFormat decimalFormat = new DecimalFormat();
+
/**
* Forge screwed the Fluid Registry up again, so I make my own, which is also much more efficient than the stupid Stuff over there.
*/
@@ -144,6 +109,11 @@ public class GT_Utility {
public static UUID defaultUuid = null; // maybe default non-null? UUID.fromString("00000000-0000-0000-0000-000000000000");
static {
+ DecimalFormatSymbols symbols = decimalFormat.getDecimalFormatSymbols();
+ symbols.setGroupingSeparator(' ');
+ decimalFormat.setDecimalFormatSymbols(symbols);
+ decimalFormat.setMaximumFractionDigits(2);
+
GregTech_API.sItemStackMappings.add(sFilledContainerToData);
GregTech_API.sItemStackMappings.add(sEmptyContainerToFluidToData);
}
@@ -438,7 +408,7 @@ public class GT_Utility {
if (isAllowedToTakeFromSlot(aTileEntity1, aGrabSlot, (byte) aGrabFrom, aTileEntity1.getStackInSlot(aGrabSlot))) {
if (Math.max(aMinMoveAtOnce, aMinTargetStackSize) <= aTileEntity1.getStackInSlot(aGrabSlot).stackSize) {
ItemStack tStack = copyAmount(Math.min(aTileEntity1.getStackInSlot(aGrabSlot).stackSize, Math.min(aMaxMoveAtOnce, aMaxTargetStackSize)), aTileEntity1.getStackInSlot(aGrabSlot));
- ItemStack rStack = ((IItemDuct) aTileEntity2).insertItem(ForgeDirection.getOrientation(aPutTo), copy(tStack));
+ ItemStack rStack = ((IItemDuct) aTileEntity2).insertItem(ForgeDirection.getOrientation(aPutTo), copyOrNull(tStack));
byte tMovedItemCount = (byte) (tStack.stackSize - (rStack == null ? 0 : rStack.stackSize));
if (tMovedItemCount >= 1/*Math.max(aMinMoveAtOnce, aMinTargetStackSize)*/) {
//((cofh.api.transport.IItemConduit)aTileEntity2).insertItem(ForgeDirection.getOrientation(aPutTo), copyAmount(tMovedItemCount, tStack), F);
@@ -458,7 +428,7 @@ public class GT_Utility {
if (isAllowedToTakeFromSlot(aTileEntity1, aGrabSlot, (byte) aGrabFrom, aTileEntity1.getStackInSlot(aGrabSlot))) {
if (Math.max(aMinMoveAtOnce, aMinTargetStackSize) <= aTileEntity1.getStackInSlot(aGrabSlot).stackSize) {
ItemStack tStack = copyAmount(Math.min(aTileEntity1.getStackInSlot(aGrabSlot).stackSize, Math.min(aMaxMoveAtOnce, aMaxTargetStackSize)), aTileEntity1.getStackInSlot(aGrabSlot));
- byte tMovedItemCount = (byte) ((buildcraft.api.transport.IPipeTile) aTileEntity2).injectItem(copy(tStack), false, ForgeDirection.getOrientation(aPutTo));
+ byte tMovedItemCount = (byte) ((buildcraft.api.transport.IPipeTile) aTileEntity2).injectItem(copyOrNull(tStack), false, ForgeDirection.getOrientation(aPutTo));
if (tMovedItemCount >= Math.max(aMinMoveAtOnce, aMinTargetStackSize)) {
tMovedItemCount = (byte) (((buildcraft.api.transport.IPipeTile) aTileEntity2).injectItem(copyAmount(tMovedItemCount, tStack), true, ForgeDirection.getOrientation(aPutTo)));
aTileEntity1.decrStackSize(aGrabSlot, tMovedItemCount);
@@ -509,7 +479,7 @@ public class GT_Utility {
ItemStack tStack1 = aTileEntity1.getStackInSlot(aGrabFrom), tStack2 = aTileEntity2.getStackInSlot(aPutTo), tStack3 = null;
if (tStack1 != null) {
if (tStack2 != null && !areStacksEqual(tStack1, tStack2)) return 0;
- tStack3 = copy(tStack1);
+ tStack3 = copyOrNull(tStack1);
aMaxTargetStackSize = (byte) Math.min(aMaxTargetStackSize, Math.min(tStack3.getMaxStackSize(), Math.min(tStack2 == null ? Integer.MAX_VALUE : tStack2.getMaxStackSize(), aTileEntity2.getInventoryStackLimit())));
tStack3.stackSize = Math.min(tStack3.stackSize, aMaxTargetStackSize - (tStack2 == null ? 0 : tStack2.stackSize));
if (tStack3.stackSize > aMaxMoveAtOnce) tStack3.stackSize = aMaxMoveAtOnce;
@@ -518,7 +488,7 @@ public class GT_Utility {
aTileEntity1.markDirty();
if (tStack3 != null) {
if (tStack2 == null) {
- aTileEntity2.setInventorySlotContents(aPutTo, copy(tStack3));
+ aTileEntity2.setInventorySlotContents(aPutTo, copyOrNull(tStack3));
} else {
tStack2.stackSize += tStack3.stackSize;
}
@@ -886,13 +856,16 @@ public class GT_Utility {
public static boolean listContainsItem(Collection<ItemStack> aList, ItemStack aStack, boolean aTIfListEmpty, boolean aInvertFilter) {
if (aStack == null || aStack.stackSize < 1) return false;
if (aList == null) return aTIfListEmpty;
- aList.removeIf(Objects::isNull);
- if (aList.size() < 1) return aTIfListEmpty;
- Iterator<ItemStack> tIterator = aList.iterator();
- ItemStack tStack = null;
- while (tIterator.hasNext())
- if ((tStack = tIterator.next()) != null && areStacksEqual(aStack, tStack)) return !aInvertFilter;
- return aInvertFilter;
+ boolean tEmpty = true;
+ for (ItemStack tStack : aList) {
+ if (tStack != null) {
+ tEmpty = false;
+ if (areStacksEqual(aStack, tStack)) {
+ return !aInvertFilter;
+ }
+ }
+ }
+ return tEmpty ? aTIfListEmpty : aInvertFilter;
}
public static boolean areStacksOrToolsEqual(ItemStack aStack1, ItemStack aStack2) {
@@ -926,7 +899,7 @@ public class GT_Utility {
}
public static boolean areUnificationsEqual(ItemStack aStack1, ItemStack aStack2, boolean aIgnoreNBT) {
- return areStacksEqual(GT_OreDictUnificator.get(aStack1), GT_OreDictUnificator.get(aStack2), aIgnoreNBT);
+ return areStacksEqual(GT_OreDictUnificator.get_nocopy(aStack1), GT_OreDictUnificator.get_nocopy(aStack2), aIgnoreNBT);
}
public static String getFluidName(Fluid aFluid, boolean aLocalized) {
@@ -996,6 +969,10 @@ public class GT_Utility {
}
public static ItemStack getFluidDisplayStack(FluidStack aFluid, boolean aUseStackSize) {
+ return getFluidDisplayStack(aFluid, aUseStackSize, false);
+ }
+
+ public static ItemStack getFluidDisplayStack(FluidStack aFluid, boolean aUseStackSize, boolean aHideStackSize) {
if (aFluid == null || aFluid.getFluid() == null) return null;
int tmp = 0;
try {
@@ -1008,6 +985,7 @@ public class GT_Utility {
tNBT.setLong("mFluidDisplayAmount", aUseStackSize ? aFluid.amount : 0);
tNBT.setLong("mFluidDisplayHeat", aFluid.getFluid().getTemperature(aFluid));
tNBT.setBoolean("mFluidState", aFluid.getFluid().isGaseous(aFluid));
+ tNBT.setBoolean("mHideStackSize", aHideStackSize);
rStack.setTagCompound(tNBT);
return rStack;
}
@@ -1143,7 +1121,7 @@ public class GT_Utility {
if(tOreName.toString().equals("dustAsh")&&tStack[0].getUnlocalizedName().equals("tile.volcanicAsh"))return false;
aRecipeList.put(new RecipeInputOreDict(tOreName.toString(), aInput.stackSize), new RecipeOutput(aNBT, tStack));
} else {
- aRecipeList.put(new RecipeInputItemStack(copy(aInput), aInput.stackSize), new RecipeOutput(aNBT, tStack));
+ aRecipeList.put(new RecipeInputItemStack(copyOrNull(aInput), aInput.stackSize), new RecipeOutput(aNBT, tStack));
}
return true;
}
@@ -1187,7 +1165,7 @@ public class GT_Utility {
rStack.setTagCompound(tNBT);
GT_Log.out.println("GT_Mod: Added Book to Book List - Mapping: '" + aMapping + "' - Name: '" + aTitle + "' - Author: '" + aAuthor + "'");
GregTech_API.sBookList.put(aMapping, rStack);
- return copy(rStack);
+ return copyOrNull(rStack);
}
public static boolean doSoundAtClient(String aSoundName, int aTimeUntilNextSound, float aSoundStrength) {
@@ -1266,6 +1244,9 @@ public class GT_Utility {
return false;
}
+ /**
+ * Note: use {@link ArrayExt#withoutNulls(Object[], IntFunction)} if you want an array as a result.
+ */
public static <T> ArrayList<T> getArrayListWithoutNulls(T... aArray) {
if (aArray == null) return new ArrayList<>();
ArrayList<T> rList = new ArrayList<>(Arrays.asList(aArray));
@@ -1273,6 +1254,9 @@ public class GT_Utility {
return rList;
}
+ /**
+ * Note: use {@link ArrayExt#withoutTrailingNulls(Object[], IntFunction)} if you want an array as a result.
+ */
public static <T> ArrayList<T> getArrayListWithoutTrailingNulls(T... aArray) {
if (aArray == null) return new ArrayList<>();
ArrayList<T> rList = new ArrayList<>(Arrays.asList(aArray));
@@ -1280,6 +1264,7 @@ public class GT_Utility {
return rList;
}
+ @Deprecated // why do you use Objects?
public static Block getBlock(Object aBlock) {
return (Block) aBlock;
}
@@ -1293,12 +1278,14 @@ public class GT_Utility {
return Block.getBlockFromItem(item);
}
+ @Deprecated // why do you use Objects? And if you want to check your block to be not null, check it directly!
public static boolean isBlockValid(Object aBlock) {
return (aBlock instanceof Block);
}
+ @Deprecated // why do you use Objects? And if you want to check your block to be null, check it directly!
public static boolean isBlockInvalid(Object aBlock) {
- return aBlock == null || !(aBlock instanceof Block);
+ return !(aBlock instanceof Block);
}
public static boolean isStringValid(Object aString) {
@@ -1583,9 +1570,17 @@ public class GT_Utility {
return isWearingFullGasHazmat(aEntity);
}
- public static boolean applyHeatDamage(EntityLivingBase aEntity, float aDamage) {
+ public static boolean applyHeatDamage(EntityLivingBase entity, float damage) {
+ return applyHeatDamage(entity, damage, GT_DamageSources.getHeatDamage());
+ }
+
+ public static boolean applyHeatDamageFromItem(EntityLivingBase entity, float damage, ItemStack item) {
+ return applyHeatDamage(entity, damage, new DamageSourceHotItem(item));
+ }
+
+ private static boolean applyHeatDamage(EntityLivingBase aEntity, float aDamage, DamageSource source) {
if (aDamage > 0 && aEntity != null && aEntity.getActivePotionEffect(Potion.fireResistance) == null && !isWearingFullHeatHazmat(aEntity)) {
- aEntity.attackEntityFrom(GT_DamageSources.getHeatDamage(), aDamage);
+ aEntity.attackEntityFrom(source, aDamage);
return true;
}
return false;
@@ -1648,6 +1643,12 @@ public class GT_Utility {
return null;
}
+ @Nullable
+ public static ItemStack copyOrNull(@Nullable ItemStack stack) {
+ if (isStackValid(stack)) return stack.copy();
+ return null;
+ }
+
public static ItemStack copyAmount(long aAmount, Object... aStacks) {
ItemStack rStack = copy(aStacks);
if (isStackInvalid(rStack)) return null;
@@ -1752,15 +1753,8 @@ public class GT_Utility {
return aMap;
}
- /**
- * Why the fuck do neither Java nor Guava have a Function to do this?
- */
- public static <X, Y extends Comparable> LinkedHashMap<X, Y> sortMapByValuesAcending(Map<X, Y> aMap) {
- List<Map.Entry<X, Y>> tEntrySet = new LinkedList<>(aMap.entrySet());
- tEntrySet.sort(Entry.comparingByValue());
- LinkedHashMap<X, Y> rMap = new LinkedHashMap<>();
- for (Map.Entry<X, Y> tEntry : tEntrySet) rMap.put(tEntry.getKey(), tEntry.getValue());
- return rMap;
+ public static <X, Y extends Comparable<Y>> LinkedHashMap<X, Y> sortMapByValuesAcending(Map<X, Y> map) {
+ return map.entrySet().stream().sorted(Entry.comparingByValue()).collect(CollectorUtils.entriesToMap(LinkedHashMap::new));
}
/**
@@ -1918,15 +1912,25 @@ public class GT_Utility {
Block tBlock = aWorld.getBlock(aX, aY, aZ);
- tList.add("----- X: " +EnumChatFormatting.AQUA+ aX +EnumChatFormatting.RESET+ " Y: " +EnumChatFormatting.AQUA+ aY +EnumChatFormatting.RESET+ " Z: " +EnumChatFormatting.AQUA+ aZ +EnumChatFormatting.RESET+ " D: " +EnumChatFormatting.AQUA+ aWorld.provider.dimensionId +EnumChatFormatting.RESET+ " -----");
+ tList.add(
+ "----- X: " + EnumChatFormatting.AQUA + formatNumbers(aX) + EnumChatFormatting.RESET +
+ " Y: " + EnumChatFormatting.AQUA + formatNumbers(aY) + EnumChatFormatting.RESET +
+ " Z: " + EnumChatFormatting.AQUA + formatNumbers(aZ) + EnumChatFormatting.RESET +
+ " D: " + EnumChatFormatting.AQUA + aWorld.provider.dimensionId + EnumChatFormatting.RESET + " -----");
try {
- if (tTileEntity != null && tTileEntity instanceof IInventory)
- tList.add(trans("162","Name: ") +EnumChatFormatting.BLUE+ ((IInventory) tTileEntity).getInventoryName() +EnumChatFormatting.RESET+ trans("163"," MetaData: ") +EnumChatFormatting.AQUA+ aWorld.getBlockMetadata(aX, aY, aZ) +EnumChatFormatting.RESET);
+ if (tTileEntity instanceof IInventory)
+ tList.add(
+ trans("162","Name: ") + EnumChatFormatting.BLUE + ((IInventory) tTileEntity).getInventoryName() + EnumChatFormatting.RESET +
+ trans("163"," MetaData: ") + EnumChatFormatting.AQUA + aWorld.getBlockMetadata(aX, aY, aZ) + EnumChatFormatting.RESET);
else
- tList.add(trans("162","Name: ") +EnumChatFormatting.BLUE+ tBlock.getUnlocalizedName() +EnumChatFormatting.RESET+ trans("163"," MetaData: ") +EnumChatFormatting.AQUA+ aWorld.getBlockMetadata(aX, aY, aZ) +EnumChatFormatting.RESET);
-
- tList.add(trans("164","Hardness: ") +EnumChatFormatting.YELLOW+ tBlock.getBlockHardness(aWorld, aX, aY, aZ) +EnumChatFormatting.RESET+ trans("165"," Blast Resistance: ") +EnumChatFormatting.YELLOW+ tBlock.getExplosionResistance(aPlayer, aWorld, aX, aY, aZ, aPlayer.posX, aPlayer.posY, aPlayer.posZ) +EnumChatFormatting.RESET);
- if (tBlock.isBeaconBase(aWorld, aX, aY, aZ, aX, aY + 1, aZ)) tList.add(EnumChatFormatting.GOLD+ trans("166","Is valid Beacon Pyramid Material") +EnumChatFormatting.RESET);
+ tList.add(
+ trans("162","Name: ") + EnumChatFormatting.BLUE + tBlock.getUnlocalizedName() + EnumChatFormatting.RESET +
+ trans("163"," MetaData: ") + EnumChatFormatting.AQUA + aWorld.getBlockMetadata(aX, aY, aZ) + EnumChatFormatting.RESET);
+
+ tList.add(
+ trans("164","Hardness: ") + EnumChatFormatting.YELLOW + tBlock.getBlockHardness(aWorld, aX, aY, aZ) + EnumChatFormatting.RESET +
+ trans("165"," Blast Resistance: ") + EnumChatFormatting.YELLOW + tBlock.getExplosionResistance(aPlayer, aWorld, aX, aY, aZ, aPlayer.posX, aPlayer.posY, aPlayer.posZ) + EnumChatFormatting.RESET);
+ if (tBlock.isBeaconBase(aWorld, aX, aY, aZ, aX, aY + 1, aZ)) tList.add(EnumChatFormatting.GOLD + trans("166","Is valid Beacon Pyramid Material") + EnumChatFormatting.RESET);
} catch (Throwable e) {
if (D1) e.printStackTrace(GT_Log.err);
}
@@ -1936,7 +1940,10 @@ public class GT_Utility {
rEUAmount += 500;
FluidTankInfo[] tTanks = ((IFluidHandler) tTileEntity).getTankInfo(ForgeDirection.getOrientation(aSide));
if (tTanks != null) for (byte i = 0; i < tTanks.length; i++) {
- tList.add(trans("167","Tank ") + i + ": " +EnumChatFormatting.GREEN+ formatNumbers((tTanks[i].fluid == null ? 0 : tTanks[i].fluid.amount)) +EnumChatFormatting.RESET+ " L / " +EnumChatFormatting.YELLOW+ formatNumbers(tTanks[i].capacity) +EnumChatFormatting.RESET+ " L " +EnumChatFormatting.GOLD+ getFluidName(tTanks[i].fluid, true)+EnumChatFormatting.RESET);
+ tList.add(
+ trans("167","Tank ") + i + ": " +
+ EnumChatFormatting.GREEN + formatNumbers((tTanks[i].fluid == null ? 0 : tTanks[i].fluid.amount)) + EnumChatFormatting.RESET + " L / " +
+ EnumChatFormatting.YELLOW + formatNumbers(tTanks[i].capacity) + EnumChatFormatting.RESET + " L " + EnumChatFormatting.GOLD + getFluidName(tTanks[i].fluid, true) + EnumChatFormatting.RESET);
}
}
} catch (Throwable e) {
@@ -1953,8 +1960,23 @@ public class GT_Utility {
try {
if (tTileEntity instanceof ic2.api.reactor.IReactor) {
rEUAmount += 500;
- tList.add(trans("168","Heat: ") +EnumChatFormatting.GREEN+ ((ic2.api.reactor.IReactor) tTileEntity).getHeat() +EnumChatFormatting.RESET+ " / " +EnumChatFormatting.YELLOW+ ((ic2.api.reactor.IReactor) tTileEntity).getMaxHeat()+EnumChatFormatting.RESET);
- tList.add(trans("169","HEM: ") +EnumChatFormatting.YELLOW+((ic2.api.reactor.IReactor) tTileEntity).getHeatEffectModifier() +EnumChatFormatting.RESET/*+ trans("170"," Base EU Output: ")/* + ((ic2.api.reactor.IReactor)tTileEntity).getOutput()*/);
+ tList.add(
+ trans("168","Heat: ") + EnumChatFormatting.GREEN + formatNumbers(((ic2.api.reactor.IReactor) tTileEntity).getHeat()) + EnumChatFormatting.RESET + " / " +
+ EnumChatFormatting.YELLOW + formatNumbers(((ic2.api.reactor.IReactor) tTileEntity).getMaxHeat()) + EnumChatFormatting.RESET);
+ tList.add(
+ trans("169","HEM: ") + EnumChatFormatting.YELLOW + ((ic2.api.reactor.IReactor) tTileEntity).getHeatEffectModifier() + EnumChatFormatting.RESET
+ /* + trans("170"," Base EU Output: ")/* + ((ic2.api.reactor.IReactor)tTileEntity).getOutput()*/);
+ }
+ } catch (Throwable e) {
+ if (D1) e.printStackTrace(GT_Log.err);
+ }
+ try {
+ if (tTileEntity instanceof IAlignmentProvider) {
+ IAlignment tAlignment = ((IAlignmentProvider) tTileEntity).getAlignment();
+ if (tAlignment != null) {
+ rEUAmount += 100;
+ tList.add(trans("219", "Extended Facing: ") + EnumChatFormatting.GREEN + tAlignment.getExtendedFacing() + EnumChatFormatting.RESET);
+ }
}
} catch (Throwable e) {
if (D1) e.printStackTrace(GT_Log.err);
@@ -1997,7 +2019,7 @@ public class GT_Utility {
try {
if (tTileEntity instanceof ic2.api.energy.tile.IEnergyConductor) {
rEUAmount += 200;
- tList.add(trans("175","Conduction Loss: ") +EnumChatFormatting.YELLOW+ ((ic2.api.energy.tile.IEnergyConductor) tTileEntity).getConductionLoss()+EnumChatFormatting.RESET);
+ tList.add(trans("175","Conduction Loss: ") + EnumChatFormatting.YELLOW + ((ic2.api.energy.tile.IEnergyConductor) tTileEntity).getConductionLoss() + EnumChatFormatting.RESET);
}
} catch (Throwable e) {
if (D1) e.printStackTrace(GT_Log.err);
@@ -2005,7 +2027,9 @@ public class GT_Utility {
try {
if (tTileEntity instanceof ic2.api.tile.IEnergyStorage) {
rEUAmount += 200;
- tList.add(trans("176","Contained Energy: ") +EnumChatFormatting.YELLOW+ ((ic2.api.tile.IEnergyStorage) tTileEntity).getStored() +EnumChatFormatting.RESET+ " EU / " +EnumChatFormatting.YELLOW+ ((ic2.api.tile.IEnergyStorage) tTileEntity).getCapacity()+EnumChatFormatting.RESET+" EU");
+ tList.add(
+ trans("176","Contained Energy: ") + EnumChatFormatting.YELLOW + formatNumbers(((ic2.api.tile.IEnergyStorage) tTileEntity).getStored()) + EnumChatFormatting.RESET + " EU / " +
+ EnumChatFormatting.YELLOW + formatNumbers(((ic2.api.tile.IEnergyStorage) tTileEntity).getCapacity()) + EnumChatFormatting.RESET + " EU");
//aList.add(((ic2.api.tile.IEnergyStorage)tTileEntity).isTeleporterCompatible(ic2.api.Direction.YP)?"Teleporter Compatible":"Not Teleporter Compatible");
}
} catch (Throwable e) {
@@ -2014,7 +2038,7 @@ public class GT_Utility {
try {
if (tTileEntity instanceof IUpgradableMachine) {
rEUAmount += 500;
- if (((IUpgradableMachine) tTileEntity).hasMufflerUpgrade()) tList.add(EnumChatFormatting.GREEN+ trans("177","Has Muffler Upgrade") +EnumChatFormatting.RESET);
+ if (((IUpgradableMachine) tTileEntity).hasMufflerUpgrade()) tList.add(EnumChatFormatting.GREEN + trans("177","Has Muffler Upgrade") + EnumChatFormatting.RESET);
}
} catch (Throwable e) {
if (D1) e.printStackTrace(GT_Log.err);
@@ -2022,7 +2046,7 @@ public class GT_Utility {
try {
if (tTileEntity instanceof IMachineProgress) {
if (((IMachineProgress) tTileEntity).isAllowedToWork()) {
- tList.add("Disabled." + EnumChatFormatting.RED + EnumChatFormatting.RESET);
+ tList.add("Disabled." + EnumChatFormatting.RED + EnumChatFormatting.RESET);
}
if (((IMachineProgress) tTileEntity).wasShutdown()) {
tList.add("Shut down due to power loss." + EnumChatFormatting.RED + EnumChatFormatting.RESET);
@@ -2030,7 +2054,8 @@ public class GT_Utility {
rEUAmount += 400;
int tValue = 0;
if (0 < (tValue = ((IMachineProgress) tTileEntity).getMaxProgress()))
- tList.add(trans("178","Progress/Load: ") +EnumChatFormatting.GREEN+ formatNumbers(((IMachineProgress) tTileEntity).getProgress()) +EnumChatFormatting.RESET+ " / " +EnumChatFormatting.YELLOW+ formatNumbers(tValue) +EnumChatFormatting.RESET);
+ tList.add(trans("178","Progress/Load: ") + EnumChatFormatting.GREEN + formatNumbers(((IMachineProgress) tTileEntity).getProgress()) + EnumChatFormatting.RESET + " / " +
+ EnumChatFormatting.YELLOW + formatNumbers(tValue) + EnumChatFormatting.RESET);
}
} catch (Throwable e) {
if (D1) e.printStackTrace(GT_Log.err);
@@ -2046,16 +2071,22 @@ public class GT_Utility {
}
try {
if (tTileEntity instanceof IBasicEnergyContainer && ((IBasicEnergyContainer) tTileEntity).getEUCapacity() > 0) {
- tList.add(trans("179","Max IN: ") +EnumChatFormatting.RED+ ((IBasicEnergyContainer) tTileEntity).getInputVoltage() + " (" + GT_Values.VN[getTier(((IBasicEnergyContainer) tTileEntity).getInputVoltage())] + ") " +EnumChatFormatting.RESET+ trans("182"," EU at ") +EnumChatFormatting.RED+((IBasicEnergyContainer)tTileEntity).getInputAmperage()+EnumChatFormatting.RESET+trans("183"," A"));
- tList.add(trans("181","Max OUT: ") +EnumChatFormatting.RED+ ((IBasicEnergyContainer) tTileEntity).getOutputVoltage() + " (" + GT_Values.VN[getTier(((IBasicEnergyContainer) tTileEntity).getOutputVoltage())] + ") " +EnumChatFormatting.RESET+ trans("182"," EU at ") +EnumChatFormatting.RED+ ((IBasicEnergyContainer) tTileEntity).getOutputAmperage() +EnumChatFormatting.RESET+ trans("183"," A"));
- tList.add(trans("184","Energy: ") +EnumChatFormatting.GREEN+ formatNumbers(((IBasicEnergyContainer) tTileEntity).getStoredEU()) +EnumChatFormatting.RESET+ " EU / " +EnumChatFormatting.YELLOW+ formatNumbers(((IBasicEnergyContainer) tTileEntity).getEUCapacity()) +EnumChatFormatting.RESET+ " EU");
+ tList.add(
+ trans("179","Max IN: ") + EnumChatFormatting.RED + formatNumbers(((IBasicEnergyContainer) tTileEntity).getInputVoltage()) + " (" + GT_Values.VN[getTier(((IBasicEnergyContainer) tTileEntity).getInputVoltage())] + ") " + EnumChatFormatting.RESET +
+ trans("182"," EU at ") + EnumChatFormatting.RED + formatNumbers(((IBasicEnergyContainer)tTileEntity).getInputAmperage()) + EnumChatFormatting.RESET + trans("183"," A"));
+ tList.add(
+ trans("181","Max OUT: ") + EnumChatFormatting.RED + formatNumbers(((IBasicEnergyContainer) tTileEntity).getOutputVoltage()) + " (" + GT_Values.VN[getTier(((IBasicEnergyContainer) tTileEntity).getOutputVoltage())] + ") " + EnumChatFormatting.RESET +
+ trans("182"," EU at ") + EnumChatFormatting.RED + formatNumbers(((IBasicEnergyContainer) tTileEntity).getOutputAmperage()) + EnumChatFormatting.RESET + trans("183"," A"));
+ tList.add(
+ trans("184","Energy: ") + EnumChatFormatting.GREEN + formatNumbers(((IBasicEnergyContainer) tTileEntity).getStoredEU()) + EnumChatFormatting.RESET + " EU / " +
+ EnumChatFormatting.YELLOW + formatNumbers(((IBasicEnergyContainer) tTileEntity).getEUCapacity()) + EnumChatFormatting.RESET + " EU");
}
} catch (Throwable e) {
if (D1) e.printStackTrace(GT_Log.err);
}
try {
if (tTileEntity instanceof IGregTechTileEntity) {
- tList.add(trans("186","Owned by: ") +EnumChatFormatting.BLUE+ ((IGregTechTileEntity) tTileEntity).getOwnerName()+EnumChatFormatting.RESET);
+ tList.add(trans("186","Owned by: ") + EnumChatFormatting.BLUE + ((IGregTechTileEntity) tTileEntity).getOwnerName() + EnumChatFormatting.RESET);
}
} catch (Throwable e) {
if (D1) e.printStackTrace(GT_Log.err);
@@ -2107,15 +2138,15 @@ public class GT_Utility {
if (aPlayer.capabilities.isCreativeMode) {
FluidStack tFluid = undergroundOilReadInformation(aWorld.getChunkFromBlockCoords(aX,aZ));//-# to only read
if (tFluid!=null)
- tList.add(EnumChatFormatting.GOLD+tFluid.getLocalizedName()+EnumChatFormatting.RESET+": " +EnumChatFormatting.YELLOW+ tFluid.amount +EnumChatFormatting.RESET+" L");
+ tList.add(EnumChatFormatting.GOLD + tFluid.getLocalizedName() + EnumChatFormatting.RESET + ": " + EnumChatFormatting.YELLOW + formatNumbers(tFluid.amount) + EnumChatFormatting.RESET + " L");
else
- tList.add(EnumChatFormatting.GOLD+trans("201","Nothing")+EnumChatFormatting.RESET+": " +EnumChatFormatting.YELLOW+ '0' +EnumChatFormatting.RESET+" L");
+ tList.add(EnumChatFormatting.GOLD + trans("201","Nothing") + EnumChatFormatting.RESET + ": " + EnumChatFormatting.YELLOW + '0' + EnumChatFormatting.RESET + " L");
}
// if(aPlayer.capabilities.isCreativeMode){
int[] chunkData = GT_Proxy.dimensionWiseChunkData.get(aWorld.provider.dimensionId).get(aWorld.getChunkFromBlockCoords(aX,aZ).getChunkCoordIntPair());
- if(chunkData !=null){
+ if(chunkData != null){
if(chunkData[GTPOLLUTION]>0){
- tList.add(trans("202","Pollution in Chunk: ")+EnumChatFormatting.RED+chunkData[GTPOLLUTION]+EnumChatFormatting.RESET+trans("203"," gibbl"));
+ tList.add(trans("202","Pollution in Chunk: ") + EnumChatFormatting.RED + formatNumbers(chunkData[GTPOLLUTION]) + EnumChatFormatting.RESET + trans("203"," gibbl"));
}else{
tList.add(EnumChatFormatting.GREEN+trans("204","No Pollution in Chunk! HAYO!")+EnumChatFormatting.RESET);
}
@@ -2223,10 +2254,11 @@ public class GT_Utility {
}
public static String formatNumbers(long aNumber) {
- DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US);
- DecimalFormatSymbols symbols = formatter.getDecimalFormatSymbols();
- symbols.setGroupingSeparator(' ');
- return formatter.format(aNumber);
+ return decimalFormat.format(aNumber);
+ }
+
+ public static String formatNumbers(double aNumber) {
+ return decimalFormat.format(aNumber);
}
/*
@@ -2852,4 +2884,8 @@ public class GT_Utility {
dropItem.delayBeforeCanPickup = 0;
}
}
+
+ public static long getNonnullElementCount(Object[] tArray) {
+ return Arrays.stream(tArray).filter(Objects::nonNull).count();
+ }
}
diff --git a/src/main/java/gregtech/api/util/IGT_HatchAdder.java b/src/main/java/gregtech/api/util/IGT_HatchAdder.java
new file mode 100644
index 0000000000..362fddaf1f
--- /dev/null
+++ b/src/main/java/gregtech/api/util/IGT_HatchAdder.java
@@ -0,0 +1,15 @@
+package gregtech.api.util;
+
+
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+
+public interface IGT_HatchAdder<T> {
+ /**
+ * Callback to add hatch, needs to check if hatch is valid (and add it)
+ *
+ * @param iGregTechTileEntity hatch
+ * @param aShort requested texture index, or null if not...
+ * @return managed to add hatch (structure still valid)
+ */
+ boolean apply(T t, IGregTechTileEntity iGregTechTileEntity, Short aShort);
+}
diff --git a/src/main/java/gregtech/api/util/LightingHelper.java b/src/main/java/gregtech/api/util/LightingHelper.java
index 598253b7d7..f131ef74a0 100644
--- a/src/main/java/gregtech/api/util/LightingHelper.java
+++ b/src/main/java/gregtech/api/util/LightingHelper.java
@@ -255,6 +255,7 @@ public class LightingHelper {
} else {
+ if (hasBrightnessOverride) tessellator.setBrightness(brightnessOverride);
tessellator.setColorOpaque_F(rgb[0] * lightness, rgb[1] * lightness, rgb[2] * lightness);
}
diff --git a/src/main/java/gregtech/api/util/extensions/ArrayExt.java b/src/main/java/gregtech/api/util/extensions/ArrayExt.java
new file mode 100644
index 0000000000..51486bc036
--- /dev/null
+++ b/src/main/java/gregtech/api/util/extensions/ArrayExt.java
@@ -0,0 +1,80 @@
+package gregtech.api.util.extensions;
+
+import java.util.function.IntFunction;
+
+public class ArrayExt {
+ public static int[] of(int... objects) {
+ return objects;
+ }
+
+ public static float[] of(float... objects) {
+ return objects;
+ }
+
+ public static double[] of(double... objects) {
+ return objects;
+ }
+
+ public static char[] of(char... objects) {
+ return objects;
+ }
+
+ public static byte[] of(byte... objects) {
+ return objects;
+ }
+
+ public static long[] of(long... objects) {
+ return objects;
+ }
+
+ @SafeVarargs
+ public static <T> T[] of(T... objects) {
+ return objects;
+ }
+
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ public static <T> T[] withoutNulls(T[] array, IntFunction<T[]> arrayFactory) {
+ int count = 0;
+ for (int i = 0; i < array.length; i++) {
+ if (array[i] != null) {
+ count++;
+ }
+ }
+
+ T[] newArr = arrayFactory.apply(count);
+ if (count == 0) return newArr;
+
+ int j = 0;
+ for (int i = 0; i < array.length; i++) {
+ if (array[i] != null) {
+ newArr[j] = array[i];
+ j++;
+ }
+ }
+
+ return newArr;
+ }
+
+ public static <T> T[] withoutTrailingNulls(T[] array, IntFunction<T[]> arrayFactory) {
+ int firstNull = -1;
+ for (int i = array.length - 1; i >= 0; i--) {
+ if (array[i] == null) {
+ firstNull = i;
+ } else {
+ break;
+ }
+ }
+
+ if (firstNull == -1) {
+ T[] newArray = arrayFactory.apply(array.length);
+ System.arraycopy(array, 0, newArray, 0, array.length);
+ return newArray;
+ } else if (firstNull == 0) {
+ return arrayFactory.apply(0);
+ } else {
+ T[] newArray = arrayFactory.apply(firstNull);
+ System.arraycopy(array, 0, newArray, 0, firstNull);
+ return newArray;
+ }
+ }
+}
diff --git a/src/main/java/gregtech/api/util/extensions/IteratorExt.java b/src/main/java/gregtech/api/util/extensions/IteratorExt.java
new file mode 100644
index 0000000000..d59bb298a4
--- /dev/null
+++ b/src/main/java/gregtech/api/util/extensions/IteratorExt.java
@@ -0,0 +1,12 @@
+package gregtech.api.util.extensions;
+
+import gregtech.api.objects.iterators.MergedIterator;
+
+import java.util.Iterator;
+
+public class IteratorExt {
+ @SafeVarargs
+ public static <T> Iterator<T> merge(Iterator<T>... iterators) {
+ return new MergedIterator<>(iterators);
+ }
+}