Jump to content

Machine doesn't save inventory contents when reloaded [1.7.10]


iLegendx98

Recommended Posts

As the title explains, I have a machine (Blast Furnace) that takes three inputs and two outputs. I can put items in these input slots but when I reload the game the items are gone. I assume this is an issue with NBT data on the block, although I cant see what the issue is.

 

TileBlastFurnace.class

 

 

package tile;

import recipe.RecipeBlastFurnace;
import block.BlockBlastFurnace;
import main.Singularity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;

public class TileBlastFurnace extends TileEntity implements ISidedInventory
{
private ItemStack slots[];

public int dualPower;
public int dualCookTime;
public static final int maxPower = 10000;
public static final int mashingSpeed = 100;

private static final int[] slots_top = new int[] {0, 1};
private static final int[] slots_bottom = new int[] {3, 4};
private static final int[] slots_side = new int[] {2};

private String customName;

public TileBlastFurnace() 
{
	slots = new ItemStack[5];
}

@Override
public int getSizeInventory() 
{
	return slots.length;
}

@Override
public ItemStack getStackInSlot(int i)
{
	return slots[i];
}

@Override
public ItemStack getStackInSlotOnClosing(int i) 
{
	if (slots[i] != null) 
	{
		ItemStack itemstack = slots[i];
		slots[i] = null;
		return itemstack;
	}
	else
	{
		return null;
	}
}

@Override
public void setInventorySlotContents(int i, ItemStack itemstack)
{
	slots[i] = itemstack;
	if (itemstack != null && itemstack.stackSize > getInventoryStackLimit())
	{
		itemstack.stackSize = getInventoryStackLimit();
	}
}

@Override
public int[] getAccessibleSlotsFromSide(int i) 
{
	return i == 0 ? slots_bottom : (i == 1 ? slots_top : slots_side);
}

@Override
public int getInventoryStackLimit()
{
	return 64;
}

@Override
public boolean isUseableByPlayer(EntityPlayer player) 
{
	if (worldObj.getTileEntity(xCoord, yCoord, zCoord) != this)
	{
		return false;
	}
	else
	{
		return player.getDistanceSq((double)xCoord + 0.5D, (double)yCoord + 0.5D, (double)zCoord + 0.5D) <= 64;
	}
}

public void openInventory() {}
public void closeInventory() {}

@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack) 
{
	return i == 2 ? false : (i == 1 ? hasItemPower(itemstack) : true);
}

public boolean hasItemPower(ItemStack itemstack) 
{
	return getItemPower(itemstack) > 0;
}

private static int getItemPower (ItemStack itemstack) 
{
	if (itemstack == null) 
	{
		return 0;
	}
	else
	{
		Item item = itemstack.getItem();

		if (item == Singularity.itemCoke ) 
		{
			return 50; //TODO FUEL
		}

		return 0;
	}
}

public ItemStack decrStackSize(int i, int j) 
{
	if (slots[i] != null)
	{
		if (slots[i].stackSize <= j)
		{
			ItemStack itemstack = slots[i];
			slots[i] = null;
			return itemstack;
		}
		ItemStack itemstack1 = slots[i].splitStack(j);
		if (slots[i].stackSize == 0) 
		{
			slots[i] = null;
		}
		return itemstack1;
	}
	else
	{
		return null;
	}
}

/** NBT START **/

public void readFromNBT (NBTTagCompound nbt) {
	super.readFromNBT(nbt);
	NBTTagList list = nbt.getTagList("Items", 10);
	slots = new ItemStack[getSizeInventory()];

	for (int i = 0; i < list.tagCount(); i++) {
		NBTTagCompound nbt1 = (NBTTagCompound)list.getCompoundTagAt(i);
		byte b0 = nbt1.getByte("Slot");

		if (b0 >= 0 && b0 < slots.length) {
			slots[b0] = ItemStack.loadItemStackFromNBT(nbt1);
		}
	}

	dualPower = nbt.getShort("PowerTime");
	dualCookTime = nbt.getShort("CookTime");
}

public void writeToNBT(NBTTagCompound nbt) {
	super.writeToNBT(nbt);
	nbt.setShort("PowerTime", (short)dualPower);
	nbt.setShort("CookTime", (short)dualCookTime);
	NBTTagList list = new NBTTagList();

	for (int i = 0; i < slots.length; i++) {
		if (slots[i] != null) {
			NBTTagCompound nbt1 = new NBTTagCompound();
			nbt1.setByte("Slot", (byte)i);
			slots[i].writeToNBT(nbt1);
			list.appendTag(nbt1);
		}
	}

	nbt.setTag("Items", list);
}

/** NBT END **/


@Override
public String getInventoryName() 
{
	return "container.ingotMasher";
}

@Override
public boolean canInsertItem(int var1, ItemStack itemstack, int var3)
{
	return this.isItemValidForSlot(var1, itemstack);
}

