cookStack как-бы работает, но как-бы не работает.

Версия Minecraft
1.7.10
API
Forge
Ну вобщем, я делаю костёр как в Better Than Wolves, и столкнулся с такой проблемой: cookStack (то есть стак, который отвечает за хранение предмета внутри костра для готовки) работает нормальсно с засунуть-вытащить, то есть он забирает и выдаёт свой предмет адекватно. Но вот почему то после того как я вытащил предмет сам cookStack не изменился на null, а изменяется он на null сразу после того как я снова как-бы положил в него еду. Причём сама еда спокойно достаётся обратно.
package mods.betterwithpatches.block.tile;

Java:
import mods.betterwithpatches.BWPRegistry;
import mods.betterwithpatches.block.CampfireBlock;
import mods.betterwithpatches.craft.CampFireCraftingManager;
import mods.betterwithpatches.util.TileEntityDataPacketHandler;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants;
import org.lwjgl.opengl.GL11;

public class CampfireTileEntity extends TileEntity implements TileEntityDataPacketHandler
{
private static final int CAMPFIRE_BURN_TIME_MULTIPLIER = 8;

private static final int TIME_TO_COOK = (400 * CAMPFIRE_BURN_TIME_MULTIPLIER *
3 / 2 ); // this line represents efficiency relative to furnace cooking

    private static final int MAX_BURN_TIME = (5 * 1200);

private static final int INITIAL_BURN_TIME = (50 * 4 * CAMPFIRE_BURN_TIME_MULTIPLIER *
2); // 50 is the furnace burn time of a shaft

    private static final int WARMUP_TIME = (10 * 20);
private static final int REVERT_TO_SMALL_TIME = (20 * 20);
private static final int BLAZE_TIME = (INITIAL_BURN_TIME * 3 / 2 );

private static final int SMOULDER_TIME = (5 * 1200); // used to be 2 minutes

    private static final int TIME_TO_BURN_FOOD = (TIME_TO_COOK / 2 );

private static final float CHANCE_OF_FIRE_SPREAD = 0.05F;
private static final float CHANCE_OF_GOING_OUT_FROM_RAIN = 0.01F;

private ItemStack spitStack = null;
private ItemStack cookStack = null;

private int burnTimeCountdown = 0;
private int burnTimeSinceLit = 0;
private int cookCounter = 0;
private int smoulderCounter = 0;
private int cookBurningCounter = 0;

public CampfireTileEntity()
    {
super();
    }


private static final String INV_SPIT_TAG = "InventorySpit";
private static final String INV_COOK_TAG = "InventoryCook";

/**
     * Данный метод вызывается при записи данных Tile Entity в чанк. Мы не рекомендуем удалять вызов родительского метода,
     * так как это может привести к ошибке загрузки данных Tile Entity.
     *
     * @param nbt данные NBT в которых будет храниться информация о Tile Entity.
     */
    @Override
    public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);

if (spitStack != null) {
NBTTagCompound inventorySpitTag = new NBTTagCompound();
spitStack.writeToNBT(inventorySpitTag);
nbt.setTag(INV_SPIT_TAG, inventorySpitTag);
        }
if (cookStack != null)
        {
NBTTagCompound cookTag = new NBTTagCompound();

cookStack.writeToNBT(cookTag);

nbt.setTag( INV_COOK_TAG, cookTag );
        }
nbt.setInteger("fcBurnCounter", burnTimeCountdown);
nbt.setInteger("fcBurnTime", burnTimeSinceLit);
nbt.setInteger("fcCookCounter", cookCounter);
nbt.setInteger("fcSmoulderCounter", smoulderCounter);
nbt.setInteger("fcCookBurning", cookBurningCounter);
    }

@Override
    public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);

if (nbt.hasKey(INV_SPIT_TAG, Constants.NBT.TAG_COMPOUND)) {
NBTTagCompound inventoryTag = nbt.getCompoundTag(INV_SPIT_TAG);
spitStack = ItemStack.loadItemStackFromNBT(inventoryTag);
        }
if (nbt.hasKey(INV_COOK_TAG, Constants.NBT.TAG_COMPOUND)) {
NBTTagCompound inventoryTag = nbt.getCompoundTag(INV_COOK_TAG);
cookStack = ItemStack.loadItemStackFromNBT(inventoryTag);
        }
if ( nbt.hasKey( "fcBurnCounter" ) )
        {
burnTimeCountdown = nbt.getInteger("fcBurnCounter");
        }

if ( nbt.hasKey( "fcBurnTime" ) )
        {
burnTimeSinceLit = nbt.getInteger("fcBurnTime");
        }

if ( nbt.hasKey( "fcCookCounter" ) )
        {
cookCounter = nbt.getInteger("fcCookCounter");
        }

if ( nbt.hasKey( "fcSmoulderCounter" ) )
        {
smoulderCounter = nbt.getInteger("fcSmoulderCounter");
        }

if ( nbt.hasKey( "fcCookBurning" ) )
        {
cookBurningCounter = nbt.getInteger("fcCookBurning");
        }
    }



