From 7711c80664fdfa703b5e60e62af437655da783ae Mon Sep 17 00:00:00 2001 From: Draknyte1 Date: Sat, 27 Feb 2016 21:24:45 +1000 Subject: Added Custom GT Cables/Wire & also added a copy of EnderIO's Gas Conduit classes. Time to combine the two, yeah? Also stripped out a heap of constants and refactored them together. --- .../miscutil/enderio/conduit/MetaConduitBase.java | 245 ++++++++++++++++++ src/Java/miscutil/enderio/conduit/ModConduits.java | 6 + .../enderio/conduit/gas/AbstractGasConduit.java | 208 +++++++++++++++ .../conduit/gas/AbstractGasTankConduit.java | 176 +++++++++++++ .../conduit/gas/AbstractGasTankConduitNetwork.java | 68 +++++ .../enderio/conduit/gas/ConduitGasTank.java | 164 ++++++++++++ .../miscutil/enderio/conduit/gas/GasConduit.java | 278 ++++++++++++++++++++ .../enderio/conduit/gas/GasConduitNetwork.java | 280 +++++++++++++++++++++ .../enderio/conduit/gas/GasConduitRenderer.java | 178 +++++++++++++ .../miscutil/enderio/conduit/gas/GasOutput.java | 57 +++++ src/Java/miscutil/enderio/conduit/gas/GasUtil.java | 75 ++++++ .../miscutil/enderio/conduit/gas/IGasConduit.java | 16 ++ .../enderio/conduit/gas/ItemGasConduit.java | 73 ++++++ .../enderio/conduit/gas/PacketGasLevel.java | 46 ++++ 14 files changed, 1870 insertions(+) create mode 100644 src/Java/miscutil/enderio/conduit/MetaConduitBase.java create mode 100644 src/Java/miscutil/enderio/conduit/ModConduits.java create mode 100644 src/Java/miscutil/enderio/conduit/gas/AbstractGasConduit.java create mode 100644 src/Java/miscutil/enderio/conduit/gas/AbstractGasTankConduit.java create mode 100644 src/Java/miscutil/enderio/conduit/gas/AbstractGasTankConduitNetwork.java create mode 100644 src/Java/miscutil/enderio/conduit/gas/ConduitGasTank.java create mode 100644 src/Java/miscutil/enderio/conduit/gas/GasConduit.java create mode 100644 src/Java/miscutil/enderio/conduit/gas/GasConduitNetwork.java create mode 100644 src/Java/miscutil/enderio/conduit/gas/GasConduitRenderer.java create mode 100644 src/Java/miscutil/enderio/conduit/gas/GasOutput.java create mode 100644 src/Java/miscutil/enderio/conduit/gas/GasUtil.java create mode 100644 src/Java/miscutil/enderio/conduit/gas/IGasConduit.java create mode 100644 src/Java/miscutil/enderio/conduit/gas/ItemGasConduit.java create mode 100644 src/Java/miscutil/enderio/conduit/gas/PacketGasLevel.java (limited to 'src/Java/miscutil/enderio') diff --git a/src/Java/miscutil/enderio/conduit/MetaConduitBase.java b/src/Java/miscutil/enderio/conduit/MetaConduitBase.java new file mode 100644 index 0000000000..ea7c431ecb --- /dev/null +++ b/src/Java/miscutil/enderio/conduit/MetaConduitBase.java @@ -0,0 +1,245 @@ +package miscutil.enderio.conduit; + +import static gregtech.api.enums.GT_Values.V; +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.items.GT_MetaBase_Item; +import gregtech.api.objects.GT_RenderedTexture; +import gregtech.api.util.GT_ModHandler; +import gregtech.api.util.GT_Utility; +import ic2.api.item.IElectricItem; +import miscutil.core.handler.GuiHandler; +import miscutil.core.util.Utils; +import miscutil.gregtech.metatileentity.implementations.GregtechMetaTileEntity; +import miscutil.gregtech.util.IMessage; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +/** + * NEVER INCLUDE THIS FILE IN YOUR MOD!!! + * + * This is the main construct for my Basic Machines such as the Automatic Extractor + * Extend this class to make a simple Machine + */ +public class MetaConduitBase extends GregtechMetaTileEntity { + + /* + * public GregtechMetaEnergyBuffer() { super.this + * setCreativeTab(GregTech_API.TAB_GREGTECH); } + */ + + public int mAmpage = 1; + public boolean mCharge = false, mDecharge = false; + public int mBatteryCount = 1, mChargeableCount = 1; + + public MetaConduitBase(int aID, String aName, String aNameRegional, int aTier, String aDescription, int aSlotCount) { + super(aID, aName, aNameRegional, aTier, aSlotCount, aDescription); + } + + public MetaConduitBase(String aName, int aTier, String aDescription, ITexture[][][] aTextures, int aSlotCount) { + super(aName, aTier, aSlotCount, aDescription, aTextures); + } + + @Override + public String[] getDescription() { + return new String[] {mDescription, mInventory.length + " Slots"}; + } + + /* + * MACHINE_STEEL_SIDE + */ + @Override + public ITexture[][][] getTextureSet(ITexture[] aTextures) { + ITexture[][][] rTextures = new ITexture[2][17][]; + for (byte i = -1; i < 16; i++) { + rTextures[0][i + 1] = new ITexture[] { new GT_RenderedTexture( + Textures.BlockIcons.MACHINE_HEATPROOFCASING) }; + rTextures[1][i + 1] = new ITexture[] { + new GT_RenderedTexture( + Textures.BlockIcons.MACHINE_HEATPROOFCASING), + mInventory.length > 4 ? Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] + : Textures.BlockIcons.OVERLAYS_ENERGY_OUT[mTier] }; + } + return rTextures; + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, byte aSide, byte aFacing, byte aColorIndex, boolean aActive, boolean aRedstone) { + return mTextures[aSide == aFacing ? 1 : 0][aColorIndex+1]; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MetaConduitBase(mName, mTier, mDescription, mTextures, mInventory.length); + } + + @Override public boolean isSimpleMachine() {return false;} + @Override public boolean isElectric() {return true;} + @Override public boolean isValidSlot(int aIndex) {return true;} + @Override public boolean isFacingValid(byte aFacing) {return true;} + @Override public boolean isEnetInput() {return true;} + @Override public boolean isEnetOutput() {return true;} + @Override public boolean isInputFacing(byte aSide) {return aSide!=getBaseMetaTileEntity().getFrontFacing();} + @Override public boolean isOutputFacing(byte aSide) {return aSide==getBaseMetaTileEntity().getFrontFacing();} + @Override public boolean isTeleporterCompatible() {return false;} + @Override public long getMinimumStoredEU() {return V[mTier]*4*mInventory.length;} + @Override public long maxEUStore() {return V[mTier]*250;} + + @Override + public long maxEUInput() { + return V[mTier]; + } + + @Override + public long maxEUOutput() { + return V[mTier]; + } + + @Override + public long maxAmperesIn() { + return mChargeableCount * mAmpage; + } + + @Override + public long maxAmperesOut() { + return mChargeableCount * mAmpage; + } + @Override public int rechargerSlotStartIndex() {return 0;} + @Override public int dechargerSlotStartIndex() {return 0;} + @Override public int rechargerSlotCount() {return mCharge?mInventory.length:0;} + @Override public int dechargerSlotCount() {return mDecharge?mInventory.length:0;} + @Override public int getProgresstime() {return (int)getBaseMetaTileEntity().getUniversalEnergyStored();} + @Override public int maxProgresstime() {return (int)getBaseMetaTileEntity().getUniversalEnergyCapacity();} + @Override public boolean isAccessAllowed(EntityPlayer aPlayer) {return true;} + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + // + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + // + } + + @Override + public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { + Utils.LOG_WARNING("Right Click on MTE by Player"); + if (aBaseMetaTileEntity.isClientSide()) return true; + //aBaseMetaTileEntity.openGUI(aPlayer); + + Utils.LOG_WARNING("MTE is Client-side"); + showEnergy(aPlayer.getEntityWorld(), aPlayer); + return true; + } + + private void showEnergy(World worldIn, EntityPlayer playerIn){ + Utils.LOG_WARNING("Begin Show Energy"); + final double c = ((double) getProgresstime() / maxProgresstime()) * 100; + Utils.LOG_WARNING(""+c); + final double roundOff = Math.round(c * 100.0) / 100.0; + IMessage.messageThePlayer("Energy: " + getProgresstime() + " EU at "+V[mTier]+"v ("+roundOff+"%)"); + Utils.LOG_WARNING("Making new instance of Guihandler"); + GuiHandler block = new GuiHandler(); + Utils.LOG_WARNING("Guihandler.toString(): "+block.toString()); + block.getClientGuiElement(1, playerIn, worldIn, (int) playerIn.posX, (int) playerIn.posY, (int) playerIn.posZ); + + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (aBaseMetaTileEntity.isServerSide()) { + mCharge = aBaseMetaTileEntity.getStoredEU() / 2 > aBaseMetaTileEntity + .getEUCapacity() / 3; + mDecharge = aBaseMetaTileEntity.getStoredEU() < aBaseMetaTileEntity.getEUCapacity() / 3; + mBatteryCount = 1; + mChargeableCount = 1; + for (ItemStack tStack : mInventory) if (GT_ModHandler.isElectricItem(tStack, mTier)) { + if (GT_ModHandler.isChargerItem(tStack)) mBatteryCount++; + mChargeableCount++; + } + } + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, byte aSide, ItemStack aStack) { + if(GT_ModHandler.isElectricItem(aStack)&&aStack.getUnlocalizedName().startsWith("gt.metaitem.01.")){ + String name = aStack.getUnlocalizedName(); + if(name.equals("gt.metaitem.01.32510")|| + name.equals("gt.metaitem.01.32511")|| + name.equals("gt.metaitem.01.32520")|| + name.equals("gt.metaitem.01.32521")|| + name.equals("gt.metaitem.01.32530")|| + name.equals("gt.metaitem.01.32531")){ + return true; + } + } + return false; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, byte aSide, ItemStack aStack) { + if(!GT_Utility.isStackValid(aStack)){ + return false; + } + if(GT_ModHandler.isElectricItem(aStack, this.mTier)){ + return true; + } + return false; + } + + public long[] getStoredEnergy(){ + long tScale = getBaseMetaTileEntity().getEUCapacity(); + long tStored = getBaseMetaTileEntity().getStoredEU(); + if (mInventory != null) { + for (ItemStack aStack : mInventory) { + if (GT_ModHandler.isElectricItem(aStack)) { + + if (aStack.getItem() instanceof GT_MetaBase_Item) { + Long[] stats = ((GT_MetaBase_Item) aStack.getItem()) + .getElectricStats(aStack); + if (stats != null) { + tScale = tScale + stats[0]; + tStored = tStored + + ((GT_MetaBase_Item) aStack.getItem()) + .getRealCharge(aStack); + } + } else if (aStack.getItem() instanceof IElectricItem) { + tStored = tStored + + (long) ic2.api.item.ElectricItem.manager + .getCharge(aStack); + tScale = tScale + + (long) ((IElectricItem) aStack.getItem()) + .getMaxCharge(aStack); + } + } + } + + } + return new long[] { tStored, tScale }; + } + + private long count=0; + private long mStored=0; + private long mMax=0; + + @Override + public String[] getInfoData() { + count++; + if(mMax==0||count%20==0){ + long[] tmp = getStoredEnergy(); + mStored=tmp[0]; + mMax=tmp[1]; + } + + return new String[] { + getLocalName(), + "Internal Storage:", + GT_Utility.formatNumbers(mStored)+" EU /", + GT_Utility.formatNumbers(mMax)+" EU"}; + } +} \ No newline at end of file diff --git a/src/Java/miscutil/enderio/conduit/ModConduits.java b/src/Java/miscutil/enderio/conduit/ModConduits.java new file mode 100644 index 0000000000..04cb120ec7 --- /dev/null +++ b/src/Java/miscutil/enderio/conduit/ModConduits.java @@ -0,0 +1,6 @@ +package miscutil.enderio.conduit; + + +public class ModConduits { + +} diff --git a/src/Java/miscutil/enderio/conduit/gas/AbstractGasConduit.java b/src/Java/miscutil/enderio/conduit/gas/AbstractGasConduit.java new file mode 100644 index 0000000000..ee7ba3d954 --- /dev/null +++ b/src/Java/miscutil/enderio/conduit/gas/AbstractGasConduit.java @@ -0,0 +1,208 @@ +package crazypants.enderio.conduit.gas; + +import com.enderio.core.common.util.BlockCoord; +import com.enderio.core.common.util.DyeColor; +import cpw.mods.fml.common.Optional.Method; +import crazypants.enderio.conduit.AbstractConduit; +import crazypants.enderio.conduit.ConduitUtil; +import crazypants.enderio.conduit.ConnectionMode; +import crazypants.enderio.conduit.IConduit; +import crazypants.enderio.conduit.IConduitBundle; +import crazypants.enderio.machine.RedstoneControlMode; +import crazypants.enderio.machine.reservoir.TileReservoir; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import mekanism.api.gas.IGasHandler; +import net.minecraft.block.Block; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +public abstract class AbstractGasConduit + extends AbstractConduit + implements IGasConduit +{ + protected final EnumMap extractionModes = new EnumMap(ForgeDirection.class); + protected final EnumMap extractionColors = new EnumMap(ForgeDirection.class); + protected final Map externalRedstoneSignals = new HashMap(); + protected boolean redstoneStateDirty = true; + + @Optional.Method(modid="MekanismAPI|gas") + public IGasHandler getExternalHandler(ForgeDirection direction) + { + IGasHandler con = GasUtil.getExternalGasHandler(getBundle().getWorld(), getLocation().getLocation(direction)); + return (con != null) && (!(con instanceof IConduitBundle)) ? con : null; + } + + @Optional.Method(modid="MekanismAPI|gas") + public IGasHandler getTankContainer(BlockCoord bc) + { + return GasUtil.getGasHandler(getBundle().getWorld(), bc); + } + + public boolean canConnectToExternal(ForgeDirection direction, boolean ignoreDisabled) + { + IGasHandler h = getExternalHandler(direction); + if (h == null) { + return false; + } + return true; + } + + public Class getBaseConduitType() + { + return IGasConduit.class; + } + + public boolean onNeighborBlockChange(Block blockId) + { + this.redstoneStateDirty = true; + return super.onNeighborBlockChange(blockId); + } + + public void setExtractionRedstoneMode(RedstoneControlMode mode, ForgeDirection dir) + { + this.extractionModes.put(dir, mode); + this.redstoneStateDirty = true; + } + + public RedstoneControlMode getExtractionRedstoneMode(ForgeDirection dir) + { + RedstoneControlMode res = (RedstoneControlMode)this.extractionModes.get(dir); + if (res == null) { + res = RedstoneControlMode.ON; + } + return res; + } + + public void setExtractionSignalColor(ForgeDirection dir, DyeColor col) + { + this.extractionColors.put(dir, col); + } + + public DyeColor getExtractionSignalColor(ForgeDirection dir) + { + DyeColor result = (DyeColor)this.extractionColors.get(dir); + if (result == null) { + return DyeColor.RED; + } + return result; + } + + public boolean canOutputToDir(ForgeDirection dir) + { + if ((isExtractingFromDir(dir)) || (getConnectionMode(dir) == ConnectionMode.DISABLED)) { + return false; + } + if (this.conduitConnections.contains(dir)) { + return true; + } + if (!this.externalConnections.contains(dir)) { + return false; + } + IGasHandler ext = getExternalHandler(dir); + if ((ext instanceof TileReservoir)) + { + TileReservoir tr = (TileReservoir)ext; + return (!tr.isMultiblock()) || (!tr.isAutoEject()); + } + return true; + } + + protected boolean autoExtractForDir(ForgeDirection dir) + { + if (!isExtractingFromDir(dir)) { + return false; + } + RedstoneControlMode mode = getExtractionRedstoneMode(dir); + if (mode == RedstoneControlMode.IGNORE) { + return true; + } + if (mode == RedstoneControlMode.NEVER) { + return false; + } + if (this.redstoneStateDirty) + { + this.externalRedstoneSignals.clear(); + this.redstoneStateDirty = false; + } + DyeColor col = getExtractionSignalColor(dir); + int signal = ConduitUtil.getInternalSignalForColor(getBundle(), col); + if ((RedstoneControlMode.isConditionMet(mode, signal)) && (mode != RedstoneControlMode.OFF)) { + return true; + } + return isConditionMetByExternalSignal(dir, mode, col); + } + + private boolean isConditionMetByExternalSignal(ForgeDirection dir, RedstoneControlMode mode, DyeColor col) + { + int externalSignal = 0; + if (col == DyeColor.RED) + { + Integer val = (Integer)this.externalRedstoneSignals.get(dir); + if (val == null) + { + TileEntity te = getBundle().getEntity(); + externalSignal = te.getWorldObj().getStrongestIndirectPower(te.xCoord, te.yCoord, te.zCoord); + this.externalRedstoneSignals.put(dir, Integer.valueOf(externalSignal)); + } + else + { + externalSignal = val.intValue(); + } + } + return RedstoneControlMode.isConditionMet(mode, externalSignal); + } + + public boolean isExtractingFromDir(ForgeDirection dir) + { + return getConnectionMode(dir) == ConnectionMode.INPUT; + } + + public void writeToNBT(NBTTagCompound nbtRoot) + { + super.writeToNBT(nbtRoot); + for (Map.Entry entry : this.extractionModes.entrySet()) { + if (entry.getValue() != null) + { + short ord = (short)((RedstoneControlMode)entry.getValue()).ordinal(); + nbtRoot.setShort("extRM." + ((ForgeDirection)entry.getKey()).name(), ord); + } + } + for (Map.Entry entry : this.extractionColors.entrySet()) { + if (entry.getValue() != null) + { + short ord = (short)((DyeColor)entry.getValue()).ordinal(); + nbtRoot.setShort("extSC." + ((ForgeDirection)entry.getKey()).name(), ord); + } + } + } + + public void readFromNBT(NBTTagCompound nbtRoot, short nbtVersion) + { + super.readFromNBT(nbtRoot, nbtVersion); + for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) + { + String key = "extRM." + dir.name(); + if (nbtRoot.hasKey(key)) + { + short ord = nbtRoot.getShort(key); + if ((ord >= 0) && (ord < RedstoneControlMode.values().length)) { + this.extractionModes.put(dir, RedstoneControlMode.values()[ord]); + } + } + key = "extSC." + dir.name(); + if (nbtRoot.hasKey(key)) + { + short ord = nbtRoot.getShort(key); + if ((ord >= 0) && (ord < DyeColor.values().length)) { + this.extractionColors.put(dir, DyeColor.values()[ord]); + } + } + } + } +} diff --git a/src/Java/miscutil/enderio/conduit/gas/AbstractGasTankConduit.java b/src/Java/miscutil/enderio/conduit/gas/AbstractGasTankConduit.java new file mode 100644 index 0000000000..7226ad8328 --- /dev/null +++ b/src/Java/miscutil/enderio/conduit/gas/AbstractGasTankConduit.java @@ -0,0 +1,176 @@ +package crazypants.enderio.conduit.gas; + +import com.enderio.core.common.util.BlockCoord; +import cpw.mods.fml.common.Optional.Method; +import crazypants.enderio.conduit.AbstractConduitNetwork; +import crazypants.enderio.conduit.ConduitUtil; +import crazypants.enderio.conduit.ConnectionMode; +import crazypants.enderio.conduit.IConduitBundle; +import crazypants.enderio.conduit.RaytraceResult; +import crazypants.enderio.conduit.geom.CollidableComponent; +import crazypants.enderio.tool.ToolUtil; +import java.util.List; +import mekanism.api.gas.GasStack; +import mekanism.api.gas.IGasHandler; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +public abstract class AbstractGasTankConduit + extends AbstractGasConduit +{ + protected ConduitGasTank tank = new ConduitGasTank(0); + protected boolean stateDirty = false; + protected long lastEmptyTick = 0L; + protected int numEmptyEvents = 0; + + public boolean onBlockActivated(EntityPlayer player, RaytraceResult res, List all) + { + if (player.getCurrentEquippedItem() == null) { + return false; + } + if (ToolUtil.isToolEquipped(player)) + { + if (!getBundle().getEntity().getWorldObj().isRemote) { + if ((res != null) && (res.component != null)) + { + ForgeDirection connDir = res.component.dir; + ForgeDirection faceHit = ForgeDirection.getOrientation(res.movingObjectPosition.sideHit); + if ((connDir == ForgeDirection.UNKNOWN) || (connDir == faceHit)) + { + if (getConnectionMode(faceHit) == ConnectionMode.DISABLED) + { + setConnectionMode(faceHit, getNextConnectionMode(faceHit)); + return true; + } + BlockCoord loc = getLocation().getLocation(faceHit); + IGasConduit n = (IGasConduit)ConduitUtil.getConduit(getBundle().getEntity().getWorldObj(), loc.x, loc.y, loc.z, IGasConduit.class); + if (n == null) { + return false; + } + if (!canJoinNeighbour(n)) { + return false; + } + if (!(n instanceof AbstractGasTankConduit)) { + return false; + } + AbstractGasTankConduit neighbour = (AbstractGasTankConduit)n; + if ((neighbour.getGasType() == null) || (getGasType() == null)) + { + GasStack type = getGasType(); + type = type != null ? type : neighbour.getGasType(); + neighbour.setGasTypeOnNetwork(neighbour, type); + setGasTypeOnNetwork(this, type); + } + return ConduitUtil.joinConduits(this, faceHit); + } + if (containsExternalConnection(connDir)) + { + setConnectionMode(connDir, getNextConnectionMode(connDir)); + } + else if (containsConduitConnection(connDir)) + { + GasStack curGasType = null; + if (getTankNetwork() != null) { + curGasType = getTankNetwork().getGasType(); + } + ConduitUtil.disconectConduits(this, connDir); + setGasType(curGasType); + } + } + } + return true; + } + return false; + } + + private void setGasTypeOnNetwork(AbstractGasTankConduit con, GasStack type) + { + AbstractConduitNetwork n = con.getNetwork(); + if (n != null) + { + AbstractGasTankConduitNetwork network = (AbstractGasTankConduitNetwork)n; + network.setGasType(type); + } + } + + protected abstract boolean canJoinNeighbour(IGasConduit paramIGasConduit); + + public abstract AbstractGasTankConduitNetwork getTankNetwork(); + + @Optional.Method(modid="MekanismAPI|gas") + public void setGasType(GasStack gasType) + { + if ((this.tank.getGas() != null) && (this.tank.getGas().isGasEqual(gasType))) { + return; + } + if (gasType != null) { + gasType = gasType.copy(); + } else if (this.tank.getGas() == null) { + return; + } + this.tank.setGas(gasType); + this.stateDirty = true; + } + + public ConduitGasTank getTank() + { + return this.tank; + } + + @Optional.Method(modid="MekanismAPI|gas") + public GasStack getGasType() + { + GasStack result = null; + if (getTankNetwork() != null) { + result = getTankNetwork().getGasType(); + } + if (result == null) { + result = this.tank.getGas(); + } + return result; + } + + public boolean canOutputToDir(ForgeDirection dir) + { + if (super.canOutputToDir(dir)) + { + IGasHandler ext = getExternalHandler(dir); + return (ext != null) && (ext.canReceiveGas(dir.getOpposite(), this.tank.getGasType())); + } + return false; + } + + protected abstract void updateTank(); + + public void readFromNBT(NBTTagCompound nbtRoot, short nbtVersion) + { + super.readFromNBT(nbtRoot, nbtVersion); + updateTank(); + if (nbtRoot.hasKey("tank")) + { + GasStack gas = GasStack.readFromNBT(nbtRoot.getCompoundTag("tank")); + this.tank.setGas(gas); + } + else + { + this.tank.setGas(null); + } + } + + public void writeToNBT(NBTTagCompound nbtRoot) + { + super.writeToNBT(nbtRoot); + GasStack gt = getGasType(); + if (GasUtil.isGasValid(gt)) + { + updateTank(); + gt = gt.copy(); + gt.amount = this.tank.getStored(); + nbtRoot.setTag("tank", gt.write(new NBTTagCompound())); + } + } +} diff --git a/src/Java/miscutil/enderio/conduit/gas/AbstractGasTankConduitNetwork.java b/src/Java/miscutil/enderio/conduit/gas/AbstractGasTankConduitNetwork.java new file mode 100644 index 0000000000..75a4a3c1ad --- /dev/null +++ b/src/Java/miscutil/enderio/conduit/gas/AbstractGasTankConduitNetwork.java @@ -0,0 +1,68 @@ +package crazypants.enderio.conduit.gas; + +import crazypants.enderio.conduit.AbstractConduitNetwork; +import mekanism.api.gas.GasStack; + +public class AbstractGasTankConduitNetwork + extends AbstractConduitNetwork +{ + protected GasStack gasType; + + protected AbstractGasTankConduitNetwork(Class cl) + { + super(cl, IGasConduit.class); + } + + public GasStack getGasType() + { + return this.gasType; + } + + public void addConduit(T con) + { + super.addConduit(con); + con.setGasType(this.gasType); + } + + public boolean setGasType(GasStack newType) + { + if ((this.gasType != null) && (this.gasType.isGasEqual(newType))) { + return false; + } + if (newType != null) + { + this.gasType = newType.copy(); + this.gasType.amount = 0; + } + else + { + this.gasType = null; + } + for (AbstractGasTankConduit conduit : this.conduits) { + conduit.setGasType(this.gasType); + } + return true; + } + + public boolean canAcceptGas(GasStack acceptable) + { + return areGassCompatable(this.gasType, acceptable); + } + + public static boolean areGassCompatable(GasStack a, GasStack b) + { + if ((a == null) || (b == null)) { + return true; + } + return a.isGasEqual(b); + } + + public int getTotalVolume() + { + int totalVolume = 0; + for (T con : this.conduits) { + totalVolume += con.getTank().getStored(); + } + return totalVolume; + } +} diff --git a/src/Java/miscutil/enderio/conduit/gas/ConduitGasTank.java b/src/Java/miscutil/enderio/conduit/gas/ConduitGasTank.java new file mode 100644 index 0000000000..08aef66656 --- /dev/null +++ b/src/Java/miscutil/enderio/conduit/gas/ConduitGasTank.java @@ -0,0 +1,164 @@ +package crazypants.enderio.conduit.gas; + +import cpw.mods.fml.common.Optional.Method; +import mekanism.api.gas.Gas; +import mekanism.api.gas.GasStack; +import mekanism.api.gas.GasTank; +import net.minecraft.nbt.NBTTagCompound; + +public class ConduitGasTank + extends GasTank +{ + private int capacity; + + ConduitGasTank(int capacity) + { + super(capacity); + this.capacity = capacity; + } + + public float getFilledRatio() + { + if (getStored() <= 0) { + return 0.0F; + } + if (getMaxGas() <= 0) { + return -1.0F; + } + float res = getStored() / getMaxGas(); + return res; + } + + public boolean isFull() + { + return getStored() >= getMaxGas(); + } + + public void setAmount(int amount) + { + if (this.stored != null) { + this.stored.amount = amount; + } + } + + public int getAvailableSpace() + { + return getMaxGas() - getStored(); + } + + public void addAmount(int amount) + { + setAmount(getStored() + amount); + } + + public int getMaxGas() + { + return this.capacity; + } + + public void setCapacity(int capacity) + { + this.capacity = capacity; + if (getStored() > capacity) { + setAmount(capacity); + } + } + + @Optional.Method(modid="MekanismAPI|gas") + public int receive(GasStack resource, boolean doReceive) + { + if ((resource == null) || (resource.getGas().getID() < 0)) { + return 0; + } + if ((this.stored == null) || (this.stored.getGas().getID() < 0)) + { + if (resource.amount <= this.capacity) + { + if (doReceive) { + setGas(resource.copy()); + } + return resource.amount; + } + if (doReceive) + { + this.stored = resource.copy(); + this.stored.amount = this.capacity; + } + return this.capacity; + } + if (!this.stored.isGasEqual(resource)) { + return 0; + } + int space = this.capacity - this.stored.amount; + if (resource.amount <= space) + { + if (doReceive) { + addAmount(resource.amount); + } + return resource.amount; + } + if (doReceive) { + this.stored.amount = this.capacity; + } + return space; + } + + @Optional.Method(modid="MekanismAPI|gas") + public GasStack draw(int maxDrain, boolean doDraw) + { + if ((this.stored == null) || (this.stored.getGas().getID() < 0)) { + return null; + } + if (this.stored.amount <= 0) { + return null; + } + int used = maxDrain; + if (this.stored.amount < used) { + used = this.stored.amount; + } + if (doDraw) { + addAmount(-used); + } + GasStack drained = new GasStack(this.stored.getGas().getID(), used); + if (this.stored.amount < 0) { + this.stored.amount = 0; + } + return drained; + } + + public String getGasName() + { + return this.stored != null ? this.stored.getGas().getLocalizedName() : null; + } + + public boolean containsValidGas() + { + return GasUtil.isGasValid(this.stored); + } + + public NBTTagCompound write(NBTTagCompound nbt) + { + if (containsValidGas()) { + this.stored.write(nbt); + } else { + nbt.setBoolean("emptyGasTank", true); + } + return nbt; + } + + public void read(NBTTagCompound nbt) + { + if (!nbt.hasKey("emptyGasTank")) + { + GasStack gas = GasStack.readFromNBT(nbt); + if (gas != null) { + setGas(gas); + } + } + } + + public boolean isEmpty() + { + return (this.stored == null) || (this.stored.amount == 0); + } +} diff --git a/src/Java/miscutil/enderio/conduit/gas/GasConduit.java b/src/Java/miscutil/enderio/conduit/gas/GasConduit.java new file mode 100644 index 0000000000..7f34570853 --- /dev/null +++ b/src/Java/miscutil/enderio/conduit/gas/GasConduit.java @@ -0,0 +1,278 @@ +package crazypants.enderio.conduit.gas; + +import com.enderio.core.client.render.IconUtil; +import com.enderio.core.client.render.IconUtil.IIconProvider; +import com.enderio.core.common.util.BlockCoord; +import cpw.mods.fml.common.Optional.Method; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import crazypants.enderio.EnderIO; +import crazypants.enderio.conduit.AbstractConduitNetwork; +import crazypants.enderio.conduit.ConnectionMode; +import crazypants.enderio.conduit.IConduit; +import crazypants.enderio.conduit.IConduitBundle; +import crazypants.enderio.conduit.geom.CollidableComponent; +import crazypants.enderio.config.Config; +import java.util.HashMap; +import java.util.Map; +import mekanism.api.gas.Gas; +import mekanism.api.gas.GasStack; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +public class GasConduit + extends AbstractGasTankConduit +{ + public static final int CONDUIT_VOLUME = 1000; + public static final String ICON_KEY = "enderio:gasConduit"; + public static final String ICON_CORE_KEY = "enderio:gasConduitCore"; + public static final String ICON_EXTRACT_KEY = "enderio:gasConduitInput"; + public static final String ICON_INSERT_KEY = "enderio:gasConduitOutput"; + public static final String ICON_EMPTY_EDGE = "enderio:gasConduitEdge"; + static final Map ICONS = new HashMap(); + private GasConduitNetwork network; + + @SideOnly(Side.CLIENT) + public static void initIcons() + { + IconUtil.addIconProvider(new IconUtil.IIconProvider() + { + public void registerIcons(IIconRegister register) + { + GasConduit.ICONS.put("enderio:gasConduit", register.registerIcon("enderio:gasConduit")); + GasConduit.ICONS.put("enderio:gasConduitCore", register.registerIcon("enderio:gasConduitCore")); + GasConduit.ICONS.put("enderio:gasConduitInput", register.registerIcon("enderio:gasConduitInput")); + GasConduit.ICONS.put("enderio:gasConduitOutput", register.registerIcon("enderio:gasConduitOutput")); + GasConduit.ICONS.put("enderio:gasConduitEdge", register.registerIcon("enderio:gasConduitEdge")); + } + + public int getTextureType() + { + return 0; + } + }); + } + + private long ticksSinceFailedExtract = 0L; + public static final int MAX_EXTRACT_PER_TICK = Config.gasConduitExtractRate; + public static final int MAX_IO_PER_TICK = Config.gasConduitMaxIoRate; + + public GasConduit() + { + updateTank(); + } + + public void updateEntity(World world) + { + super.updateEntity(world); + if (world.isRemote) { + return; + } + doExtract(); + if (this.stateDirty) + { + getBundle().dirty(); + this.stateDirty = false; + } + } + + private void doExtract() + { + BlockCoord loc = getLocation(); + if (!hasConnectionMode(ConnectionMode.INPUT)) { + return; + } + if (this.network == null) { + return; + } + this.ticksSinceFailedExtract += 1L; + if ((this.ticksSinceFailedExtract > 25L) && (this.ticksSinceFailedExtract % 10L != 0L)) { + return; + } + Gas f = this.tank.getGas() == null ? null : this.tank.getGas().getGas(); + for (ForgeDirection dir : this.externalConnections) { + if ((autoExtractForDir(dir)) && + (this.network.extractFrom(this, dir, MAX_EXTRACT_PER_TICK))) { + this.ticksSinceFailedExtract = 0L; + } + } + } + + protected void updateTank() + { + this.tank.setCapacity(1000); + if (this.network != null) { + this.network.updateConduitVolumes(); + } + } + + public ItemStack createItem() + { + return new ItemStack(EnderIO.itemGasConduit); + } + + public AbstractConduitNetwork getNetwork() + { + return this.network; + } + + public boolean setNetwork(AbstractConduitNetwork network) + { + if (network == null) + { + this.network = null; + return true; + } + if (!(network instanceof GasConduitNetwork)) { + return false; + } + GasConduitNetwork n = (GasConduitNetwork)network; + if (this.tank.getGas() == null) { + this.tank.setGas(n.getGasType() == null ? null : n.getGasType().copy()); + } else if (n.getGasType() == null) { + n.setGasType(this.tank.getGas()); + } else if (!this.tank.getGas().isGasEqual(n.getGasType())) { + return false; + } + this.network = n; + return true; + } + + public boolean canConnectToConduit(ForgeDirection direction, IConduit con) + { + if (!super.canConnectToConduit(direction, con)) { + return false; + } + if (!(con instanceof GasConduit)) { + return false; + } + if ((getGasType() != null) && (((GasConduit)con).getGasType() == null)) { + return false; + } + return GasConduitNetwork.areGassCompatable(getGasType(), ((GasConduit)con).getGasType()); + } + + public void setConnectionMode(ForgeDirection dir, ConnectionMode mode) + { + super.setConnectionMode(dir, mode); + refreshInputs(dir); + } + + private void refreshInputs(ForgeDirection dir) + { + if (this.network == null) { + return; + } + GasOutput lo = new GasOutput(getLocation().getLocation(dir), dir.getOpposite()); + this.network.removeInput(lo); + if ((getConnectionMode(dir).acceptsOutput()) && (containsExternalConnection(dir))) { + this.network.addInput(lo); + } + } + + public void externalConnectionAdded(ForgeDirection fromDirection) + { + super.externalConnectionAdded(fromDirection); + refreshInputs(fromDirection); + } + + public void externalConnectionRemoved(ForgeDirection fromDirection) + { + super.externalConnectionRemoved(fromDirection); + refreshInputs(fromDirection); + } + + public IIcon getTextureForState(CollidableComponent component) + { + if (component.dir == ForgeDirection.UNKNOWN) { + return (IIcon)ICONS.get("enderio:gasConduitCore"); + } + return (IIcon)ICONS.get("enderio:gasConduit"); + } + + public IIcon getTextureForInputMode() + { + return (IIcon)ICONS.get("enderio:gasConduitInput"); + } + + public IIcon getTextureForOutputMode() + { + return (IIcon)ICONS.get("enderio:gasConduitOutput"); + } + + public IIcon getNotSetEdgeTexture() + { + return (IIcon)ICONS.get("enderio:gasConduitEdge"); + } + + public IIcon getTransmitionTextureForState(CollidableComponent component) + { + if ((isActive()) && (this.tank.containsValidGas())) { + return this.tank.getGas().getGas().getIcon(); + } + return null; + } + + @Deprecated + @Optional.Method(modid="MekanismAPI|gas") + public int receiveGas(ForgeDirection side, GasStack stack) + { + return receiveGas(side, stack, true); + } + + @Optional.Method(modid="MekanismAPI|gas") + public int receiveGas(ForgeDirection side, GasStack stack, boolean doTransfer) + { + if ((this.network == null) || (!getConnectionMode(side).acceptsInput())) { + return 0; + } + return this.network.fill(side, stack, doTransfer); + } + + @Deprecated + @Optional.Method(modid="MekanismAPI|gas") + public GasStack drawGas(ForgeDirection side, int amount) + { + return drawGas(side, amount, true); + } + + @Optional.Method(modid="MekanismAPI|gas") + public GasStack drawGas(ForgeDirection side, int amount, boolean doTransfer) + { + if ((this.network == null) || (!getConnectionMode(side).acceptsOutput())) { + return null; + } + return this.network.drain(side, amount, doTransfer); + } + + @Optional.Method(modid="MekanismAPI|gas") + public boolean canReceiveGas(ForgeDirection from, Gas gas) + { + if (this.network == null) { + return false; + } + return (getConnectionMode(from).acceptsInput()) && (GasConduitNetwork.areGassCompatable(getGasType(), new GasStack(gas, 0))); + } + + @Optional.Method(modid="MekanismAPI|gas") + public boolean canDrawGas(ForgeDirection from, Gas gas) + { + if (this.network == null) { + return false; + } + return (getConnectionMode(from).acceptsOutput()) && (GasConduitNetwork.areGassCompatable(getGasType(), new GasStack(gas, 0))); + } + + protected boolean canJoinNeighbour(IGasConduit n) + { + return n instanceof GasConduit; + } + + public AbstractGasTankConduitNetwork getTankNetwork() + { + return this.network; + } +} diff --git a/src/Java/miscutil/enderio/conduit/gas/GasConduitNetwork.java b/src/Java/miscutil/enderio/conduit/gas/GasConduitNetwork.java new file mode 100644 index 0000000000..79990c6959 --- /dev/null +++ b/src/Java/miscutil/enderio/conduit/gas/GasConduitNetwork.java @@ -0,0 +1,280 @@ +package crazypants.enderio.conduit.gas; + +import com.enderio.core.common.util.BlockCoord; +import crazypants.enderio.conduit.ConnectionMode; +import crazypants.enderio.conduit.IConduit; +import crazypants.enderio.conduit.IConduitBundle; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import mekanism.api.gas.GasStack; +import mekanism.api.gas.IGasHandler; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +public class GasConduitNetwork + extends AbstractGasTankConduitNetwork +{ + private final ConduitGasTank tank = new ConduitGasTank(0); + private final Set outputs = new HashSet(); + private Iterator outputIterator; + private int ticksActiveUnsynced; + private boolean lastSyncedActive = false; + private int lastSyncedVolume = -1; + + public GasConduitNetwork() + { + super(GasConduit.class); + } + + public void addConduit(GasConduit con) + { + this.tank.setCapacity(this.tank.getMaxGas() + 1000); + if (con.getTank().containsValidGas()) { + this.tank.addAmount(con.getTank().getStored()); + } + for (ForgeDirection dir : con.getExternalConnections()) { + if (con.getConnectionMode(dir).acceptsOutput()) { + this.outputs.add(new GasOutput(con.getLocation().getLocation(dir), dir.getOpposite())); + } + } + this.outputIterator = null; + super.addConduit(con); + } + + public boolean setGasType(GasStack newType) + { + if (super.setGasType(newType)) + { + GasStack ft = getGasType(); + this.tank.setGas(ft == null ? null : ft.copy()); + return true; + } + return false; + } + + public void destroyNetwork() + { + setConduitVolumes(); + this.outputs.clear(); + super.destroyNetwork(); + } + + private void setConduitVolumes() + { + GasStack gasPerConduit; + int leftOvers; + if ((this.tank.containsValidGas()) && (!this.conduits.isEmpty())) + { + gasPerConduit = this.tank.getGas().copy(); + int numCons = this.conduits.size(); + leftOvers = gasPerConduit.amount % numCons; + gasPerConduit.amount /= numCons; + for (GasConduit con : this.conduits) + { + GasStack f = gasPerConduit.copy(); + if (leftOvers > 0) + { + f.amount += 1; + leftOvers--; + } + con.getTank().setGas(f); + BlockCoord bc = con.getLocation(); + con.getBundle().getEntity().getWorldObj().markTileEntityChunkModified(bc.x, bc.y, bc.z, con.getBundle().getEntity()); + } + } + } + + public void doNetworkTick() + { + if ((this.gasType == null) || (this.outputs.isEmpty()) || (!this.tank.containsValidGas()) || (this.tank.isEmpty())) + { + updateActiveState(); + return; + } + if ((this.outputIterator == null) || (!this.outputIterator.hasNext())) { + this.outputIterator = this.outputs.iterator(); + } + updateActiveState(); + + int numVisited = 0; + while ((!this.tank.isEmpty()) && (numVisited < this.outputs.size())) + { + if (!this.outputIterator.hasNext()) { + this.outputIterator = this.outputs.iterator(); + } + GasOutput output = (GasOutput)this.outputIterator.next(); + if (output != null) + { + IGasHandler cont = getTankContainer(output.location); + if (cont != null) + { + GasStack offer = this.tank.getGas().copy(); + int filled = cont.receiveGas(output.dir, offer); + if (filled > 0) { + this.tank.addAmount(-filled); + } + } + } + numVisited++; + } + } + + private void updateActiveState() + { + boolean isActive = (this.tank.containsValidGas()) && (!this.tank.isEmpty()); + if (this.lastSyncedActive != isActive) { + this.ticksActiveUnsynced += 1; + } else { + this.ticksActiveUnsynced = 0; + } + if ((this.ticksActiveUnsynced >= 10) || ((this.ticksActiveUnsynced > 0) && (isActive))) + { + if (!isActive) { + setGasType(null); + } + for (IConduit con : this.conduits) { + con.setActive(isActive); + } + this.lastSyncedActive = isActive; + this.ticksActiveUnsynced = 0; + } + } + + public int fill(ForgeDirection from, GasStack resource, boolean doFill) + { + if (resource == null) { + return 0; + } + resource.amount = Math.min(resource.amount, GasConduit.MAX_IO_PER_TICK); + boolean gasWasValid = this.tank.containsValidGas(); + int res = this.tank.receive(resource, doFill); + if ((doFill) && (res > 0) && (gasWasValid)) + { + int vol = this.tank.getStored(); + setGasType(resource); + this.tank.setAmount(vol); + } + return res; + } + + public GasStack drain(ForgeDirection from, GasStack resource, boolean doDrain) + { + if ((resource == null) || (this.tank.isEmpty()) || (!this.tank.containsValidGas()) || (!areGassCompatable(getGasType(), resource))) { + return null; + } + int amount = Math.min(resource.amount, this.tank.getStored()); + amount = Math.min(amount, GasConduit.MAX_IO_PER_TICK); + GasStack result = resource.copy(); + result.amount = amount; + if (doDrain) { + this.tank.addAmount(-amount); + } + return result; + } + + public GasStack drain(ForgeDirection from, int maxDrain, boolean doDrain) + { + if ((this.tank.isEmpty()) || (!this.tank.containsValidGas())) { + return null; + } + int amount = Math.min(maxDrain, this.tank.getStored()); + GasStack result = this.tank.getGas().copy(); + result.amount = amount; + if (doDrain) { + this.tank.addAmount(-amount); + } + return result; + } + + public boolean extractFrom(GasConduit advancedGasConduit, ForgeDirection dir, int maxExtractPerTick) + { + if (this.tank.isFull()) { + return false; + } + IGasHandler extTank = getTankContainer(advancedGasConduit, dir); + if (extTank != null) + { + int maxExtract = Math.min(maxExtractPerTick, this.tank.getAvailableSpace()); + if ((this.gasType == null) || (!this.tank.containsValidGas())) + { + GasStack drained = extTank.drawGas(dir.getOpposite(), maxExtract); + if ((drained == null) || (drained.amount <= 0)) { + return false; + } + setGasType(drained); + this.tank.setGas(drained.copy()); + return true; + } + GasStack couldDrain = this.gasType.copy(); + couldDrain.amount = maxExtract; + + + + + + + + + GasStack drained = extTank.drawGas(dir.getOpposite(), maxExtract); + if ((drained == null) || (drained.amount == 0)) { + return false; + } + if (drained.isGasEqual(getGasType())) { + this.tank.addAmount(drained.amount); + } + return true; + } + return false; + } + + public IGasHandler getTankContainer(BlockCoord bc) + { + World w = getWorld(); + if (w == null) { + return null; + } + TileEntity te = w.getTileEntity(bc.x, bc.y, bc.z); + if ((te instanceof IGasHandler)) { + return (IGasHandler)te; + } + return null; + } + + public IGasHandler getTankContainer(GasConduit con, ForgeDirection dir) + { + BlockCoord bc = con.getLocation().getLocation(dir); + return getTankContainer(bc); + } + + World getWorld() + { + if (this.conduits.isEmpty()) { + return null; + } + return ((GasConduit)this.conduits.get(0)).getBundle().getWorld(); + } + + public void removeInput(GasOutput lo) + { + this.outputs.remove(lo); + this.outputIterator = null; + } + + public void addInput(GasOutput lo) + { + this.outputs.add(lo); + this.outputIterator = null; + } + + public void updateConduitVolumes() + { + if (this.tank.getStored() == this.lastSyncedVolume) { + return; + } + setConduitVolumes(); + this.lastSyncedVolume = this.tank.getStored(); + } +} diff --git a/src/Java/miscutil/enderio/conduit/gas/GasConduitRenderer.java b/src/Java/miscutil/enderio/conduit/gas/GasConduitRenderer.java new file mode 100644 index 0000000000..4bb0a2eb1c --- /dev/null +++ b/src/Java/miscutil/enderio/conduit/gas/GasConduitRenderer.java @@ -0,0 +1,178 @@ +package crazypants.enderio.conduit.gas; + +import com.enderio.core.client.render.BoundingBox; +import com.enderio.core.client.render.CubeRenderer; +import com.enderio.core.client.render.RenderUtil; +import com.enderio.core.common.vecmath.Vector2f; +import com.enderio.core.common.vecmath.Vector3d; +import com.enderio.core.common.vecmath.Vertex; +import crazypants.enderio.EnderIO; +import crazypants.enderio.conduit.BlockConduitBundle; +import crazypants.enderio.conduit.ConnectionMode; +import crazypants.enderio.conduit.IConduit; +import crazypants.enderio.conduit.IConduitBundle; +import crazypants.enderio.conduit.geom.CollidableComponent; +import crazypants.enderio.conduit.geom.ConnectionModeGeometry; +import crazypants.enderio.conduit.geom.Offset; +import crazypants.enderio.conduit.render.ConduitBundleRenderer; +import crazypants.enderio.conduit.render.DefaultConduitRenderer; +import java.util.List; +import mekanism.api.gas.Gas; +import mekanism.api.gas.GasStack; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.IIcon; +import net.minecraftforge.common.util.ForgeDirection; + +public class GasConduitRenderer + extends DefaultConduitRenderer +{ + public boolean isRendererForConduit(IConduit conduit) + { + return conduit instanceof GasConduit; + } + + public void renderEntity(ConduitBundleRenderer conduitBundleRenderer, IConduitBundle te, IConduit conduit, double x, double y, double z, float partialTick, float worldLight, RenderBlocks rb) + { + super.renderEntity(conduitBundleRenderer, te, conduit, x, y, z, partialTick, worldLight, rb); + if ((!conduit.hasConnectionMode(ConnectionMode.INPUT)) && (!conduit.hasConnectionMode(ConnectionMode.OUTPUT))) { + return; + } + GasConduit pc = (GasConduit)conduit; + for (ForgeDirection dir : conduit.getExternalConnections()) + { + IIcon tex = null; + if (conduit.getConnectionMode(dir) == ConnectionMode.INPUT) { + tex = pc.getTextureForInputMode(); + } else if (conduit.getConnectionMode(dir) == ConnectionMode.OUTPUT) { + tex = pc.getTextureForOutputMode(); + } + if (tex != null) + { + Offset offset = te.getOffset(IGasConduit.class, dir); + ConnectionModeGeometry.renderModeConnector(dir, offset, tex, true); + } + } + } + + protected void renderConduit(IIcon tex, IConduit conduit, CollidableComponent component, float brightness) + { + super.renderConduit(tex, conduit, component, brightness); + if (isNSEWUD(component.dir)) + { + GasConduit lc = (GasConduit)conduit; + + GasStack gas = lc.getGasType(); + IIcon texture = null; + if (gas != null) { + texture = gas.getGas().getIcon(); + } + if (texture == null) { + texture = lc.getNotSetEdgeTexture(); + } + float scaleFactor = 0.75F; + float xLen = Math.abs(component.dir.offsetX) == 1 ? 1.0F : scaleFactor; + float yLen = Math.abs(component.dir.offsetY) == 1 ? 1.0F : scaleFactor; + float zLen = Math.abs(component.dir.offsetZ) == 1 ? 1.0F : scaleFactor; + + BoundingBox cube = component.bound; + BoundingBox bb = cube.scale(xLen, yLen, zLen); + for (ForgeDirection d : ForgeDirection.VALID_DIRECTIONS) { + if ((d != component.dir) && (d != component.dir.getOpposite())) + { + ForgeDirection vDir = RenderUtil.getVDirForFace(d); + if ((component.dir == ForgeDirection.UP) || (component.dir == ForgeDirection.DOWN)) { + vDir = RenderUtil.getUDirForFace(d); + } else if (((component.dir == ForgeDirection.NORTH) || (component.dir == ForgeDirection.SOUTH)) && (d.offsetY != 0)) { + vDir = RenderUtil.getUDirForFace(d); + } + float minU = texture.getMinU(); + float maxU = texture.getMaxU(); + float minV = texture.getMinV(); + float maxV = texture.getMaxV(); + + float sideScale = Math.max(bb.sizeX(), bb.sizeY()) * 2.0F / 16.0F; + sideScale = Math.max(sideScale, bb.sizeZ() * 2.0F / 16.0F); + float width = Math.min(bb.sizeX(), bb.sizeY()) * 15.0F / 16.0F; + + List corners = bb.getCornersWithUvForFace(d, minU, maxU, minV, maxV); + moveEdgeCorners(corners, vDir, width); + moveEdgeCorners(corners, component.dir.getOpposite(), sideScale); + for (Vertex c : corners) { + CubeRenderer.addVecWithUV(c.xyz, c.uv.x, c.uv.y); + } + corners = bb.getCornersWithUvForFace(d, minU, maxU, minV, maxV); + moveEdgeCorners(corners, vDir.getOpposite(), width); + moveEdgeCorners(corners, component.dir.getOpposite(), sideScale); + for (Vertex c : corners) { + CubeRenderer.addVecWithUV(c.xyz, c.uv.x, c.uv.y); + } + } + } + if (conduit.getConnectionMode(component.dir) == ConnectionMode.DISABLED) + { + tex = EnderIO.blockConduitBundle.getConnectorIcon(component.data); + Object corners = component.bound.getCornersWithUvForFace(component.dir, tex.getMinU(), tex.getMaxU(), tex.getMinV(), tex.getMaxV()); + Tessellator tessellator = Tessellator.instance; + for (Vertex c : (List)corners) { + CubeRenderer.addVecWithUV(c.xyz, c.uv.x, c.uv.y); + } + for (int i = ((List)corners).size() - 1; i >= 0; i--) + { + Vertex c = (Vertex)((List)corners).get(i); + CubeRenderer.addVecWithUV(c.xyz, c.uv.x, c.uv.y); + } + } + } + } + + protected void renderTransmission(IConduit conduit, IIcon tex, CollidableComponent component, float selfIllum) + { + super.renderTransmission(conduit, tex, component, selfIllum); + } + + private void moveEdgeCorners(List vertices, ForgeDirection edge, float scaleFactor) + { + int[] indices = getClosest(edge, vertices); + ((Vertex)vertices.get(indices[0])).xyz.x -= scaleFactor * edge.offsetX; + ((Vertex)vertices.get(indices[1])).xyz.x -= scaleFactor * edge.offsetX; + ((Vertex)vertices.get(indices[0])).xyz.y -= scaleFactor * edge.offsetY; + ((Vertex)vertices.get(indices[1])).xyz.y -= scaleFactor * edge.offsetY; + ((Vertex)vertices.get(indices[0])).xyz.z -= scaleFactor * edge.offsetZ; + ((Vertex)vertices.get(indices[1])).xyz.z -= scaleFactor * edge.offsetZ; + } + + private int[] getClosest(ForgeDirection edge, List vertices) + { + int[] res = { -1, -1 }; + boolean highest = (edge.offsetX > 0) || (edge.offsetY > 0) || (edge.offsetZ > 0); + double minMax = highest ? -1.797693134862316E+308D : 1.7976931348623157E+308D; + int index = 0; + for (Vertex v : vertices) + { + double val = get(v.xyz, edge); + if (highest ? val >= minMax : val <= minMax) + { + if (val != minMax) { + res[0] = index; + } else { + res[1] = index; + } + minMax = val; + } + index++; + } + return res; + } + + private double get(Vector3d xyz, ForgeDirection edge) + { + if ((edge == ForgeDirection.EAST) || (edge == ForgeDirection.WEST)) { + return xyz.x; + } + if ((edge == ForgeDirection.UP) || (edge == ForgeDirection.DOWN)) { + return xyz.y; + } + return xyz.z; + } +} diff --git a/src/Java/miscutil/enderio/conduit/gas/GasOutput.java b/src/Java/miscutil/enderio/conduit/gas/GasOutput.java new file mode 100644 index 0000000000..02bb4e71dd --- /dev/null +++ b/src/Java/miscutil/enderio/conduit/gas/GasOutput.java @@ -0,0 +1,57 @@ +package crazypants.enderio.conduit.gas; + +import com.enderio.core.common.util.BlockCoord; +import net.minecraftforge.common.util.ForgeDirection; + +public class GasOutput +{ + final ForgeDirection dir; + final BlockCoord location; + + public GasOutput(BlockCoord bc, ForgeDirection dir) + { + this.dir = dir; + this.location = bc; + } + + public int hashCode() + { + int prime = 31; + int result = 1; + result = 31 * result + (this.location == null ? 0 : this.location.hashCode()); + result = 31 * result + (this.dir == null ? 0 : this.dir.hashCode()); + return result; + } + + public boolean equals(Object obj) + { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + GasOutput other = (GasOutput)obj; + if (this.location == null) + { + if (other.location != null) { + return false; + } + } + else if (!this.location.equals(other.location)) { + return false; + } + if (this.dir != other.dir) { + return false; + } + return true; + } + + public String toString() + { + return "GasOutput [dir=" + this.dir + ", location=" + this.location + "]"; + } +} diff --git a/src/Java/miscutil/enderio/conduit/gas/GasUtil.java b/src/Java/miscutil/enderio/conduit/gas/GasUtil.java new file mode 100644 index 0000000000..1ccadc9485 --- /dev/null +++ b/src/Java/miscutil/enderio/conduit/gas/GasUtil.java @@ -0,0 +1,75 @@ +package crazypants.enderio.conduit.gas; + +import com.enderio.core.common.util.BlockCoord; +import cpw.mods.fml.common.ModAPIManager; +import cpw.mods.fml.common.Optional.Method; +import crazypants.enderio.conduit.IConduitBundle; +import crazypants.enderio.config.Config; +import mekanism.api.gas.Gas; +import mekanism.api.gas.GasStack; +import mekanism.api.gas.IGasHandler; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.IBlockAccess; + +public final class GasUtil +{ + private static boolean useCheckPerformed = false; + private static boolean isGasConduitEnabled = false; + public static final String API_NAME = "MekanismAPI|gas"; + + public static boolean isGasConduitEnabled() + { + if (!useCheckPerformed) + { + if (Config.isGasConduitEnabled) { + isGasConduitEnabled = ModAPIManager.INSTANCE.hasAPI("MekanismAPI|gas"); + } else { + isGasConduitEnabled = false; + } + useCheckPerformed = true; + } + return isGasConduitEnabled; + } + + @Optional.Method(modid="MekanismAPI|gas") + public static IGasHandler getExternalGasHandler(IBlockAccess world, BlockCoord bc) + { + IGasHandler con = getGasHandler(world, bc); + return (con != null) && (!(con instanceof IConduitBundle)) ? con : null; + } + + @Optional.Method(modid="MekanismAPI|gas") + public static IGasHandler getGasHandler(IBlockAccess world, BlockCoord bc) + { + return getGasHandler(world, bc.x, bc.y, bc.z); + } + + @Optional.Method(modid="MekanismAPI|gas") + public static IGasHandler getGasHandler(IBlockAccess world, int x, int y, int z) + { + TileEntity te = world.getTileEntity(x, y, z); + return getGasHandler(te); + } + + @Optional.Method(modid="MekanismAPI|gas") + public static IGasHandler getGasHandler(TileEntity te) + { + if ((te instanceof IGasHandler)) { + return (IGasHandler)te; + } + return null; + } + + @Optional.Method(modid="MekanismAPI|gas") + public static boolean isGasValid(GasStack gas) + { + if (gas != null) + { + String name = gas.getGas().getLocalizedName(); + if ((name != null) && (!name.trim().isEmpty())) { + return true; + } + } + return false; + } +} diff --git a/src/Java/miscutil/enderio/conduit/gas/IGasConduit.java b/src/Java/miscutil/enderio/conduit/gas/IGasConduit.java new file mode 100644 index 0000000000..f41f6ba9fc --- /dev/null +++ b/src/Java/miscutil/enderio/conduit/gas/IGasConduit.java @@ -0,0 +1,16 @@ +package crazypants.enderio.conduit.gas; + +import cpw.mods.fml.common.Optional.Interface; +import crazypants.enderio.conduit.IConduit; +import crazypants.enderio.conduit.IExtractor; +import mekanism.api.gas.IGasHandler; +import net.minecraftforge.common.util.ForgeDirection; + +@Optional.Interface(iface="mekanism.api.gas.IGasHandler", modid="MekanismAPI|gas") +public abstract interface IGasConduit + extends IConduit, IGasHandler, IExtractor +{ + public abstract boolean canOutputToDir(ForgeDirection paramForgeDirection); + + public abstract boolean isExtractingFromDir(ForgeDirection paramForgeDirection); +} diff --git a/src/Java/miscutil/enderio/conduit/gas/ItemGasConduit.java b/src/Java/miscutil/enderio/conduit/gas/ItemGasConduit.java new file mode 100644 index 0000000000..df9fe0844b --- /dev/null +++ b/src/Java/miscutil/enderio/conduit/gas/ItemGasConduit.java @@ -0,0 +1,73 @@ +package crazypants.enderio.conduit.gas; + +import com.enderio.core.api.client.gui.IAdvancedTooltipProvider; +import com.enderio.core.client.handlers.SpecialTooltipHandler; +import com.enderio.core.common.Lang; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import crazypants.enderio.EnderIO; +import crazypants.enderio.ModObject; +import crazypants.enderio.conduit.AbstractItemConduit; +import crazypants.enderio.conduit.IConduit; +import crazypants.enderio.conduit.ItemConduitSubtype; +import crazypants.enderio.config.Config; +import java.util.List; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +public class ItemGasConduit + extends AbstractItemConduit + implements IAdvancedTooltipProvider +{ + private static ItemConduitSubtype[] subtypes = { new ItemConduitSubtype(ModObject.itemGasConduit + .name(), "enderio:itemGasConduit") }; + + public static ItemGasConduit create() + { + ItemGasConduit result = new ItemGasConduit(); + if (GasUtil.isGasConduitEnabled()) { + result.init(); + } + return result; + } + + protected ItemGasConduit() + { + super(ModObject.itemGasConduit, subtypes); + if (!GasUtil.isGasConduitEnabled()) { + setCreativeTab(null); + } + } + + public Class getBaseConduitType() + { + return IGasConduit.class; + } + + public IConduit createConduit(ItemStack stack, EntityPlayer player) + { + return new GasConduit(); + } + + @SideOnly(Side.CLIENT) + public void addCommonEntries(ItemStack itemstack, EntityPlayer entityplayer, List list, boolean flag) {} + + @SideOnly(Side.CLIENT) + public void addBasicEntries(ItemStack itemstack, EntityPlayer entityplayer, List list, boolean flag) {} + + @SideOnly(Side.CLIENT) + public void addDetailedEntries(ItemStack itemstack, EntityPlayer entityplayer, List list, boolean flag) + { + String gpt = " " + EnderIO.lang.localize("gas.gasTick"); + int extractRate = Config.gasConduitExtractRate; + int maxIo = Config.gasConduitMaxIoRate; + list.add(EnderIO.lang.localize("itemGasConduit.tooltip.maxExtract") + " " + extractRate + gpt); + list.add(EnderIO.lang.localize("itemGasConduit.tooltip.maxIo") + " " + maxIo + gpt); + SpecialTooltipHandler.addDetailedTooltipFromResources(list, "enderio.itemGasConduit"); + } + + public boolean shouldHideFacades(ItemStack stack, EntityPlayer player) + { + return true; + } +} diff --git a/src/Java/miscutil/enderio/conduit/gas/PacketGasLevel.java b/src/Java/miscutil/enderio/conduit/gas/PacketGasLevel.java new file mode 100644 index 0000000000..0e1b96313c --- /dev/null +++ b/src/Java/miscutil/enderio/conduit/gas/PacketGasLevel.java @@ -0,0 +1,46 @@ +package crazypants.enderio.conduit.gas; + +import com.enderio.core.common.network.MessageTileEntity; +import cpw.mods.fml.common.network.ByteBufUtils; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import crazypants.enderio.conduit.IConduitBundle; +import crazypants.util.ClientUtil; +import io.netty.buffer.ByteBuf; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; + +public class PacketGasLevel + extends MessageTileEntity + implements IMessageHandler +{ + public NBTTagCompound tc; + + public PacketGasLevel() {} + + public PacketGasLevel(IGasConduit conduit) + { + super(conduit.getBundle().getEntity()); + this.tc = new NBTTagCompound(); + conduit.writeToNBT(this.tc); + } + + public void toBytes(ByteBuf buf) + { + super.toBytes(buf); + ByteBufUtils.writeTag(buf, this.tc); + } + + public void fromBytes(ByteBuf buf) + { + super.fromBytes(buf); + this.tc = ByteBufUtils.readTag(buf); + } + + public IMessage onMessage(PacketGasLevel message, MessageContext ctx) + { + ClientUtil.doGasLevelUpdate(message.x, message.y, message.z, message); + return null; + } +} -- cgit