diff --git a/.gitignore b/.gitignore index efa356a..d7f5e11 100644 --- a/.gitignore +++ b/.gitignore @@ -70,3 +70,4 @@ gradle/ gradlew gradlew.bat logs/ +!/run/eula.txt diff --git a/run/eula.txt b/run/eula.txt new file mode 100644 index 0000000..f943552 --- /dev/null +++ b/run/eula.txt @@ -0,0 +1,3 @@ +#By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula). +#Sun Mar 12 21:15:07 CDT 2017 +eula=true diff --git a/src/main/java/com/quantumindustries/minecraft/mod/CustomMod.java b/src/main/java/com/quantumindustries/minecraft/mod/CustomMod.java index 63ffd61..3ec0893 100644 --- a/src/main/java/com/quantumindustries/minecraft/mod/CustomMod.java +++ b/src/main/java/com/quantumindustries/minecraft/mod/CustomMod.java @@ -20,11 +20,15 @@ public class CustomMod { serverSide = "com.quantumindustries.minecraft.mod.proxy.CommonProxy") public static CommonProxy proxy; - @Mod.Instance + @Mod.Instance(MODID) public static CustomMod instance; public static final CustomTab tab = new CustomTab(); + public enum GUI { + GRINDER + } + static { FluidRegistry.enableUniversalBucket(); } diff --git a/src/main/java/com/quantumindustries/minecraft/mod/blocks/ModBlocks.java b/src/main/java/com/quantumindustries/minecraft/mod/blocks/ModBlocks.java index 6d9a576..648887c 100644 --- a/src/main/java/com/quantumindustries/minecraft/mod/blocks/ModBlocks.java +++ b/src/main/java/com/quantumindustries/minecraft/mod/blocks/ModBlocks.java @@ -2,9 +2,11 @@ import com.quantumindustries.minecraft.mod.CustomMod; import com.quantumindustries.minecraft.mod.ItemModelProvider; +import com.quantumindustries.minecraft.mod.blocks.grinder.BlockGrinder; import com.quantumindustries.minecraft.mod.blocks.infiniteproducer.BlockInfiniteProducer; import com.quantumindustries.minecraft.mod.blocks.poweranalyzer.BlockPowerAnalyzer; import com.quantumindustries.minecraft.mod.items.ItemOreDict; +import com.quantumindustries.minecraft.mod.tileentities.BlockContainerTileEntity; import com.quantumindustries.minecraft.mod.multiblock.*; import com.quantumindustries.minecraft.mod.tileentities.BlockTileEntity; import net.minecraft.block.Block; @@ -15,7 +17,7 @@ public class ModBlocks { - // BlockOres + // Ores public static BlockOre oreCobalt; public static BlockOre oreNeodymium; public static BlockOre oreRhodium; @@ -23,11 +25,14 @@ public class ModBlocks { public static BlockOre blockNeodymium; public static BlockOre blockRhodium; - // BlockBase + // Magnets public static BlockBase blockNeoIronMagnet; public static BlockBase blockNeoCobaltMagnet; public static BlockBase blockNeoRhodiumMagnet; + // Miscellaneous + public static BlockGrinder blockGrinder; + // Particle Accelerator Blocks public static ParticleAcceleratorBlockWall blockAcceleratorWall; public static ParticleAcceleratorBlockPort blockAcceleratorPowerPort; @@ -44,9 +49,13 @@ public static void init() { initMagnetBlocks(); initOres(); initOreBlocks(); + initParticleAcceleratorBlocks(); + register(new BlockInfiniteProducer()); register(new BlockPowerAnalyzer()); + + blockGrinder = register(new BlockGrinder()); } private static void initMagnetBlocks() { @@ -133,10 +142,16 @@ private static T register(T block, ItemBlock itemBlock) { ); } + if(block instanceof BlockContainerTileEntity) { + GameRegistry.registerTileEntity( + ((BlockContainerTileEntity) block).getTileEntityClass(), + block.getRegistryName().toString() + ); + } + if(itemBlock instanceof ItemOreDict) { ((ItemOreDict) itemBlock).initOreDict(); } - } return block; diff --git a/src/main/java/com/quantumindustries/minecraft/mod/blocks/grinder/BlockGrinder.java b/src/main/java/com/quantumindustries/minecraft/mod/blocks/grinder/BlockGrinder.java new file mode 100644 index 0000000..6591400 --- /dev/null +++ b/src/main/java/com/quantumindustries/minecraft/mod/blocks/grinder/BlockGrinder.java @@ -0,0 +1,231 @@ +package com.quantumindustries.minecraft.mod.blocks.grinder; + +import java.util.Random; + +import com.quantumindustries.minecraft.mod.CustomMod; +import com.quantumindustries.minecraft.mod.blocks.ModBlocks; +import com.quantumindustries.minecraft.mod.tileentities.BlockContainerTileEntity; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyDirection; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.InventoryHelper; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumBlockRenderType; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import javax.annotation.Nullable; + +public class BlockGrinder extends BlockContainerTileEntity { + + public static final PropertyDirection FACING = PropertyDirection.create( + "facing", EnumFacing.Plane.HORIZONTAL + ); + private boolean hasTileEntity; + + public BlockGrinder() { + super(Material.ROCK, "blockGrinder"); + setDefaultState(blockState.getBaseState().withProperty( + FACING, + EnumFacing.NORTH + )); + hasTileEntity = false; + blockSoundType = SoundType.SNOW; + blockParticleGravity = 1.0f; + slipperiness = 0.6f; + lightOpacity = 20; + setTickRandomly(false); + useNeighborBrightness = false; + } + + @Override + public Item getItemDropped(IBlockState state, Random rand, int fortune) { + return Item.getItemFromBlock(ModBlocks.blockGrinder); + } + + @Override + public void onBlockAdded(World world, BlockPos blockPos, IBlockState blockState) { + if(!world.isRemote) { + EnumFacing enumFacing = getUnblockedFace( + world, + blockPos, + blockState + ); + + world.setBlockState( + blockPos, + blockState.withProperty(FACING, enumFacing), + 2 + ); + } + } + + @Override + public boolean onBlockActivated(World world, BlockPos blockPos, + IBlockState blockState, EntityPlayer player, + EnumHand hand, ItemStack stack, EnumFacing facing, + float hitX, float hitY, float hitZ) { + if(!world.isRemote) { + player.openGui( + CustomMod.instance, + CustomMod.GUI.GRINDER.ordinal(), + world, + blockPos.getX(), + blockPos.getY(), + blockPos.getZ() + ); + } + + return true; + } + + @Override + public TileEntity createNewTileEntity(World worldIn, int meta) { + return new TileEntityGrinder(); + } + + @Override + public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, + float hitX, float hitY, float hitZ, int meta, + EntityLivingBase placer, ItemStack stack) { + return getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()); + } + + @Override + public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, + EntityLivingBase placer, ItemStack stack) { + worldIn.setBlockState(pos, state.withProperty( + FACING, + placer.getHorizontalFacing().getOpposite()), + 2 + ); + + if(stack.hasDisplayName()) { + TileEntity tileEntity = worldIn.getTileEntity(pos); + + if(tileEntity instanceof TileEntityGrinder) { + ((TileEntityGrinder) tileEntity).setCustomInventoryName(stack.getDisplayName()); + } + } + } + + @Override + public void breakBlock(World worldIn, BlockPos pos, IBlockState state) { + if(!hasTileEntity) { + TileEntity tileEntity = worldIn.getTileEntity(pos); + + if(tileEntity instanceof TileEntityGrinder) { + InventoryHelper.dropInventoryItems(worldIn, pos, (TileEntityGrinder) tileEntity); + worldIn.updateComparatorOutputLevel(pos, this); + } + } + + super.breakBlock(worldIn, pos, state); + } + + @Override + @SideOnly(Side.CLIENT) + public ItemStack getPickBlock(IBlockState state, RayTraceResult target, World world, + BlockPos pos, EntityPlayer player) { + return new ItemStack(Item.getItemFromBlock(ModBlocks.blockGrinder)); + } + + @Override + public EnumBlockRenderType getRenderType(IBlockState blockState) { + return EnumBlockRenderType.MODEL; + } + + @SuppressWarnings("deprecation") + @Override + public IBlockState getStateFromMeta(int meta) { + EnumFacing enumFacing = EnumFacing.getFront(meta); + + if(enumFacing.getAxis() == EnumFacing.Axis.Y) { + enumFacing = EnumFacing.NORTH; + } + + return getDefaultState().withProperty(FACING, enumFacing); + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(FACING).getIndex(); + } + + @Override + public Class getTileEntityClass() { + return TileEntityGrinder.class; + } + + @Nullable + @Override + public TileEntityGrinder createTileEntity(World world, IBlockState state) { + return new TileEntityGrinder(); + } + + @Override + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, new IProperty[] { FACING }); + } + + private EnumFacing getUnblockedFace(World world, BlockPos blockPos, IBlockState blockState) { + IBlockState blockToNorth = world.getBlockState(blockPos.north()); + IBlockState blockToSouth = world.getBlockState(blockPos.south()); + IBlockState blockToWest = world.getBlockState(blockPos.west()); + IBlockState blockToEast = world.getBlockState(blockPos.east()); + + EnumFacing enumFacing = blockState.getValue(FACING); + + if(shouldFaceSouth(blockToNorth, blockToSouth, enumFacing)) { + enumFacing = EnumFacing.SOUTH; + } + else if(shouldFaceNorth(blockToNorth, blockToSouth, enumFacing)) { + enumFacing = EnumFacing.NORTH; + } + else if(shouldFaceEast(blockToWest, blockToEast, enumFacing)) { + enumFacing = EnumFacing.EAST; + } + else if(shouldFaceWest(blockToWest, blockToEast, enumFacing)) { + enumFacing = EnumFacing.WEST; + } + + return enumFacing; + } + + private boolean shouldFaceSouth(IBlockState blockToNorth, IBlockState blockToSouth, EnumFacing enumFacing) { + return enumFacing == EnumFacing.NORTH && + blockToNorth.isFullBlock() && + !blockToSouth.isFullBlock(); + } + + private boolean shouldFaceNorth(IBlockState blockToNorth, IBlockState blockToSouth, EnumFacing enumFacing) { + return enumFacing == EnumFacing.SOUTH && + blockToSouth.isFullBlock() && + !blockToNorth.isFullBlock(); + } + + private boolean shouldFaceEast(IBlockState blockToWest, IBlockState blockToEast, EnumFacing enumFacing) { + return enumFacing == EnumFacing.WEST && + blockToWest.isFullBlock() && + !blockToEast.isFullBlock(); + } + + private boolean shouldFaceWest(IBlockState blockToWest, IBlockState blockToEast, EnumFacing enumFacing) { + return enumFacing == EnumFacing.EAST && + blockToEast.isFullBlock() && + !blockToWest.isFullBlock(); + } + +} diff --git a/src/main/java/com/quantumindustries/minecraft/mod/blocks/grinder/ContainerGrinder.java b/src/main/java/com/quantumindustries/minecraft/mod/blocks/grinder/ContainerGrinder.java new file mode 100644 index 0000000..2738230 --- /dev/null +++ b/src/main/java/com/quantumindustries/minecraft/mod/blocks/grinder/ContainerGrinder.java @@ -0,0 +1,199 @@ +package com.quantumindustries.minecraft.mod.blocks.grinder; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.IContainerListener; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +public class ContainerGrinder extends Container { + + private final IInventory tileGrinder; + private final int sizeInventory; + private int ticksGrindingItemSoFar; + private int ticksPerItem; + + public ContainerGrinder(InventoryPlayer inventoryPlayer, IInventory inventory) { + tileGrinder = inventory; + sizeInventory = tileGrinder.getSizeInventory(); + addContainerSlots(inventoryPlayer); + addPlayerInventorySlots(inventoryPlayer); + addHotbarSlots(inventoryPlayer); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for(int i = 0; i < listeners.size(); i++) { + IContainerListener listener = listeners.get(i); + + if(ticksGrindingItemSoFar != tileGrinder.getField(1)) { + listener.sendProgressBarUpdate(this, 1, tileGrinder.getField(1)); + } + + if(ticksPerItem != tileGrinder.getField(2)) { + listener.sendProgressBarUpdate(this, 2, tileGrinder.getField(2)); + } + } + + ticksGrindingItemSoFar = tileGrinder.getField(1); + ticksPerItem = tileGrinder.getField(2); + } + + @Override + @SideOnly(Side.CLIENT) + public void updateProgressBar(int id, int data) { + tileGrinder.setField(id, data); + } + + @Override + public boolean canInteractWith(EntityPlayer playerIn) { + return tileGrinder.isUseableByPlayer(playerIn); + } + + @Override + public ItemStack transferStackInSlot(EntityPlayer playerIn, int slotIndex) { + ItemStack itemStack1 = null; + Slot slot = inventorySlots.get(slotIndex); + + if(isValidSlot(slot)) { + ItemStack itemStack2 = slot.getStack(); + itemStack1 = itemStack2.copy(); + + if(isOutputSlot(slotIndex)) { + int start = sizeInventory; + int end = sizeInventory + 36; + if(!mergeItemStack(itemStack2, start, end, true)) { + return null; + } + slot.onSlotChange(itemStack2, itemStack1); + } + else { + Indices indices = getMergeIndices(itemStack2, slotIndex); + if(indices != null && + !mergeItemStack( + itemStack2, + indices.start, + indices.end, + false) + ) { + return null; + } + } + + if(itemStack2.stackSize == 0) { + slot.putStack(null); + } + else { + slot.onSlotChanged(); + } + + if(itemStack2.stackSize == itemStack1.stackSize) { + return null; + } + + slot.onPickupFromSlot(playerIn, itemStack2); + } + + return itemStack1; + } + + private boolean isPlayerInventorySlot(int slotIndex) { + return slotIndex >= sizeInventory && slotIndex < sizeInventory + 27; + } + + private void addContainerSlots(InventoryPlayer inventoryPlayer) { + addSlotToContainer(new Slot( + tileGrinder, + TileEntityGrinder.slotEnum.INPUT_SLOT.ordinal(), + 56, + 35 + )); + addSlotToContainer(new SlotGrinderOutput( + inventoryPlayer.player, + tileGrinder, + TileEntityGrinder.slotEnum.OUTPUT_SLOT.ordinal(), + 116, + 35 + )); + } + + private void addPlayerInventorySlots(InventoryPlayer inventoryPlayer) { + for(int i = 0; i < 3; ++i) { + for(int j = 0; j < 9; ++j) { + addSlotToContainer(new Slot( + inventoryPlayer, + j + i * 9 + 9, + 8 + j * 18, + 84 + i * 18 + )); + } + } + } + + private void addHotbarSlots(InventoryPlayer inventoryPlayer) { + for(int i = 0; i < 9; ++i) { + addSlotToContainer(new Slot( + inventoryPlayer, + i, + 8 + i * 18, + 142 + )); + } + } + + private boolean isValidSlot(Slot slot) { + return slot != null && slot.getHasStack(); + } + + private boolean isInputSlot(int slotIndex) { + return slotIndex == TileEntityGrinder.slotEnum.INPUT_SLOT.ordinal(); + } + + private boolean isOutputSlot(int slotIndex) { + return slotIndex == TileEntityGrinder.slotEnum.OUTPUT_SLOT.ordinal(); + } + + private Indices getMergeIndices(ItemStack itemStack, int slotIndex) { + if(!isInputSlot(slotIndex)) { + if(grindingRecipeExists(itemStack)) { + return new Indices(0, 1); + } + else if(isPlayerInventorySlot(slotIndex)) { + return new Indices(sizeInventory + 27, sizeInventory + 36); + } + else if(isHotbarSlot(slotIndex)) { + return new Indices(sizeInventory + 1, sizeInventory + 27); + } + return null; + } + else { + return new Indices(sizeInventory, sizeInventory + 36); + } + } + + private boolean grindingRecipeExists(ItemStack itemStack2) { + return GrinderRecipes.getGrindingResult(itemStack2) != null; + } + + private boolean isHotbarSlot(int slotIndex) { + return slotIndex >= sizeInventory + 27 && + slotIndex < sizeInventory + 36; + } + + private class Indices { + public int start; + public int end; + + public Indices(int start, int end) { + this.start = start; + this.end = end; + } + } + +} diff --git a/src/main/java/com/quantumindustries/minecraft/mod/blocks/grinder/GrinderRecipes.java b/src/main/java/com/quantumindustries/minecraft/mod/blocks/grinder/GrinderRecipes.java new file mode 100644 index 0000000..648264d --- /dev/null +++ b/src/main/java/com/quantumindustries/minecraft/mod/blocks/grinder/GrinderRecipes.java @@ -0,0 +1,110 @@ +package com.quantumindustries.minecraft.mod.blocks.grinder; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +public class GrinderRecipes { + + private static Map grindingList; + private static Map experienceList; + private static Map grindingTimes; + private static int metadata; + + public static void init() { + // TODO(TT): collapse all of these maps into a single map + grindingList = new HashMap(); + experienceList = new HashMap(); + grindingTimes = new HashMap(); + metadata = 32767; + + // TODO(TT): remove recipes that are not intended to be used + initRecipe(Blocks.STONEBRICK, Item.getItemFromBlock(Blocks.GRAVEL), 1, 200); + initRecipe(Blocks.STONE_SLAB, Item.getItemFromBlock(Blocks.GRAVEL), 1, 200); + initRecipe(Blocks.STONE_SLAB2, Item.getItemFromBlock(Blocks.GRAVEL), 1, 200); + initRecipe(Blocks.SANDSTONE_STAIRS, Item.getItemFromBlock(Blocks.GRAVEL), 1, 200); + initRecipe(Blocks.STONE, Item.getItemFromBlock(Blocks.GRAVEL), 1, 200); + initRecipe(Blocks.GRAVEL, Item.getItemFromBlock(Blocks.SAND), 1, 200); + initRecipe(Blocks.SANDSTONE, Item.getItemFromBlock(Blocks.SAND), 1, 200); + initRecipe(Blocks.GLASS, Item.getItemFromBlock(Blocks.SAND), 1, 200); + initRecipe(Blocks.BRICK_BLOCK, Item.getItemFromBlock(Blocks.GRAVEL), 1, 200); + initRecipe(Blocks.PLANKS, Items.PAPER, 10, 200); + initRecipe(Blocks.LOG, Items.PAPER, 1, 200); + initRecipe(Blocks.LOG2, Items.PAPER, 1, 200); + initRecipe(Blocks.NETHER_BRICK, Item.getItemFromBlock(Blocks.NETHERRACK), 1, 200); + initRecipe(Blocks.NETHER_BRICK_STAIRS, Item.getItemFromBlock(Blocks.NETHERRACK), 1, 200); + initRecipe(Blocks.NETHER_BRICK_FENCE, Item.getItemFromBlock(Blocks.NETHERRACK), 1, 200); + initRecipe(Blocks.NETHERRACK, Item.getItemFromBlock(Blocks.SOUL_SAND), 1, 200); + initRecipe(Blocks.SOUL_SAND, Items.GUNPOWDER, 5, 200); + initRecipe(Blocks.SLIME_BLOCK, Items.SLIME_BALL, 10, 200); + initRecipe(Blocks.OBSIDIAN, Items.FLINT, 10, 200); + initRecipe(Blocks.PRISMARINE, Items.PRISMARINE_SHARD, 10, 200); + initRecipe(Blocks.SEA_LANTERN, Items.PRISMARINE_CRYSTALS, 10, 200); + } + + public static void addGrindingRecipe(ItemStack itemStackIn, ItemStack itemStackOut, + float experience, int time) { + grindingList.put(itemStackIn, itemStackOut); + experienceList.put(itemStackOut, Float.valueOf(experience)); + grindingTimes.put(itemStackIn.getItem().getUnlocalizedName(), time); + } + + public static ItemStack getGrindingResult(ItemStack itemStack) { + Iterator> iterator = grindingList.entrySet().iterator(); + Entry entry; + + do { + if(!iterator.hasNext()) { + return null; + } + entry = iterator.next(); + } + while(!itemStacksAreEqual(itemStack, entry.getKey())); + + return entry.getValue(); + } + + public static float getGrindingExperience(ItemStack itemStack) { + Iterator> iterator = experienceList.entrySet().iterator(); + Entry entry; + + do { + if(!iterator.hasNext()) { + return 0; + } + entry = iterator.next(); + } + while(!itemStacksAreEqual(itemStack, entry.getKey())); + + return entry.getValue(); + } + + public static int getGrindingTime(String name) { + if(grindingTimes.get(name) != null) { + return grindingTimes.get(name); + } + return 0; + } + + private static void initRecipe(Block block, Item item, int amount, int time) { + addGrindingRecipe( + new ItemStack(Item.getItemFromBlock(block), 1, metadata), + new ItemStack(item, amount), 0.7f, time + ); + } + + private static boolean itemStacksAreEqual(ItemStack itemStack1, ItemStack itemStack2) { + return itemStack2.getItem() == itemStack1.getItem() && + (itemStack2.getMetadata() == metadata || + itemStack2.getMetadata() == itemStack1.getMetadata() + ); + } + +} diff --git a/src/main/java/com/quantumindustries/minecraft/mod/blocks/grinder/SlotGrinderOutput.java b/src/main/java/com/quantumindustries/minecraft/mod/blocks/grinder/SlotGrinderOutput.java new file mode 100644 index 0000000..f430074 --- /dev/null +++ b/src/main/java/com/quantumindustries/minecraft/mod/blocks/grinder/SlotGrinderOutput.java @@ -0,0 +1,94 @@ +package com.quantumindustries.minecraft.mod.blocks.grinder; + +import net.minecraft.entity.item.EntityXPOrb; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.MathHelper; + +public class SlotGrinderOutput extends Slot { + + private final EntityPlayer thePlayer; + private int numGrinderOutput; + + public SlotGrinderOutput(EntityPlayer player, IInventory inventory, + int slotIndex, int xDisplayPosition, int yDisplayPosition) { + super(inventory, slotIndex, xDisplayPosition, yDisplayPosition); + thePlayer = player; + } + + @Override + public boolean isItemValid(ItemStack stack) { + return false; + } + + @Override + public ItemStack decrStackSize(int amount) { + if(getHasStack()) { + numGrinderOutput += Math.min(amount, getStack().stackSize); + } + return super.decrStackSize(amount); + } + + @Override + public void onPickupFromSlot(EntityPlayer playerIn, ItemStack stack) { + onCrafting(stack); + super.onPickupFromSlot(playerIn, stack); + } + + /** + * The itemStack passed in is the output - ie, iron ingots, and pickaxes, not ore and wood + */ + @Override + protected void onCrafting(ItemStack itemStack, int amountGround) { + numGrinderOutput += amountGround; + onCrafting(itemStack); + } + + /** + * The itemStack passed in is the output - ie, iron ingots, and pickaxes, not ore and wood. + */ + @Override + protected void onCrafting(ItemStack itemStack) { + if(!thePlayer.worldObj.isRemote) { + float expFactor = GrinderRecipes.getGrindingExperience(itemStack); + int expEarned = getExpEarned(numGrinderOutput, expFactor); + createExperienceOrbs(expEarned); + } + numGrinderOutput = 0; + } + + private int getExpEarned(int expEarned, float expFactor) { + if(expFactor == 0) { + expEarned = 0; + } + else if(expFactor < 1.0f) { + int possibleExpEarned = MathHelper.floor_float(expEarned*expFactor); + + if(possibleExpEarned < MathHelper.ceiling_float_int(expEarned*expFactor) && + Math.random() < expEarned*expFactor - possibleExpEarned) { + ++possibleExpEarned; + } + + expEarned = possibleExpEarned; + } + return expEarned; + } + + private void createExperienceOrbs(int expEarned) { + int expInOrb; + while(expEarned > 0) { + expInOrb = EntityXPOrb.getXPSplit(expEarned); + expEarned -= expInOrb; + thePlayer.worldObj.spawnEntityInWorld(new EntityXPOrb( + thePlayer.worldObj, + thePlayer.posX, + thePlayer.posY + 0.5d, + thePlayer.posZ + 0.5d, + expInOrb + )); + } + } + +} diff --git a/src/main/java/com/quantumindustries/minecraft/mod/blocks/grinder/TileEntityGrinder.java b/src/main/java/com/quantumindustries/minecraft/mod/blocks/grinder/TileEntityGrinder.java new file mode 100644 index 0000000..14cfd46 --- /dev/null +++ b/src/main/java/com/quantumindustries/minecraft/mod/blocks/grinder/TileEntityGrinder.java @@ -0,0 +1,344 @@ +package com.quantumindustries.minecraft.mod.blocks.grinder; + +import com.quantumindustries.minecraft.mod.CustomMod; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.ITickable; +import net.minecraft.tileentity.TileEntityLockable; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public class TileEntityGrinder extends TileEntityLockable + implements ITickable { + + public enum slotEnum { + INPUT_SLOT, OUTPUT_SLOT + } + + private ItemStack[] grinderItemStackArray = new ItemStack[2]; + private int currentItemGrindTime; + private int ticksGrindingItemSoFar; + private int ticksPerItem; + private String grinderCustomName; + + @Override + public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, + IBlockState newSate) { + return oldState.getBlock() != newSate.getBlock(); + } + + @Override + public int getSizeInventory() { + return grinderItemStackArray.length; + } + + @Override + public ItemStack getStackInSlot(int index) { + return grinderItemStackArray[index]; + } + + @Override + public ItemStack decrStackSize(int index, int count) { + if(grinderItemStackArray[index] != null) { + ItemStack itemstack; + + if(grinderItemStackArray[index].stackSize <= count) { + itemstack = grinderItemStackArray[index]; + grinderItemStackArray[index] = null; + return itemstack; + } + else { + itemstack = grinderItemStackArray[index].splitStack(count); + if(grinderItemStackArray[index].stackSize == 0) { + grinderItemStackArray[index] = null; + } + return itemstack; + } + } + else { + return null; + } + } + + @Override + public ItemStack removeStackFromSlot(int index) { + if(grinderItemStackArray[index] != null) { + ItemStack itemstack = grinderItemStackArray[index]; + grinderItemStackArray[index] = null; + return itemstack; + } + else { + return null; + } + } + + @Override + public void setInventorySlotContents(int index, ItemStack stack) { + boolean isSameItemStackAlreadyInSlot = stack != null && + stack.isItemEqual(grinderItemStackArray[index]) && + ItemStack.areItemStackTagsEqual(stack, grinderItemStackArray[index]); + grinderItemStackArray[index] = stack; + + if(stack != null && stack.stackSize > getInventoryStackLimit()) { + stack.stackSize = getInventoryStackLimit(); + } + + if(index == slotEnum.INPUT_SLOT.ordinal() && !isSameItemStackAlreadyInSlot) { + resetTimers(stack); + markDirty(); + } + } + + @Override + public String getName() { + if(hasCustomName()) { + return grinderCustomName; + } + else { + return "container.grinder"; + } + } + + @Override + public boolean hasCustomName() { + return grinderCustomName != null && grinderCustomName.length() > 0; + } + + public void setCustomInventoryName(String customName) { + grinderCustomName = customName; + } + + @Override + public void readFromNBT(NBTTagCompound compound) { + super.readFromNBT(compound); + NBTTagList nbttaglist = compound.getTagList("Items", 10); + grinderItemStackArray = new ItemStack[getSizeInventory()]; + + for(int i = 0; i < nbttaglist.tagCount(); ++i) { + NBTTagCompound nbtTagCompound = nbttaglist.getCompoundTagAt(i); + byte slot = nbtTagCompound.getByte("Slot"); + + if(slot >= 0 && slot < grinderItemStackArray.length) { + grinderItemStackArray[slot] = ItemStack.loadItemStackFromNBT(nbtTagCompound); + } + } + + ticksGrindingItemSoFar = compound.getShort("GrindTime"); + ticksPerItem = compound.getShort("GrindTimeTotal"); + + if(compound.hasKey("CustomName", 8)) { + grinderCustomName = compound.getString("CustomName"); + } + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound compound) { + super.writeToNBT(compound); + compound.setShort("GrindTime", (short) ticksGrindingItemSoFar); + compound.setShort("GrindTimeTotal", (short) ticksPerItem); + NBTTagList nbttaglist = new NBTTagList(); + + for(int i = 0; i < grinderItemStackArray.length; ++i) { + if(grinderItemStackArray[i] != null) { + NBTTagCompound nbtTagCompound = new NBTTagCompound(); + nbtTagCompound.setByte("Slot", (byte) i); + grinderItemStackArray[i].writeToNBT(nbtTagCompound); + nbttaglist.appendTag(nbtTagCompound); + } + } + + compound.setTag("Items", nbttaglist); + + if(hasCustomName()) { + compound.setString("CustomName", grinderCustomName); + } + + return compound; + } + + @Override + public int getInventoryStackLimit() { + return 64; + } + + @Override + public void update() { + boolean changedGrindingState = false; + + if(!worldObj.isRemote) { + if(inputSlotIsOccupied()) { + if(canGrind()) { + changedGrindingState = continueGrinding(changedGrindingState); + } + else { + ticksGrindingItemSoFar = 0; + } + } + } + + if(changedGrindingState) { + markDirty(); + } + } + + public void grindNextItem() { + if(canGrind()) { + int inputSlot = slotEnum.INPUT_SLOT.ordinal(); + int outputSlot = slotEnum.OUTPUT_SLOT.ordinal(); + ItemStack inputStack = grinderItemStackArray[inputSlot]; + ItemStack outputStack = grinderItemStackArray[outputSlot]; + + ItemStack itemstack = GrinderRecipes.getGrindingResult(inputStack); + + if(outputStack == null) { + grinderItemStackArray[outputSlot] = itemstack.copy(); + } + else if(outputStack.getItem() == itemstack.getItem()) { + outputStack.stackSize += itemstack.stackSize; + } + + --inputStack.stackSize; + + if(inputStack.stackSize <= 0) { + grinderItemStackArray[inputSlot] = null; + } + } + } + + @Override + public boolean isUseableByPlayer(EntityPlayer playerIn) { + if(worldObj.getTileEntity(pos) != this) { + return false; + } + else { + double x = pos.getX() + 0.5d; + double y = pos.getY() + 0.5d; + double z = pos.getZ() + 0.5d; + return playerIn.getDistanceSq(x, y, z) <= 64.0d; + } + } + + @Override + public void openInventory(EntityPlayer playerIn) {} + + @Override + public void closeInventory(EntityPlayer playerIn) {} + + @Override + public boolean isItemValidForSlot(int index, ItemStack stack) { + return index == slotEnum.INPUT_SLOT.ordinal(); + } + + @Override + public String getGuiID() { + return CustomMod.MODID + ":blockGrinder"; + } + + @Override + public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn) { + return new ContainerGrinder(playerInventory, this); + } + + @Override + public int getField(int id) { + if(id == 0) { + return currentItemGrindTime; + } + else if(id == 1) { + return ticksGrindingItemSoFar; + } + else if(id == 2) { + return ticksPerItem; + } + return 0; + } + + @Override + public void setField(int id, int value) { + if(id == 0) { + currentItemGrindTime = value; + } + else if(id == 1) { + ticksGrindingItemSoFar = value; + } + else if(id == 2) { + ticksPerItem = value; + } + } + + @Override + public int getFieldCount() { + return 4; + } + + @Override + public void clear() { + for(int i = 0; i < grinderItemStackArray.length; ++i) { + grinderItemStackArray[i] = null; + } + } + + private boolean continueGrinding(boolean changedGrindingState) { + ++ticksGrindingItemSoFar; + if(currentItemGrindingCompleted()) { + ticksGrindingItemSoFar = 0; + ticksPerItem = timeToGrindOneItem(grinderItemStackArray[0]); + grindNextItem(); + changedGrindingState = true; + } + return changedGrindingState; + } + + private boolean currentItemGrindingCompleted() { + return ticksGrindingItemSoFar == ticksPerItem; + } + + private boolean inputSlotIsOccupied() { + return grinderItemStackArray[slotEnum.INPUT_SLOT.ordinal()] != null; + } + + private int timeToGrindOneItem(ItemStack itemStack) { + if(itemStack != null && itemStack.getItem() != null) { + return GrinderRecipes.getGrindingTime( + itemStack.getItem().getUnlocalizedName() + ); + } + return 0; + } + + private boolean canGrind() { + int inputSlot = slotEnum.INPUT_SLOT.ordinal(); + int outputSlot = slotEnum.OUTPUT_SLOT.ordinal(); + ItemStack inputStack = grinderItemStackArray[inputSlot]; + ItemStack outputStack = grinderItemStackArray[outputSlot]; + if(inputStack == null) { + return false; + } + else { + ItemStack itemStackToOutput = GrinderRecipes.getGrindingResult(inputStack); + if(itemStackToOutput == null) { + return false; + } + if(outputStack == null) { + return true; + } + if(!outputStack.isItemEqual(itemStackToOutput)) { + return false; + } + int result = outputStack.stackSize + itemStackToOutput.stackSize; + return result <= getInventoryStackLimit() && + result <= outputStack.getMaxStackSize(); + } + } + + private void resetTimers(ItemStack stack) { + ticksPerItem = timeToGrindOneItem(stack); + ticksGrindingItemSoFar = 0; + } + +} diff --git a/src/main/java/com/quantumindustries/minecraft/mod/guis/GuiGrinder.java b/src/main/java/com/quantumindustries/minecraft/mod/guis/GuiGrinder.java new file mode 100644 index 0000000..15b5d27 --- /dev/null +++ b/src/main/java/com/quantumindustries/minecraft/mod/guis/GuiGrinder.java @@ -0,0 +1,75 @@ +package com.quantumindustries.minecraft.mod.guis; + +import com.quantumindustries.minecraft.mod.CustomMod; +import com.quantumindustries.minecraft.mod.blocks.grinder.ContainerGrinder; +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.player.InventoryPlayer; +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 GuiGrinder extends GuiContainer { + + private static final ResourceLocation grinderGuiTextures = new ResourceLocation( + CustomMod.MODID + ":textures/gui/container/grinder.png" + ); + private final InventoryPlayer inventoryPlayer; + private final IInventory tileGrinder; + + public GuiGrinder(InventoryPlayer inventoryPlayer, IInventory inventoryGrinder) { + super(new ContainerGrinder(inventoryPlayer, inventoryGrinder)); + this.inventoryPlayer = inventoryPlayer; + tileGrinder = inventoryGrinder; + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + String s = tileGrinder.getDisplayName().getUnformattedText(); + int color = 4210752; + fontRendererObj.drawString( + s, + xSize/2 - fontRendererObj.getStringWidth(s)/2, + 6, + color + ); + fontRendererObj.drawString( + inventoryPlayer.getDisplayName().getUnformattedText(), + 8, + ySize - 96 + 2, + color + ); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { + GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f); + mc.getTextureManager().bindTexture(grinderGuiTextures); + int marginHorizontal = (width - xSize)/2; + int marginVertical = (height - ySize)/2; + drawTexturedModalRect( + marginHorizontal, marginVertical, + 0, 0, xSize, ySize + ); + + int progressLevel = getProgressLevel(24); + drawTexturedModalRect( + marginHorizontal + 79, marginVertical + 34, + 176, 14, + progressLevel + 1, 16 + ); + } + + private int getProgressLevel(int progressIndicatorPixelWidth) { + int ticksGrindingItemSoFar = tileGrinder.getField(1); + int ticksPerItem = tileGrinder.getField(2); + + if(ticksPerItem != 0 && ticksGrindingItemSoFar != 0) { + return ticksGrindingItemSoFar*progressIndicatorPixelWidth/ticksPerItem; + } + return 0; + } + +} diff --git a/src/main/java/com/quantumindustries/minecraft/mod/guis/GuiHandler.java b/src/main/java/com/quantumindustries/minecraft/mod/guis/GuiHandler.java new file mode 100644 index 0000000..9c6b5a6 --- /dev/null +++ b/src/main/java/com/quantumindustries/minecraft/mod/guis/GuiHandler.java @@ -0,0 +1,44 @@ +package com.quantumindustries.minecraft.mod.guis; + +import com.quantumindustries.minecraft.mod.CustomMod; +import com.quantumindustries.minecraft.mod.blocks.grinder.ContainerGrinder; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.tileentity.TileEntity; +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, EntityPlayer player, World world, int x, int y, int z) { + TileEntity tileEntity = world.getTileEntity(new BlockPos(x, y, z)); + + if(tileEntity != null) { + if(isGrinderID(ID)) { + return new ContainerGrinder(player.inventory, (IInventory) tileEntity); + } + } + + return null; + } + + @Override + public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { + TileEntity tileEntity = world.getTileEntity(new BlockPos(x, y, z)); + + if(tileEntity != null) { + if(isGrinderID(ID)) { + return new GuiGrinder(player.inventory, (IInventory) tileEntity); + } + } + + return null; + } + + private boolean isGrinderID(int ID) { + return ID == CustomMod.GUI.GRINDER.ordinal(); + } + +} diff --git a/src/main/java/com/quantumindustries/minecraft/mod/items/ModItems.java b/src/main/java/com/quantumindustries/minecraft/mod/items/ModItems.java index 6852e40..84c77ff 100644 --- a/src/main/java/com/quantumindustries/minecraft/mod/items/ModItems.java +++ b/src/main/java/com/quantumindustries/minecraft/mod/items/ModItems.java @@ -6,10 +6,7 @@ public class ModItems { - // ItemBases - public static ItemBase airFilter; - - // ItemOres + // Ores public static ItemOre ingotCobalt; public static ItemOre ingotNeodymium; public static ItemOre ingotRhodium; @@ -17,6 +14,9 @@ public class ModItems { public static ItemOre dustNeodymium; public static ItemOre dustRhodium; + // Miscellaneous + public static ItemBase airFilter; + public static void init() { initIngots(); initDusts(); diff --git a/src/main/java/com/quantumindustries/minecraft/mod/proxy/ClientProxy.java b/src/main/java/com/quantumindustries/minecraft/mod/proxy/ClientProxy.java index 3809f74..35f5267 100644 --- a/src/main/java/com/quantumindustries/minecraft/mod/proxy/ClientProxy.java +++ b/src/main/java/com/quantumindustries/minecraft/mod/proxy/ClientProxy.java @@ -1,10 +1,16 @@ package com.quantumindustries.minecraft.mod.proxy; +import com.quantumindustries.minecraft.mod.CustomMod; import com.quantumindustries.minecraft.mod.ModWorldGen; import com.quantumindustries.minecraft.mod.blocks.ModBlocks; +import com.quantumindustries.minecraft.mod.blocks.grinder.GrinderRecipes; import com.quantumindustries.minecraft.mod.fluids.ModFluids; import com.quantumindustries.minecraft.mod.items.ModItems; import com.quantumindustries.minecraft.mod.recipes.ModRecipes; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.RenderItem; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.item.Item; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; @@ -18,17 +24,26 @@ public void preInit(FMLPreInitializationEvent event) { ModFluids.init(); ModItems.init(); ModRecipes.init(); + GrinderRecipes.init(); GameRegistry.registerWorldGenerator(new ModWorldGen(), 3); } @Override public void init(FMLInitializationEvent event) { - // TODO + RenderItem renderItem = Minecraft.getMinecraft().getRenderItem(); + renderItem.getItemModelMesher().register( + Item.getItemFromBlock(ModBlocks.blockGrinder), + 0, + new ModelResourceLocation( + CustomMod.MODID + ":" + ModBlocks.blockGrinder + .getUnlocalizedName(), + "inventory" + ) + ); + super.init(event); } @Override - public void postInit(FMLPostInitializationEvent event) { - // TODO - } + public void postInit(FMLPostInitializationEvent event) {} } diff --git a/src/main/java/com/quantumindustries/minecraft/mod/proxy/CommonProxy.java b/src/main/java/com/quantumindustries/minecraft/mod/proxy/CommonProxy.java index b915783..f512b1f 100644 --- a/src/main/java/com/quantumindustries/minecraft/mod/proxy/CommonProxy.java +++ b/src/main/java/com/quantumindustries/minecraft/mod/proxy/CommonProxy.java @@ -1,26 +1,24 @@ package com.quantumindustries.minecraft.mod.proxy; import com.quantumindustries.minecraft.mod.CustomMod; +import com.quantumindustries.minecraft.mod.guis.GuiHandler; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.item.Item; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; +import net.minecraftforge.fml.common.network.NetworkRegistry; public class CommonProxy { - public void preInit(FMLPreInitializationEvent event) { - // TODO - } + public void preInit(FMLPreInitializationEvent event) {} public void init(FMLInitializationEvent event) { - // TODO + registerGuiHandlers(); } - public void postInit(FMLPostInitializationEvent event) { - // TODO - } + public void postInit(FMLPostInitializationEvent event) {} public void registerItemRenderer(Item item, int meta, String id) { ModelResourceLocation location = new ModelResourceLocation( @@ -30,4 +28,11 @@ public void registerItemRenderer(Item item, int meta, String id) { ModelLoader.setCustomModelResourceLocation(item, meta, location); } + private void registerGuiHandlers() { + NetworkRegistry.INSTANCE.registerGuiHandler( + CustomMod.instance, + new GuiHandler() + ); + } + } diff --git a/src/main/java/com/quantumindustries/minecraft/mod/tileentities/BlockContainerTileEntity.java b/src/main/java/com/quantumindustries/minecraft/mod/tileentities/BlockContainerTileEntity.java new file mode 100644 index 0000000..e59c28b --- /dev/null +++ b/src/main/java/com/quantumindustries/minecraft/mod/tileentities/BlockContainerTileEntity.java @@ -0,0 +1,37 @@ +package com.quantumindustries.minecraft.mod.tileentities; + +import com.quantumindustries.minecraft.mod.CustomMod; +import com.quantumindustries.minecraft.mod.ItemModelProvider; +import com.quantumindustries.minecraft.mod.blocks.BlockBase; +import net.minecraft.block.BlockContainer; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import javax.annotation.Nullable; +public abstract class BlockContainerTileEntity + extends BlockContainer { + + public BlockContainerTileEntity(Material material, String name) { + super(material); + + setUnlocalizedName(name); + setRegistryName(name); + setCreativeTab(CustomMod.tab); + } + + public abstract Class getTileEntityClass(); + + @Override + public boolean hasTileEntity(IBlockState state) { + return true; + } + + @Nullable + @Override + public abstract TE createTileEntity(World world, IBlockState state); + +} diff --git a/src/main/java/com/quantumindustries/minecraft/mod/tileentities/BlockTileEntity.java b/src/main/java/com/quantumindustries/minecraft/mod/tileentities/BlockTileEntity.java index 9846fc2..ab29838 100644 --- a/src/main/java/com/quantumindustries/minecraft/mod/tileentities/BlockTileEntity.java +++ b/src/main/java/com/quantumindustries/minecraft/mod/tileentities/BlockTileEntity.java @@ -18,7 +18,7 @@ public BlockTileEntity(Material material, String name) { public abstract Class getTileEntityClass(); public TE getTileEntity(IBlockAccess world, BlockPos pos) { - return (TE)world.getTileEntity(pos); + return (TE) world.getTileEntity(pos); } @Override diff --git a/src/main/resources/assets/custommod/blockstates/blockGrinder.json b/src/main/resources/assets/custommod/blockstates/blockGrinder.json new file mode 100644 index 0000000..c2eb319 --- /dev/null +++ b/src/main/resources/assets/custommod/blockstates/blockGrinder.json @@ -0,0 +1,17 @@ +{ + "forge_marker": 1, + "variants": { + "facing=north": { + "model": "custommod:blockGrinder" + }, + "facing=south": { + "model": "custommod:blockGrinder", "y": 180 + }, + "facing=west": { + "model": "custommod:blockGrinder", "y": 270 + }, + "facing=east": { + "model": "custommod:blockGrinder", "y": 90 + } + } +} diff --git a/src/main/resources/assets/custommod/lang/en_US.lang b/src/main/resources/assets/custommod/lang/en_US.lang index e966ba1..c465873 100644 --- a/src/main/resources/assets/custommod/lang/en_US.lang +++ b/src/main/resources/assets/custommod/lang/en_US.lang @@ -24,6 +24,7 @@ tile.blockNeoCobaltMagnet.name=Neodymium-Cobalt Magnet tile.blockNeoRhodiumMagnet.name=Neodymium-Rhodium Magnet tile.powerAnalyzer.name=Power Analyzer tile.infiniteProducer.name=Infinite Power Block +tile.blockGrinder.name=Grinder # Particle Accelerator Blocks tile.particleAcceleratorPowerPort.name=PA Power Port @@ -46,3 +47,6 @@ tile.blockFluidArgon.name=Liquid Argon fluid.fluid_nitrogen=Liquid Nitrogen fluid.fluid_oxygen=Liquid Oxygen fluid.fluid_argon=Liquid Argon + +# Mod Containers +container.grinder=Grinder diff --git a/src/main/resources/assets/custommod/models/block/blockGrinder.json b/src/main/resources/assets/custommod/models/block/blockGrinder.json new file mode 100644 index 0000000..018f483 --- /dev/null +++ b/src/main/resources/assets/custommod/models/block/blockGrinder.json @@ -0,0 +1,8 @@ +{ + "parent": "block/orientable", + "textures": { + "top": "blocks/furnace_top", + "front": "blocks/furnace_front_off", + "side": "blocks/furnace_side" + } +} diff --git a/src/main/resources/assets/custommod/models/item/blockGrinder.json b/src/main/resources/assets/custommod/models/item/blockGrinder.json new file mode 100644 index 0000000..1914fb6 --- /dev/null +++ b/src/main/resources/assets/custommod/models/item/blockGrinder.json @@ -0,0 +1,10 @@ +{ + "parent": "custommod:block/blockGrinder", + "display": { + "thirdperson": { + "rotation": [ 10, -45, 170 ], + "translation": [ 0, 1.5, -2.75 ], + "scale": [ 0.375, 0.375, 0.375 ] + } + } +} diff --git a/src/main/resources/assets/custommod/textures/gui/container/grinder.png b/src/main/resources/assets/custommod/textures/gui/container/grinder.png new file mode 100644 index 0000000..6a4f774 Binary files /dev/null and b/src/main/resources/assets/custommod/textures/gui/container/grinder.png differ