@Override
    public void updateEntity()
    {
super.updateEntity();

if ( !worldObj.isRemote )
        {
int iCurrentFireLevel = getCurrentFireLevel();

if ( iCurrentFireLevel > 0 )
            {
//  if ( iCurrentFireLevel > 1 && worldObj.rand.nextFloat() <= CHANCE_OF_FIRE_SPREAD)
              //  {
              //      FireBlock.checkForFireSpreadFromLocation(worldObj, xCoord, yCoord, zCoord, worldObj.rand, 0);
               // }

                burnTimeSinceLit++;

if (burnTimeCountdown > 0 )
                {
burnTimeCountdown--;

if ( iCurrentFireLevel == 3 )
                    {
// blaze burns extra fast

                        burnTimeCountdown--;
                    }
                }

                iCurrentFireLevel = validateFireLevel();

if ( iCurrentFireLevel > 0 )
                {
                    updateCookState();

if (worldObj.rand.nextFloat() <= CHANCE_OF_GOING_OUT_FROM_RAIN && isRainingOnCampfire() )
                    {
extinguishFire(false);
                    }
                }
            }
else if (smoulderCounter > 0 )
            {
smoulderCounter--;

if (smoulderCounter == 0 || worldObj.rand.nextFloat() <= CHANCE_OF_GOING_OUT_FROM_RAIN && isRainingOnCampfire() )
                {
                    stopSmouldering();
                }
            }
        }
    }

@Override
    public Packet getDescriptionPacket()
    {
NBTTagCompound tag = new NBTTagCompound();

if (cookStack != null)
        {
NBTTagCompound cookTag = new NBTTagCompound();

cookStack.writeToNBT(cookTag);

tag.setTag( "tag01", cookTag );
        }

if (spitStack != null)
        {
NBTTagCompound spitTag = new NBTTagCompound();

spitStack.writeToNBT(spitTag);

tag.setTag( "tag02", spitTag );
        }

return new S35PacketUpdateTileEntity( xCoord, yCoord, zCoord, 1, tag );
    }

//------------- FCITileEntityDataPacketHandler ------------//

    @Override
    public void readNBTFromPacket( NBTTagCompound tag )
    {
NBTTagCompound cookTag = tag.getCompoundTag( "tag01" );

if (cookStack.hasTagCompound() )
        {
cookStack = ItemStack.loadItemStackFromNBT(cookTag);
        }

NBTTagCompound spitTag = tag.getCompoundTag( "tag02" );

if (spitStack.hasTagCompound() )
        {
spitStack = ItemStack.loadItemStackFromNBT(spitTag);
        }

// force a visual update for the block since the above variables affect it

        worldObj.markBlockRangeForRenderUpdate( xCoord, yCoord, zCoord, xCoord, yCoord, zCoord );
    }

//------------- Class Specific Methods ------------//

    public void setSpitStack(ItemStack stack)
    {
if ( stack != null )
        {
spitStack = stack.copy();

spitStack.stackSize = 1;
        }
else
        {
spitStack = null;
        }

worldObj.markBlockForUpdate( xCoord, yCoord, zCoord );
    }

public ItemStack getSpitStack()
    {
return spitStack;
    }

public void setCookStack(ItemStack stack)
    {
if ( stack != null )
        {
cookStack = stack.copy();

cookStack.stackSize = 1;
        }
else
        {
cookStack = null;

cookBurningCounter = 0;
        }

cookCounter = 0;

worldObj.markBlockForUpdate( xCoord, yCoord, zCoord );
    }

public ItemStack getCookStack()
    {
return cookStack;
    }

public void ejectContents()
    {
if (spitStack != null )
        {
if (!worldObj.isRemote) {
worldObj.spawnEntityInWorld(new EntityItem(worldObj, xCoord, yCoord, zCoord, new ItemStack(spitStack.getItem())));

            }
spitStack = null;
        }

if (cookStack != null )
        {
if (!worldObj.isRemote) {
worldObj.spawnEntityInWorld(new EntityItem(worldObj, xCoord, yCoord, zCoord, new ItemStack(cookStack.getItem())));
            }
cookStack = null;
        }
else{
System.out.println("nah bro there was nothing  💀");
        }
    }

public void addBurnTime(int iBurnTime)
    {
burnTimeCountdown += iBurnTime * CAMPFIRE_BURN_TIME_MULTIPLIER * 2;

if (burnTimeCountdown > MAX_BURN_TIME)
        {
burnTimeCountdown = MAX_BURN_TIME;
        }

        validateFireLevel();
    }

public void onFirstLit()
    {
burnTimeCountdown = INITIAL_BURN_TIME;
burnTimeSinceLit = 0;
    }

public int validateFireLevel()
    {
int iCurrentFireLevel = getCurrentFireLevel();

if ( iCurrentFireLevel > 0 )
        {
// int iFuelState = FCBetterThanWolves.fcBlockCampfireUnlit.GetFuelState( worldObj, xCoord, yCoord, zCoord );

            if (burnTimeCountdown <= 0 )
            {
extinguishFire(true);

return 0;
            }
else
            {
int iDesiredFireLevel = 2;

if (burnTimeSinceLit < WARMUP_TIME || burnTimeCountdown < REVERT_TO_SMALL_TIME)
                {
iDesiredFireLevel = 1;
                }
else if (burnTimeCountdown > BLAZE_TIME)
                {
iDesiredFireLevel = 3;
                }

if ( iDesiredFireLevel != iCurrentFireLevel )
                {
                    changeFireLevel(iDesiredFireLevel);

if ( iDesiredFireLevel == 1 && iCurrentFireLevel == 2 )
                    {
worldObj.playAuxSFX(10, xCoord, yCoord, zCoord, 1 );
                    }

return iDesiredFireLevel;
                }
            }

        }
else // iCurrenFireLevel == 0
        {
if (burnTimeCountdown > 0 &&
BWPRegistry.unlitCampfire.getFuelState(worldObj, xCoord, yCoord, zCoord) ==
CampfireBlock.CAMPFIRE_FUEL_STATE_SMOULDERING)
            {
                relightSmouldering();

return 1;
            }
        }

return iCurrentFireLevel;
    }

