package gregtech.api.metatileentity; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.function.Supplier; import net.minecraft.block.Block; import net.minecraft.client.renderer.RenderBlocks; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTankInfo; import org.jetbrains.annotations.Nullable; import com.gtnewhorizons.modularui.api.forge.ItemStackHandler; import appeng.api.implementations.IPowerChannelState; import appeng.api.networking.energy.IEnergyGrid; import appeng.api.networking.pathing.IPathingGrid; import appeng.api.util.AECableType; import appeng.core.localization.WailaText; import appeng.me.helpers.AENetworkProxy; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import gnu.trove.list.TIntList; import gnu.trove.list.array.TIntArrayList; import gregtech.api.GregTech_API; import gregtech.api.enums.Dyes; import gregtech.api.enums.GT_Values; import gregtech.api.enums.SoundResource; import gregtech.api.enums.SteamVariant; import gregtech.api.gui.GT_GUIColorOverride; import gregtech.api.gui.modularui.GUITextureSet; import gregtech.api.interfaces.ICleanroom; import gregtech.api.interfaces.ICleanroomReceiver; import gregtech.api.interfaces.IConfigurationCircuitSupport; import gregtech.api.interfaces.metatileentity.IMetaTileEntity; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; 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_TooltipDataCache; import gregtech.api.util.GT_Util; import gregtech.api.util.GT_Utility; import gregtech.common.GT_Client; import gregtech.common.covers.CoverInfo; import mcp.mobius.waila.api.IWailaConfigHandler; import mcp.mobius.waila.api.IWailaDataAccessor; /** * NEVER INCLUDE THIS FILE IN YOUR MOD!!! *
* Extend this Class to add a new MetaMachine Call the Constructor with the desired ID at the load-phase (not preload * and also not postload!) Implement the newMetaEntity-Method to return a new ready instance of your MetaTileEntity * * Call the Constructor like the following example inside the Load Phase, to register it. "new * GT_MetaTileEntity_E_Furnace(54, "GT_E_Furnace", "Automatic E-Furnace");" */ @SuppressWarnings("unused") public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomReceiver { /** * Only assigned for the MetaTileEntity in the List! Also only used to get the localized Name for the ItemStack and * for getInvName. */ public final String mName; /** * The Inventory of the MetaTileEntity. Amount of Slots can be larger than 256. HAYO! */ public final ItemStack[] mInventory; /** * Inventory wrapper for ModularUI */ public final ItemStackHandler inventoryHandler; protected GT_GUIColorOverride colorOverride; protected GT_TooltipDataCache mTooltipCache = new GT_TooltipDataCache(); @Override public ItemStackHandler getInventoryHandler() { return inventoryHandler; } public boolean doTickProfilingInThisTick = true; private ICleanroom cleanroom; /** * accessibility to this Field is no longer given, see below */ private IGregTechTileEntity mBaseMetaTileEntity; public long mSoundRequests = 0; /** * This registers your Machine at the List. Use only ID's larger than 2048 - the ones lower are reserved by GT. * See also the list in the API package - it has a description that contains all the reservations. ** The constructor can be overloaded as follows: *
*
*
*
* public GT_MetaTileEntity_EBench(int id, String name, String nameRegional) {
* super(id, name, nameRegional);
* }
*
*
*
*
* @param aID the machine ID
*/
public MetaTileEntity(int aID, String aBasicName, String aRegionalName, int aInvSlotCount) {
if (GregTech_API.sPostloadStarted || !GregTech_API.sPreloadStarted)
throw new IllegalAccessError("This Constructor has to be called in the load Phase");
if (GregTech_API.METATILEENTITIES[aID] == null) {
GregTech_API.METATILEENTITIES[aID] = this;
} else {
throw new IllegalArgumentException("MetaMachine-Slot Nr. " + aID + " is already occupied!");
}
mName = aBasicName.replace(" ", "_")
.toLowerCase(Locale.ENGLISH);
setBaseMetaTileEntity(GregTech_API.constructBaseMetaTileEntity());
getBaseMetaTileEntity().setMetaTileID((short) aID);
GT_LanguageManager.addStringLocalization("gt.blockmachines." + mName + ".name", aRegionalName);
mInventory = new ItemStack[aInvSlotCount];
inventoryHandler = new ItemStackHandler(mInventory);
}
/**
* This is the normal Constructor.
*/
public MetaTileEntity(String aName, int aInvSlotCount) {
mInventory = new ItemStack[aInvSlotCount];
mName = aName;
inventoryHandler = new ItemStackHandler(mInventory);
colorOverride = GT_GUIColorOverride.get(getGUITextureSet().getMainBackground().location);
}
/**
* This method will only be called on client side
*
* @return whether the secondary description should be display. default is false
*/
@Deprecated
public boolean isDisplaySecondaryDescription() {
return false;
}
@Override
public IGregTechTileEntity getBaseMetaTileEntity() {
return mBaseMetaTileEntity;
}
@Override
public void setBaseMetaTileEntity(IGregTechTileEntity aBaseMetaTileEntity) {
if (mBaseMetaTileEntity != null && aBaseMetaTileEntity == null) {
mBaseMetaTileEntity.getMetaTileEntity()
.inValidate();
mBaseMetaTileEntity.setMetaTileEntity(null);
}
mBaseMetaTileEntity = aBaseMetaTileEntity;
if (mBaseMetaTileEntity != null) {
mBaseMetaTileEntity.setMetaTileEntity(this);
}
}
public boolean isValid() {
return getBaseMetaTileEntity() != null && getBaseMetaTileEntity().getMetaTileEntity() == this
&& !getBaseMetaTileEntity().isDead();
}
@Override
public ItemStack getStackForm(long aAmount) {
return new ItemStack(GregTech_API.sBlockMachines, (int) aAmount, getBaseMetaTileEntity().getMetaTileID());
}
@Override
public String getLocalName() {
return GT_LanguageManager.getTranslation("gt.blockmachines." + mName + ".name");
}
@Override
public void onServerStart() {
/* Do nothing */
}
@Override
public void onWorldSave(File aSaveDirectory) {
/* Do nothing */
}
@Override
public void onWorldLoad(File aSaveDirectory) {
/* Do nothing */
}
@Override
public void onConfigLoad(GT_Config aConfig) {
/* Do nothing */
}
@Override
public void setItemNBT(NBTTagCompound aNBT) {
/* Do nothing */
}
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IIconRegister aBlockIconRegister) {
/* Do nothing */
}
@Override
public boolean allowCoverOnSide(ForgeDirection side, GT_ItemStack aStack) {
return true;
}
@Override
public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ,
ItemStack aTool) {
onScrewdriverRightClick(side, aPlayer, aX, aY, aZ);
}
@Override
public boolean onWrenchRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer entityPlayer,
float aX, float aY, float aZ, ItemStack aTool) {
// glue
if (onWrenchRightClick(side, wrenchingSide, entityPlayer, aX, aY, aZ)) {
return true;
}
if (getBaseMetaTileEntity().isValidFacing(wrenchingSide)) {
getBaseMetaTileEntity().setFrontFacing(wrenchingSide);
return true;
}
return false;
}
@Override
public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer,
float aX, float aY, float aZ, ItemStack aTool) {
// glue
if (onWireCutterRightClick(side, wrenchingSide, aPlayer, aX, aY, aZ)) {
return true;
}
if (!aPlayer.isSneaking()) return false;
final ForgeDirection oppositeSide = wrenchingSide.getOpposite();
final TileEntity tTileEntity = getBaseMetaTileEntity().getTileEntityAtSide(wrenchingSide);
if ((tTileEntity instanceof IGregTechTileEntity gtTE)
&& (gtTE.getMetaTileEntity() instanceof GT_MetaPipeEntity_Cable)) {
// The tile entity we're facing is a cable, let's try to connect to it
return gtTE.getMetaTileEntity()
.onWireCutterRightClick(wrenchingSide, oppositeSide, aPlayer, aX, aY, aZ, aTool);
}
return false;
}
@Override
public boolean onSolderingToolRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer,
float aX, float aY, float aZ, ItemStack aTool) {
// glue
if (onSolderingToolRightClick(side, wrenchingSide, aPlayer, aX, aY, aZ)) {
return true;
}
if (!aPlayer.isSneaking()) return false;
final ForgeDirection oppositeSide = wrenchingSide.getOpposite();
TileEntity tTileEntity = getBaseMetaTileEntity().getTileEntityAtSide(wrenchingSide);
if ((tTileEntity instanceof IGregTechTileEntity gtTE)
&& (gtTE.getMetaTileEntity() instanceof GT_MetaPipeEntity_Cable)) {
// The tile entity we're facing is a cable, let's try to connect to it
return gtTE.getMetaTileEntity()
.onSolderingToolRightClick(wrenchingSide, oppositeSide, aPlayer, aX, aY, aZ, aTool);
}
return false;
}
@Deprecated
public boolean onSolderingToolRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer,
float aX, float aY, float aZ) {
return false;
}
@Deprecated
public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer,
float aX, float aY, float aZ) {
return false;
}
@Deprecated
public boolean onWrenchRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer, float aX,
float aY, float aZ) {
return false;
}
@Deprecated
public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) {
}
@Override
public void onExplosion() {
GT_Log.exp.println(
"Machine at " + this.getBaseMetaTileEntity()
.getXCoord()
+ " | "
+ this.getBaseMetaTileEntity()
.getYCoord()
+ " | "
+ this.getBaseMetaTileEntity()
.getZCoord()
+ " DIMID: "
+ this.getBaseMetaTileEntity()
.getWorld().provider.dimensionId
+ " exploded.");
}
@Override
public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) {
/* Do nothing */
}
@Override
public void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
/* Do nothing */
}
@Override
public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
if (aBaseMetaTileEntity.isClientSide() && GT_Client.changeDetected == 4) {
/*
* Client tick counter that is set to 5 on hiding pipes and covers. It triggers a texture update next client
* tick when reaching 4, with provision for 3 more update tasks, spreading client change detection related
* work and network traffic on different ticks, until it reaches 0.
*/
aBaseMetaTileEntity.issueTextureUpdate();
}
}
public void onTickFail(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {}
public void onSetActive(boolean active) {}
public void onDisableWorking() {}
@Override
public void inValidate() {
/* Do nothing */
}
@Override
public void onRemoval() {
/* Do nothing */
}
@Override
public void initDefaultModes(NBTTagCompound aNBT) {
/* Do nothing */
}
/**
* When a GUI is opened
*/
public void onOpenGUI() {
/* Do nothing */
}
/**
* When a GUI is closed
*/
public void onCloseGUI() {
/* Do nothing */
}
/**
* a Player rightclicks the Machine Sneaky rightclicks are not getting passed to this!
*/
public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) {
return false;
}
@Override
public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer, ForgeDirection side,
float aX, float aY, float aZ) {
return onRightclick(aBaseMetaTileEntity, aPlayer);
}
@Override
public void onLeftclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) {
/* Do nothing */
}
@Override
public void onValueUpdate(byte aValue) {
/* Do nothing */
}
@Override
public byte getUpdateData() {
return 0;
}
@Override
public void doSound(byte aIndex, double aX, double aY, double aZ) {
/* Do nothing */
}
@Override
public void startSoundLoop(byte aIndex, double aX, double aY, double aZ) {
/* Do nothing */
}
@Override
public void stopSoundLoop(byte aValue, double aX, double aY, double aZ) {
/* Do nothing */
}
@Nullable
@Override
public ICleanroom getCleanroom() {
return cleanroom;
}
@Override
public void setCleanroom(ICleanroom cleanroom) {
this.cleanroom = cleanroom;
}
@Override
public final void sendSound(byte aIndex) {
if (!getBaseMetaTileEntity().hasMufflerUpgrade())
getBaseMetaTileEntity().sendBlockEvent(GregTechTileClientEvents.DO_SOUND, aIndex);
}
@Override
public final void sendLoopStart(byte aIndex) {
if (!getBaseMetaTileEntity().hasMufflerUpgrade())
getBaseMetaTileEntity().sendBlockEvent(GregTechTileClientEvents.START_SOUND_LOOP, aIndex);
mSoundRequests++;
}
@Override
public final void sendLoopEnd(byte aIndex) {
if (!getBaseMetaTileEntity().hasMufflerUpgrade())
getBaseMetaTileEntity().sendBlockEvent(GregTechTileClientEvents.STOP_SOUND_LOOP, aIndex);
}
/**
* @return true if this Device emits Energy at all
*/
public boolean isElectric() {
return true;
}
/**
* @return true if this Device emits Energy at all
*/
public boolean isPneumatic() {
return false;
}
/**
* @return true if this Device emits Energy at all
*/
public boolean isSteampowered() {
return false;
}
/**
* @return what type of texture does this machine use for GUI, i.e. Bronze, Steel, or Primitive
*/
public SteamVariant getSteamVariant() {
return SteamVariant.NONE;
}
/**
* @return true if this Device emits Energy at all
*/
public boolean isEnetOutput() {
return false;
}
/**
* @return true if this Device consumes Energy at all
*/
public boolean isEnetInput() {
return false;
}
/**
* @return the amount of EU, which can be stored in this Device. Default is 0 EU.
*/
public long maxEUStore() {
return 0;
}
/**
* @return the amount of EU/t, which can be accepted by this Device before it explodes.
*/
public long maxEUInput() {
return 0;
}
/**
* @return the amount of EU/t, which can be outputted by this Device.
*/
public long maxEUOutput() {
return 0;
}
/**
* @return the amount of E-net Impulses of the maxEUOutput size, which can be outputted by this Device. Default is 1
* Pulse, this shouldn't be set to smaller Values than 1, as it won't output anything in that Case!
*/
public long maxAmperesOut() {
return 1;
}
/**
* How many Amperes this Block can suck at max. Surpassing this value won't blow it up.
*/
public long maxAmperesIn() {
return 1;
}
/**
* @return true if that Side is an Output.
*/
public boolean isOutputFacing(ForgeDirection side) {
return false;
}
/**
* @return true if that Side is an Input.
*/
public boolean isInputFacing(ForgeDirection side) {
return false;
}
/**
* @return true if Transformer Upgrades increase Packet Amount.
*/
public boolean isTransformingLowEnergy() {
return true;
}
@Override
public boolean isFacingValid(ForgeDirection facing) {
return false;
}
@Override
public boolean isAccessAllowed(EntityPlayer aPlayer) {
return false;
}
@Override
public boolean isValidSlot(int aIndex) {
return true;
}
@Override
public boolean shouldDropItemAt(int index) {
return true;
}
@Override
public boolean setStackToZeroInsteadOfNull(int aIndex) {
return false;
}
/**
* This is used to get the internal Energy. I use this for the IDSU.
*/
public long getEUVar() {
return ((BaseMetaTileEntity) mBaseMetaTileEntity).mStoredEnergy;
}
/**
* This is used to set the internal Energy to the given Parameter. I use this for the IDSU.
*/
public void setEUVar(long aEnergy) {
if (aEnergy != ((BaseMetaTileEntity) mBaseMetaTileEntity).mStoredEnergy) {
markDirty();
((BaseMetaTileEntity) mBaseMetaTileEntity).mStoredEnergy = aEnergy;
}
}
/**
* This is used to get the internal Steam Energy.
*/
public long getSteamVar() {
return ((BaseMetaTileEntity) mBaseMetaTileEntity).mStoredSteam;
}
/**
* This is used to set the internal Steam Energy to the given Parameter.
*/
public void setSteamVar(long aSteam) {
if (((BaseMetaTileEntity) mBaseMetaTileEntity).mStoredSteam != aSteam) {
markDirty();
((BaseMetaTileEntity) mBaseMetaTileEntity).mStoredSteam = aSteam;
}
}
/**
* @return the amount of Steam, which can be stored in this Device. Default is 0 EU.
*/
public long maxSteamStore() {
return 0;
}
/**
* @return the amount of EU, which this Device stores before starting to emit Energy. useful if you don't want to
* emit stored Energy until a certain Level is reached.
*/
public long getMinimumStoredEU() {
return 512;
}
/**
* Determines the Tier of the Machine, used for de-charging Tools.
*/
public long getInputTier() {
return GT_Utility.getTier(getBaseMetaTileEntity().getInputVoltage());
}
/**
* Determines the Tier of the Machine, used for charging Tools.
*/
public long getOutputTier() {
return GT_Utility.getTier(getBaseMetaTileEntity().getOutputVoltage());
}
/**
* gets the first RechargerSlot
*/
public int rechargerSlotStartIndex() {
return 0;
}
/**
* gets the amount of RechargerSlots
*/
public int rechargerSlotCount() {
return 0;
}
/**
* gets the first DechargerSlot
*/
public int dechargerSlotStartIndex() {
return 0;
}
/**
* gets the amount of DechargerSlots
*/
public int dechargerSlotCount() {
return 0;
}
/**
* gets if this is protected from other Players per default or not
*/
public boolean ownerControl() {
return false;
}
@Override
public ArrayList