Thank you so much for your help. You can also browse my code on github: https://github.com/Autodidax86/demoncycle
assets.dcm.blockstates.block_spinning_wheel.json
{
"forge_marker":1,
"defaults": {"model":"dcm:spinning_wheel"},
"variants": {
"normal": { "model": "dcm:spinning_wheel" },
"facing=north,static=true": { "model": "dcm:spinning_wheel" },
"facing=east,static=true": { "model": "dcm:spinning_wheel", "y": 90 },
"facing=south,static=true": { "model": "dcm:spinning_wheel", "y": 180 },
"facing=west,static=true": { "model": "dcm:spinning_wheel", "y": 270 },
"facing=north,static=false": { "model": "dcm:spinning_wheel_animated" },
"facing=east,static=false": { "model": "dcm:spinning_wheel_animated", "y": 90 },
"facing=south,static=false": { "model": "dcm:spinning_wheel_animated", "y": 180 },
"facing=west,static=false": { "model": "dcm:spinning_wheel_animated", "y": 270 },
"inventory": {
"model": "dcm:spinning_wheel_animated"
}
}
}
assets.dcm.models.block.spinning_wheel.json https://pastebin.com/LrU5t3HL
assets.dcm.models.block.spinning_wheel_animated.json
https://pastebin.com/g23StqQj
block.BlockSpinningWheel.java
package com.autodidax.demoncycle.block;
import java.util.Random;
import com.autodidax.demoncycle.Main;
import com.autodidax.demoncycle.container.BlockContainerBase;
import com.autodidax.demoncycle.init.ModBlocks;
import com.autodidax.demoncycle.tileentities.TileEntitySpinningWheel;
import com.autodidax.demoncycle.util.Reference;
import net.minecraft.block.BlockHorizontal;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.state.BlockFaceShape;
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.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.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.property.ExtendedBlockState;
import net.minecraftforge.common.property.IUnlistedProperty;
import net.minecraftforge.common.property.Properties;
public class BlockSpinningWheel extends BlockContainerBase implements ITileEntityProvider {
public static final AxisAlignedBB SPINNING_WHEEL_NORTH_AABB = new AxisAlignedBB(1D, 0, 0.75D, 0.125D, 1.25D, 0.25D);
public static final AxisAlignedBB SPINNING_WHEEL_WEST_AABB = new AxisAlignedBB(0.25D, 0, 0, 0.75D, 1.25D, 0.875D);
public static final AxisAlignedBB SPINNING_WHEEL_SOUTH_AABB = new AxisAlignedBB(0, 0, 0.25D, 0.875D, 1.25D, 0.75D);
public static final AxisAlignedBB SPINNING_WHEEL_EAST_AABB = new AxisAlignedBB(0.75D, 0, 0.125D, 0.25D, 1.25D, 1D);
public static final PropertyDirection FACING = BlockHorizontal.FACING;
//public static final PropertyBool SPINNING = PropertyBool.create("spinning");
public BlockSpinningWheel(String name) {
super(name, Material.WOOD);
setSoundType(SoundType.WOOD);
//this.setDefaultState(this.blockState.getBaseState().withProperty(FACING, EnumFacing.NORTH));
}
@Override
public boolean isOpaqueCube(IBlockState state) {
return false;
}
@Override
public boolean isFullCube(IBlockState state) {
return true;
}
@Override
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) {
switch ((EnumFacing)state.getValue(FACING))
{
case NORTH:
return SPINNING_WHEEL_NORTH_AABB;
case SOUTH:
return SPINNING_WHEEL_SOUTH_AABB;
case WEST:
return SPINNING_WHEEL_WEST_AABB;
case EAST:
return SPINNING_WHEEL_EAST_AABB;
default:
return SPINNING_WHEEL_SOUTH_AABB;
}
}
@Override
public Item getItemDropped(IBlockState state, Random rand, int fortune) {
return Item.getItemFromBlock(ModBlocks.BLOCK_SPINNING_WHEEL);
}
@Override
public ItemStack getItem(World worldIn, BlockPos pos, IBlockState state) {
return new ItemStack(ModBlocks.BLOCK_SPINNING_WHEEL);
}
@Override
public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn,
EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
if(!worldIn.isRemote) {
TileEntity tileentity = worldIn.getTileEntity(pos);
if(tileentity instanceof TileEntitySpinningWheel) {
playerIn.openGui(Main.Instance, Reference.GUI_SPINNING_WHEEL, worldIn, pos.getX(), pos.getY(), pos.getZ());
}
}
return true;
}
@Override
public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state)
{
if (!worldIn.isRemote)
{
IBlockState north = worldIn.getBlockState(pos.north());
IBlockState south = worldIn.getBlockState(pos.south());
IBlockState west = worldIn.getBlockState(pos.west());
IBlockState east = worldIn.getBlockState(pos.east());
EnumFacing face = (EnumFacing)state.getValue(FACING);
if (face == EnumFacing.NORTH && north.isFullBlock() && !south.isFullBlock()) face = EnumFacing.SOUTH;
else if (face == EnumFacing.SOUTH && south.isFullBlock() && !north.isFullBlock()) face = EnumFacing.NORTH;
else if (face == EnumFacing.WEST && west.isFullBlock() && !east.isFullBlock()) face = EnumFacing.EAST;
else if (face == EnumFacing.EAST && east.isFullBlock() && !west.isFullBlock()) face = EnumFacing.WEST;
worldIn.setBlockState(pos, state.withProperty(FACING, face), 2);
}
}
// public static void setState(boolean active, World worldIn, BlockPos pos)
// {
// IBlockState state = worldIn.getBlockState(pos);
// TileEntity tileentity = worldIn.getTileEntity(pos);
// if(active) {
// System.out.println("BlockUpdate: Spinning=true");
// worldIn.setBlockState(pos, state.withProperty(SPINNING, true), 3);
// }
// else {
// System.out.println("BlockUpdate: Spinning=false");
// worldIn.setBlockState(pos, state.withProperty(SPINNING, false), 3);
// }
// if(tileentity != null)
// {
// tileentity.validate();
// worldIn.setTileEntity(pos, tileentity);
// }
// }
@Override
public boolean hasTileEntity(IBlockState state)
{
return true;
}
@Override
public TileEntity createNewTileEntity(World worldIn, int meta) {
// TODO Auto-generated method stub
return new TileEntitySpinningWheel();
}
@Override
public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand)
{
return this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite());
}
@Override
public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack)
{
worldIn.setBlockState(pos, this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()), 2);
}
@Override
public EnumBlockRenderType getRenderType(IBlockState state)
{
return EnumBlockRenderType.MODEL;
}
@Override
public IBlockState withRotation(IBlockState state, Rotation rot)
{
return state.withProperty(FACING, rot.rotate((EnumFacing)state.getValue(FACING)));
}
@Override
public IBlockState withMirror(IBlockState state, Mirror mirrorIn)
{
return state.withRotation(mirrorIn.toRotation((EnumFacing)state.getValue(FACING)));
}
@Override
protected BlockStateContainer createBlockState()
{
//return new BlockStateContainer(this, new IProperty[] {SPINNING,FACING});
return new ExtendedBlockState(this, new IProperty<?>[] { FACING, Properties.StaticProperty }, new IUnlistedProperty<?>[] { Properties.AnimationProperty });
}
@Override
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) {
// TODO Auto-generated method stub
return state.withProperty(Properties.StaticProperty, true);
}
@Override
public IBlockState getStateFromMeta(int meta)
{
EnumFacing facing = EnumFacing.getFront(meta);
if(facing.getAxis() == EnumFacing.Axis.Y) facing = EnumFacing.NORTH;
return this.getDefaultState().withProperty(FACING, facing);
}
@Override
public int getMetaFromState(IBlockState state)
{
return ((EnumFacing)state.getValue(FACING)).getIndex();
}
}
tileentities.TileEntitySpinningWheel.java
package com.autodidax.demoncycle.tileentities;
import com.autodidax.demoncycle.Main;
import com.autodidax.demoncycle.block.BlockSpinningWheel;
import com.autodidax.demoncycle.init.ModBlocks;
import com.autodidax.demoncycle.init.ModItems;
import com.autodidax.demoncycle.items.ItemBase;
import com.autodidax.demoncycle.recipes.SpinningWheelRecipes;
import com.autodidax.demoncycle.util.Reference;
import com.google.common.collect.ImmutableMap;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.FurnaceRecipes;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.model.animation.CapabilityAnimation;
import net.minecraftforge.common.model.animation.IAnimationStateMachine;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.ItemStackHandler;
public class TileEntitySpinningWheel extends TileEntity implements ITickable {
private ItemStackHandler spinningWheelItemStacks = new ItemStackHandler(2);
private String customName;
private ItemStack spinning = ItemStack.EMPTY;
private final IAnimationStateMachine asm;
private int processTime;
private int totalProcessTime;
public TileEntitySpinningWheel() {
if (FMLCommonHandler.instance().getSide() == Side.CLIENT) {
asm = ModelLoaderRegistry.loadASM(new ResourceLocation(Reference.MOD_ID + ":asms/block/spinning_wheel_animated.json"), ImmutableMap.of());
} else asm = null;
}
@Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
if (capability == CapabilityAnimation.ANIMATION_CAPABILITY) {
return CapabilityAnimation.ANIMATION_CAPABILITY.cast(asm);
}
else if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
return (T) this.spinningWheelItemStacks;
}
return super.getCapability(capability, facing);
}
@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
// TODO Auto-generated method stub
return getCapability(capability, facing) != null;
}
public boolean hasCustomName() {
return this.customName != null && !this.customName.isEmpty();
}
public void setCustomName(String customName) {
this.customName = customName;
}
@Override
public ITextComponent getDisplayName() {
return this.hasCustomName() ? new TextComponentString(this.customName)
: new TextComponentTranslation("container.spinning_wheel");
}
@Override
public void readFromNBT(NBTTagCompound compound) {
super.readFromNBT(compound);
this.spinningWheelItemStacks.deserializeNBT(compound.getCompoundTag("Inventory"));
this.processTime = compound.getInteger("ProcessTime");
this.totalProcessTime = compound.getInteger("ProcessTimeTotal");
if (compound.hasKey("CustomName", 8))
this.setCustomName(compound.getString("CustomName"));
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound compound) {
super.writeToNBT(compound);
compound.setInteger("ProcessTime", (short) this.processTime);
compound.setInteger("ProcessTimeTotal", (short) this.totalProcessTime);
compound.setTag("Inventory", this.spinningWheelItemStacks.serializeNBT());
if (this.hasCustomName())
compound.setString("CustomName", this.customName);
return compound;
}
public boolean isWorking() {
return true; //this "furnace" will always work
}
@SideOnly(Side.CLIENT)
public static boolean isWorking(TileEntitySpinningWheel te) {
return te.getField(0) > 0;
}
public void update()
{
if(!this.world.isRemote)
{
ItemStack input = this.spinningWheelItemStacks.getStackInSlot(0);
this.totalProcessTime = this.getItemProcessTime(input);
if (!input.isEmpty())
{
if (this.canBeProcessed(input)) {
++this.processTime;
if(this.processTime == this.totalProcessTime)
{
this.processTime = 0;
this.totalProcessTime = this.getItemProcessTime(input);
this.processItem(input);
}
else {
//BlockSpinningWheel.setState(true, this.world, pos);
}
}
else
{
this.processTime = 0;
//BlockSpinningWheel.setState(false, this.world, pos);
}
}
else if (this.processTime > 0)
{
this.processTime = MathHelper.clamp(this.processTime - 2, 0, this.totalProcessTime);
}
else {
//BlockSpinningWheel.setState(false, this.world, pos);
}
}
this.markDirty();
}
public void processItem(ItemStack input)
{
if (this.canBeProcessed(input))
{
int inputAmount = SpinningWheelRecipes.getInstance().getInputAmount(input);
ItemStack resultItem = SpinningWheelRecipes.getInstance().getSpinningResult(input);
ItemStack output = this.spinningWheelItemStacks.getStackInSlot(1); //output
if (output.isEmpty())
{
this.spinningWheelItemStacks.setStackInSlot(1, resultItem.copy());
}
else if (output.getItem() == resultItem.getItem())
{
output.grow(resultItem.getCount());
}
input.shrink(inputAmount);
}
}
private boolean canBeProcessed(ItemStack item) {
if (item.isEmpty())
{
return false;
}
else {
ItemStack result = SpinningWheelRecipes.getInstance().getSpinningResult(item);
if (result.isEmpty()) {
return false;
}
else {
ItemStack output = (ItemStack) this.spinningWheelItemStacks.getStackInSlot(1);
if (output.isEmpty()) return true;
if (!output.isItemEqual(result)) return false;
int res = output.getCount() + result.getCount();
return res <= 64 && res <= output.getMaxStackSize();
}
}
}
public static int getItemProcessTime(ItemStack item) {
return 200; //we have no fuel but we want to have a process time per item
}
public static boolean isItemValid(ItemStack item) {
return SpinningWheelRecipes.getInstance().getSpinningResult(item) != ItemStack.EMPTY;
}
public boolean isUsableByPlayer(EntityPlayer player) {
return this.world.getTileEntity(this.pos) != this ? false
: player.getDistanceSq((double) this.pos.getX() + 0.5D, (double) this.pos.getY() + 0.5D,
(double) this.pos.getZ() + 0.5D) <= 64.0D;
}
public int getField(int id) {
switch (id) {
case 0:
return this.processTime;
case 1:
return this.totalProcessTime;
default:
return 0;
}
}
public void setField(int id, int value) {
switch (id) {
case 0:
this.processTime = value;
break;
case 1:
this.totalProcessTime = value;
}
}
}