private void extinguishFire(boolean bSmoulder)
    {
if ( bSmoulder )
        {
smoulderCounter = SMOULDER_TIME;
        }
else
        {
smoulderCounter = 0;
        }

cookCounter = 0; // reset cook counter in case fire is relit later
        cookBurningCounter = 0;

CampfireBlock block = (CampfireBlock)(worldObj.getBlock( xCoord, yCoord, zCoord ));

block.extinguishFire(worldObj, xCoord, yCoord, zCoord, bSmoulder);
    }

private void changeFireLevel(int iNewLevel)
    {
CampfireBlock block = (CampfireBlock)(worldObj.getBlock( xCoord, yCoord, zCoord ));

block.changeFireLevel(worldObj, xCoord, yCoord, zCoord, iNewLevel, worldObj.getBlockMetadata(xCoord, yCoord, zCoord));
    }

private int getCurrentFireLevel()
    {
CampfireBlock block = (CampfireBlock)(worldObj.getBlock( xCoord, yCoord, zCoord ));

return block.fireLevel;
    }





private void updateCookState()
    {
if (cookStack != null )
        {
int iFireLevel = getCurrentFireLevel();

if ( iFireLevel >= 2 )
            {
ItemStack cookResult = CampFireCraftingManager.instance.getRecipeResult(cookStack.getItem());

if ( cookResult != null )
                {
cookCounter++;

if (cookCounter >= TIME_TO_COOK)
                    {
                        setCookStack(cookResult);

cookCounter = 0;

// don't reset burn counter here, as the food can still burn after cooking
                    }
                }

if ( iFireLevel >= 3 && cookStack.getItem() != BWPRegistry.itemShaft ) // gonna replace w burned meat
                {
cookBurningCounter++;

if (cookBurningCounter >= TIME_TO_BURN_FOOD)
                    {
setCookStack(new ItemStack(BWPRegistry.itemShaft)); // gonna replace w burned meat

                        cookCounter = 0;
cookBurningCounter = 0;
                    }
                }
            }
        }
    }

public boolean getIsCooking()
    {
if (cookStack != null && getCurrentFireLevel() >= 2 )
        {
ItemStack cookResult = CampFireCraftingManager.instance.getRecipeResult(cookStack.getItem());

if ( cookResult != null )
            {
return true;
            }
        }

return false;
    }

public boolean getIsFoodBurning()
    {
if (cookStack != null && getCurrentFireLevel() >= 3 && cookStack.getItem() != BWPRegistry.itemShaft ) // gonna replace w burned meat
        {
return true;
        }

return false;
    }

public boolean isRainingOnCampfire()
    {
CampfireBlock block = (CampfireBlock)(worldObj.getBlock( xCoord, yCoord, zCoord ));

return block.isRainingOnCampfire(worldObj, xCoord, yCoord, zCoord);
    }

private void stopSmouldering()
    {
smoulderCounter = 0;

CampfireBlock block = (CampfireBlock)(worldObj.getBlock( xCoord, yCoord, zCoord ));

block.stopSmouldering(worldObj, xCoord, yCoord, zCoord);
    }

private void relightSmouldering()
    {
burnTimeSinceLit = 0;

CampfireBlock block = (CampfireBlock)(worldObj.getBlock( xCoord, yCoord, zCoord ));

block.relightFire(worldObj, xCoord, yCoord, zCoord);
    }


}

package mods.betterwithpatches.block;



Java:
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import mods.betterwithpatches.BWPRegistry;
import mods.betterwithpatches.block.tile.CampfireTileEntity;
import mods.betterwithpatches.craft.CampFireCraftingManager;
import mods.betterwithpatches.features.HCFurnace;
import mods.betterwithpatches.proxy.ClientProxy;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.IIcon;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraft.block.Block;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraftforge.fluids.BlockFluidBase;

import java.util.Random;



public class CampfireBlock extends BlockContainer
{

public final int fireLevel;

public static final int CAMPFIRE_FUEL_STATE_NORMAL = 0;
public static final int CAMPFIRE_FUEL_STATE_BURNED_OUT = 1;
public static final int CAMPFIRE_FUEL_STATE_SMOULDERING = 2;
public static CampfireBlock[] fireLevelBlockArray = new CampfireBlock[4];

public static boolean campfireChangingState = false; // temporarily true when block is being changed from one block ID to another