@Override
public boolean canExtractItem(int i, ItemStack itemstack, int j) 
{
	return j != 0 || i != 1 || itemstack.getItem() == Items.bucket;
}

@Override
public boolean hasCustomInventoryName() 
{
	return this.customName != null && this.customName.length() > 0;
}

public int getMasherProgressScaled(int i) 
{
	return (dualCookTime * i) / this.mashingSpeed;
}

public int getPowerRemainingScaled(int i) 
{
	return (dualPower * i) / maxPower;
}

private boolean canMash()
{
	if (slots[0] == null || slots[1] == null) 
	{
		return false;
	}
	ItemStack itemstack = RecipeBlastFurnace.getMashingResult(slots[0].getItem(), slots[1].getItem());
	if (itemstack == null) 
	{
		return false;
	}
	if (slots[3] == null) 
	{
		return true;
	}
	if (!slots[3].isItemEqual(itemstack)) 
	{
		return false;
	}
	if (slots[3].stackSize < getInventoryStackLimit() && slots[3].stackSize < slots[3].getMaxStackSize()) 
	{
		return true;
	}
	else
	{
		return slots[3].stackSize < itemstack.getMaxStackSize();
	}
}

private void mashItem() 
{
	if (canMash()) 
	{
		ItemStack itemstack = RecipeBlastFurnace.getMashingResult(slots[0].getItem(), slots[1].getItem());

		if (slots[3] == null) 
		{
			slots[3] = itemstack.copy();
		}
		else if (slots[3].isItemEqual(itemstack)) 
		{
			slots[3].stackSize += itemstack.stackSize;
		}

		for (int i = 0; i < 2; i++) 
		{
			if (slots[i].stackSize <= 0) 
			{
				slots[i] = new ItemStack(slots[i].getItem().setFull3D());
			}
			else
			{
				slots[i].stackSize--;
			}

			if (slots[i].stackSize <= 0)
			{
				slots[i] = null;
			}
		}
	}
}

public boolean hasPower() 
{
	return dualPower > 0;
}

public boolean isMashing()
{
	return this.dualCookTime > 0;
}

public void updateEntity() 
{
	boolean flag = this.hasPower();
	boolean flag1= false;

	if(hasPower() && this.isMashing()) 
	{
		this.dualPower--;
	}

	if(!worldObj.isRemote) 
	{
		if (this.hasItemPower(this.slots[2]) && this.dualPower < (this.maxPower - this.getItemPower(this.slots[2]))) 
		{
			this.dualPower += getItemPower(this.slots[2]);
			if(this.slots[2] != null) 
			{
				flag1 = true;
				this.slots[2].stackSize--;
				if(this.slots[2].stackSize == 0) 
				{
					this.slots[2] = this.slots[2].getItem().getContainerItem(this.slots[2]);
				}
			}
		}	
		if (hasPower() && canMash()) 
		{
			dualCookTime++;

			if (this.dualCookTime == this.mashingSpeed) 
			{
				this.dualCookTime = 0;
				this.mashItem();
				flag1 = true;
			}
		}
		else
		{
			dualCookTime = 0;
		}

		if (flag != this.isMashing()) 
		{
			flag1 = true;
			BlockBlastFurnace.updateBlockState(this.isMashing(), this.worldObj, this.xCoord, this.yCoord, this.zCoord);
		}
	}

	if (flag1) 
	{
		this.markDirty();
	}
    }
}

 

 

 

Thanks for any help :)

Link to comment
Share on other sites

Does this also happen when you just move away from it and let it unload? Did you let it run at some point while testing?

Well on the reload part that is...

 

As far as I can see, whenever you just put in items, and don't let it run. It will never be #markDirty()-ied... Or I am missing something...

"I guess as this is pretty much WIP, I can just 'borrow' the sounds from that game without problem. They are just 'placeholders' anyway." -Me, while extracting the Tear sounds of Bioshock Infinite.

Link to comment
Share on other sites

I am in the middle of the development of my own mod, and I really hoped nbt-data would sync correctly between the server and client whenever you don't pull anything fancy. But I guess I was wrong...

Basically, you need to override #getDiscriptionPacket() and #onDataPacket().

 

I found a tutorial here: http://cazzar.net/minecraft/tutorials/Tile-Entity-Updates-The-Quick-and-Dirty-Method/

 

Make sure whenever an internal state changes you #markDirty(), or worldObj.markForUpdate(xCoord, yCoord, zCoord).

The difference being that #markDirty() seems to mark the whole chunk to be updated, and the #markForUpdate(...) one you can force only one block to change.

"I guess as this is pretty much WIP, I can just 'borrow' the sounds from that game without problem. They are just 'placeholders' anyway." -Me, while extracting the Tear sounds of Bioshock Infinite.

Link to comment
Share on other sites

I have added these three methods to my tile entity class :

