enumClass) {
+ this(material, enumClass, "type");
+ }
+
+ @Override
+ protected BlockStateContainer createStateContainer() {
+ return new BlockStateContainer.Builder(this).add(getProperty(), UP, NORTH, EAST, SOUTH, WEST).build();
+ }
+
+ @Override
+ public AxisAlignedBB getBoundingBox(BlockState state, IBlockAccess source, BlockPos pos) {
+ state = state.getActualState(source, pos);
+ return AABB_BY_INDEX[getAABBIndex(state)];
+ }
+
+ @Override
+ public AxisAlignedBB getCollisionBoundingBox(BlockState blockState, IBlockAccess worldIn, BlockPos pos) {
+ blockState = blockState.getActualState(worldIn, pos);
+ return CLIP_AABB_BY_INDEX[getAABBIndex(blockState)];
+ }
+
+ public boolean isFullCube(BlockState state) {
+ return false;
+ }
+
+ public boolean isPassable(IBlockAccess worldIn, BlockPos pos) {
+ return false;
+ }
+
+ @Override
+ public boolean isOpaqueCube(BlockState state) {
+ return false;
+ }
+
+ private boolean canConnectTo(IBlockAccess worldIn, BlockPos pos) {
+ BlockState worldState = worldIn.getBlockState(pos);
+ Block block = worldState.getBlock();
+ return block != Blocks.BARRIER && (!(block != this && !(block instanceof FenceGateBlock)) || ((worldState.getMaterial().isOpaque() && worldState.isFullCube()) && worldState.getMaterial() != Material.GOURD));
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public boolean shouldSideBeRendered(BlockState blockState, IBlockAccess blockAccess, BlockPos pos, Direction side) {
+ return side != Direction.DOWN || super.shouldSideBeRendered(blockState, blockAccess, pos, side);
+ }
+
+ @Override
+ public BlockState getActualState(BlockState state, IBlockAccess worldIn, BlockPos pos) {
+ boolean canNorth = this.canConnectTo(worldIn, pos.north());
+ boolean canEast = this.canConnectTo(worldIn, pos.east());
+ boolean canSouth = this.canConnectTo(worldIn, pos.south());
+ boolean canWest = this.canConnectTo(worldIn, pos.west());
+ boolean flag4 = canNorth && !canEast && canSouth && !canWest || !canNorth && canEast && !canSouth && canWest;
+ return state.withProperty(UP, !flag4 || !worldIn.isAirBlock(pos.up())).withProperty(NORTH, canNorth).withProperty(EAST, canEast).withProperty(SOUTH, canSouth).withProperty(WEST, canWest);
+ }
+
+ @Override
+ protected ItemStack getSilkTouchDrop(BlockState state) {
+ return new ItemStack(this, 1, damageDropped(state));
+ }
+
+ @Override
+ public int damageDropped(BlockState state) {
+ return super.getMetaFromState(state);
+ }
+
+ private static int getAABBIndex(BlockState state) {
+ int i = 0;
+
+ if (state.getValue(NORTH)) {
+ i |= 1 << Direction.NORTH.getHorizontalIndex();
+ }
+
+ if (state.getValue(EAST)) {
+ i |= 1 << Direction.EAST.getHorizontalIndex();
+ }
+
+ if (state.getValue(SOUTH)) {
+ i |= 1 << Direction.SOUTH.getHorizontalIndex();
+ }
+
+ if (state.getValue(WEST)) {
+ i |= 1 << Direction.WEST.getHorizontalIndex();
+ }
+
+ return i;
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/block/base/BlockInteger.java b/src/main/java/WayofTime/bloodmagic/block/base/BlockInteger.java
new file mode 100644
index 00000000..0427e11a
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/block/base/BlockInteger.java
@@ -0,0 +1,81 @@
+package WayofTime.bloodmagic.block.base;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.properties.PropertyInteger;
+import net.minecraft.block.state.BlockStateContainer;
+import net.minecraft.block.BlockState;
+import net.minecraft.item.ItemGroup;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.NonNullList;
+
+/**
+ * Creates a block that has multiple meta-based states.
+ *
+ * These states will be numbered 0 through {@code maxMeta}.
+ */
+public class BlockInteger extends Block {
+ private final int maxMeta;
+ private final PropertyInteger property;
+ private final BlockStateContainer realStateContainer;
+
+ public BlockInteger(Material material, int maxMeta, String propName) {
+ super(material);
+
+ this.maxMeta = maxMeta;
+ this.property = PropertyInteger.create(propName, 0, maxMeta);
+ this.realStateContainer = createStateContainer();
+ setDefaultState(getBlockState().getBaseState());
+ }
+
+ public BlockInteger(Material material, int maxMeta) {
+ this(material, maxMeta, "meta");
+ }
+
+ @Override
+ protected final BlockStateContainer createBlockState() {
+ return new BlockStateContainer.Builder(this).build(); // Blank to avoid crashes
+ }
+
+ @Override
+ public final BlockStateContainer getBlockState() {
+ return realStateContainer;
+ }
+
+ @Override
+ public BlockState getStateFromMeta(int meta) {
+ return getDefaultState().withProperty(property, meta);
+ }
+
+ @Override
+ public int getMetaFromState(BlockState state) {
+ return state.getValue(property);
+ }
+
+ @Override
+ public int damageDropped(BlockState state) {
+ return getMetaFromState(state);
+ }
+
+ @Override
+ public void getSubBlocks(ItemGroup tab, NonNullList subBlocks) {
+ for (int i = 0; i < maxMeta; i++)
+ subBlocks.add(new ItemStack(this, 1, i));
+ }
+
+ protected BlockStateContainer createStateContainer() {
+ return new BlockStateContainer.Builder(this).add(property).build();
+ }
+
+ public int getMaxMeta() {
+ return maxMeta;
+ }
+
+ public PropertyInteger getProperty() {
+ return property;
+ }
+
+ public BlockStateContainer getRealStateContainer() {
+ return realStateContainer;
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/block/enums/BloodRuneType.java b/src/main/java/WayofTime/bloodmagic/block/enums/BloodRuneType.java
new file mode 100644
index 00000000..702fe5d9
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/block/enums/BloodRuneType.java
@@ -0,0 +1,29 @@
+package WayofTime.bloodmagic.block.enums;
+
+import net.minecraft.util.IStringSerializable;
+
+import java.util.Locale;
+
+public enum BloodRuneType implements IStringSerializable {
+ BLANK,
+ SPEED,
+ EFFICIENCY,
+ SACRIFICE,
+ SELF_SACRIFICE,
+ DISPLACEMENT,
+ CAPACITY,
+ AUGMENTED_CAPACITY,
+ ORB,
+ ACCELERATION,
+ CHARGING;
+
+ @Override
+ public String toString() {
+ return name().toLowerCase(Locale.ENGLISH);
+ }
+
+ @Override
+ public String getName() {
+ return this.toString();
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/block/enums/EnumDecorative.java b/src/main/java/WayofTime/bloodmagic/block/enums/EnumDecorative.java
new file mode 100644
index 00000000..7bceae13
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/block/enums/EnumDecorative.java
@@ -0,0 +1,22 @@
+package WayofTime.bloodmagic.block.enums;
+
+import net.minecraft.util.IStringSerializable;
+
+import java.util.Locale;
+
+public enum EnumDecorative implements IStringSerializable {
+ BLOODSTONE_TILE,
+ BLOODSTONE_BRICK,
+ CRYSTAL_TILE,
+ CRYSTAL_BRICK;
+
+ @Override
+ public String toString() {
+ return name().toLowerCase(Locale.ROOT);
+ }
+
+ @Override
+ public String getName() {
+ return toString();
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/block/enums/EnumDemonBlock1.java b/src/main/java/WayofTime/bloodmagic/block/enums/EnumDemonBlock1.java
new file mode 100644
index 00000000..84b42602
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/block/enums/EnumDemonBlock1.java
@@ -0,0 +1,23 @@
+package WayofTime.bloodmagic.block.enums;
+
+import net.minecraft.util.IStringSerializable;
+
+import java.util.Locale;
+
+public enum EnumDemonBlock1 implements IStringSerializable {
+ BRICK1_RAW,
+ BRICK1_CORROSIVE,
+ BRICK1_DESTRUCTIVE,
+ BRICK1_VENGEFUL,
+ BRICK1_STEADFAST;
+
+ @Override
+ public String toString() {
+ return name().toLowerCase(Locale.ENGLISH);
+ }
+
+ @Override
+ public String getName() {
+ return this.toString();
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/block/enums/EnumDemonBlock2.java b/src/main/java/WayofTime/bloodmagic/block/enums/EnumDemonBlock2.java
new file mode 100644
index 00000000..b9a35aab
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/block/enums/EnumDemonBlock2.java
@@ -0,0 +1,33 @@
+package WayofTime.bloodmagic.block.enums;
+
+import net.minecraft.util.IStringSerializable;
+
+import java.util.Locale;
+
+public enum EnumDemonBlock2 implements IStringSerializable {
+ SMALLBRICK_RAW,
+ SMALLBRICK_CORROSIVE,
+ SMALLBRICK_DESTRUCTIVE,
+ SMALLBRICK_VENGEFUL,
+ SMALLBRICK_STEADFAST,
+ TILE_RAW,
+ TILE_CORROSIVE,
+ TILE_DESTRUCTIVE,
+ TILE_VENGEFUL,
+ TILE_STEADFAST,
+ TILESPECIAL_RAW,
+ TILESPECIAL_CORROSIVE,
+ TILESPECIAL_DESTRUCTIVE,
+ TILESPECIAL_VENGEFUL,
+ TILESPECIAL_STEADFAST;
+
+ @Override
+ public String toString() {
+ return name().toLowerCase(Locale.ENGLISH);
+ }
+
+ @Override
+ public String getName() {
+ return this.toString();
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/block/enums/EnumDemonBlock3.java b/src/main/java/WayofTime/bloodmagic/block/enums/EnumDemonBlock3.java
new file mode 100644
index 00000000..c7a54ac6
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/block/enums/EnumDemonBlock3.java
@@ -0,0 +1,33 @@
+package WayofTime.bloodmagic.block.enums;
+
+import net.minecraft.util.IStringSerializable;
+
+import java.util.Locale;
+
+public enum EnumDemonBlock3 implements IStringSerializable {
+ STONE_RAW,
+ STONE_CORROSIVE,
+ STONE_DESTRUCTIVE,
+ STONE_VENGEFUL,
+ STONE_STEADFAST,
+ POLISHED_RAW,
+ POLISHED_CORROSIVE,
+ POLISHED_DESTRUCTIVE,
+ POLISHED_VENGEFUL,
+ POLISHED_STEADFAST,
+ METAL_RAW,
+ METAL_CORROSIVE,
+ METAL_DESTRUCTIVE,
+ METAL_VENGEFUL,
+ METAL_STEADFAST;
+
+ @Override
+ public String toString() {
+ return name().toLowerCase(Locale.ENGLISH);
+ }
+
+ @Override
+ public String getName() {
+ return this.toString();
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/block/enums/EnumInversionCap.java b/src/main/java/WayofTime/bloodmagic/block/enums/EnumInversionCap.java
new file mode 100644
index 00000000..b760a46b
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/block/enums/EnumInversionCap.java
@@ -0,0 +1,28 @@
+package WayofTime.bloodmagic.block.enums;
+
+import net.minecraft.util.IStringSerializable;
+
+import java.util.Locale;
+
+public enum EnumInversionCap implements IStringSerializable {
+ RAW_BOTTOM,
+ RAW_TOP,
+ CORROSIVE_BOTTOM,
+ CORROSIVE_TOP,
+ DESTRUCTIVE_BOTTOM,
+ DESTRUCTIVE_TOP,
+ VENGEFUL_BOTTOM,
+ VENGEFUL_TOP,
+ STEADFAST_BOTTOM,
+ STEADFAST_TOP;
+
+ @Override
+ public String toString() {
+ return name().toLowerCase(Locale.ENGLISH);
+ }
+
+ @Override
+ public String getName() {
+ return this.toString();
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/block/enums/EnumMimic.java b/src/main/java/WayofTime/bloodmagic/block/enums/EnumMimic.java
new file mode 100644
index 00000000..18e2053e
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/block/enums/EnumMimic.java
@@ -0,0 +1,23 @@
+package WayofTime.bloodmagic.block.enums;
+
+import net.minecraft.util.IStringSerializable;
+
+import java.util.Locale;
+
+public enum EnumMimic implements IStringSerializable {
+ NOHITBOX,
+ SOLIDOPAQUE,
+ SOLIDCLEAR,
+ SOLIDLIGHT,
+ SENTIENT;
+
+ @Override
+ public String toString() {
+ return name().toLowerCase(Locale.ENGLISH);
+ }
+
+ @Override
+ public String getName() {
+ return this.toString();
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/block/enums/EnumPath.java b/src/main/java/WayofTime/bloodmagic/block/enums/EnumPath.java
new file mode 100644
index 00000000..79c768bb
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/block/enums/EnumPath.java
@@ -0,0 +1,26 @@
+package WayofTime.bloodmagic.block.enums;
+
+import net.minecraft.util.IStringSerializable;
+
+import java.util.Locale;
+
+public enum EnumPath implements IStringSerializable {
+ WOOD,
+ WOODTILE,
+ STONE,
+ STONETILE,
+ WORNSTONE,
+ WORNSTONETILE,
+ OBSIDIAN,
+ OBSIDIANTILE;
+
+ @Override
+ public String toString() {
+ return name().toLowerCase(Locale.ENGLISH);
+ }
+
+ @Override
+ public String getName() {
+ return this.toString();
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/block/enums/EnumRitualController.java b/src/main/java/WayofTime/bloodmagic/block/enums/EnumRitualController.java
new file mode 100644
index 00000000..bfc67190
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/block/enums/EnumRitualController.java
@@ -0,0 +1,22 @@
+package WayofTime.bloodmagic.block.enums;
+
+import net.minecraft.util.IStringSerializable;
+
+import java.util.Locale;
+
+public enum EnumRitualController implements IStringSerializable {
+ MASTER,
+ IMPERFECT,
+ INVERTED,
+ ;
+
+ @Override
+ public String toString() {
+ return name().toLowerCase(Locale.ENGLISH);
+ }
+
+ @Override
+ public String getName() {
+ return this.toString();
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/block/enums/EnumSubWillType.java b/src/main/java/WayofTime/bloodmagic/block/enums/EnumSubWillType.java
new file mode 100644
index 00000000..01c05b88
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/block/enums/EnumSubWillType.java
@@ -0,0 +1,33 @@
+package WayofTime.bloodmagic.block.enums;
+
+import WayofTime.bloodmagic.soul.EnumDemonWillType;
+import net.minecraft.util.IStringSerializable;
+
+import java.util.Locale;
+
+public enum EnumSubWillType implements IStringSerializable {
+ RAW,
+ CORROSIVE,
+ DESTRUCTIVE,
+ VENGEFUL,
+ STEADFAST;
+
+ @Override
+ public String toString() {
+ return name().toLowerCase(Locale.ENGLISH);
+ }
+
+ @Override
+ public String getName() {
+ return this.toString();
+ }
+
+ public EnumDemonWillType getType() {
+ String name = name();
+
+ if (this == RAW)
+ name = EnumDemonWillType.DEFAULT.name();
+
+ return EnumDemonWillType.valueOf(name);
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/block/enums/EnumSubWillType1.java b/src/main/java/WayofTime/bloodmagic/block/enums/EnumSubWillType1.java
new file mode 100644
index 00000000..4f51f8e8
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/block/enums/EnumSubWillType1.java
@@ -0,0 +1,20 @@
+package WayofTime.bloodmagic.block.enums;
+
+import net.minecraft.util.IStringSerializable;
+
+import java.util.Locale;
+
+public enum EnumSubWillType1 implements IStringSerializable {
+ RAW,
+ CORROSIVE;
+
+ @Override
+ public String toString() {
+ return name().toLowerCase(Locale.ENGLISH);
+ }
+
+ @Override
+ public String getName() {
+ return this.toString();
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/block/enums/EnumSubWillType2.java b/src/main/java/WayofTime/bloodmagic/block/enums/EnumSubWillType2.java
new file mode 100644
index 00000000..5f1a6aca
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/block/enums/EnumSubWillType2.java
@@ -0,0 +1,20 @@
+package WayofTime.bloodmagic.block.enums;
+
+import net.minecraft.util.IStringSerializable;
+
+import java.util.Locale;
+
+public enum EnumSubWillType2 implements IStringSerializable {
+ DESTRUCTIVE,
+ VENGEFUL;
+
+ @Override
+ public String toString() {
+ return name().toLowerCase(Locale.ENGLISH);
+ }
+
+ @Override
+ public String getName() {
+ return this.toString();
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/block/enums/EnumSubWillType3.java b/src/main/java/WayofTime/bloodmagic/block/enums/EnumSubWillType3.java
new file mode 100644
index 00000000..963704e8
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/block/enums/EnumSubWillType3.java
@@ -0,0 +1,19 @@
+package WayofTime.bloodmagic.block.enums;
+
+import net.minecraft.util.IStringSerializable;
+
+import java.util.Locale;
+
+public enum EnumSubWillType3 implements IStringSerializable {
+ STEADFAST;
+
+ @Override
+ public String toString() {
+ return name().toLowerCase(Locale.ENGLISH);
+ }
+
+ @Override
+ public String getName() {
+ return this.toString();
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/block/enums/EnumWillWall.java b/src/main/java/WayofTime/bloodmagic/block/enums/EnumWillWall.java
new file mode 100644
index 00000000..172c6d2b
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/block/enums/EnumWillWall.java
@@ -0,0 +1,33 @@
+package WayofTime.bloodmagic.block.enums;
+
+import net.minecraft.util.IStringSerializable;
+
+import java.util.Locale;
+
+public enum EnumWillWall implements IStringSerializable {
+ BRICK_RAW,
+ BRICK_CORROSIVE,
+ BRICK_DESTRUCTIVE,
+ BRICK_VENGEFUL,
+ BRICK_STEADFAST,
+ SMALLBRICK_RAW,
+ SMALLBRICK_CORROSIVE,
+ SMALLBRICK_DESTRUCTIVE,
+ SMALLBRICK_VENGEFUL,
+ SMALLBRICK_STEADFAST,
+ LARGE_RAW,
+ LARGE_CORROSIVE,
+ LARGE_DESTRUCTIVE,
+ LARGE_VENGEFUL,
+ LARGE_STEADFAST;
+
+ @Override
+ public String toString() {
+ return name().toLowerCase(Locale.ENGLISH);
+ }
+
+ @Override
+ public String getName() {
+ return this.toString();
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/client/IMeshProvider.java b/src/main/java/WayofTime/bloodmagic/client/IMeshProvider.java
new file mode 100644
index 00000000..fb8ec3c2
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/client/IMeshProvider.java
@@ -0,0 +1,40 @@
+package WayofTime.bloodmagic.client;
+
+import net.minecraft.client.renderer.ItemMeshDefinition;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+import javax.annotation.Nullable;
+import java.util.function.Consumer;
+
+/**
+ * Provides a custom {@link ItemMeshDefinition} for automatic registration of
+ * renders.
+ */
+public interface IMeshProvider {
+ /**
+ * Gets the custom ItemMeshDefinition to use for the item.
+ *
+ * @return - the custom ItemMeshDefinition to use for the item.
+ */
+ @SideOnly(Side.CLIENT)
+ ItemMeshDefinition getMeshDefinition();
+
+ /**
+ * Gathers all possible variants for this item
+ */
+ void gatherVariants(Consumer variants);
+
+ /**
+ * If a custom ResourceLocation is required, return it here.
+ *
+ * Can be null if unneeded.
+ *
+ * @return - The custom ResourceLocation
+ */
+ @Nullable
+ default ResourceLocation getCustomLocation() {
+ return null;
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/client/IVariantProvider.java b/src/main/java/WayofTime/bloodmagic/client/IVariantProvider.java
new file mode 100644
index 00000000..cffbd900
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/client/IVariantProvider.java
@@ -0,0 +1,13 @@
+package WayofTime.bloodmagic.client;
+
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import net.minecraft.block.Block;
+
+import javax.annotation.Nonnull;
+
+public interface IVariantProvider {
+
+ default void gatherVariants(@Nonnull Int2ObjectMap variants) {
+ variants.put(0, this instanceof Block ? "normal" : "inventory");
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/client/Sprite.java b/src/main/java/WayofTime/bloodmagic/client/Sprite.java
new file mode 100644
index 00000000..f6e54ea6
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/client/Sprite.java
@@ -0,0 +1,58 @@
+package WayofTime.bloodmagic.client;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.BufferBuilder;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
+import net.minecraft.util.ResourceLocation;
+
+public class Sprite {
+
+ private final ResourceLocation textureLocation;
+ private final int textureX;
+ private final int textureY;
+ private final int textureWidth;
+ private final int textureHeight;
+
+ public Sprite(ResourceLocation textureLocation, int textureX, int textureY, int textureWidth, int textureHeight) {
+ this.textureLocation = textureLocation;
+ this.textureX = textureX;
+ this.textureY = textureY;
+ this.textureWidth = textureWidth;
+ this.textureHeight = textureHeight;
+ }
+
+ public ResourceLocation getTextureLocation() {
+ return textureLocation;
+ }
+
+ public int getTextureX() {
+ return textureX;
+ }
+
+ public int getTextureY() {
+ return textureY;
+ }
+
+ public int getTextureWidth() {
+ return textureWidth;
+ }
+
+ public int getTextureHeight() {
+ return textureHeight;
+ }
+
+ public void draw(int x, int y) {
+ Minecraft.getInstance().renderEngine.bindTexture(textureLocation);
+ float f = 0.00390625F;
+ float f1 = 0.00390625F;
+ Tessellator tessellator = Tessellator.getInstance();
+ BufferBuilder buffer = tessellator.getBuffer();
+ buffer.begin(7, DefaultVertexFormats.POSITION_TEX);
+ buffer.pos((double) x, (double) (y + getTextureHeight()), 1.0F).tex((double) ((float) (getTextureX()) * f), (double) ((float) (getTextureY() + getTextureHeight()) * f1)).endVertex();
+ buffer.pos((double) (x + getTextureWidth()), (double) (y + getTextureHeight()), 1.0F).tex((double) ((float) (getTextureX() + getTextureWidth()) * f), (double) ((float) (getTextureY() + getTextureHeight()) * f1)).endVertex();
+ buffer.pos((double) (x + getTextureWidth()), (double) (y), 1.0F).tex((double) ((float) (getTextureX() + getTextureWidth()) * f), (double) ((float) (getTextureY()) * f1)).endVertex();
+ buffer.pos((double) x, (double) (y), 1.0F).tex((double) ((float) (getTextureX()) * f), (double) ((float) (getTextureY()) * f1)).endVertex();
+ tessellator.draw();
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/client/gui/GuiAlchemyTable.java b/src/main/java/WayofTime/bloodmagic/client/gui/GuiAlchemyTable.java
new file mode 100644
index 00000000..3a203214
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/client/gui/GuiAlchemyTable.java
@@ -0,0 +1,65 @@
+package WayofTime.bloodmagic.client.gui;
+
+import WayofTime.bloodmagic.BloodMagic;
+import WayofTime.bloodmagic.tile.TileAlchemyTable;
+import WayofTime.bloodmagic.tile.container.ContainerAlchemyTable;
+import WayofTime.bloodmagic.util.helper.TextHelper;
+import net.minecraft.client.gui.screen.inventory.ContainerScreen;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.container.Slot;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+public class GuiAlchemyTable extends ContainerScreen {
+ public IInventory tileTable;
+
+ public GuiAlchemyTable(PlayerInventory playerInventory, IInventory tileTable) {
+ super(new ContainerAlchemyTable(playerInventory, tileTable));
+ this.tileTable = tileTable;
+ this.xSize = 176;
+ this.ySize = 205;
+ }
+
+ @Override
+ public void drawScreen(int mouseX, int mouseY, float partialTicks) {
+ this.drawDefaultBackground();
+ super.drawScreen(mouseX, mouseY, partialTicks);
+ this.renderHoveredToolTip(mouseX, mouseY);
+ }
+
+ @Override
+ protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
+ this.fontRenderer.drawString(TextHelper.localize("tile.bloodmagic.alchemyTable.name"), 8, 5, 4210752);
+ this.fontRenderer.drawString(TextHelper.localize("container.inventory"), 8, 111, 4210752);
+ }
+
+ @Override
+ protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
+ GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
+ ResourceLocation soulForgeGuiTextures = new ResourceLocation(BloodMagic.MODID + ":textures/gui/alchemyTable.png");
+ this.mc.getTextureManager().bindTexture(soulForgeGuiTextures);
+ int i = (this.width - this.xSize) / 2;
+ int j = (this.height - this.ySize) / 2;
+ this.drawTexturedModalRect(i, j, 0, 0, this.xSize, this.ySize);
+
+ int l = this.getCookProgressScaled(90);
+ this.drawTexturedModalRect(i + 115, j + 14 + 90 - l, 176, 90 - l, 18, l);
+
+ for (int slotId = 0; slotId < 6; slotId++) {
+ if (!((TileAlchemyTable) tileTable).isInputSlotAccessible(slotId)) {
+ Slot slot = this.inventorySlots.getSlot(slotId);
+
+ this.drawTexturedModalRect(i + slot.xPos, j + slot.yPos, 195, 1, 16, 16);
+ }
+ }
+ }
+
+ public int getCookProgressScaled(int scale) {
+ double progress = ((TileAlchemyTable) tileTable).getProgressForGui();
+ return (int) (progress * scale);
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/client/gui/GuiBloodMagicConfig.java b/src/main/java/WayofTime/bloodmagic/client/gui/GuiBloodMagicConfig.java
new file mode 100644
index 00000000..a14c5710
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/client/gui/GuiBloodMagicConfig.java
@@ -0,0 +1,64 @@
+package WayofTime.bloodmagic.client.gui;
+
+import WayofTime.bloodmagic.BloodMagic;
+import WayofTime.bloodmagic.ConfigHandler;
+import WayofTime.bloodmagic.client.hud.ConfigEntryEditHUD;
+import com.google.common.collect.Lists;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraftforge.common.config.ConfigElement;
+import net.minecraftforge.fml.client.IModGuiFactory;
+import net.minecraftforge.fml.client.config.DummyConfigElement;
+import net.minecraftforge.fml.client.config.GuiConfig;
+import net.minecraftforge.fml.client.config.IConfigElement;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+public class GuiBloodMagicConfig extends GuiConfig {
+
+ public GuiBloodMagicConfig(Screen parentScreen) {
+ super(parentScreen, getElements(), BloodMagic.MODID, false, false, BloodMagic.NAME);
+ }
+
+ public static List getElements() {
+ List elements = Lists.newArrayList();
+
+ elements.addAll(ConfigElement.from(ConfigHandler.class).getChildElements());
+ elements.add(new ConfigElement(BloodMagic.RITUAL_MANAGER.getConfig().getCategory("rituals")));
+ if (Minecraft.getInstance().world != null)
+ elements.add(new DummyElementEditHUD(BloodMagic.NAME, "config." + BloodMagic.MODID + ".edit_hud"));
+
+ return elements;
+ }
+
+ public static class DummyElementEditHUD extends DummyConfigElement.DummyCategoryElement {
+
+ public DummyElementEditHUD(String name, String langKey) {
+ super(name, langKey, Collections.emptyList(), ConfigEntryEditHUD.class);
+ }
+ }
+
+ public static class Factory implements IModGuiFactory {
+ @Override
+ public void initialize(Minecraft minecraftInstance) {
+
+ }
+
+ @Override
+ public boolean hasConfigGui() {
+ return true;
+ }
+
+ @Override
+ public Screen createConfigGui(Screen parentScreen) {
+ return new GuiBloodMagicConfig(parentScreen);
+ }
+
+ @Override
+ public Set runtimeGuiCategories() {
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/client/gui/GuiHandler.java b/src/main/java/WayofTime/bloodmagic/client/gui/GuiHandler.java
new file mode 100644
index 00000000..a942839d
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/client/gui/GuiHandler.java
@@ -0,0 +1,64 @@
+package WayofTime.bloodmagic.client.gui;
+
+import WayofTime.bloodmagic.util.Constants;
+import WayofTime.bloodmagic.item.inventory.ContainerHolding;
+import WayofTime.bloodmagic.item.inventory.InventoryHolding;
+import WayofTime.bloodmagic.tile.TileAlchemyTable;
+import WayofTime.bloodmagic.tile.TileSoulForge;
+import WayofTime.bloodmagic.tile.TileTeleposer;
+import WayofTime.bloodmagic.tile.container.*;
+import WayofTime.bloodmagic.tile.routing.TileFilteredRoutingNode;
+import WayofTime.bloodmagic.tile.routing.TileMasterRoutingNode;
+import net.minecraft.client.world.ClientWorld;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.World;
+import net.minecraftforge.fml.common.network.IGuiHandler;
+
+public class GuiHandler implements IGuiHandler {
+ @Override
+ public Object getServerGuiElement(int id, PlayerEntity player, World world, int x, int y, int z) {
+ BlockPos pos = new BlockPos(x, y, z);
+
+ switch (id) {
+ case Constants.Gui.TELEPOSER_GUI:
+ return new ContainerTeleposer(player.inventory, (TileTeleposer) world.getTileEntity(pos));
+ case Constants.Gui.SOUL_FORGE_GUI:
+ return new ContainerSoulForge(player.inventory, (TileSoulForge) world.getTileEntity(pos));
+ case Constants.Gui.ROUTING_NODE_GUI:
+ return new ContainerItemRoutingNode(player.inventory, (TileFilteredRoutingNode) world.getTileEntity(pos));
+ case Constants.Gui.MASTER_ROUTING_NODE_GUI:
+ return new ContainerMasterRoutingNode(player.inventory, (TileMasterRoutingNode) world.getTileEntity(pos));
+ case Constants.Gui.ALCHEMY_TABLE_GUI:
+ return new ContainerAlchemyTable(player.inventory, (TileAlchemyTable) world.getTileEntity(pos));
+ case Constants.Gui.SIGIL_HOLDING_GUI:
+ return new ContainerHolding(player, new InventoryHolding(player.getHeldItemMainhand()));
+ }
+
+ return null;
+ }
+
+ @Override
+ public Object getClientGuiElement(int id, PlayerEntity player, World world, int x, int y, int z) {
+ if (world instanceof ClientWorld) {
+ BlockPos pos = new BlockPos(x, y, z);
+
+ switch (id) {
+ case Constants.Gui.TELEPOSER_GUI:
+ return new GuiTeleposer(player.inventory, (TileTeleposer) world.getTileEntity(pos));
+ case Constants.Gui.SOUL_FORGE_GUI:
+ return new GuiSoulForge(player.inventory, (TileSoulForge) world.getTileEntity(pos));
+ case Constants.Gui.ROUTING_NODE_GUI:
+ return new GuiItemRoutingNode(player.inventory, (TileFilteredRoutingNode) world.getTileEntity(pos));
+ case Constants.Gui.MASTER_ROUTING_NODE_GUI:
+ return new GuiMasterRoutingNode(player.inventory, (TileMasterRoutingNode) world.getTileEntity(pos));
+ case Constants.Gui.ALCHEMY_TABLE_GUI:
+ return new GuiAlchemyTable(player.inventory, (TileAlchemyTable) world.getTileEntity(pos));
+ case Constants.Gui.SIGIL_HOLDING_GUI:
+ return new GuiHolding(player, new InventoryHolding(player.getHeldItemMainhand()));
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/client/gui/GuiHolding.java b/src/main/java/WayofTime/bloodmagic/client/gui/GuiHolding.java
new file mode 100644
index 00000000..d20cb33e
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/client/gui/GuiHolding.java
@@ -0,0 +1,57 @@
+package WayofTime.bloodmagic.client.gui;
+
+import WayofTime.bloodmagic.BloodMagic;
+import WayofTime.bloodmagic.core.RegistrarBloodMagicItems;
+import WayofTime.bloodmagic.item.inventory.ContainerHolding;
+import WayofTime.bloodmagic.item.inventory.InventoryHolding;
+import WayofTime.bloodmagic.item.sigil.ItemSigilHolding;
+import WayofTime.bloodmagic.util.helper.TextHelper;
+import net.minecraft.client.gui.screen.inventory.ContainerScreen;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.Hand;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+public class GuiHolding extends ContainerScreen {
+ private ResourceLocation texture = new ResourceLocation(BloodMagic.MODID, "gui/SigilHolding.png");
+ private PlayerEntity player;
+
+ public GuiHolding(PlayerEntity player, InventoryHolding inventoryHolding) {
+ super(new ContainerHolding(player, inventoryHolding));
+ xSize = 176;
+ ySize = 121;
+ this.player = player;
+ }
+
+ @Override
+ public void drawScreen(int mouseX, int mouseY, float partialTicks) {
+ this.drawDefaultBackground();
+ super.drawScreen(mouseX, mouseY, partialTicks);
+ this.renderHoveredToolTip(mouseX, mouseY);
+ }
+
+ @Override
+ protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
+ //the parameters for drawString are: string, x, y, color
+ fontRenderer.drawString(TextHelper.localize("item.bloodmagic.sigil.holding.name"), 53, 4, 4210752);
+ }
+
+ @Override
+ protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouse) {
+ //draw your Gui here, only thing you need to change is the path
+ GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
+ this.mc.getTextureManager().bindTexture(texture);
+ int x = (width - xSize) / 2;
+ int y = (height - ySize) / 2;
+ this.drawTexturedModalRect(x, y, 0, 0, xSize, ySize);
+ ItemStack held = player.getHeldItem(Hand.MAIN_HAND);
+ if (!held.isEmpty() && held.getItem() == RegistrarBloodMagicItems.SIGIL_HOLDING) {
+ GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
+ this.drawTexturedModalRect(4 + x + 36 * ItemSigilHolding.getCurrentItemOrdinal(player.getHeldItemMainhand()), y + 13, 0, 123, 24, 24);
+ }
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/client/gui/GuiItemRoutingNode.java b/src/main/java/WayofTime/bloodmagic/client/gui/GuiItemRoutingNode.java
new file mode 100644
index 00000000..edf65f6a
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/client/gui/GuiItemRoutingNode.java
@@ -0,0 +1,200 @@
+package WayofTime.bloodmagic.client.gui;
+
+import WayofTime.bloodmagic.BloodMagic;
+import WayofTime.bloodmagic.network.BloodMagicPacketHandler;
+import WayofTime.bloodmagic.network.ItemRouterAmountPacketProcessor;
+import WayofTime.bloodmagic.network.ItemRouterButtonPacketProcessor;
+import WayofTime.bloodmagic.tile.container.ContainerItemRoutingNode;
+import WayofTime.bloodmagic.tile.routing.TileFilteredRoutingNode;
+import WayofTime.bloodmagic.util.GhostItemHelper;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.screen.inventory.ContainerScreen;
+import net.minecraft.client.gui.widget.TextFieldWidget;
+import net.minecraft.client.gui.widget.button.Button;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.container.Slot;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.Direction;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+import java.io.IOException;
+
+@SideOnly(Side.CLIENT)
+public class GuiItemRoutingNode extends ContainerScreen {
+ private TextFieldWidget textBox;
+
+ private TileFilteredRoutingNode inventory;
+ private ContainerItemRoutingNode container;
+
+ private int left, top;
+
+ public GuiItemRoutingNode(PlayerInventory playerInventory, IInventory tileRoutingNode) {
+ super(new ContainerItemRoutingNode(playerInventory, tileRoutingNode));
+ this.xSize = 201;
+ this.ySize = 169;
+ inventory = (TileFilteredRoutingNode) tileRoutingNode;
+ container = (ContainerItemRoutingNode) this.inventorySlots;
+ }
+
+ private int getCurrentActiveSlotPriority() {
+ Direction direction = Direction.byIndex(inventory.currentActiveSlot);
+ if (direction != null) {
+ return inventory.getPriority(direction);
+ }
+
+ return 0;
+ }
+
+ @Override
+ public void initGui() {
+ super.initGui();
+ left = (this.width - this.xSize) / 2;
+ top = (this.height - this.ySize) / 2;
+
+ this.buttonList.clear();
+ this.buttonList.add(new Button(0, left + 176, top + 14, 18, 18, "D"));
+ this.buttonList.add(new Button(1, left + 176, top + 32, 18, 18, "U"));
+ this.buttonList.add(new Button(2, left + 176, top + 50, 18, 18, "N"));
+ this.buttonList.add(new Button(3, left + 176, top + 68, 18, 18, "S"));
+ this.buttonList.add(new Button(4, left + 176, top + 86, 18, 18, "W"));
+ this.buttonList.add(new Button(5, left + 176, top + 104, 18, 18, "E"));
+ this.buttonList.add(new Button(6, left + 160, top + 50, 10, 18, ">"));
+ this.buttonList.add(new Button(7, left + 132, top + 50, 10, 18, "<"));
+ disableDirectionalButton(inventory.currentActiveSlot);
+
+ this.textBox = new TextFieldWidget(0, this.fontRenderer, left + 94, top + 37, 70, 12);
+ this.textBox.setEnableBackgroundDrawing(false);
+ this.textBox.setText("");
+ }
+
+ @Override
+ protected void keyTyped(char typedChar, int keyCode) throws IOException {
+ if (this.textBox.textboxKeyTyped(typedChar, keyCode)) {
+ if (container.lastGhostSlotClicked != -1) {
+// this.renameItem();
+ String str = this.textBox.getText();
+ int amount = 0;
+
+ if (!str.isEmpty()) {
+ try {
+ Integer testVal = Integer.decode(str);
+ if (testVal != null) {
+ amount = testVal;
+ }
+ } catch (NumberFormatException d) {
+ }
+ }
+
+// inventory.setGhostItemAmount(container.lastGhostSlotClicked, amount);
+ setValueOfGhostItemInSlot(container.lastGhostSlotClicked, amount);
+ }
+ } else {
+ super.keyTyped(typedChar, keyCode);
+ }
+ }
+
+ private void setValueOfGhostItemInSlot(int ghostItemSlot, int amount) {
+ BloodMagicPacketHandler.INSTANCE.sendToServer(new ItemRouterAmountPacketProcessor(ghostItemSlot, amount, inventory.getPos(), inventory.getWorld()));
+ }
+
+ /**
+ * Called when the mouse is clicked. Args : mouseX, mouseY, clickedButton
+ */
+ @Override
+ protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
+ super.mouseClicked(mouseX, mouseY, mouseButton);
+ this.textBox.mouseClicked(mouseX, mouseY, mouseButton);
+ if (container.lastGhostSlotClicked != -1) {
+ Slot slot = container.getSlot(container.lastGhostSlotClicked + 1);
+ ItemStack stack = slot.getStack();
+ if (!stack.isEmpty()) {
+ int amount = GhostItemHelper.getItemGhostAmount(stack);
+ this.textBox.setText("" + amount);
+ } else {
+ this.textBox.setText("");
+ }
+ }
+ }
+
+ /**
+ * Draws the screen and all the components in it.
+ */
+ @Override
+ public void drawScreen(int mouseX, int mouseY, float partialTicks) {
+ this.drawDefaultBackground();
+ super.drawScreen(mouseX, mouseY, partialTicks);
+ this.renderHoveredToolTip(mouseX, mouseY);
+
+ Minecraft.getInstance().fontRenderer.drawString(inventory.getName(), xSize, ySize / 4, 4210752);
+ }
+
+ /**
+ * Called by the controls from the buttonList when activated. (Mouse pressed
+ * for buttons)
+ */
+ @Override
+ protected void actionPerformed(Button button) throws IOException {
+ if (button.enabled) {
+ BloodMagicPacketHandler.INSTANCE.sendToServer(new ItemRouterButtonPacketProcessor(button.id, inventory.getPos(), inventory.getWorld()));
+ if (button.id < 6) {
+ inventory.currentActiveSlot = button.id;
+ enableAllDirectionalButtons();
+ button.enabled = false;
+ }
+ }
+ }
+
+ private void enableAllDirectionalButtons() {
+ for (Button button : this.buttonList) {
+ button.enabled = true;
+ }
+ }
+
+ private void disableDirectionalButton(int id) {
+ this.buttonList.get(id).enabled = false;
+ }
+
+ @Override
+ protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
+ this.fontRenderer.drawString("" + getCurrentActiveSlotPriority(), 143 + 5, 51 + 4, 0xFFFFFF);
+ String s = "";
+ if (container.lastGhostSlotClicked != -1) {
+ ItemStack clickedStack = inventorySlots.getSlot(1 + container.lastGhostSlotClicked).getStack();
+ if (!clickedStack.isEmpty()) {
+ s = clickedStack.getDisplayName();
+ }
+ }
+
+ this.fontRenderer.drawStringWithShadow(s.substring(0, Math.min(16, s.length())), 81, 19, 0xFFFFFF);
+ }
+
+ @Override
+ protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
+ GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
+ ResourceLocation soulForgeGuiTextures = new ResourceLocation(BloodMagic.MODID + ":textures/gui/routingNode.png");
+ this.mc.getTextureManager().bindTexture(soulForgeGuiTextures);
+ this.drawTexturedModalRect(left, top, 0, 0, this.xSize, this.ySize);
+ GlStateManager.disableLighting();
+ GlStateManager.disableBlend();
+ this.textBox.drawTextBox();
+ }
+
+// @Override
+// public void sendSlotContents(Container containerToSend, int slotInd, ItemStack stack)
+// {
+// if (slotInd == 0)
+// {
+// this.nameField.setText(stack == null ? "" : stack.getOwnerName());
+// this.nameField.setEnabled(stack != null);
+//
+// if (stack != null)
+// {
+// this.renameItem();
+// }
+// }
+// }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/client/gui/GuiMasterRoutingNode.java b/src/main/java/WayofTime/bloodmagic/client/gui/GuiMasterRoutingNode.java
new file mode 100644
index 00000000..f8693ba3
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/client/gui/GuiMasterRoutingNode.java
@@ -0,0 +1,44 @@
+package WayofTime.bloodmagic.client.gui;
+
+import WayofTime.bloodmagic.BloodMagic;
+import WayofTime.bloodmagic.tile.container.ContainerMasterRoutingNode;
+import net.minecraft.client.gui.screen.inventory.ContainerScreen;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+public class GuiMasterRoutingNode extends ContainerScreen {
+
+ public GuiMasterRoutingNode(PlayerInventory playerInventory, IInventory tileRoutingNode) {
+ super(new ContainerMasterRoutingNode(playerInventory, tileRoutingNode));
+ this.xSize = 216;
+ this.ySize = 216;
+ }
+
+ @Override
+ public void drawScreen(int mouseX, int mouseY, float partialTicks) {
+ this.drawDefaultBackground();
+ super.drawScreen(mouseX, mouseY, partialTicks);
+ this.renderHoveredToolTip(mouseX, mouseY);
+ }
+
+ @Override
+ protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
+// this.fontRendererObj.drawString(TextHelper.localize("tile.bloodmagic.soulForge.name"), 8, 5, 4210752);
+// this.fontRendererObj.drawString(TextHelper.localize("container.inventory"), 8, 111, 4210752);
+ }
+
+ @Override
+ protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
+ GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
+ ResourceLocation soulForgeGuiTextures = new ResourceLocation(BloodMagic.MODID + ":textures/gui/masterRoutingNode.png");
+ this.mc.getTextureManager().bindTexture(soulForgeGuiTextures);
+ int i = (this.width - this.xSize) / 2;
+ int j = (this.height - this.ySize) / 2;
+ this.drawTexturedModalRect(i, j, 0, 0, this.xSize, this.ySize);
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/client/gui/GuiSoulForge.java b/src/main/java/WayofTime/bloodmagic/client/gui/GuiSoulForge.java
new file mode 100644
index 00000000..3e890f88
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/client/gui/GuiSoulForge.java
@@ -0,0 +1,56 @@
+package WayofTime.bloodmagic.client.gui;
+
+import WayofTime.bloodmagic.BloodMagic;
+import WayofTime.bloodmagic.tile.TileSoulForge;
+import WayofTime.bloodmagic.tile.container.ContainerSoulForge;
+import WayofTime.bloodmagic.util.helper.TextHelper;
+import net.minecraft.client.gui.screen.inventory.ContainerScreen;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+public class GuiSoulForge extends ContainerScreen {
+ public IInventory tileSoulForge;
+
+ public GuiSoulForge(PlayerInventory playerInventory, IInventory tileSoulForge) {
+ super(new ContainerSoulForge(playerInventory, tileSoulForge));
+ this.tileSoulForge = tileSoulForge;
+ this.xSize = 176;
+ this.ySize = 205;
+ }
+
+ @Override
+ public void drawScreen(int mouseX, int mouseY, float partialTicks) {
+ this.drawDefaultBackground();
+ super.drawScreen(mouseX, mouseY, partialTicks);
+ this.renderHoveredToolTip(mouseX, mouseY);
+ }
+
+ @Override
+ protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
+ this.fontRenderer.drawString(TextHelper.localize("tile.bloodmagic.soulForge.name"), 8, 5, 4210752);
+ this.fontRenderer.drawString(TextHelper.localize("container.inventory"), 8, 111, 4210752);
+ }
+
+ @Override
+ protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
+ GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
+ ResourceLocation soulForgeGuiTextures = new ResourceLocation(BloodMagic.MODID + ":textures/gui/soulForge.png");
+ this.mc.getTextureManager().bindTexture(soulForgeGuiTextures);
+ int i = (this.width - this.xSize) / 2;
+ int j = (this.height - this.ySize) / 2;
+ this.drawTexturedModalRect(i, j, 0, 0, this.xSize, this.ySize);
+
+ int l = this.getCookProgressScaled(90);
+ this.drawTexturedModalRect(i + 115, j + 14 + 90 - l, 176, 90 - l, 18, l);
+ }
+
+ public int getCookProgressScaled(int scale) {
+ double progress = ((TileSoulForge) tileSoulForge).getProgressForGui();
+ return (int) (progress * scale);
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/client/gui/GuiTeleposer.java b/src/main/java/WayofTime/bloodmagic/client/gui/GuiTeleposer.java
new file mode 100644
index 00000000..be9cde2e
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/client/gui/GuiTeleposer.java
@@ -0,0 +1,42 @@
+package WayofTime.bloodmagic.client.gui;
+
+import WayofTime.bloodmagic.BloodMagic;
+import WayofTime.bloodmagic.tile.container.ContainerTeleposer;
+import WayofTime.bloodmagic.util.helper.TextHelper;
+import net.minecraft.client.gui.screen.inventory.ContainerScreen;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+public class GuiTeleposer extends ContainerScreen {
+ public GuiTeleposer(PlayerInventory playerInventory, IInventory tileTeleposer) {
+ super(new ContainerTeleposer(playerInventory, tileTeleposer));
+ }
+
+ @Override
+ public void drawScreen(int mouseX, int mouseY, float partialTicks) {
+ this.drawDefaultBackground();
+ super.drawScreen(mouseX, mouseY, partialTicks);
+ this.renderHoveredToolTip(mouseX, mouseY);
+ }
+
+ @Override
+ protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
+ this.fontRenderer.drawString(TextHelper.localize("tile.bloodmagic.teleposer.name"), 64, 23, 4210752);
+ this.fontRenderer.drawString(TextHelper.localize("container.inventory"), 8, 47, 4210752);
+ }
+
+ @Override
+ protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
+ GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
+ ResourceLocation teleposerGuiTextures = new ResourceLocation(BloodMagic.MODID + ":textures/gui/teleposer.png");
+ this.mc.getTextureManager().bindTexture(teleposerGuiTextures);
+ int i = (this.width - this.xSize) / 2;
+ int j = (this.height - this.ySize) / 2;
+ this.drawTexturedModalRect(i, j + 18, 0, 0, this.xSize, this.ySize);
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/client/helper/ShaderHelper.java b/src/main/java/WayofTime/bloodmagic/client/helper/ShaderHelper.java
new file mode 100644
index 00000000..950af569
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/client/helper/ShaderHelper.java
@@ -0,0 +1,182 @@
+package WayofTime.bloodmagic.client.helper;
+
+import net.minecraft.client.renderer.OpenGlHelper;
+import net.minecraftforge.fml.common.FMLLog;
+import org.apache.logging.log4j.Level;
+import org.lwjgl.opengl.ARBFragmentShader;
+import org.lwjgl.opengl.ARBShaderObjects;
+import org.lwjgl.opengl.ARBVertexShader;
+import org.lwjgl.opengl.GL11;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+/**
+ * This class was created by . It's distributed as
+ * part of the Botania Mod. Get the Source Code in github:
+ * https://github.com/Vazkii/Botania
+ *
+ * Botania is Open Source and distributed under the
+ * Botania License: http://botaniamod.net/license.php
+ *
+ * File Created @ [Apr 9, 2014, 11:20:26 PM (GMT)]
+ */
+public final class ShaderHelper {
+ private static final int VERT_ST = ARBVertexShader.GL_VERTEX_SHADER_ARB;
+ private static final int FRAG_ST = ARBFragmentShader.GL_FRAGMENT_SHADER_ARB;
+
+ private static final int VERT = 1;
+ private static final int FRAG = 2;
+
+ private static final String VERT_EXTENSION = ".vsh";
+ private static final String FRAG_EXTENSION = ".frag";
+
+ public static int psiBar;
+
+ public static void init() {
+ if (!useShaders())
+ return;
+
+ psiBar = createProgram("/assets/bloodmagic/shaders/beam", FRAG);
+ }
+
+ public static void useShader(int shader, int ticks) {
+ if (!useShaders())
+ return;
+
+ ARBShaderObjects.glUseProgramObjectARB(shader);
+
+ if (shader != 0) {
+ int time = ARBShaderObjects.glGetUniformLocationARB(shader, "time");
+ ARBShaderObjects.glUniform1iARB(time, ticks);
+ }
+ }
+
+ public static void releaseShader() {
+ useShader(0, 0);
+ }
+
+ public static boolean useShaders() {
+ return OpenGlHelper.shadersSupported;
+ }
+
+ private static int createProgram(String s, int sides) {
+ boolean vert = (sides & VERT) != 0;
+ boolean frag = (sides & FRAG) != 0;
+
+ return createProgram(vert ? (s + VERT_EXTENSION) : null, frag ? (s + FRAG_EXTENSION) : null);
+ }
+
+ // Most of the code taken from the LWJGL wiki
+ // http://lwjgl.org/wiki/index.php?title=GLSL_Shaders_with_LWJGL
+
+ private static int createProgram(String vert, String frag) {
+ int vertId = 0, fragId = 0, program = 0;
+ if (vert != null)
+ vertId = createShader(vert, VERT_ST);
+ if (frag != null)
+ fragId = createShader(frag, FRAG_ST);
+
+ program = ARBShaderObjects.glCreateProgramObjectARB();
+ if (program == 0)
+ return 0;
+
+ if (vert != null)
+ ARBShaderObjects.glAttachObjectARB(program, vertId);
+ if (frag != null)
+ ARBShaderObjects.glAttachObjectARB(program, fragId);
+
+ ARBShaderObjects.glLinkProgramARB(program);
+ if (ARBShaderObjects.glGetObjectParameteriARB(program, ARBShaderObjects.GL_OBJECT_LINK_STATUS_ARB) == GL11.GL_FALSE) {
+ FMLLog.log(Level.ERROR, getLogInfo(program));
+ return 0;
+ }
+
+ ARBShaderObjects.glValidateProgramARB(program);
+ if (ARBShaderObjects.glGetObjectParameteriARB(program, ARBShaderObjects.GL_OBJECT_VALIDATE_STATUS_ARB) == GL11.GL_FALSE) {
+ FMLLog.log(Level.ERROR, getLogInfo(program));
+ return 0;
+ }
+
+ return program;
+ }
+
+ private static int createShader(String filename, int shaderType) {
+ int shader = 0;
+ try {
+ shader = ARBShaderObjects.glCreateShaderObjectARB(shaderType);
+
+ if (shader == 0)
+ return 0;
+
+ ARBShaderObjects.glShaderSourceARB(shader, readFileAsString(filename));
+ ARBShaderObjects.glCompileShaderARB(shader);
+
+ if (ARBShaderObjects.glGetObjectParameteriARB(shader, ARBShaderObjects.GL_OBJECT_COMPILE_STATUS_ARB) == GL11.GL_FALSE)
+ throw new RuntimeException("Error creating shader: " + getLogInfo(shader));
+
+ return shader;
+ } catch (Exception e) {
+ ARBShaderObjects.glDeleteObjectARB(shader);
+ e.printStackTrace();
+ return -1;
+ }
+ }
+
+ private static String getLogInfo(int obj) {
+ return ARBShaderObjects.glGetInfoLogARB(obj, ARBShaderObjects.glGetObjectParameteriARB(obj, ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB));
+ }
+
+ private static String readFileAsString(String filename) throws Exception {
+ StringBuilder source = new StringBuilder();
+ InputStream in = ShaderHelper.class.getResourceAsStream(filename);
+ Exception exception = null;
+ BufferedReader reader;
+
+ if (in == null)
+ return "";
+
+ try {
+ reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
+
+ Exception innerExc = null;
+ try {
+ String line;
+ while ((line = reader.readLine()) != null)
+ source.append(line).append('\n');
+ } catch (Exception exc) {
+ exception = exc;
+ } finally {
+ try {
+ reader.close();
+ } catch (Exception exc) {
+ if (innerExc == null)
+ innerExc = exc;
+ else
+ exc.printStackTrace();
+ }
+ }
+
+ if (innerExc != null)
+ throw innerExc;
+ } catch (Exception exc) {
+ exception = exc;
+ } finally {
+ try {
+ in.close();
+ } catch (Exception exc) {
+ if (exception == null)
+ exception = exc;
+ else
+ exc.printStackTrace();
+ }
+
+ if (exception != null)
+ throw exception;
+ }
+
+ return source.toString();
+ }
+
+}
diff --git a/src/main/java/WayofTime/bloodmagic/client/hud/ConfigEntryEditHUD.java b/src/main/java/WayofTime/bloodmagic/client/hud/ConfigEntryEditHUD.java
new file mode 100644
index 00000000..d713e3b6
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/client/hud/ConfigEntryEditHUD.java
@@ -0,0 +1,39 @@
+package WayofTime.bloodmagic.client.hud;
+
+import net.minecraftforge.fml.client.config.GuiConfig;
+import net.minecraftforge.fml.client.config.GuiConfigEntries;
+import net.minecraftforge.fml.client.config.IConfigElement;
+
+public class ConfigEntryEditHUD extends GuiConfigEntries.CategoryEntry {
+
+ public ConfigEntryEditHUD(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement element) {
+ super(owningScreen, owningEntryList, element);
+
+ this.childScreen = new GuiEditHUD(owningScreen);
+ }
+
+ @Override
+ public boolean isDefault() {
+ return true;
+ }
+
+ @Override
+ public void setToDefault() {
+ ElementRegistry.resetPos();
+ }
+
+ @Override
+ public boolean isChanged() {
+ return ((GuiEditHUD) childScreen).changes;
+ }
+
+ @Override
+ public void undoChanges() {
+
+ }
+
+ @Override
+ public boolean saveConfigElement() {
+ return false;
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/client/hud/ElementInfo.java b/src/main/java/WayofTime/bloodmagic/client/hud/ElementInfo.java
new file mode 100644
index 00000000..9544dcdc
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/client/hud/ElementInfo.java
@@ -0,0 +1,39 @@
+package WayofTime.bloodmagic.client.hud;
+
+import javax.vecmath.Vector2f;
+
+public class ElementInfo {
+
+ public static final ElementInfo DUMMY = new ElementInfo(new Vector2f(0F, 0F), ElementRegistry.getRandomColor());
+
+ private final Vector2f defaultPosition;
+ private final int boxColor;
+ private Vector2f currentPosition;
+
+ public ElementInfo(Vector2f defaultPosition, int boxColor) {
+ this.defaultPosition = defaultPosition;
+ this.boxColor = boxColor;
+ this.currentPosition = defaultPosition;
+ }
+
+ public Vector2f getDefaultPosition() {
+ return defaultPosition;
+ }
+
+ public int getBoxColor() {
+ return boxColor;
+ }
+
+ public ElementInfo setPosition(Vector2f position) {
+ this.currentPosition = position;
+ return this;
+ }
+
+ public Vector2f getPosition() {
+ return currentPosition;
+ }
+
+ public void resetPosition() {
+ this.currentPosition = defaultPosition;
+ }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/client/hud/ElementRegistry.java b/src/main/java/WayofTime/bloodmagic/client/hud/ElementRegistry.java
new file mode 100644
index 00000000..642ea5e4
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/client/hud/ElementRegistry.java
@@ -0,0 +1,149 @@
+package WayofTime.bloodmagic.client.hud;
+
+import WayofTime.bloodmagic.BloodMagic;
+import WayofTime.bloodmagic.client.hud.element.HUDElement;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Maps;
+import com.google.common.reflect.TypeToken;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.client.event.RenderGameOverlayEvent;
+import net.minecraftforge.fml.common.Loader;
+import net.minecraftforge.fml.common.Mod;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+import javax.vecmath.Vector2f;
+import java.awt.Color;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.function.BiFunction;
+
+@Mod.EventBusSubscriber(modid = BloodMagic.MODID, value = Side.CLIENT)
+public class ElementRegistry {
+
+ private static final File CONFIG = new File(Loader.instance().getConfigDir(), BloodMagic.MODID + "/hud_elements.json");
+ private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
+ private static final Map HUD_ELEMENTS = Maps.newLinkedHashMap();
+ private static final Map REVERSE = Maps.newHashMap();
+ private static final Map ELEMENT_INFO = Maps.newHashMap();
+
+ public static void registerHandler(ResourceLocation key, HUDElement element, Vector2f defaultPosition) {
+ HUD_ELEMENTS.put(key, element);
+ REVERSE.put(element, key);
+
+
+ ELEMENT_INFO.put(key, new ElementInfo(defaultPosition, getRandomColor()));
+ }
+
+ public static void resetPos() {
+ ELEMENT_INFO.values().forEach(ElementInfo::resetPosition);
+ }
+
+ public static List getElements() {
+ return ImmutableList.copyOf(HUD_ELEMENTS.values());
+ }
+
+ public static ResourceLocation getKey(HUDElement element) {
+ return REVERSE.get(element);
+ }
+
+ public static int getColor(ResourceLocation element) {
+ return ELEMENT_INFO.getOrDefault(element, ElementInfo.DUMMY).getBoxColor();
+ }
+
+ public static Vector2f getPosition(ResourceLocation element) {
+ return ELEMENT_INFO.get(element).getPosition();
+ }
+
+ public static void setPosition(ResourceLocation element, Vector2f point) {
+ ELEMENT_INFO.compute(element, (resourceLocation, elementInfo) -> {
+ if (elementInfo == null)
+ return new ElementInfo(point, getRandomColor());
+
+ elementInfo.setPosition(point);
+ return elementInfo;
+ });
+ }
+
+ public static void save(Map newLocations) {
+ newLocations.forEach((k, v) -> {
+ ElementInfo info = ELEMENT_INFO.get(k);
+ if (info != null)
+ info.setPosition(v);
+ });
+
+ Map toWrite = Maps.newHashMap();
+ for (Map.Entry entry : ELEMENT_INFO.entrySet())
+ toWrite.put(entry.getKey().toString(), entry.getValue().getPosition());
+
+ String json = GSON.toJson(toWrite);
+ try (FileWriter writer = new FileWriter(CONFIG)) {
+ writer.write(json);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void readConfig() {
+ if (!CONFIG.exists())
+ return;
+
+ try (FileReader reader = new FileReader(CONFIG)) {
+ Map toLoad = GSON.fromJson(reader, new TypeToken