    private static final float SPIT_THICKNESS = (1F / 16F );
private static final float HALF_SPIT_THICKNESS = (SPIT_THICKNESS / 2F );
private static final float SPIT_HEIGHT = (12F / 16F );
private static final float SPIT_MIN_Y = (SPIT_HEIGHT - HALF_SPIT_THICKNESS);
private static final float SPIT_MAX_Y = (SPIT_MIN_Y + SPIT_THICKNESS);

private static final float SPIT_SUPPORT_WIDTH = (1F / 16F );
private static final float HALF_SPIT_SUPPORT_WIDTH = (SPIT_SUPPORT_WIDTH / 2F );
private static final float SPIT_SUPPORT_BORDER = (0.5F / 16F );

private static final float SPIT_FORK_WIDTH = (1F / 16F );
private static final float SPIT_FORK_HEIGHT = (3F / 16F );
private static final float SPIT_FORK_HEIGHT_OFFSET = (1F / 16F );
private static final float SPIT_FORK_MIN_Y = (SPIT_MIN_Y - SPIT_FORK_HEIGHT_OFFSET);
private static final float SPIT_FORK_MAX_Y = (SPIT_FORK_MIN_Y + SPIT_FORK_HEIGHT);

private static final double SPIT_COLLISION_HEIGHT = (SPIT_HEIGHT + 1.5D / 16D );
private static final double SPIT_COLLISION_WIDTH = (3D / 16D );
private static final double SPIT_COLLISION_HALF_WIDTH = (SPIT_COLLISION_WIDTH / 2D );

public CampfireBlock(int iFireLevel )
    {
super(  Material.circuits );
fireLevel = iFireLevel;
fireLevelBlockArray[iFireLevel] = this;
setHardness( 0.1F );
setStepSound( soundTypeWood );
setBlockName( "bwm:fcBlockCampfire" );

    }

@Override
    public Item getItemDropped( int meta, Random random, int fortune )
    {
if (fireLevel != 0 || getFuelState(meta) != CAMPFIRE_FUEL_STATE_NORMAL)
        {
return null;
        }

return super.getItemDropped( meta, random, fortune );
    }

@Override
    public TileEntity createNewTileEntity(World worldIn, int meta )
    {
return new CampfireTileEntity();
    }

@Override
    public void breakBlock( World worldIn, int x, int y, int z, Block blockBroken, int meta )
    {
if ( !campfireChangingState)
        {
            CampfireTileEntity tileEntity = (CampfireTileEntity)worldIn.getTileEntity(x, y, z );


                tileEntity.ejectContents();


// only called when not changing state as super kills the tile entity
            super.breakBlock( worldIn, x, y, z, worldIn.getBlock(x,y,z), meta );
        }
    }

@Override
    public boolean isOpaqueCube()
    {
return false;
    }

@Override
    public boolean renderAsNormalBlock()
    {
return false;
    }

@Override
    public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k )
    {
return null;
    }

@Override
    protected boolean canSilkHarvest()
    {
return false;
    }



@Override
    public int onBlockPlaced( World world, int i, int j, int k, int iFacing, float fClickX, float fClickY, float fClickZ, int iMetadata )
    {
return setIAligned(iMetadata, isFacingIAligned(iFacing));
    }




@Override
    public int tickRate( World world )
    {
return 2;
    }




public boolean getCanBeSetOnFireDirectly(IBlockAccess blockAccess, int i, int j, int k)
    {
return fireLevel == 0 && getFuelState(blockAccess, i, j, k) == CAMPFIRE_FUEL_STATE_NORMAL;
    }


public boolean setOnFireDirectly(World world, int i, int j, int k)
    {
if ( getCanBeSetOnFireDirectly(world, i, j, k) )
        {
if ( !isRainingOnCampfire(world, i, j, k) )
            {
changeFireLevel(world, i, j, k, 1, world.getBlockMetadata(i, j, k));

                CampfireTileEntity tileEntity = (CampfireTileEntity)world.getTileEntity(
                        i, j, k );

                tileEntity.onFirstLit();

world.playSoundEffect( i + 0.5D, j + 0.5D, k + 0.5D,
"mob.ghast.fireball", 1F, world.rand.nextFloat() * 0.4F + 0.8F );

if ( !Blocks.portal.func_150000_e( world, i, j, k ) )
                {
// FCTODO: A bit hacky here.  Should probably be a general way to start a
                    // bigger fire atop flammable blocks

                    Block iBlockBelowID = world.getBlock( i, j - 1, k );

if ( iBlockBelowID == Blocks.netherrack) //|| iBlockBelowID ==  BTWBlocks.fallingNetherrack.blockID )
                    {
world.setBlock( i, j, k, Blocks.fire);
                    }
                }
            }
else
            {
world.playAuxSFX( 10, i, j, k, 0 );
            }

return true;
        }

return false;
    }


public int getChanceOfFireSpreadingDirectlyTo(IBlockAccess blockAccess, int i, int j, int k)
    {
if (fireLevel == 0 && getFuelState(blockAccess, i, j, k) == CAMPFIRE_FUEL_STATE_NORMAL)
        {
return 60; // same chance as leaves and other highly flammable objects
        }

return 0;
    }



