diff --git a/gradle.properties b/gradle.properties index d1f51dd..13c5cc8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ minecraft_version=1.7.10 forge_version=10.13.4.1492-1.7.10 forgeDep_version=10.13.4 -mod_version=0.2.1 +mod_version=0.3.0 #Comment out this line to get rid of the appendix mod_appendix=beta @@ -13,7 +13,7 @@ ccc_version=1.0.7.46 ccl_version=1.1.3.138 ae2_version=rv1-stable-1 endercore_version=1.7.10-0.1.0.25_beta -enderio_version=1.7.10-2.3.0.416_beta +enderio_version=1.7.10-2.3.0.417_beta forestry_version=forestry_1.7.10:3.6.2.19 waterhooks_version=1.1.2 diff --git a/src/main/java/info/loenwind/enderioaddons/common/GuiIds.java b/src/main/java/info/loenwind/enderioaddons/common/GuiIds.java index 76efcf4..f9165dc 100644 --- a/src/main/java/info/loenwind/enderioaddons/common/GuiIds.java +++ b/src/main/java/info/loenwind/enderioaddons/common/GuiIds.java @@ -12,6 +12,7 @@ public class GuiIds { public static int GUI_ID_COBBLEWORKS = 0; public static int GUI_ID_WATERWORKS = 0; public static int GUI_ID_IHOPPER = 0; + public static int GUI_ID_NIARD = 0; private GuiIds() { } @@ -21,6 +22,7 @@ public static void compute_GUI_IDs() { GUI_ID_COBBLEWORKS = nextID(); GUI_ID_WATERWORKS = nextID(); GUI_ID_IHOPPER = nextID(); + GUI_ID_NIARD = nextID(); } private static int lastId = crazypants.enderio.GuiHandler.GUI_ID_CAP_BANK; diff --git a/src/main/java/info/loenwind/enderioaddons/config/Config.java b/src/main/java/info/loenwind/enderioaddons/config/Config.java index 8baae7d..f5468fe 100644 --- a/src/main/java/info/loenwind/enderioaddons/config/Config.java +++ b/src/main/java/info/loenwind/enderioaddons/config/Config.java @@ -63,6 +63,11 @@ public enum Config { impulseHopperEnabled(Section.RECIPES, true, "Enable the crafting recipe for the Impulse Hopper"), // + niardContinuousEnergyUseRF(Section.NIARD, 10, "The amount of power used by a niard per tick."), // + niardPerBucketEnergyUseRF(Section.NIARD, 400, "The amount of power used by a niard per 1000mB of liquid placed into the world."), // + + niardEnabled(Section.RECIPES, true, "Enable the crafting recipe for the Niard"), // + ; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/main/java/info/loenwind/enderioaddons/config/Section.java b/src/main/java/info/loenwind/enderioaddons/config/Section.java index 1608bb6..6ac0187 100644 --- a/src/main/java/info/loenwind/enderioaddons/config/Section.java +++ b/src/main/java/info/loenwind/enderioaddons/config/Section.java @@ -3,7 +3,7 @@ import javax.annotation.Nonnull; public enum Section { - DRAIN("drain"), COBBLEWORKS("cobbleworks"), WATERWORKS("waterworks"), RECIPES("recipes"), DEV("development"), IHOPPER("impulsehopper"); + DRAIN("drain"), COBBLEWORKS("cobbleworks"), WATERWORKS("waterworks"), RECIPES("recipes"), DEV("development"), IHOPPER("impulsehopper"), NIARD("niard"); @Nonnull public final String name; diff --git a/src/main/java/info/loenwind/enderioaddons/fluid/FluidType.java b/src/main/java/info/loenwind/enderioaddons/fluid/FluidType.java new file mode 100644 index 0000000..75ea65a --- /dev/null +++ b/src/main/java/info/loenwind/enderioaddons/fluid/FluidType.java @@ -0,0 +1,7 @@ +package info.loenwind.enderioaddons.fluid; + +public enum FluidType { + VANILLA, + CLASSIC, + FINITE +} \ No newline at end of file diff --git a/src/main/java/info/loenwind/enderioaddons/gui/StdSlot.java b/src/main/java/info/loenwind/enderioaddons/gui/StdSlot.java new file mode 100644 index 0000000..febb53e --- /dev/null +++ b/src/main/java/info/loenwind/enderioaddons/gui/StdSlot.java @@ -0,0 +1,17 @@ +package info.loenwind.enderioaddons.gui; + +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +public final class StdSlot extends Slot { + + public StdSlot(IInventory inventory, int slotIndex, int x, int y) { + super(inventory, slotIndex, x, y); + } + + @Override + public boolean isItemValid(ItemStack itemStack) { + return inventory.isItemValidForSlot(getSlotIndex(), itemStack); + } +} \ No newline at end of file diff --git a/src/main/java/info/loenwind/enderioaddons/machine/drain/FluidHelper.java b/src/main/java/info/loenwind/enderioaddons/machine/drain/FluidHelper.java index f838c93..a840c8a 100644 --- a/src/main/java/info/loenwind/enderioaddons/machine/drain/FluidHelper.java +++ b/src/main/java/info/loenwind/enderioaddons/machine/drain/FluidHelper.java @@ -2,6 +2,7 @@ import static info.loenwind.enderioaddons.common.NullHelper.notnull; import static info.loenwind.enderioaddons.common.NullHelper.notnullF; +import info.loenwind.enderioaddons.fluid.FluidType; import java.util.HashSet; import java.util.Set; @@ -37,7 +38,7 @@ public final class FluidHelper { @Nonnull private final ForgeDirection upflowDirection; @Nonnull - private final FType type; + private final FluidType type; @Nullable private final BlockCoord startbc; private IDrainingCallback hook; @@ -58,11 +59,11 @@ private FluidHelper(@Nonnull World world, @Nonnull FluidStack stack, @Nullable B this.downflowDirection = fluid.getDensity() > 0 ? ForgeDirection.DOWN : ForgeDirection.UP; this.upflowDirection = downflowDirection == ForgeDirection.UP ? ForgeDirection.DOWN : ForgeDirection.UP; if (this.block instanceof BlockFluidClassic) { - this.type = FType.CLASSIC; + this.type = FluidType.CLASSIC; } else if (this.block instanceof BlockFluidFinite) { - this.type = FType.FINITE; + this.type = FluidType.FINITE; } else if (this.block instanceof BlockLiquid) { - this.type = FType.VANILLA; + this.type = FluidType.VANILLA; } else { throw new Exception(); } @@ -146,12 +147,6 @@ public static FluidHelper getInstance(@Nonnull World world, @Nonnull FluidStack return getInstance(world, stack, null); } - private enum FType { - VANILLA, - CLASSIC, - FINITE - } - private static boolean isInWorld(@Nonnull BlockCoord bc) { return bc.y > 0 && bc.y <= 255; } diff --git a/src/main/java/info/loenwind/enderioaddons/machine/niard/BlockItemNiard.java b/src/main/java/info/loenwind/enderioaddons/machine/niard/BlockItemNiard.java new file mode 100644 index 0000000..b4cec9a --- /dev/null +++ b/src/main/java/info/loenwind/enderioaddons/machine/niard/BlockItemNiard.java @@ -0,0 +1,41 @@ +package info.loenwind.enderioaddons.machine.niard; + +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemBlockWithMetadata; +import net.minecraft.item.ItemStack; + +import com.enderio.core.api.client.gui.IAdvancedTooltipProvider; + +import crazypants.enderio.EnderIOTab; + +public class BlockItemNiard extends ItemBlockWithMetadata implements IAdvancedTooltipProvider { + + public BlockItemNiard() { + this(BlockNiard.blockNiard); + } + + public BlockItemNiard(Block block) { + super(block, block); + setHasSubtypes(false); + setCreativeTab(EnderIOTab.tabEnderIO); + } + + @Override + public void addCommonEntries(ItemStack itemstack, EntityPlayer entityplayer, List list, boolean flag) { + BlockNiard.blockNiard.addCommonEntries(itemstack, entityplayer, list, flag); + } + + @Override + public void addBasicEntries(ItemStack itemstack, EntityPlayer entityplayer, List list, boolean flag) { + BlockNiard.blockNiard.addBasicEntries(itemstack, entityplayer, list, flag); + } + + @Override + public void addDetailedEntries(ItemStack itemstack, EntityPlayer entityplayer, List list, boolean flag) { + BlockNiard.blockNiard.addDetailedEntries(itemstack, entityplayer, list, flag); + } + +} diff --git a/src/main/java/info/loenwind/enderioaddons/machine/niard/BlockNiard.java b/src/main/java/info/loenwind/enderioaddons/machine/niard/BlockNiard.java new file mode 100644 index 0000000..350d9c3 --- /dev/null +++ b/src/main/java/info/loenwind/enderioaddons/machine/niard/BlockNiard.java @@ -0,0 +1,230 @@ +package info.loenwind.enderioaddons.machine.niard; + +import info.loenwind.enderioaddons.EnderIOAddons; +import info.loenwind.enderioaddons.common.GuiIds; + +import java.util.List; +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IIcon; +import net.minecraft.util.MathHelper; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.common.util.EnumHelper; +import net.minecraftforge.fluids.FluidStack; + +import com.enderio.core.api.client.gui.IAdvancedTooltipProvider; +import com.enderio.core.client.handlers.SpecialTooltipHandler; + +import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import crazypants.enderio.ClientProxy; +import crazypants.enderio.EnderIO; +import crazypants.enderio.ModObject; +import crazypants.enderio.machine.AbstractMachineBlock; +import crazypants.enderio.machine.AbstractMachineEntity; +import crazypants.enderio.machine.power.PowerDisplayUtil; +import crazypants.enderio.network.PacketHandler; + +public class BlockNiard extends AbstractMachineBlock implements IAdvancedTooltipProvider { + + public static final ModObject ModObject_blockNiard = EnumHelper.addEnum(ModObject.class, "blockNiard", new Class[0], new Object[0]); + public static BlockNiard blockNiard; + public int localRenderId; + + public static BlockNiard create() { + PacketHandler.INSTANCE.registerMessage(PacketNiard.class, PacketNiard.class, PacketHandler.nextID(), Side.CLIENT); + blockNiard = new BlockNiard(); + blockNiard.init(); + return blockNiard; + } + + protected BlockNiard() { + super(ModObject_blockNiard, TileNiard.class); + setStepSound(Block.soundTypeGlass); + setLightOpacity(0); + setBlockName(name); + } + + @Override + protected void init() { + GameRegistry.registerBlock(this, BlockItemNiard.class, modObject.unlocalisedName); + GameRegistry.registerTileEntity(teClass, modObject.unlocalisedName + "TileEntity"); + EnderIO.guiHandler.registerGuiHandler(getGuiId(), this); + } + + @Override + public int damageDropped(int par1) { + return par1; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + @SideOnly(Side.CLIENT) + public void getSubBlocks(Item item, CreativeTabs p_149666_2_, List list) { + list.add(new ItemStack(this, 1, 0)); + } + + @Override + public TileEntity createTileEntity(World world, int metadata) { + return new TileNiard(); + } + + @Override + public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { + TileEntity te = world.getTileEntity(x, y, z); + if (!(te instanceof TileNiard)) { + return null; + } + return new ContainerNiard(player.inventory, (TileNiard) te); + } + + @Override + public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { + final TileEntity te = world.getTileEntity(x, y, z); + final InventoryPlayer inventory = player.inventory; + if (te instanceof TileNiard && inventory != null) { + return new GuiNiard(inventory, (TileNiard) te); + } + return null; + } + + @Override + public boolean isOpaqueCube() { + return false; + } + + @Override + protected int getGuiId() { + return GuiIds.GUI_ID_NIARD; + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(IBlockAccess world, int x, int y, int z, int blockSide) { + + // used to render the block in the world + TileEntity te = world.getTileEntity(x, y, z); + int facing = 0; + if (te instanceof AbstractMachineEntity) { + AbstractMachineEntity me = (AbstractMachineEntity) te; + facing = me.facing; + } + int meta = world.getBlockMetadata(x, y, z); + meta = MathHelper.clamp_int(meta, 0, 1); + if (meta == 1) { + return iconBuffer[0][ClientProxy.sideAndFacingToSpriteOffset[blockSide][facing] + 6]; + } else { + return iconBuffer[0][ClientProxy.sideAndFacingToSpriteOffset[blockSide][facing]]; + } + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(int blockSide, int blockMeta) { + int offset = MathHelper.clamp_int(blockMeta, 0, 1) == 0 ? 0 : 6; + return iconBuffer[0][blockSide + offset]; + } + + @Override + protected String getMachineFrontIconKey(boolean active) { + return EnderIOAddons.DOMAIN + ":blockNiardSide"; + } + + @Override + protected String getSideIconKey(boolean active) { + return getMachineFrontIconKey(active); + } + + @Override + protected String getBackIconKey(boolean active) { + return getMachineFrontIconKey(active); + } + + @Override + protected String getTopIconKey(boolean active) { + return EnderIOAddons.DOMAIN + ":blockNiard"; + } + + @Override + protected String getBottomIconKey(boolean active) { + return "enderio:machineTemplate"; + } + + @Override + @SideOnly(Side.CLIENT) + public void addCommonEntries(ItemStack itemstack, EntityPlayer entityplayer, List list, boolean flag) { + } + + @Override + public boolean hasComparatorInputOverride() { + return true; + } + + @Override + public int getComparatorInputOverride(World w, int x, int y, int z, int side) { + TileEntity te = w.getTileEntity(x, y, z); + if (te instanceof TileNiard) { + return ((TileNiard) te).getComparatorOutput(); + } + return 0; + } + + @Override + @SideOnly(Side.CLIENT) + public void addBasicEntries(ItemStack itemstack, EntityPlayer entityplayer, List list, boolean flag) { + if (itemstack.stackTagCompound != null && itemstack.stackTagCompound.hasKey("tankContents")) { + FluidStack fl = FluidStack.loadFluidStackFromNBT((NBTTagCompound) itemstack.stackTagCompound.getTag("tankContents")); + if (fl != null && fl.getFluid() != null) { + String str = fl.amount + " " + EnderIO.lang.localize("fluid.millibucket.abr") + " " + PowerDisplayUtil.ofStr() + " " + + fl.getFluid().getLocalizedName(fl); + list.add(str); + } + } + } + + @Override + @SideOnly(Side.CLIENT) + public void addDetailedEntries(ItemStack itemstack, EntityPlayer entityplayer, List list, boolean flag) { + SpecialTooltipHandler.addDetailedTooltipFromResources(list, itemstack); + } + + @Override + public String getUnlocalizedNameForTooltip(ItemStack stack) { + return stack.getUnlocalizedName(); + } + + @Override + public void getWailaInfo(List tooltip, EntityPlayer player, World world, int x, int y, int z) { + TileEntity te = world.getTileEntity(x, y, z); + if (te instanceof TileNiard) { + TileNiard tank = (TileNiard) te; + FluidStack stored = tank.tank.getFluid(); + String fluid = stored == null ? EnderIO.lang.localize("tooltip.none") : stored.getFluid().getLocalizedName(stored); + int amount = stored == null ? 0 : stored.amount; + + tooltip.add(String.format("%s%s : %s (%d %s)", EnumChatFormatting.WHITE, EnderIO.lang.localize("tooltip.fluidStored"), fluid, amount, + EnderIO.lang.localize("fluid.millibucket.abr"))); + } + } + + @Override + public int getRenderType() { + return localRenderId; + } + + @SideOnly(Side.CLIENT) + @Override + public void randomDisplayTick(World world, int x, int y, int z, Random rand) { + } +} diff --git a/src/main/java/info/loenwind/enderioaddons/machine/niard/ContainerNiard.java b/src/main/java/info/loenwind/enderioaddons/machine/niard/ContainerNiard.java new file mode 100644 index 0000000..d794a19 --- /dev/null +++ b/src/main/java/info/loenwind/enderioaddons/machine/niard/ContainerNiard.java @@ -0,0 +1,19 @@ +package info.loenwind.enderioaddons.machine.niard; + +import info.loenwind.enderioaddons.baseclass.AbstractMachineContainerA; +import info.loenwind.enderioaddons.gui.StdSlot; +import net.minecraft.entity.player.InventoryPlayer; + +public class ContainerNiard extends AbstractMachineContainerA { + + public ContainerNiard(InventoryPlayer playerInv, TileNiard te) { + super(playerInv, te); + } + + @Override + protected void addMachineSlots(InventoryPlayer playerInv) { + addSlotToContainer(new StdSlot(getInv(), 0, 44, 21)); + addSlotToContainer(new StdSlot(getInv(), 1, 44, 52)); + } + +} diff --git a/src/main/java/info/loenwind/enderioaddons/machine/niard/Engine.java b/src/main/java/info/loenwind/enderioaddons/machine/niard/Engine.java new file mode 100644 index 0000000..df3660c --- /dev/null +++ b/src/main/java/info/loenwind/enderioaddons/machine/niard/Engine.java @@ -0,0 +1,170 @@ +package info.loenwind.enderioaddons.machine.niard; + +import info.loenwind.enderioaddons.fluid.FluidType; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.Nonnull; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockLiquid; +import net.minecraft.entity.item.EntityXPOrb; +import net.minecraft.init.Blocks; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.BlockFluidClassic; +import net.minecraftforge.fluids.BlockFluidFinite; +import net.minecraftforge.fluids.Fluid; + +import com.enderio.core.common.util.BlockCoord; + +import crazypants.enderio.xp.XpUtil; + +public class Engine { + + private final TileNiard owner; + private Fluid fluid = null; + private Block block; + private FluidType type; + private ForgeDirection downflowDirection; + private int radius = -1; + private RadiusIterator radiusItr; + + public Engine(TileNiard owner) { + this.owner = owner; + } + + public Engine setFluid(Fluid fluid) { + if (fluid.canBePlacedInWorld()) { + this.radiusItr = radius >= 0 ? new RadiusIterator(owner.getLocation(), radius) : null; + this.fluid = fluid; + this.downflowDirection = fluid.getDensity() > 0 ? ForgeDirection.DOWN : ForgeDirection.UP; + block = fluid.getBlock(); + if (block instanceof BlockFluidClassic) { + type = FluidType.CLASSIC; + } else if (block instanceof BlockFluidFinite) { + type = FluidType.FINITE; + } else if (block instanceof BlockLiquid) { + type = FluidType.VANILLA; + } else { + this.fluid = null; + } + } else { + this.fluid = null; + } + return this; + } + + public Engine setRadius(int radius) { + if (radius != this.radius) { + this.radius = radius; + this.radiusItr = new RadiusIterator(owner.getLocation(), radius); + } + return this; + } + + public boolean work() { + if (fluid == null || radius < 0) { + return false; + } + for (int i = 0; i < radiusItr.size(); i++) { + List seen = new ArrayList<>(); + BlockCoord base = radiusItr.next(); + BlockCoord next = base.getLocation(downflowDirection); + while (isInWorld(next) && (owner.getWorldObj().isAirBlock(next.x, next.y, next.z) || (isSameLiquid(next) && isFlowingBlock(next)))) { + seen.add(next); + next = next.getLocation(downflowDirection); + } + if (!seen.isEmpty()) { + setSourceBlock(seen.remove(seen.size() - 1)); + if (!seen.isEmpty()) { + for (BlockCoord bc : seen) { + setVerticalBlock(bc, false); + } + owner.getWorldObj().notifyBlockChange(base.x, base.y, base.z, base.getBlock(owner.getWorldObj())); + } + return true; + } + } + return false; + } + + public int work(int xp_in_mb) { + int remaining = XpUtil.liquidToExperience(xp_in_mb); + if (radius >= 0) { + for (int i = 0; i < radiusItr.size(); i++) { + BlockCoord next = radiusItr.next().getLocation(ForgeDirection.DOWN); + if (isInWorld(next) && owner.getWorldObj().isAirBlock(next.x, next.y, next.z)) { + int i1 = EntityXPOrb.getXPSplit(remaining / (owner.getWorldObj().rand.nextInt(4) + 1)); + remaining -= i1; + final EntityXPOrb xpOrb = new EntityXPOrb(owner.getWorldObj(), next.x + 0.5D, next.y + 0.7D, next.z + 0.5D, i1); + xpOrb.motionX /= 4d; + xpOrb.motionY = 0; + xpOrb.motionZ /= 4d; + owner.getWorldObj().spawnEntityInWorld(xpOrb); + if (remaining <= 0) { + return 0; + } + } + } + } + return XpUtil.experienceToLiquid(remaining); + } + + // Tools of the trade + + private static boolean isInWorld(BlockCoord bc) { + return bc.y > 0 && bc.y <= 255; + } + + private boolean isSameLiquid(@Nonnull BlockCoord bc) { + final Block wblock = bc.getBlock(owner.getWorldObj()); + return wblock == block || (block == Blocks.water && wblock == Blocks.flowing_water) || (block == Blocks.lava && wblock == Blocks.flowing_lava); + } + + private boolean isFlowingBlock(@Nonnull BlockCoord bc) { + switch (type) { + case CLASSIC: + return !((BlockFluidClassic) block).isSourceBlock(owner.getWorldObj(), bc.x, bc.y, bc.z); + case FINITE: + return false; + case VANILLA: + return owner.getWorldObj().getBlockMetadata(bc.x, bc.y, bc.z) != 0; + } + throw new IllegalStateException("unreachable code"); + } + + private void setSourceBlock(BlockCoord bc) { + Block blockToSet = block; + int metaToSet = 0; + switch (type) { + case CLASSIC: + metaToSet = ((BlockFluidClassic) block).getMaxRenderHeightMeta(); + break; + case FINITE: + metaToSet = ((BlockFluidFinite) block).getMaxRenderHeightMeta(); + break; + case VANILLA: + metaToSet = 0; + break; + } + owner.getWorldObj().setBlock(bc.x, bc.y, bc.z, blockToSet, metaToSet, 3); + } + + private void setVerticalBlock(BlockCoord bc, boolean blockUpdate) { + Block blockToSet = block; + int metaToSet = 0; + switch (type) { + case CLASSIC: + metaToSet = 1; + break; + case FINITE: + return; + case VANILLA: + metaToSet = 8; + break; + } + owner.getWorldObj().setBlock(bc.x, bc.y, bc.z, blockToSet, metaToSet, blockUpdate ? 3 : 2); + } + +} diff --git a/src/main/java/info/loenwind/enderioaddons/machine/niard/GuiNiard.java b/src/main/java/info/loenwind/enderioaddons/machine/niard/GuiNiard.java new file mode 100644 index 0000000..4672dfc --- /dev/null +++ b/src/main/java/info/loenwind/enderioaddons/machine/niard/GuiNiard.java @@ -0,0 +1,114 @@ +package info.loenwind.enderioaddons.machine.niard; + +import info.loenwind.enderioaddons.EnderIOAddons; + +import java.awt.Rectangle; + +import javax.annotation.Nonnull; + +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.util.IIcon; +import net.minecraftforge.fluids.FluidStack; + +import org.lwjgl.opengl.GL11; + +import com.enderio.core.client.gui.widget.GuiToolTip; +import com.enderio.core.client.render.RenderUtil; + +import crazypants.enderio.EnderIO; +import crazypants.enderio.fluid.Fluids; +import crazypants.enderio.machine.gui.GuiPoweredMachineBase; + +public class GuiNiard extends GuiPoweredMachineBase { + + public GuiNiard(@Nonnull InventoryPlayer par1InventoryPlayer, @Nonnull TileNiard te) { + super(te, new ContainerNiard(par1InventoryPlayer, te)); + + addToolTip(new GuiToolTip(new Rectangle(80, 21, 16, 47), "") { + + @Override + protected void updateText() { + text.clear(); + String heading = EnderIO.lang.localize("tank.tank"); + if (getTileEntity().tank.getFluid() != null) { + heading += ": " + getTileEntity().tank.getFluid().getLocalizedName(); + } + text.add(heading); + text.add(Fluids.toCapactityString(getTileEntity().tank)); + } + + }); + } + + @Override + protected boolean showRecipeButton() { + return false; + } + + @Override + protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + RenderUtil.bindTexture(EnderIOAddons.DOMAIN + ":textures/gui/niard.png"); + int sx = (width - xSize) / 2; + int sy = (height - ySize) / 2; + + drawTexturedModalRect(sx, sy, 0, 0, xSize, ySize); + + super.drawGuiContainerBackgroundLayer(par1, par2, par3); + + RenderUtil.bindBlockTexture(); + RenderUtil.renderGuiTank(getTileEntity().tank, guiLeft + 80, guiTop + 21, zLevel, 16, 47); + + renderFlowingFluid(getTileEntity().tank.getFluid(), sx + 112, sy + 28, 39, 56); + + RenderUtil.bindTexture(EnderIOAddons.DOMAIN + ":textures/gui/niard.png"); + GL11.glEnable(GL11.GL_BLEND); + drawTexturedModalRect(sx + 112, sy + 28, 200, 0, 39, 56); + GL11.glDisable(GL11.GL_BLEND); + } + + public static void renderFlowingFluid(FluidStack fluid, double x, double y, double width, double height) { + if (fluid == null || fluid.getFluid() == null || fluid.amount <= 0) { + return; + } + + IIcon icon = fluid.getFluid().getFlowingIcon(); + if (icon == null) { + icon = fluid.getFluid().getIcon(); + if (icon == null) { + return; + } + } + + RenderUtil.bindBlockTexture(); + int color = fluid.getFluid().getColor(fluid); + GL11.glColor3ub((byte) (color >> 16 & 0xFF), (byte) (color >> 8 & 0xFF), (byte) (color & 0xFF)); + + GL11.glEnable(GL11.GL_BLEND); + for (int i = 0; i < width; i += 16) { + for (int j = 0; j < (int) height; j += 16) { + int drawWidth = (int) Math.min(width - i, 16); + int drawHeight = Math.min((int) height - j, 16); + + int drawX = (int) (x + i); + int drawY = (int) y + j; + + double minU = icon.getMinU(); + double maxU = icon.getMaxU(); + double minV = icon.getMinV(); + double maxV = icon.getMaxV(); + + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(drawX, drawY + drawHeight, 0, minU, minV + (maxV - minV) * drawHeight / 16F); + tessellator.addVertexWithUV(drawX + drawWidth, drawY + drawHeight, 0, minU + (maxU - minU) * drawWidth / 16F, minV + (maxV - minV) * drawHeight / 16F); + tessellator.addVertexWithUV(drawX + drawWidth, drawY, 0, minU + (maxU - minU) * drawWidth / 16F, minV); + tessellator.addVertexWithUV(drawX, drawY, 0, minU, minV); + tessellator.draw(); + } + } + GL11.glDisable(GL11.GL_BLEND); + } + +} diff --git a/src/main/java/info/loenwind/enderioaddons/machine/niard/PacketNiard.java b/src/main/java/info/loenwind/enderioaddons/machine/niard/PacketNiard.java new file mode 100644 index 0000000..d9e4a11 --- /dev/null +++ b/src/main/java/info/loenwind/enderioaddons/machine/niard/PacketNiard.java @@ -0,0 +1,62 @@ +package info.loenwind.enderioaddons.machine.niard; + +import io.netty.buffer.ByteBuf; + +import javax.annotation.Nonnull; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; + +import com.enderio.core.common.network.MessageTileEntity; +import com.enderio.core.common.network.NetworkUtil; + +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.EnderIO; + +public class PacketNiard extends MessageTileEntity implements IMessageHandler { + + private NBTTagCompound nbtRoot; + + public PacketNiard() { + } + + public PacketNiard(@Nonnull TileNiard tile) { + super(tile); + nbtRoot = new NBTTagCompound(); + if(tile.tank.getFluidAmount() > 0) { + NBTTagCompound tankRoot = new NBTTagCompound(); + tile.tank.writeToNBT(tankRoot); + nbtRoot.setTag("tank", tankRoot); + } + } + + @Override + public void toBytes(ByteBuf buf) { + super.toBytes(buf); + NetworkUtil.writeNBTTagCompound(nbtRoot, buf); + } + + @Override + public void fromBytes(ByteBuf buf) { + super.fromBytes(buf); + nbtRoot = NetworkUtil.readNBTTagCompound(buf); + } + + @Override + public IMessage onMessage(PacketNiard message, MessageContext ctx) { + EntityPlayer player = EnderIO.proxy.getClientPlayer(); + TileNiard tile = message.getTileEntity(player.worldObj); + if(tile == null) { + return null; + } + if(message.nbtRoot.hasKey("tank")) { + NBTTagCompound tankRoot = message.nbtRoot.getCompoundTag("tank"); + tile.tank.readFromNBT(tankRoot); + } else { + tile.tank.setFluid(null); + } + return null; + } +} \ No newline at end of file diff --git a/src/main/java/info/loenwind/enderioaddons/machine/niard/RadiusIterator.java b/src/main/java/info/loenwind/enderioaddons/machine/niard/RadiusIterator.java new file mode 100644 index 0000000..ab51756 --- /dev/null +++ b/src/main/java/info/loenwind/enderioaddons/machine/niard/RadiusIterator.java @@ -0,0 +1,36 @@ +package info.loenwind.enderioaddons.machine.niard; + +import java.util.ArrayList; +import java.util.List; + +import com.enderio.core.common.util.BlockCoord; + +public class RadiusIterator { + + private final List bcl = new ArrayList<>(); + private int idx = -1; + + public RadiusIterator(BlockCoord bc, int radius) { + bcl.add(bc); + for (int i = 1; i <= radius; i++) { + for (int j = -i; j < i; j++) { + bcl.add(new BlockCoord(bc.x - i, bc.y, bc.z + j)); + bcl.add(new BlockCoord(bc.x + i, bc.y, bc.z - j)); + bcl.add(new BlockCoord(bc.x + j, bc.y, bc.z + i)); + bcl.add(new BlockCoord(bc.x - j, bc.y, bc.z - i)); + } + } + } + + public BlockCoord next() { + if (++idx >= bcl.size()) { + idx = 0; + } + return bcl.get(idx); + } + + public int size() { + return bcl.size(); + } + +} diff --git a/src/main/java/info/loenwind/enderioaddons/machine/niard/TileNiard.java b/src/main/java/info/loenwind/enderioaddons/machine/niard/TileNiard.java new file mode 100644 index 0000000..8dc6c4b --- /dev/null +++ b/src/main/java/info/loenwind/enderioaddons/machine/niard/TileNiard.java @@ -0,0 +1,387 @@ +package info.loenwind.enderioaddons.machine.niard; + +import info.loenwind.autosave.annotations.Storable; +import info.loenwind.autosave.annotations.Store; +import info.loenwind.enderioaddons.baseclass.TileEnderIOAddons; +import info.loenwind.enderioaddons.config.Config; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidContainerRegistry; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTank; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidContainerItem; +import net.minecraftforge.fluids.IFluidHandler; + +import com.enderio.core.api.common.util.ITankAccess; +import com.enderio.core.common.util.BlockCoord; +import com.enderio.core.common.util.FluidUtil; +import com.enderio.core.common.util.FluidUtil.FluidAndStackResult; +import com.enderio.core.common.util.ItemUtil; + +import crazypants.enderio.EnderIO; +import crazypants.enderio.machine.ContinuousTask; +import crazypants.enderio.machine.IMachineRecipe; +import crazypants.enderio.machine.IPoweredTask; +import crazypants.enderio.machine.IoMode; +import crazypants.enderio.machine.SlotDefinition; +import crazypants.enderio.network.PacketHandler; +import crazypants.enderio.power.BasicCapacitor; +import crazypants.enderio.tool.SmartTank; + +@Storable +public class TileNiard extends TileEnderIOAddons implements IFluidHandler, ITankAccess { + + private static final int ONE_BLOCK_OF_LIQUID = 1000; + + private static int IO_MB_TICK = 100; + + @Nonnull + @Store + protected SmartTank tank = new SmartTank(2 * ONE_BLOCK_OF_LIQUID); + protected int lastUpdateLevel = -1; + + private boolean tankDirty = false; + private final Engine engine; + + public TileNiard() { + super(new SlotDefinition(1, 1, 1)); + engine = new Engine(this); + } + + @Override + protected boolean doPush(@Nullable ForgeDirection dir) { + return false; + } + + @Override + protected boolean doPull(ForgeDirection dir) { + + if (isSideDisabled(dir.ordinal())) { + return false; + } + + boolean res = super.doPull(dir); + if (tank.getFluidAmount() < tank.getCapacity()) { + BlockCoord loc = getLocation().getLocation(dir); + IFluidHandler target = FluidUtil.getFluidHandler(worldObj, loc); + if(target != null) { + + if (tank.getFluidAmount() > 0) { + FluidStack canPull = tank.getFluid().copy(); + canPull.amount = tank.getCapacity() - tank.getFluidAmount(); + canPull.amount = Math.min(canPull.amount, IO_MB_TICK); + FluidStack drained = target.drain(dir.getOpposite(), canPull, true); + if (drained != null && drained.amount > 0) { + tank.fill(drained, true); + tankDirty = true; + return res; + } + } else { + + FluidTankInfo[] infos = target.getTankInfo(dir.getOpposite()); + if (infos != null) { + for (FluidTankInfo info : infos) { + if (info.fluid != null && info.fluid.amount > 0) { + if (canFill(dir, info.fluid.getFluid())) { + FluidStack canPull = info.fluid.copy(); + canPull.amount = Math.min(IO_MB_TICK, canPull.amount); + FluidStack drained = target.drain(dir.getOpposite(), canPull, true); + if (drained != null && drained.amount > 0) { + tank.fill(drained, true); + tankDirty = true; + return res; + } + } + } + } + } + } + + } + } + return res; + } + + @Override + public int fill(@Nullable ForgeDirection from, @Nullable FluidStack resource, boolean doFill) { + if (!canFill(from) || resource == null || !isValidFluid(resource)) { + return 0; + } + return fillInternal(resource, doFill); + } + + private boolean canFill(ForgeDirection from) { + IoMode mode = getIoMode(from); + return mode != IoMode.PUSH && mode != IoMode.DISABLED; + } + + protected int fillInternal(@Nonnull FluidStack resource, boolean doFill) { + int res = tank.fill(resource, doFill); + if(res > 0 && doFill) { + tankDirty = true; + } + return res; + } + + @Override + public FluidStack drain(@Nullable ForgeDirection from, @Nullable FluidStack resource, boolean doDrain) { + return null; + } + + protected FluidStack drainInternal(@Nonnull FluidStack resource, boolean doDrain) { + FluidStack res = tank.drain(resource, doDrain); + if(res != null && res.amount > 0 && doDrain) { + tankDirty = true; + } + return res; + } + + @Override + public FluidStack drain(@Nullable ForgeDirection from, int maxDrain, boolean doDrain) { + return null; + } + + protected FluidStack drainInternal(int maxDrain, boolean doDrain) { + FluidStack res = tank.drain(maxDrain, doDrain); + if(res != null && res.amount > 0 && doDrain) { + tankDirty = true; + } + return res; + } + + @Override + public boolean canFill(@Nullable ForgeDirection from, @Nullable Fluid fluid) { + return canFill(from) && fluid != null && (tank.getFluidAmount() > 0 && tank.getFluid().getFluidID() == fluid.getID() || tank.getFluidAmount() == 0) + && isValidFluid(fluid); + } + + @Override + public boolean canDrain(@Nullable ForgeDirection from, @Nullable Fluid fluid) { + return false; + } + + @Override + public FluidTankInfo[] getTankInfo(@Nullable ForgeDirection from) { + return new FluidTankInfo[] { new FluidTankInfo(tank) }; + } + + private int getFilledLevel() { + int level = (int) Math.floor(16 * tank.getFilledRatio()); + if(level == 0 && tank.getFluidAmount() > 0) { + level = 1; + } + return level; + } + + @Override + public String getMachineName() { + return BlockNiard.ModObject_blockNiard.unlocalisedName; + } + + @Override + protected boolean isMachineItemValidForSlot(int i, @Nullable ItemStack item) { + if (i == 0 && item != null) { + FluidStack fluid = FluidContainerRegistry.getFluidForFilledItem(item); + if (fluid != null) { + return isValidFluid(fluid); + } + if (item.getItem() == Items.water_bucket) { + return true; + } + if (item.getItem() == Items.lava_bucket) { + return true; + } + if (item.getItem() instanceof IFluidContainerItem && ((IFluidContainerItem) item.getItem()).getFluid(item) != null) { + return isValidFluid(((IFluidContainerItem) item.getItem()).getFluid(item)); + } + return false; + } + return false; + } + + private static boolean isValidFluid(Fluid fluid) { + return fluid != null && (fluid.canBePlacedInWorld() || fluid == EnderIO.fluidXpJuice); + } + + private static boolean isValidFluid(FluidStack fluid) { + return fluid != null && isValidFluid(fluid.getFluid()); + } + + // tick goes in here + @Override + protected boolean checkProgress(boolean redstoneChecksPassed) { + if(canTick(redstoneChecksPassed) && redstoneChecksPassed) { + return doTick(); + } + return false; + } + + protected boolean canTick(boolean redstoneChecksPassed) { + if(redstoneChecksPassed) { + if(getEnergyStored() < getPowerUsePerTick()) { + return false; + } + usePower(); + } + int curScaled = getProgressScaled(16); + if(curScaled != lastProgressScaled) { + sendTaskProgressPacket(); + lastProgressScaled = curScaled; + } + return true; + } + + private int sleep = 0; + + protected boolean doTick() { + if(shouldDoWorkThisTick(20)) { + drainFullContainer(); + } + + if (sleep == 0) { + + // scale by cap + int modulo = 10; + int range = 0; + switch (getCapacitorType()) { + case BASIC_CAPACITOR: + modulo = 20; + range = 0; // 1x1 + break; + case ACTIVATED_CAPACITOR: + modulo = 10; + range = 1; // 3x3 + break; + case ENDER_CAPACITOR: + modulo = 2; + range = 3; // 7x7 + break; + } + + if (shouldDoWorkThisTick(modulo) && tank.getFluidAmount() > 0) { + if (tank.getFluid().getFluid() == EnderIO.fluidXpJuice) { + int amount = tank.getFluidAmount(); + boolean looping = true; + while (looping) { + int remaining = engine.setRadius(range).work(amount); + if (remaining == amount || remaining == 0) { + looping = false; + } + amount = remaining; + } + if (amount != tank.getFluidAmount()) { + usePower(Config.niardPerBucketEnergyUseRF.getInt() * (tank.getFluidAmount() - amount) / 1000); + tank.setFluidAmount(amount); + } else { + sleep = 200; + } + } else if (tank.getFluidAmount() >= ONE_BLOCK_OF_LIQUID && engine.setFluid(tank.getFluid().getFluid()).setRadius(range).work()) { + tank.setFluidAmount(tank.getFluidAmount() - ONE_BLOCK_OF_LIQUID); + usePower(Config.niardPerBucketEnergyUseRF.getInt()); + } else { + sleep = 200; + } + } + + } else { + sleep--; + } + + int filledLevel = getFilledLevel(); + if (lastUpdateLevel != filledLevel) { + lastUpdateLevel = filledLevel; + tankDirty = true; + } + + if (tankDirty && shouldDoWorkThisTick(10)) { + PacketHandler.sendToAllAround(new PacketNiard(this), this); + worldObj.func_147453_f(xCoord, yCoord, zCoord, getBlockType()); + tankDirty = false; + } + + return false; + } + + public int getComparatorOutput() { + FluidTankInfo info = getTankInfo(null)[0]; + return info == null || info.fluid == null ? 0 : (int) (((double) info.fluid.amount / (double) info.capacity) * 15); + } + + private boolean drainFullContainer() { + FluidAndStackResult fill = FluidUtil.tryDrainContainer(inventory[getSlotDefinition().getMinInputSlot()], this); + if (fill.result.fluidStack == null) { + return false; + } + + int slot = getSlotDefinition().getMinOutputSlot(); + + if (inventory[slot] != null && fill.result.itemStack != null) { + if (inventory[slot].isStackable() && ItemUtil.areStackMergable(inventory[slot], fill.result.itemStack) + && inventory[slot].stackSize < inventory[slot].getMaxStackSize()) { + fill.result.itemStack.stackSize += inventory[slot].stackSize; + } else { + return false; + } + } + + getInputTank(fill.result.fluidStack).setFluid(fill.remainder.fluidStack); + setInventorySlotContents(getSlotDefinition().getMinInputSlot(), fill.remainder.itemStack); + if (fill.result.itemStack != null) { + setInventorySlotContents(slot, fill.result.itemStack); + } + + setTanksDirty(); + markDirty(); + return false; + } + + @Override + protected IPoweredTask createTask(NBTTagCompound taskTagCompound) { + return new ContinuousTask(getPowerUsePerTick()); + } + + @Override + protected IPoweredTask createTask(IMachineRecipe nextRecipe, float chance) { + return createTask(null); + } + + @Override + public void onCapacitorTypeChange() { + switch (getCapacitorType()) { + case BASIC_CAPACITOR: + setCapacitor(new BasicCapacitor(Config.niardContinuousEnergyUseRF.getInt() * 40, 250000, Config.niardContinuousEnergyUseRF.getInt())); + break; + case ACTIVATED_CAPACITOR: + setCapacitor(new BasicCapacitor(Config.niardContinuousEnergyUseRF.getInt() * 40, 500000, Config.niardContinuousEnergyUseRF.getInt())); + break; + case ENDER_CAPACITOR: + setCapacitor(new BasicCapacitor(Config.niardContinuousEnergyUseRF.getInt() * 40, 1000000, Config.niardContinuousEnergyUseRF.getInt())); + break; + } + currentTask = createTask(null); + } + + @Override + public FluidTank getInputTank(FluidStack forFluidType) { + return tank; + } + + @Override + public FluidTank[] getOutputTanks() { + return new FluidTank[] {}; + } + + @Override + public void setTanksDirty() { + tankDirty = true; + } + +} diff --git a/src/main/java/info/loenwind/enderioaddons/nei/NEIEnderIOConfig.java b/src/main/java/info/loenwind/enderioaddons/nei/NEIEnderIOConfig.java index 89b42d9..342e728 100644 --- a/src/main/java/info/loenwind/enderioaddons/nei/NEIEnderIOConfig.java +++ b/src/main/java/info/loenwind/enderioaddons/nei/NEIEnderIOConfig.java @@ -7,6 +7,7 @@ import info.loenwind.enderioaddons.machine.cobbleworks.BlockCobbleworks; import info.loenwind.enderioaddons.machine.framework.AbstractBlockFramework; import info.loenwind.enderioaddons.machine.ihopper.BlockIHopper; +import info.loenwind.enderioaddons.machine.niard.BlockNiard; import info.loenwind.enderioaddons.machine.part.ItemMachinePart; import info.loenwind.enderioaddons.machine.part.MachinePart; import info.loenwind.enderioaddons.machine.waterworks.BlockWaterworks; @@ -38,6 +39,9 @@ public void loadConfig() { API.hideItem(new ItemStack(ItemMachinePart.itemMachinePart, 1, MachinePart.IHOPPER_CONTROLLER.ordinal())); API.hideItem(new ItemStack(BlockIHopper.blockIHopper, 1, OreDictionary.WILDCARD_VALUE)); } + if (!Config.niardEnabled.getBoolean()) { + API.hideItem(new ItemStack(BlockNiard.blockNiard, 1, OreDictionary.WILDCARD_VALUE)); + } } @Override diff --git a/src/main/java/info/loenwind/enderioaddons/proxy/ClientAndServerProxy.java b/src/main/java/info/loenwind/enderioaddons/proxy/ClientAndServerProxy.java index ea79175..00e0ac4 100644 --- a/src/main/java/info/loenwind/enderioaddons/proxy/ClientAndServerProxy.java +++ b/src/main/java/info/loenwind/enderioaddons/proxy/ClientAndServerProxy.java @@ -9,6 +9,7 @@ import info.loenwind.enderioaddons.machine.drain.InfiniteWaterSourceStopper; import info.loenwind.enderioaddons.machine.framework.AbstractBlockFramework; import info.loenwind.enderioaddons.machine.ihopper.BlockIHopper; +import info.loenwind.enderioaddons.machine.niard.BlockNiard; import info.loenwind.enderioaddons.machine.part.ItemMachinePart; import info.loenwind.enderioaddons.machine.waterworks.BlockWaterworks; import cpw.mods.fml.common.event.FMLInitializationEvent; @@ -29,6 +30,7 @@ public void init(FMLPreInitializationEvent event) { BlockWaterworks.create(); BlockIHopper.create(); ItemMachinePart.create(); + BlockNiard.create(); } @Override diff --git a/src/main/java/info/loenwind/enderioaddons/recipe/Recipes.java b/src/main/java/info/loenwind/enderioaddons/recipe/Recipes.java index 18299cb..f27cc75 100644 --- a/src/main/java/info/loenwind/enderioaddons/recipe/Recipes.java +++ b/src/main/java/info/loenwind/enderioaddons/recipe/Recipes.java @@ -5,12 +5,14 @@ import info.loenwind.enderioaddons.machine.cobbleworks.BlockCobbleworks; import info.loenwind.enderioaddons.machine.drain.BlockDrain; import info.loenwind.enderioaddons.machine.ihopper.BlockIHopper; +import info.loenwind.enderioaddons.machine.niard.BlockNiard; import info.loenwind.enderioaddons.machine.part.ItemMachinePart; import info.loenwind.enderioaddons.machine.part.MachinePart; import info.loenwind.enderioaddons.machine.waterworks.BlockWaterworks; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; +import net.minecraftforge.oredict.OreDictionary; import net.minecraftforge.oredict.ShapedOreRecipe; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; @@ -72,13 +74,20 @@ public void init(FMLPreInitializationEvent event) { @Override public void init(FMLInitializationEvent event) { - //Drain + // Drain if (Config.drainEnabled.getBoolean()) { ItemStack drain = new ItemStack(BlockDrain.blockDrain, 1, 0); GameRegistry.addRecipe(new ShapedOreRecipe(drain, "btb", "pmp", "eve", 'm', machineChassi, 't', basicTank, 'p', Blocks.piston, 'b', Items.bucket, 'e', electricSteel, 'v', Items.cauldron)); } + // Niard + if (Config.niardEnabled.getBoolean()) { + ItemStack niard = new ItemStack(BlockNiard.blockNiard, 1, OreDictionary.WILDCARD_VALUE); + GameRegistry.addRecipe(new ShapedOreRecipe(niard, "btb", "pmp", "eve", 'm', machineChassi, 't', basicTank, 'p', Blocks.piston, 'b', Items.bucket, 'e', + electricSteel, 'v', darkSteelBars)); + } + ItemStack zombieBit; ItemStack crystal; if (crazypants.enderio.config.Config.useHardRecipes) { diff --git a/src/main/resources/assets/enderioaddons/lang/en_US.lang b/src/main/resources/assets/enderioaddons/lang/en_US.lang index e3e2a7b..8683f9a 100644 --- a/src/main/resources/assets/enderioaddons/lang/en_US.lang +++ b/src/main/resources/assets/enderioaddons/lang/en_US.lang @@ -42,6 +42,12 @@ enderio.waterworks.stashprogress=Internal Buffer tile.blockIHopper.name=Impulse Hopper +tile.blockNiard.name=Niard +tile.blockNiard.tooltip.detailed.line1="Niard ythgim eht" places liquids into the world. +tile.blockNiard.tooltip.detailed.line2=Liquids are placed below it, as low as possible. +tile.blockNiard.tooltip.detailed.line3=Range can be upgraded with capacitors (1x1, 3x3, 7x7). +tile.blockNiard.tooltip.detailed.line4=Can also convert Liquid XP into XP orbs. + enderioaddons.gui.tooltip.redstoneControlMode=Redstone Mode enderioaddons.gui.tooltip.redstoneControlMode.rising_edge=Rising edge enderioaddons.gui.tooltip.redstoneControlMode.falling_edge=Falling edge diff --git a/src/main/resources/assets/enderioaddons/textures/gui/niard.png b/src/main/resources/assets/enderioaddons/textures/gui/niard.png new file mode 100644 index 0000000..b1f541e Binary files /dev/null and b/src/main/resources/assets/enderioaddons/textures/gui/niard.png differ