@Override
public Packet getDescriptionPacket() {
    NBTTagCompound tag = new NBTTagCompound();
    writeToNBT(tag);
    return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 0, tag);
}
@Override
public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) {
    readFromNBT(pkt.func_148857_g());
}

public void markForUpdate() {
    worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}

 

This still doesn't work and I now crash when ever I place my blast furnace down.

 

This is the crash report:

 

 

---- Minecraft Crash Report ----
// This is a token for 1 free hug. Redeem at your nearest Mojangsta: [~~HUG~~]

Time: 9/8/14 7:51 PM
Description: Exception ticking world

java.lang.RuntimeException: class tile.TileBlastFurnace is missing a mapping! This is a bug!
at net.minecraft.tileentity.TileEntity.writeToNBT(TileEntity.java:100)
at tile.TileBlastFurnace.writeToNBT(TileBlastFurnace.java:177)
at tile.TileBlastFurnace.getDescriptionPacket(TileBlastFurnace.java:364)
at net.minecraft.server.management.PlayerManager$PlayerInstance.sendTileToAllPlayersWatchingChunk(PlayerManager.java:638)
at net.minecraft.server.management.PlayerManager$PlayerInstance.sendChunkUpdate(PlayerManager.java:623)
at net.minecraft.server.management.PlayerManager.updatePlayerInstances(PlayerManager.java:84)
at net.minecraft.world.WorldServer.tick(WorldServer.java:195)
at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:702)
at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:624)
at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:118)
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:495)
at net.minecraft.server.MinecraftServer$2.run(MinecraftServer.java:762)


A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Stacktrace:
at net.minecraft.tileentity.TileEntity.writeToNBT(TileEntity.java:100)
at tile.TileBlastFurnace.writeToNBT(TileBlastFurnace.java:177)
at tile.TileBlastFurnace.getDescriptionPacket(TileBlastFurnace.java:364)
at net.minecraft.server.management.PlayerManager$PlayerInstance.sendTileToAllPlayersWatchingChunk(PlayerManager.java:638)
at net.minecraft.server.management.PlayerManager$PlayerInstance.sendChunkUpdate(PlayerManager.java:623)
at net.minecraft.server.management.PlayerManager.updatePlayerInstances(PlayerManager.java:84)
at net.minecraft.world.WorldServer.tick(WorldServer.java:195)

-- Affected level --
Details:
Level name: New World
All players: 1 total; [EntityPlayerMP['ForgeDevName'/34261, l='New World', x=-997.70, y=4.00, z=-998.60]]
Chunk stats: ServerChunkCache: 1290 Drop: 0
Level seed: -2109880100455827262
Level generator: ID 01 - flat, ver 0. Features enabled: true
Level generator options: 
Level spawn location: World: (36,4,314), Chunk: (at 4,0,10 in 2,19; contains blocks 32,0,304 to 47,255,319), Region: (0,0; contains chunks 0,0 to 31,31, blocks 0,0,0 to 511,255,511)
Level time: 53080 game time, 53080 day time
Level dimension: 0
Level storage version: 0x04ABD - Anvil
Level weather: Rain time: 64667 (now: false), thunder time: 136619 (now: false)
Level game mode: Game mode: creative (ID 1). Hardcore: false. Cheats: true
Stacktrace:
at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:702)
at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:624)
at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:118)
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:495)
at net.minecraft.server.MinecraftServer$2.run(MinecraftServer.java:762)

-- System Details --
Details:
Minecraft Version: 1.7.10
Operating System: Windows 7 (amd64) version 6.1
Java Version: 1.8.0_05, Oracle Corporation
Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
Memory: 819226808 bytes (781 MB) / 1037959168 bytes (989 MB) up to 1037959168 bytes (989 MB)
JVM Flags: 3 total; -Xincgc -Xmx1024M -Xms1024M
AABB Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used
IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0
FML: MCP v9.05 FML v7.10.18.1180 Minecraft Forge 10.13.0.1180 4 mods loaded, 4 mods active
mcp{9.05} [Minecraft Coder Pack] (minecraft.jar) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available->Available->Available->Available->Available->Available
FML{7.10.18.1180} [Forge Mod Loader] (forgeSrc-1.7.10-10.13.0.1180.jar) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available->Available->Available->Available->Available->Available
Forge{10.13.0.1180} [Minecraft Forge] (forgeSrc-1.7.10-10.13.0.1180.jar) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available->Available->Available->Available->Available->Available
singularity{v1.0} [singularity] (bin) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available->Available->Available->Available->Available->Available
Profiler Position: N/A (disabled)
Vec3 Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used
Player Count: 1 / 8; [EntityPlayerMP['ForgeDevName'/34261, l='New World', x=-997.70, y=4.00, z=-998.60]]
Type: Integrated Server (map_client.txt)
Is Modded: Definitely; Client brand changed to 'fml,forge'

 

 

 

I am so confused!!!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.