@Override
    public boolean onBlockActivated( World world, int i, int j, int k, EntityPlayer player, int iFacing, float fXClick, float fYClick, float fZClick )
    {
        ItemStack stack = player.getCurrentEquippedItem();
        CampfireTileEntity tileEntityNew =
                (CampfireTileEntity)world.getTileEntity( i, j, k );
        ItemStack nocrash = tileEntityNew.getSpitStack();

if ( stack != null )
        {
            Item item = stack.getItem();

if ( !getHasSpit(world, i, j, k) )
            {
if ( item == BWPRegistry.itemPointyStick)
                {
setHasSpit(world, i, j, k, true);

                    CampfireTileEntity tileEntity =
                            (CampfireTileEntity)world.getTileEntity( i, j, k );

                    tileEntity.setSpitStack(stack);

stack.stackSize--;

return true;
                }
            }
else
            {
                CampfireTileEntity tileEntity =
                        (CampfireTileEntity)world.getTileEntity( i, j, k );

                ItemStack cookStack = tileEntity.getCookStack();

if ( cookStack == null )
                {
if ( isValidCookItem(stack) && nocrash != null )
                    {
                        ItemStack spitStack = tileEntity.getSpitStack();

if ( spitStack.getItemDamage() == 0 )
                        {
                            tileEntity.setCookStack(stack);
                        }
else
                        {
// break the damaged spit when the player attempts to place an item on it
                            // this is to discourage early game exploits involving half damaged sticks.

                            tileEntity.setSpitStack(null);

setHasSpit(world, i, j, k, false);

if ( !world.isRemote )
                            {
                                ItemStack ejectStack = stack.copy();

ejectStack.stackSize = 1;

world.spawnEntityInWorld(new EntityItem(world, i, j, k, ejectStack));;


world.playAuxSFX( 10,
i, j, k, 0 );
                            }
                        }

stack.stackSize--;

return true;
                    }
                }
else if ( cookStack.getItem() == stack.getItem() &&
stack.stackSize < stack.getMaxStackSize() )
                {
player.worldObj.playSoundAtEntity( player, "random.pop", 0.2F, 2F );

stack.stackSize++;

tileEntity.setCookStack(null);

return true;
                }
            }
if (item == Items.flint_and_steel){
if (fireLevel == 0){
stack.damageItem(2, player);
double a = Math.random()*4;
if (a >= 3.0) {
                        setOnFireDirectly(world, i, j, k);
                    }
return true;

                }
            }
if (item == BWPRegistry.itemOakBark){
if (world.isRemote) {
System.out.print(tileEntityNew.getCookStack());
return true;
                }
            }

if (fireLevel > 0 || getFuelState(world, i, j, k) == CAMPFIRE_FUEL_STATE_SMOULDERING)
            {
int iItemDamage = stack.getItemDamage();



if ( getCanBeFedDirectlyIntoCampfire(iItemDamage) )
                {
if ( !world.isRemote )
                    {
                        CampfireTileEntity tileEntity =
                                (CampfireTileEntity)world.getTileEntity( i, j, k );

world.playSoundEffect( i + 0.5D, j + 0.5D, k + 0.5D, "mob.ghast.fireball",
0.2F + world.rand.nextFloat() * 0.1F,
world.rand.nextFloat() * 0.25F + 1.25F );

                        tileEntity.addBurnTime(getCampfireBurnTime(iItemDamage));
                    }

stack.stackSize--;

return true;
                }

            }
        }
else // empty hand
        {
            CampfireTileEntity tileEntity =
                    (CampfireTileEntity)world.getTileEntity( i, j, k );

            ItemStack cookStack = tileEntity.getCookStack();

if ( cookStack != null && !world.isRemote )
            {
world.spawnEntityInWorld(new EntityItem(world, i, j, k, new ItemStack(cookStack.getItem())));
System.out.println("popped a cooking item out");


tileEntity.setCookStack(null);

return true;
            }
else
            {
                ItemStack spitStack = tileEntity.getSpitStack();

if ( spitStack != null )
                {
if (!world.isRemote) {

world.spawnEntityInWorld(new EntityItem(world, i, j, k, spitStack));
System.out.println("popped a spit item out");
setHasSpit(world, i, j, k, false);
tileEntity.setSpitStack(null);


return true;
                    }
                }
            }
        }

return false;
    }



public int getCampfireBurnTime(int iItemDamage)
    {
return 4800;
    }
public boolean getCanItemBeSetOnFireOnUse(int iItemDamage)
    {
return false;
    }

public boolean getCanItemStartFireOnUse(int iItemDamage)
    {
return false;
    }

public boolean getCanBeFedDirectlyIntoCampfire(int iItemDamage) //ill leave it like this for now, going to change it soon
    {
return !getCanItemBeSetOnFireOnUse(iItemDamage) && !getCanItemStartFireOnUse(iItemDamage) &&
getCampfireBurnTime(iItemDamage) > 0;
    }



@Override
    public void onEntityCollidedWithBlock( World world, int i, int j, int k, Entity entity )
    {
if ( !world.isRemote && entity.isEntityAlive() && (fireLevel > 0 ||
getFuelState(world, i, j, k) == CAMPFIRE_FUEL_STATE_SMOULDERING) )
        {
if ( entity instanceof EntityItem)
            {
                EntityItem entityItem = (EntityItem)entity;
                ItemStack targetStack = entityItem.getEntityItem();
                Item item = targetStack.getItem();
int iBurnTime = getCampfireBurnTime(targetStack.getItemDamage());

if ( iBurnTime > 0 )
                {
iBurnTime *= targetStack.stackSize;

                    CampfireTileEntity tileEntity =
                            (CampfireTileEntity)world.getTileEntity( i, j, k );

world.playSoundEffect( i + 0.5D, j + 0.5D, k + 0.5D, "mob.ghast.fireball",
world.rand.nextFloat() * 0.1F + 0.2F,
world.rand.nextFloat() * 0.25F + 1.25F );

                    tileEntity.addBurnTime(iBurnTime);

                    entity.setDead();
                }
            }
        }
    }


public boolean getDoesFireDamageToEntities(World world, int i, int j, int k, Entity entity)
    {
return fireLevel > 2 || (fireLevel == 2 && entity instanceof EntityLiving );
    }


public boolean getCanBlockLightItemOnFire(IBlockAccess blockAccess, int i, int j, int k)
    {

return fireLevel > 0;
    }


public void onFluidFlowIntoBlock(World world, int i, int j, int k, BlockFluidBase newBlock)
    {
if (fireLevel > 0 )
        {
world.playAuxSFX(10, i, j, k, 0 );
        }


    }


//------------- Class Specific Methods ------------//

    public void setIAligned(World world, int i, int j, int k, boolean bIAligned)
    {
int iMetadata = setIAligned(world.getBlockMetadata(i, j, k), bIAligned);

world.setBlockMetadataWithNotify( i, j, k, iMetadata,2 );
    }

public int setIAligned(int iMetadata, boolean bIAligned)
    {
if ( bIAligned )
        {
iMetadata |= 1;
        }
else
        {
iMetadata &= (~1);
        }

return iMetadata;
    }

public boolean getIsIAligned(IBlockAccess blockAccess, int i, int j, int k)
    {
return getIsIAligned(blockAccess.getBlockMetadata(i, j, k));
    }

public boolean getIsIAligned(int iMetadata)
    {
return ( iMetadata & 1 ) != 0;
    }

public boolean isFacingIAligned(int iFacing)
    {
return iFacing >= 4;
    }

public void setHasSpit(World world, int i, int j, int k, boolean bHasSpit)
    {
int iMetadata = setHasSpit(world.getBlockMetadata(i, j, k), bHasSpit);

world.setBlockMetadataWithNotify( i, j, k, iMetadata,2 );
    }

public int setHasSpit(int iMetadata, boolean bHasSpit)
    {
if ( bHasSpit )
        {
iMetadata |= 2;
        }
else
        {
iMetadata &= (~2);
        }

return iMetadata;
    }

public boolean getHasSpit(IBlockAccess blockAccess, int i, int j, int k)
    {
return getHasSpit(blockAccess.getBlockMetadata(i, j, k));
    }

public boolean getHasSpit(int iMetadata)
    {
return ( iMetadata & 2 ) != 0;
    }

public void setFuelState(World world, int i, int j, int k, int iCampfireState)
    {
int iMetadata = setFuelState(world.getBlockMetadata(i, j, k), iCampfireState);

world.setBlockMetadataWithNotify( i, j, k, iMetadata,2 );
    }

public int setFuelState(int iMetadata, int iCampfireState)
    {
iMetadata &= ~12; // filter out old state

        return iMetadata | ( iCampfireState << 2 );
    }

public int getFuelState(IBlockAccess blockAccess, int i, int j, int k)
    {
return getFuelState(blockAccess.getBlockMetadata(i, j, k));
    }

public int getFuelState(int iMetadata)
    {
return ( iMetadata & 12 ) >> 2;
    }

public boolean isValidCookItem(ItemStack stack)
    {
if (CampFireCraftingManager.instance.getRecipeResult(stack.getItem()) != null )
        {
return true;
        }

return false;
    }

public void extinguishFire(World world, int i, int j, int k, boolean bSmoulder)
    {
int iMetadata = world.getBlockMetadata( i, j, k );

if ( bSmoulder )
        {
iMetadata = setFuelState(iMetadata, CAMPFIRE_FUEL_STATE_SMOULDERING);
        }
else
        {
iMetadata = setFuelState(iMetadata, CAMPFIRE_FUEL_STATE_BURNED_OUT);
        }

changeFireLevel(world, i, j, k, 0, iMetadata);

if ( !world.isRemote )
        {
world.playAuxSFX( 10, i, j, k, 1 );
        }
    }

public void relightFire(World world, int i, int j, int k)
    {
changeFireLevel(world, i, j, k, 1, setFuelState(world.getBlockMetadata(i, j, k), CAMPFIRE_FUEL_STATE_NORMAL));
    }

public void stopSmouldering(World world, int i, int j, int k)
    {
setFuelState(world, i, j, k, CAMPFIRE_FUEL_STATE_BURNED_OUT);
    }

public void changeFireLevel(World world, int i, int j, int k, int iFireLevel, int iMetadata)
    {
CampfireBlock.campfireChangingState = true;

world.setBlock( i, j, k, CampfireBlock.fireLevelBlockArray[iFireLevel], iMetadata, 2 );

CampfireBlock.campfireChangingState = false;
    }


public boolean isRainingAtPos(World world, int i, int j, int k)
    {
if ( world.isRaining() && world.canBlockSeeTheSky( i, j, k ) &&
                j >= world.getPrecipitationHeight( i, k )  )
        {
            BiomeGenBase biome = world.getBiomeGenForCoords( i, k );

return biome.canSpawnLightningBolt();
        }

return false;
    }

public boolean isRainingOnCampfire(World world, int i, int j, int k)
    {
return isRainingAtPos(world, i, j, k);
    }

public int getFireLevel() {
return fireLevel;
    }

@Override
    public void updateTick(World worldIn, int x, int y, int z, Random random){
if (!World.doesBlockHaveSolidTopSurface(worldIn, x, y - 1, z)){
if (fireLevel > 0 )
            {
worldIn.playAuxSFX( 10, x, y, z, 1 );
            }

dropBlockAsItem( worldIn, x, y, z, worldIn.getBlockMetadata( x, y, z ), 0 );

            worldIn.setBlockToAir( x, y, z );
        }

    }

@Override
    public void onNeighborBlockChange(World worldIn, int x, int y, int z, Block neighbor) {
if (!World.doesBlockHaveSolidTopSurface(worldIn, x, y - 1, z)){
if (fireLevel > 0 )
            {
worldIn.playAuxSFX( 10, x, y, z, 1 );
            }

dropBlockAsItem( worldIn, x, y, z, worldIn.getBlockMetadata( x, y, z ), 0 );

            worldIn.setBlockToAir( x, y, z );
        }
    }

//----------- Client Side Functionality -----------//


    @SideOnly(Side.CLIENT)
public IIcon[] icons;

static final double[] fireAnimationScaleArray = new double[] {0D, 0.25D, 0.5D, 0.875D };




@Override
    public void registerBlockIcons( IIconRegister reg )
{ this.icons = new IIcon[7];
this.icons[0] = reg.registerIcon( "fcBlockCampfire" );
this.icons[1] = reg.registerIcon("fcBlockCampfire_spit");
this.icons[2] = reg.registerIcon("fcBlockCampfire_support");
this.icons[3] = reg.registerIcon("fcBlockCampfire_burned");
this.icons[4] = reg.registerIcon("fcOverlayEmbers");
    }

@Override
    public IIcon getIcon(int side,int meta ) {

return this.icons[1];
    }
@Override

    public boolean shouldSideBeRendered( IBlockAccess blockAccess, int iNeighborI, int iNeighborJ, int iNeighborK, int iSide )
    {
return true;
    }

@Override
    public int getRenderType() {
return ClientProxy.renderBlockCampfire;
    }






@Override
    @SideOnly(Side.CLIENT)
public void randomDisplayTick( World world, int i, int j, int k, Random rand )
    {
if (fireLevel > 1 )
        {
for (int iTempCount = 0; iTempCount < fireLevel; iTempCount++ )
            {
double xPos = i + rand.nextFloat();
double yPos = j + 0.5F + ( rand.nextFloat() * 0.5F );
double zPos = k + rand.nextFloat();

world.spawnParticle( "smoke", xPos, yPos, zPos, 0D, 0D, 0D );
            }

            CampfireTileEntity tileEntity =
                    (CampfireTileEntity)world.getTileEntity( i, j, k );

if ( tileEntity.getIsFoodBurning() )
            {
for ( int iTempCount = 0; iTempCount < 1; ++iTempCount )
                {
double xPos = i + 0.375F + rand.nextFloat() * 0.25F;
double yPos = j + 0.5F + rand.nextFloat() * 0.5F;
double zPos = k + 0.375F + rand.nextFloat() * 0.25F;

world.spawnParticle( "largesmoke", xPos, yPos, zPos, 0D, 0D, 0D );
                }
            }
else if ( tileEntity.getIsCooking() )
            {
for ( int iTempCount = 0; iTempCount < 1; ++iTempCount )
                {
double xPos = i + 0.375F + rand.nextFloat() * 0.25F;
double yPos = j + 0.5F + rand.nextFloat() * 0.5F;
double zPos = k + 0.375F + rand.nextFloat() * 0.25F;

world.spawnParticle( "fcwhitesmoke", xPos, yPos, zPos, 0D, 0D, 0D );
                }
            }
        }
else if (fireLevel == 1 || getFuelState(world, i, j, k) == CAMPFIRE_FUEL_STATE_SMOULDERING)
        {
double xPos = (double)i + 0.375D + ( rand.nextDouble() * 0.25D );
double yPos = (double)j + 0.25D + ( rand.nextDouble() * 0.25D );
double zPos = (double)k + 0.375D + ( rand.nextDouble() * 0.25D );

world.spawnParticle( "smoke", xPos, yPos, zPos, 0D, 0D, 0D );
        }

if (fireLevel > 0 )
        {
if ( rand.nextInt(24) == 0 )
            {
float fVolume = (fireLevel * 0.25F ) + rand.nextFloat();

world.playSound( i + 0.5D, j + 0.5D, k + 0.5D, "fire.fire",
fVolume, rand.nextFloat() * 0.7F + 0.3F, false );
            }
        }
    }
}
package mods.betterwithpatches.client;
Java:
import mods.betterwithpatches.BWPRegistry;
import mods.betterwithpatches.block.tile.CampfireTileEntity;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import org.lwjgl.opengl.GL11;

public class CampfireRenderer extends TileEntitySpecialRenderer
{
public void renderTileEntityAt(TileEntity tileEntity, double xCoord, double yCoord, double zCoord, float fPartialTickCount )
    {
        CampfireTileEntity campfire = (CampfireTileEntity)tileEntity;

        renderCookStack(campfire, xCoord, yCoord, zCoord);
    }

private void renderCookStack(CampfireTileEntity campfire, double xCoord, double yCoord, double zCoord)
    {
        ItemStack stack = campfire.getCookStack();

if ( stack != null )
        {

int iMetadata = campfire.getBlockMetadata();
boolean bIAligned = BWPRegistry.unlitCampfire.getIsIAligned(iMetadata);

EntityItem entity = new EntityItem(campfire.getWorldObj(), xCoord, yCoord, zCoord, stack);

entity.getEntityItem().stackSize = 1;
entity.hoverStart = 0.0F;


GL11.glPushMatrix();
GL11.glTranslatef( (float)xCoord + 0.5F, (float)yCoord + ( 9F / 16F ), (float)zCoord + 0.5F );

if ( !bIAligned && RenderManager.instance.options.fancyGraphics )
            {
GL11.glRotatef( 90F, 0.0F, 1.0F, 0.0F);
            }

RenderManager.instance.renderEntityWithPosYaw(entity, 0.0D, 0.0D, 0.0D, 0.0F, 0.0F);

GL11.glPopMatrix();



        }
    }
}
Видео загрузить не могу, поэтому загружу текст где показываю что происходит с cookstack
null - Начальное положение
1xitem.beefRaw@0 - положил еду
1xitem.beefRaw@0 - достал еду
null -положил еду
null -достал еду - как бы вернул в Н.П.
UPD: Основную проблему пофиксил, но после релога клиент " забывает " про cookStack и SpitStack
 
Последнее редактирование:
Решение
1.
import net.minecraft.client.renderer.entity.RenderManager;
Использование строго клиентских классов в общих частях мода - это сильно. О разделении клиент/сервер читали? Сервер даст краш.

2. Оформление кода в блок </> означает не только перенос этого кода, но и ФОРМАТИРОВАНИЕ ЕГО. В текущем состоянии он трудночитаем в шапке темы.

3.
После релога клиент забывает про cookStack и SpitStack
Нет пакета обновления (синхронизации) данных.

В целом твоя беда из-за отсутствия синхронизации тайла между клиентом и сервером. Для этого нужен отдельный пакет.
решил посмотреть как всё происходит в самой функции
1xitem.porkchopRaw@0 ab 1xitem.porkchopRaw@0 ab - засунул еду
null a - вытащил еду
null a 1xitem.porkchopRaw@0 ab - поставил еду обратно
null a - вытащил еду

вот код функции
Java:
public void setCookStack(ItemStack stack)
    {
        if ( stack != null )
        {
            cookStack = stack.copy();

            cookStack.stackSize = 1;
            System.out.print(getCookStack() + "ab");
        }
        else
        {
            cookStack = null;

            cookBurningCounter = 0;
            System.out.print(getCookStack() + "a");
        }

        cookCounter = 0;

        worldObj.markBlockForUpdate( xCoord, yCoord, zCoord );
    }
 
1.
import net.minecraft.client.renderer.entity.RenderManager;
Использование строго клиентских классов в общих частях мода - это сильно. О разделении клиент/сервер читали? Сервер даст краш.

2. Оформление кода в блок </> означает не только перенос этого кода, но и ФОРМАТИРОВАНИЕ ЕГО. В текущем состоянии он трудночитаем в шапке темы.

3.
После релога клиент забывает про cookStack и SpitStack
Нет пакета обновления (синхронизации) данных.

В целом твоя беда из-за отсутствия синхронизации тайла между клиентом и сервером. Для этого нужен отдельный пакет.
 
RenderManager нигде не учавствует, я пытался сделать ренедр тайла в самом коде тайла, не получилось - сделал отдельно, а импорт удалить забыл
Я только недавно начал пользоваться этим форумом, поэтому ещё не освоился...
Попытался что-то сделать, но теперь клиент ничего не отвечает вообще, вне зависимости от того перезашёл я или нет

Java:
 @Override
public Packet getDescriptionPacket()
{
NBTTagCompound tag = new NBTTagCompound();

if (cookStack != null)
    {
NBTTagCompound cookTag = new NBTTagCompound();

cookStack.writeToNBT(cookTag);

tag.setTag( "tag01", cookTag );
    }

if (spitStack != null)
    {
NBTTagCompound spitTag = new NBTTagCompound();

spitStack.writeToNBT(spitTag);

tag.setTag( "tag02", spitTag );
    }


return new S35PacketUpdateTileEntity( xCoord, yCoord, zCoord, 0, tag );
}


@Override
public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity packet) {
TileEntity tile = worldObj.getTileEntity(packet.func_148856_c(), packet.func_148855_d(), packet.func_148854_e());
if (tile instanceof CampfireTileEntity) {
NBTTagCompound tag = new NBTTagCompound();
NBTTagCompound cookTag = tag.getCompoundTag( "tag01" );

if ( cookTag != null )
{ System.out.print(cookTag + "<- cookTag");
cookStack = ItemStack.loadItemStackFromNBT(cookTag );
System.out.print("  this was a thing from NBT -> " + cookStack + " <- this was a thing from NBT");
        }

NBTTagCompound spitTag = tag.getCompoundTag( "tag02" );

if ( spitTag != null )
        {
spitStack = ItemStack.loadItemStackFromNBT(spitTag);
        }
    }
}
 
Последнее редактирование:
Так, я путём вставки рандомных принтов понял что почему то у меня передаётся пустой пакет
{}<- cookTag this was a thing from NBT -> null <- this was a thing from NBT
и при этом у меня проверка на то, чтобы cookTag не был нулевым
 
Назад
Сверху