Jump to content

[1.10.02] Overlay item texture on block texture


TrekkieCub314

Recommended Posts

Hmmm... I know a mod, called "HoloInventory":

https://github.com/dries007/HoloInventory

You could look, how he made it (with Vanilla Chests)

 

EDIT: This: https://github.com/dries007/HoloInventory/blob/master/src/main/java/net/dries007/holoInventory/client/renderers/RenderHelper.java#L52 should be the method you need :) (I think, you can remove all the OpenGL-Stuff and replace it with your own OpenGL-Methods, that means all you need :) )

Bringing the best mod back alive! Our mod REFORGED!

Balkon's Weapons for 1.8: https://github.com/TheOnlySilverClaw/Reforged/releases

Link to comment
Share on other sites

OpenGL coding is something I've had very little experience with.  Maybe if I let you know exactly what I'm trying to do, I can be pointed in the right direction.

 

I have a block whose model has block/cross as its parent.  What I'm trying to do is change the texture of the block such that the texture of the item is overlaid on the block texture, then the new texture is rendered in the form of a cross.  I *might* have been able to figure out how to do this in 1.7.2, but exactly how models are used and rendering in general is confusing for me.  Can anyone either explain how I can accomplish what I want or point me to a tutorial that can help me?  I know I could theoretically accomplish something similar with an entity, but if I can change how the block renders rather than spawning a new entity, I'd prefer that.

Link to comment
Share on other sites

OpenGL coding is something I've had very little experience with.  Maybe if I let you know exactly what I'm trying to do, I can be pointed in the right direction.

 

I have a block whose model has block/cross as its parent.  What I'm trying to do is change the texture of the block such that the texture of the item is overlaid on the block texture, then the new texture is rendered in the form of a cross.  I *might* have been able to figure out how to do this in 1.7.2, but exactly how models are used and rendering in general is confusing for me.  Can anyone either explain how I can accomplish what I want or point me to a tutorial that can help me?  I know I could theoretically accomplish something similar with an entity, but if I can change how the block renders rather than spawning a new entity, I'd prefer that.

You want to render items aka "EntityItems" you will want to use a TESR i think as it will be dependant on what items are in there. I dont think much has changed in that aspect from 1.7 so look at examples of that and try to "replicate" that for 1.10.2. If you need anymore advice or direction ask away.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

After looking at the rendering code for the item frame, I think I'm close to getting this to work.  The problem I'm having right now is the textures for the tile entity look green most of the time (they occasionally show up correctly, but if I move the cursor or the player, it usually reverts to the solid green look).  Also, my items aren't showing up.  Can anyone tell me what I might need to do?

 

[spoiler=Renderer]

package com.trekkiecub.oddsandends.render;

import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockRendererDispatcher;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.RenderItem;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
import net.minecraft.client.renderer.block.model.ModelManager;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;

import com.trekkiecub.oddsandends.tileentity.TileEntity_Sceptre;

public class RenderTileSceptre extends TileEntitySpecialRenderer {
private static final ResourceLocation TEX_SCEPTRE = new ResourceLocation("tc_oae:textures/blocks/sceptre_top.png");
private final Minecraft mc = Minecraft.getMinecraft();
private final ModelResourceLocation sceptreModel = new ModelResourceLocation("tc_oae:sceptre_top");
private final RenderItem itemRenderer;

public RenderTileSceptre(RenderItem itemRend)
{
	this.itemRenderer = itemRend;
}

@Override
public void renderTileEntityAt(TileEntity te, double x, double y, double z, float partialTick, int destroyStage) {
	GlStateManager.pushMatrix();
	GlStateManager.translate(x, y, z);

	// Bind texture
	//this.rendererDispatcher.renderEngine.bindTexture(TEX_SCEPTRE);

	BlockRendererDispatcher blockrendererdispatcher = this.mc.getBlockRendererDispatcher();
        ModelManager modelmanager = blockrendererdispatcher.getBlockModelShapes().getModelManager();
        // Get the model from the ModelLocation
        IBakedModel ibakedmodel = modelmanager.getModel(this.sceptreModel);
        
        TileEntity_Sceptre powerTile = (TileEntity_Sceptre)te;
        
        // Translation, not sure why
        GlStateManager.pushMatrix();
        //GlStateManager.translate(-0.5, -0.5, -0.5);
        
        // Render the block model
        blockrendererdispatcher.getBlockModelRenderer().renderModelBrightnessColor(ibakedmodel, 1.0F, 1.0F, 1.0F, 1.0F);
        
        GlStateManager.popMatrix();
        
        this.renderItem(powerTile);
        GlStateManager.popMatrix();
        
}

private void renderItem(TileEntity_Sceptre sceptre)
{
	ItemStack stack = sceptre.getItem();
	if (stack != null)
	{
		EntityItem entityitem = new EntityItem(sceptre.getWorld(), sceptre.getPos().getX(), sceptre.getPos().getY(), sceptre.getPos().getZ(), stack);
		Item item = entityitem.getEntityItem().getItem();
		entityitem.getEntityItem().stackSize = 1;
		entityitem.hoverStart = 0;

		GlStateManager.pushMatrix();
		GlStateManager.disableLighting();

		// Actual rendering codeish
		GlStateManager.scale(0.5, 0.5, 0.5);
		GlStateManager.pushAttrib();
		RenderHelper.enableStandardItemLighting();
		this.itemRenderer.renderItem(entityitem.getEntityItem(), ItemCameraTransforms.TransformType.FIXED);
		RenderHelper.disableStandardItemLighting();
		GlStateManager.popAttrib();

		// Reset Stuff
		GlStateManager.enableLighting();
		GlStateManager.popMatrix();
	}
}

}

 

 

Link to comment
Share on other sites

Set the GL color.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

the green textures?

 

Green textures.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

What I tried to do didn't work for the green textures, but then again, I have very little experience with OpenGL and I'm not sure what specific bit of code you were asking me to write.

 

I noticed that the textures only flash green if I'm looking in front of me.  If I'm looking down (less than a 45 degree angle from directly down), the texture usually shows up fine, even if I move around.  Don't know if this will help or not.

Link to comment
Share on other sites

I've got this working almost perfectly.  By that, I mean the process of rendering an item is now complete.  The problem I'm having now smells like a client/server sync issue, but I'm not entirely sure.

 

My render code runs a getItem() method in my tile entity, which should return the first item in the inventory.  Even after right-clicking to add an item, it either still thinks the first item slot is empty or I'm not correctly updating the renderer when the item slot changes.  I'm fairly sure the item slot is not empty as I can right-click to remove the item and the tile entities stop spawning power orbs when their item's damage hits is max damage value.  Either somehow the entity stuff is working while the client and server aren't syncing or I'm failing to tell the renderer to update based on the tile entity's changed data.

 

[spoiler=Renderer]

package com.trekkiecub.oddsandends.render;

import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.RenderItem;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;

import com.trekkiecub.oddsandends.items.Item_Crystal;
import com.trekkiecub.oddsandends.tileentity.TileEntity_Sceptre;

public class RenderTileSceptre extends TileEntitySpecialRenderer<TileEntity_Sceptre> {
private static final ResourceLocation TEX_SCEPTRE = new ResourceLocation("tc_oae:textures/blocks/sceptre_top.png");
private final Minecraft mc = Minecraft.getMinecraft();
private final ModelResourceLocation sceptreModel = new ModelResourceLocation("tc_oae:sceptre_top");
private final RenderItem itemRenderer;

public RenderTileSceptre(RenderItem itemRend)
{
	this.itemRenderer = itemRend;
}

@Override
 public void renderTileEntityAt(TileEntity_Sceptre te, double x, double y, double z, float partialTicks, int destroyStage)
	{
	GlStateManager.pushAttrib();
	GlStateManager.pushMatrix();

	GlStateManager.translate(x, y, z);
	GlStateManager.disableRescaleNormal();

	this.renderItem(te, true);
	this.renderItem(te, false);

	GlStateManager.popMatrix();
	GlStateManager.popAttrib();
        
}

private void renderItem(TileEntity_Sceptre sceptre, boolean firstPass)
{
	ItemStack stack = sceptre.getItem();
	if (stack != null)
	{
		RenderHelper.enableStandardItemLighting();
		GlStateManager.enableLighting();
		GlStateManager.pushMatrix();
		GlStateManager.translate(0.5, 0.5, 0.5);
		GlStateManager.scale(0.4f, 0.4f, 0.4f);

		if (firstPass)
		{
			GlStateManager.rotate(45, 0, 1, 0);
		}
		else
		{
			GlStateManager.rotate(-45, 0, 1, 0);
		}

		// Rotate Along X if needed
		if (stack.getItem() instanceof Item_Crystal)
		{
			if (((Item_Crystal)stack.getItem()).getRotate())
			{
				GlStateManager.rotate(45,0,0,1);
			}
		}

		Minecraft.getMinecraft().getRenderItem().renderItem(stack, ItemCameraTransforms.TransformType.NONE);

		GlStateManager.popMatrix();
	}
}

}

 

 

[spoiler=Tile Entity]

package com.trekkiecub.oddsandends.tileentity;

import java.util.ArrayList;
import java.util.List;

import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

import com.trekkiecub.oddsandends.entity.Entity_PowerOrb;
import com.trekkiecub.oddsandends.init.ItemInit;
import com.trekkiecub.oddsandends.items.Item_Crystal;
import com.trekkiecub.oddsandends.items.Item_HealingCrystal;
import com.trekkiecub.oddsandends.util.OAE_Func;
import com.trekkiecub.oddsandends.util.Type_CoordEntry;

public class TileEntity_Sceptre extends TileEntity implements IPowerCrystal, ITickable, IInventory {
private List<Type_CoordEntry> sources = new ArrayList<Type_CoordEntry>();
private List<Type_CoordEntry> destinations = new ArrayList<Type_CoordEntry>();
private ItemStack itemStacks[] = new ItemStack[1];
int cooldown = 0;
int maxCooldown = 30;

/**
 * Fetches the item to render
 * Null if N/A
 * @return The ItemStack to render
 */
public ItemStack getItem()
{
	if (itemStacks == null || OAE_Func.isStackEmpty(itemStacks[0]))
	{
		return new ItemStack(ItemInit.gem_anatase);
	}
	else
	{
		return itemStacks[0].copy();
	}
}

/**
 *  Incoming Power Orb Handling
 */

public int getReceiverOrientation()
{
	if (this.itemStacks == null || OAE_Func.isStackEmpty(itemStacks[0]))
	{
		return Item_HealingCrystal.errorValue;
	}
	else
	{
		return ((Item_HealingCrystal)itemStacks[0].getItem()).getOrientation();
	}
}

/**
 *  Outgoing Power Orb Handling
 */

// Positive return from this
public int getPowerRoom()
{
	if (this.itemStacks == null || OAE_Func.isStackEmpty(itemStacks[0]))
	{
		return 0;
	}
	else
	{
		return itemStacks[0].getItemDamage();
	}
}

public int getInversePowerRoom()
{
	if (this.itemStacks == null || OAE_Func.isStackEmpty(itemStacks[0]))
	{
		return 0;
	}
	else
	{
		return itemStacks[0].getMaxDamage();
	}
}
private void transmitPower(Type_CoordEntry coords)
{
	if (itemStacks == null || OAE_Func.isStackEmpty(itemStacks[0]))
	{
		// do nothing
	}
	else
	{
		if (itemStacks[0].getItem() instanceof Item_HealingCrystal && itemStacks[0].getItemDamage() != itemStacks[0].getMaxDamage())
		{
			// Only if tile entity is IPowerCrystal
			// powerRoom = getPowerRoom();
			// If orientation is the same and we have room, send
			// If orientation is the same and don't have room, don't send
			// If orientation is opposite, send
			BlockPos targetPos = coords.getBlockPos();
			TileEntity targetEntity = this.worldObj.getTileEntity(targetPos);
			if (targetEntity instanceof IPowerCrystal)
			{
				boolean canSend = false;
				int receiver = ((IPowerCrystal)targetEntity).getReceiverOrientation();
				if (receiver == Item_HealingCrystal.errorValue)
				{
					// do nothing
				}
				// If we are able to send anything to this crystal
				// or the receiver is the same type as us
				else if (receiver == -1 || receiver-this.getReceiverOrientation() == 0)
				{
					int room = ((IPowerCrystal)targetEntity).getPowerRoom();
					if (room != 0)
					{
						canSend = true;
					}
				}
				else
				{
					canSend = true;
				}
				if (canSend)
				{
					int energyTargetCanReceive = 0;
					// Restrict energy flow if needed.
					if (receiver == -1 || receiver-this.getReceiverOrientation() == 0)
					{
						energyTargetCanReceive = Math.min(((IPowerCrystal)targetEntity).getPowerRoom(), ((Item_HealingCrystal)itemStacks[0].getItem()).maxPacketSize());
					}
					else
					{
						energyTargetCanReceive = Math.min(((IPowerCrystal)targetEntity).getInversePowerRoom(), ((Item_HealingCrystal)itemStacks[0].getItem()).maxPacketSize());
					}
					int energyToSend = Math.min(energyTargetCanReceive, itemStacks[0].getMaxDamage() - itemStacks[0].getItemDamage());

					// Moonstone default
					int orientation = 0;
					// Set orientation based on reciever's orientation
					if (this.getReceiverOrientation() == -1)
					{
						orientation = ((IPowerCrystal)targetEntity).getReceiverOrientation();
					}
					// Set to sunstone if this is sunstone or receiver is also -1
					if (this.getReceiverOrientation() == 1 || orientation == -1)
					{
						orientation = 1;
					}

					Entity_PowerOrb entity = new Entity_PowerOrb(this.worldObj, this.pos.getX() + 0.5, this.pos.getY() + 0.375, this.pos.getZ() + 0.5);
					entity.setOrientation(orientation);
					float speedMultiplier = ((Item_HealingCrystal)itemStacks[0].getItem()).getTier() * 1.5F;
					speedMultiplier += 1F;
					entity.setThrowableHeading(targetPos.getX() + 0.5 - entity.posX, targetPos.getY() + 0.375 - entity.posY, targetPos.getZ() + 0.5 - entity.posZ, 0.05F * speedMultiplier, 0);
					entity.setEnergy(energyToSend);
					entity.setDestination(targetPos);
					this.worldObj.spawnEntityInWorld(entity);
					itemStacks[0].attemptDamageItem(energyToSend, this.worldObj.rand);
					this.lockDest(coords.getDimension(), coords.getBlockPos());
				}
			}
		}
		else
		{
			// Check for things like ender pearl and quantum-entangled pearls
			// Transmit instantly
		}
	}
}

/**
 * Update Entity
 */


public void updateEntity()
{
	if (!this.worldObj.isRemote)
	{
		cooldown++;
		cooldown = cooldown%maxCooldown;
		if (cooldown == 0 && destinations.size() != 0)
		{
			// Add stuff like a power level check
			for (int i = 0; i < destinations.size(); i++)
			{
				if (!destinations.get(i).isLocked())
				{
					transmitPower(destinations.get(i));
				}
			}
		}
		markDirty();
	}
}

/**
 * Clearing information
 * REPLACE dropItems functionality with InventoryHelper.drop
 */
public void dropItems()
{
	if (!this.worldObj.isRemote)
	{
		for (int i = 0; i < this.getInventoryStackLimit(); ++i)
		{
			if (itemStacks[i] != null)
			{
				Vec3d center = OAE_Func.blockCenter(this.pos);
				EntityItem entity = new EntityItem(worldObj, center.xCoord, center.yCoord, center.zCoord, itemStacks[i].copy());
				entity.motionY = 0;
				this.worldObj.spawnEntityInWorld(entity);
				this.setInventorySlotContents(i, null);

				this.clearConnections();
			}
		}
	}
}
@Override
public void clearConnections()
{
	for (Type_CoordEntry entry : sources)
	{
		TileEntity entity = DimensionManager.getWorld(entry.getDimension()).getTileEntity(entry.getBlockPos());
		if (entity instanceof IPowerCrystal)
		{
			((IPowerCrystal)entity).removeCoords(this.getMyCoordEntry(), false);
		}
	}
	for (Type_CoordEntry entry : destinations)
	{
		TileEntity entity = DimensionManager.getWorld(entry.getDimension()).getTileEntity(entry.getBlockPos());
		if (entity instanceof IPowerCrystal)
		{
			((IPowerCrystal)entity).removeCoords(this.getMyCoordEntry(), true);
		}
	}
	this.sources = new ArrayList<Type_CoordEntry>();
	this.destinations = new ArrayList<Type_CoordEntry>();
}

/**
 * Source/Destination Manipulation
 * Possible Actions:
 *  - Add source if it doesn't exist
 *  - Remove source if it's in sources
 *  - Move from destinations to sources, reversing direction
 */
@Override
public boolean changeConnections(ItemStack linker)
{
	boolean actionTaken = false;
	// Make sure the linker isn't empty
	if (linker.getTagCompound() != null)
	{
		// Again, make sure linker isn't empty
		if (linker.getTagCompound().hasKey("coords"))
		{
			// Get the coordinates in question
			NBTTagCompound nbt = (NBTTagCompound) linker.getTagCompound().getTag("coords");
			Type_CoordEntry coords = new Type_CoordEntry(nbt);
			// Check if these are our own coordinates
			if (coords != this.getMyCoordEntry())
			{
				TileEntity entity = this.worldObj.getTileEntity(coords.getBlockPos());
				if (entity != null && entity instanceof IPowerCrystal)
				{
					// Check to see if the coordinates supplied are in the destinations
					// Meaning we're switching the flow direction
					if (destinations.contains(coords))
					{
						// Make sure we can switch before we switch
						if (canWeSwitch((IPowerCrystal) entity))
						{
							this.switchCoordFunc(coords);
							((IPowerCrystal)entity).switchCoordFunc(this.getMyCoordEntry());
							actionTaken = true;
						}

					}
					// We've repeated a previous action, so we're now undoing it
					else if (sources.contains(coords))
					{
						this.removeCoords(coords, true);
						((IPowerCrystal)entity).removeCoords(this.getMyCoordEntry(), false);
						actionTaken = true;
					}
					// We don't have these coords anywhere, this is a new connection
					else
					{
						this.addCoords(coords, true);
						((IPowerCrystal)entity).addCoords(this.getMyCoordEntry(), false);
						actionTaken = true;
					}
				}
			}
		}
	}
	return actionTaken;
}
private boolean canWeSwitch(IPowerCrystal entity)
{
	return this.canReceivePower() && entity.canSendPower();
}
@Override
public void switchCoordFunc(Type_CoordEntry coords)
{
	if (this.destinations.contains(coords))
	{
		destinations.remove(coords);
		sources.add(coords);
	}
	else
	{
		sources.remove(coords);
		destinations.add(coords);
	}
}


private Type_CoordEntry getMyCoordEntry()
{
	return new Type_CoordEntry(this.worldObj.provider.getDimension(), this.getPos());
}

public Type_CoordEntry getSourceEntry(int i)
{
	if (i >= 0 && i < sources.size())
	{
		return sources.get(i);
	}
	else
	{
		return null;
	}
}
public Type_CoordEntry getDestEntry(int i)
{
	if (i >= 0 && i < destinations.size())
	{
		return destinations.get(i);
	}
	else
	{
		return null;
	}
}

@Override
public List<String> printInventory()
{
	List<String> inventory = new ArrayList<String>();
	for (int i = 0; i < this.getSizeInventory(); i++)
	{
		if (itemStacks[i] != null)
		{
			String line = "Slot " + i + ": " + itemStacks[i].getDisplayName();
			inventory.add(line);
		}
	}
	return inventory;
}
@Override
public List<String> printConnections()
{
	List<String> connections = new ArrayList<String>();
	if (this.canReceivePower())
	{
		connections.add("Sources:");
		for (Type_CoordEntry entry : sources)
		{
			connections.add(entry.printThis());
		}
	}
	if (this.canSendPower())
	{
		connections.add("Destinations:");
		for (Type_CoordEntry entry : destinations)
		{
			connections.add(entry.printThis());
		}
	}
	return connections;
}
@Override
public boolean canSendPower() {
	return true;
	// false if empty
}
@Override
public boolean canReceivePower() {
	return true;
	// false if empty
}
@Override
public void removeCoords(Type_CoordEntry coords, boolean removeFromSource)
{
	Type_CoordEntry locked = new Type_CoordEntry(coords, true);
	if (removeFromSource)
	{
		sources.remove(locked);
		sources.remove(coords);
	}
	else
	{
		destinations.remove(locked);
		destinations.remove(coords);
	}
	markDirty();
}
@Override
public void addCoords(Type_CoordEntry coords, boolean addToSource)
{
	if (addToSource)
	{
		sources.add(coords);
	}
	else
	{
		destinations.add(coords);
	}
	markDirty();
}
//
//  Merge the given item stack with the inventory slots either
//  until the stack is empty or the inventory runs out.
public ItemStack mergeStack(ItemStack stack)
{
	ItemStack returnThisStack = stack.copy();
	for (int i = 0; i < getSizeInventory() && returnThisStack.stackSize > 0; i++)
	{
		// This is the maximum amount we can deposit into each slot
		// based on both this tile entity and the number of items
		// Number of items can't go above the item's max stack size
		// Will never be zero: First is hard-coded, second breaks loop
		int remainingSpace = OAE_Func.getMaxStackToAdd(this, returnThisStack, i);
		if (remainingSpace > 0)
		{
			if (itemStacks[i] == null)
			{
				setInventorySlotContents(i, returnThisStack.splitStack(remainingSpace));
			}
			else if (OAE_Func.canWeStack(itemStacks[i], returnThisStack))
			{
				itemStacks[i].stackSize += remainingSpace;
				returnThisStack.splitStack(remainingSpace);
				markDirty();
			}
		}
	}
	if (returnThisStack.stackSize == 0)
	{
		returnThisStack = null;
	}
	return returnThisStack;
}
@Override
public void readFromNBT(NBTTagCompound compound) {
	super.readFromNBT(compound);

	sources = new ArrayList<Type_CoordEntry>();
	destinations = new ArrayList<Type_CoordEntry>();
	if (compound.hasKey("sources"))
	{
		NBTTagList entryList = (NBTTagList) compound.getTag("sources");
		for (int i = 0; i < entryList.tagCount(); i++)
		{
			NBTTagCompound entryCompound = entryList.getCompoundTagAt(i);
			Type_CoordEntry entry = Type_CoordEntry.readEntryFromNBT(entryCompound);
			sources.add(entry);
		}

		entryList = (NBTTagList) compound.getTag("destinations");
		for (int i = 0; i < entryList.tagCount(); i++)
		{
			NBTTagCompound entryCompound = entryList.getCompoundTagAt(i);
			Type_CoordEntry entry = Type_CoordEntry.readEntryFromNBT(entryCompound);
			destinations.add(entry);
		}
		this.cooldown = compound.getInteger("cooldown");
		entryList = (NBTTagList) compound.getTagList("Items", 10);

		for (int i = 0; i < entryList.tagCount(); i++)
		{
			NBTTagCompound stackTag = entryList.getCompoundTagAt(i);
			int slot = stackTag.getByte("Slot") & 255;
			setInventorySlotContents(slot, ItemStack.loadItemStackFromNBT(stackTag));
		}
	}
}

@Override
public NBTTagCompound writeToNBT(NBTTagCompound compound) {
	// Store sources under 'sources'
	NBTTagList entryList = new NBTTagList();
	for (Type_CoordEntry entry : sources)
	{
		NBTTagCompound entryCompound = new NBTTagCompound();
		entry.writeToNBT(entryCompound);
		entryList.appendTag(entryCompound);
	}
	compound.setTag("sources", entryList);
	// Store destinations under 'destinations'
	entryList = new NBTTagList();
	for (Type_CoordEntry entry : destinations)
	{
		NBTTagCompound entryCompound = new NBTTagCompound();
		entry.writeToNBT(entryCompound);
		entryList.appendTag(entryCompound);
	}
	compound.setTag("destinations", entryList);
	compound.setInteger("cooldown", this.cooldown);
	// Store inventory
	NBTTagList tagList = new NBTTagList();
	for (int i = 0; i < getSizeInventory(); i++)
	{
		if (getStackInSlot(i) != null)
		{
			NBTTagCompound slotTag = new NBTTagCompound();
			slotTag.setByte("Slot", (byte)i);
			getStackInSlot(i).writeToNBT(slotTag);
			tagList.appendTag(slotTag);
		}
	}
	compound.setTag("Items", tagList);
	return super.writeToNBT(compound);

}

@Override
public void update() {
	updateEntity();

}

@Override
public String getName() {
	return null;
}

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

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

@Override
public ItemStack getStackInSlot(int slot) {
	if (slot < 0 || slot >= this.getSizeInventory())
	{
		return null;
	}
	return this.itemStacks[slot];
}

public boolean canAddPartial(ItemStack stack)
{
	for (int i = 0; i < getSizeInventory(); i++)
	{
		if (OAE_Func.isStackEmpty(itemStacks[i]))
		{
			return true;
		}
		else if (OAE_Func.getMaxStackToAdd(this, stack, i) > 0)
		{
			return true;
		}
	}
	return false;
}
@Override
public ItemStack decrStackSize(int slot, int amount) {
	ItemStack stack = getStackInSlot(slot);
	if (stack != null)
	{
		if (stack.stackSize <= amount)
		{
			setInventorySlotContents(slot, null);
			this.markDirty();
		}
		else
		{
			stack = stack.splitStack(amount);
			if (stack.stackSize == 0)
			{
				setInventorySlotContents(slot, null);
			}
			this.markDirty();
		}
	}
	return stack;
}

@Override
public ItemStack removeStackFromSlot(int index) {
	ItemStack stack = getStackInSlot(index);
	setInventorySlotContents(index, null);
	return stack;
}

@Override
public void setInventorySlotContents(int index, ItemStack stack) {
	if (index >= 0 && index < this.itemStacks.length)
	{
		ItemStack newStack = null;
		if (!OAE_Func.isStackEmpty(stack))
		{
			newStack = stack.copy();
			if (stack.stackSize > getInventoryStackLimit())
			{
				newStack.stackSize = getInventoryStackLimit();
			}
		}
		itemStacks[index] = newStack;
		this.markDirty();
	}

}

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

@Override
public boolean isUseableByPlayer(EntityPlayer player) {
	return false;
}

@Override
public void openInventory(EntityPlayer player) {
	// TODO Auto-generated method stub

}

@Override
public void closeInventory(EntityPlayer player) {
	// TODO Auto-generated method stub

}

@Override
public boolean isItemValidForSlot(int index, ItemStack stack) {
	// TODO Auto-generated method stub
	return false;
}

@Override
public int getField(int id) {
	// TODO Auto-generated method stub
	return 0;
}

@Override
public void setField(int id, int value) {
	// TODO Auto-generated method stub

}

@Override
public int getFieldCount() {
	// TODO Auto-generated method stub
	return 0;
}

@Override
public void clear() {
	// TODO Auto-generated method stub

}

@Override
public int acceptPower(int powerInPacket, int orientation) {
	// The energy left over after the orb transfers power
	int leftoverPower = powerInPacket;
	if (!this.canReceivePower())
	{
		return leftoverPower;
	}
	// If we don't have an item to damage, don't bother trying
	if (itemStacks == null || OAE_Func.isStackEmpty(itemStacks[0]))
	{
		return leftoverPower;
	}
	else
	{
		if (itemStacks[0].getItem() instanceof Item_HealingCrystal)
		{
			// Add a third case for orientation == -1
			// If the orientation is the same, charge as much as possible
			if (((Item_HealingCrystal)itemStacks[0].getItem()).getOrientation() == orientation)
			{
				int energyToTransfer = Math.min(powerInPacket, itemStacks[0].getItemDamage());
				itemStacks[0].setItemDamage(itemStacks[0].getItemDamage() - energyToTransfer);
				leftoverPower = powerInPacket - energyToTransfer;
			}
			else // Drain energy from the stack
			{
				int remainingPossibleDamage = itemStacks[0].getMaxDamage() - itemStacks[0].getItemDamage();
				int powerToDrain = Math.min(remainingPossibleDamage, powerInPacket);
				itemStacks[0].setItemDamage(itemStacks[0].getItemDamage() + powerToDrain);
				// Get how much energy we drained and subtract
				leftoverPower -= powerToDrain;
				// If we drained the crystal, break or flip orientation, then charge
				if (leftoverPower > 0)
				{
					// TODO Break if power crystal, flip and charge if other
				}
			}

		}
		return leftoverPower;
	}

}
@Override
public void lockDest(int dimension, BlockPos pos) {
	Type_CoordEntry findThis = new Type_CoordEntry(dimension, pos);
	int index = destinations.indexOf(findThis);
	if (index != -1)
	{
		destinations.set(index, new Type_CoordEntry(findThis, true));
	}

}
@Override
public void unlockDest(int dimension, BlockPos pos) {
	Type_CoordEntry findThis = new Type_CoordEntry(dimension, pos, true);
	int index = destinations.indexOf(findThis);
	if (index != -1)
	{
		destinations.set(index, new Type_CoordEntry(findThis));
	}

}

@Override
public SPacketUpdateTileEntity getUpdatePacket()
{
	NBTTagCompound tag = new NBTTagCompound();
	this.writeToNBT(tag);
	return new SPacketUpdateTileEntity(this.getPos(), 1, tag);
}

@Override
public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity packet)
{
	this.readFromNBT(packet.getNbtCompound());
}
}

 

 

Link to comment
Share on other sites

The document you referenced was somewhat helpful, but I'm still doing something wrong.  Do you know of any examples or tutorials I can look at that are updated to 1.9?  Better yet, can you see/explain to me what I'm doing wrong?

 

This is my current TileEntity file.

[spoiler=TileEntity]

package com.trekkiecub.oddsandends.tileentity;

import java.util.ArrayList;
import java.util.List;

import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.common.DimensionManager;

import com.trekkiecub.oddsandends.entity.Entity_PowerOrb;
import com.trekkiecub.oddsandends.init.ItemInit;
import com.trekkiecub.oddsandends.items.Item_HealingCrystal;
import com.trekkiecub.oddsandends.util.OAE_Func;
import com.trekkiecub.oddsandends.util.Type_CoordEntry;

public class TileEntity_Sceptre extends TileEntity implements IPowerCrystal, ITickable, IInventory {
private List<Type_CoordEntry> sources = new ArrayList<Type_CoordEntry>();
private List<Type_CoordEntry> destinations = new ArrayList<Type_CoordEntry>();
private ItemStack itemStacks[] = new ItemStack[1];
int cooldown = 0;
int maxCooldown = 30;

/**
 * Fetches the item to render
 * Null if N/A
 * @return The ItemStack to render
 */

@Override
public NBTTagCompound getUpdateTag()
    {
	NBTTagCompound tag = super.getUpdateTag();
        tag.setInteger("x", this.pos.getX());
        tag.setInteger("y", this.pos.getY());
        tag.setInteger("z", this.pos.getZ());
        return this.writeToNBT(tag);
    }

@Override
public void handleUpdateTag(NBTTagCompound tag)
    {
	super.handleUpdateTag(tag);
	this.readFromNBT(tag);
    }

public ItemStack getItem()
{
	if (itemStacks == null || OAE_Func.isStackEmpty(itemStacks[0]))
	{
		return new ItemStack(ItemInit.gem_linarite);
	}
	else
	{
		return itemStacks[0].copy();
	}
}

/**
 *  Incoming Power Orb Handling
 */

public int getReceiverOrientation()
{
	if (this.itemStacks == null || OAE_Func.isStackEmpty(itemStacks[0]))
	{
		return Item_HealingCrystal.errorValue;
	}
	else
	{
		return ((Item_HealingCrystal)itemStacks[0].getItem()).getOrientation();
	}
}

/**
 *  Outgoing Power Orb Handling
 */

// Positive return from this
public int getPowerRoom()
{
	if (this.itemStacks == null || OAE_Func.isStackEmpty(itemStacks[0]))
	{
		return 0;
	}
	else
	{
		return itemStacks[0].getItemDamage();
	}
}

public int getInversePowerRoom()
{
	if (this.itemStacks == null || OAE_Func.isStackEmpty(itemStacks[0]))
	{
		return 0;
	}
	else
	{
		return itemStacks[0].getMaxDamage();
	}
}
private void transmitPower(Type_CoordEntry coords)
{
	if (itemStacks == null || OAE_Func.isStackEmpty(itemStacks[0]))
	{
		// do nothing
	}
	else
	{
		if (itemStacks[0].getItem() instanceof Item_HealingCrystal && itemStacks[0].getItemDamage() != itemStacks[0].getMaxDamage())
		{
			// Only if tile entity is IPowerCrystal
			// powerRoom = getPowerRoom();
			// If orientation is the same and we have room, send
			// If orientation is the same and don't have room, don't send
			// If orientation is opposite, send
			BlockPos targetPos = coords.getBlockPos();
			TileEntity targetEntity = this.worldObj.getTileEntity(targetPos);
			if (targetEntity instanceof IPowerCrystal)
			{
				boolean canSend = false;
				int receiver = ((IPowerCrystal)targetEntity).getReceiverOrientation();
				if (receiver == Item_HealingCrystal.errorValue)
				{
					// do nothing
				}
				// If we are able to send anything to this crystal
				// or the receiver is the same type as us
				else if (receiver == -1 || receiver-this.getReceiverOrientation() == 0)
				{
					int room = ((IPowerCrystal)targetEntity).getPowerRoom();
					if (room != 0)
					{
						canSend = true;
					}
				}
				else
				{
					canSend = true;
				}
				if (canSend)
				{
					int energyTargetCanReceive = 0;
					// Restrict energy flow if needed.
					if (receiver == -1 || receiver-this.getReceiverOrientation() == 0)
					{
						energyTargetCanReceive = Math.min(((IPowerCrystal)targetEntity).getPowerRoom(), ((Item_HealingCrystal)itemStacks[0].getItem()).maxPacketSize());
					}
					else
					{
						energyTargetCanReceive = Math.min(((IPowerCrystal)targetEntity).getInversePowerRoom(), ((Item_HealingCrystal)itemStacks[0].getItem()).maxPacketSize());
					}
					int energyToSend = Math.min(energyTargetCanReceive, itemStacks[0].getMaxDamage() - itemStacks[0].getItemDamage());

					// Moonstone default
					int orientation = 0;
					// Set orientation based on reciever's orientation
					if (this.getReceiverOrientation() == -1)
					{
						orientation = ((IPowerCrystal)targetEntity).getReceiverOrientation();
					}
					// Set to sunstone if this is sunstone or receiver is also -1
					if (this.getReceiverOrientation() == 1 || orientation == -1)
					{
						orientation = 1;
					}

					Entity_PowerOrb entity = new Entity_PowerOrb(this.worldObj, this.pos.getX() + 0.5, this.pos.getY() + 0.375, this.pos.getZ() + 0.5);
					entity.setOrientation(orientation);
					float speedMultiplier = ((Item_HealingCrystal)itemStacks[0].getItem()).getTier() * 1.5F;
					speedMultiplier += 1F;
					entity.setThrowableHeading(targetPos.getX() + 0.5 - entity.posX, targetPos.getY() + 0.375 - entity.posY, targetPos.getZ() + 0.5 - entity.posZ, 0.05F * speedMultiplier, 0);
					entity.setEnergy(energyToSend);
					entity.setDestination(targetPos);
					this.worldObj.spawnEntityInWorld(entity);
					itemStacks[0].attemptDamageItem(energyToSend, this.worldObj.rand);
					this.lockDest(coords.getDimension(), coords.getBlockPos());
				}
			}
		}
		else
		{
			// Check for things like ender pearl and quantum-entangled pearls
			// Transmit instantly
		}
	}
}

/**
 * Update Entity
 */


public void updateEntity()
{
	if (!this.worldObj.isRemote)
	{
		cooldown++;
		cooldown = cooldown%maxCooldown;
		if (cooldown == 0 && destinations.size() != 0)
		{
			// Add stuff like a power level check
			for (int i = 0; i < destinations.size(); i++)
			{
				if (!destinations.get(i).isLocked())
				{
					transmitPower(destinations.get(i));
				}
			}
		}
		markDirty();
	}
}

/**
 * Clearing information
 * REPLACE dropItems functionality with InventoryHelper.drop
 */
public void dropItems()
{
	if (!this.worldObj.isRemote)
	{
		for (int i = 0; i < this.getInventoryStackLimit(); ++i)
		{
			if (itemStacks[i] != null)
			{
				Vec3d center = OAE_Func.blockCenter(this.pos);
				EntityItem entity = new EntityItem(worldObj, center.xCoord, center.yCoord, center.zCoord, itemStacks[i].copy());
				entity.motionY = 0;
				this.worldObj.spawnEntityInWorld(entity);
				this.setInventorySlotContents(i, null);

				this.clearConnections();
			}
		}
	}
}
@Override
public void clearConnections()
{
	for (Type_CoordEntry entry : sources)
	{
		TileEntity entity = DimensionManager.getWorld(entry.getDimension()).getTileEntity(entry.getBlockPos());
		if (entity instanceof IPowerCrystal)
		{
			((IPowerCrystal)entity).removeCoords(this.getMyCoordEntry(), false);
		}
	}
	for (Type_CoordEntry entry : destinations)
	{
		TileEntity entity = DimensionManager.getWorld(entry.getDimension()).getTileEntity(entry.getBlockPos());
		if (entity instanceof IPowerCrystal)
		{
			((IPowerCrystal)entity).removeCoords(this.getMyCoordEntry(), true);
		}
	}
	this.sources = new ArrayList<Type_CoordEntry>();
	this.destinations = new ArrayList<Type_CoordEntry>();
}

/**
 * Source/Destination Manipulation
 * Possible Actions:
 *  - Add source if it doesn't exist
 *  - Remove source if it's in sources
 *  - Move from destinations to sources, reversing direction
 */
@Override
public boolean changeConnections(ItemStack linker)
{
	boolean actionTaken = false;
	// Make sure the linker isn't empty
	if (linker.getTagCompound() != null)
	{
		// Again, make sure linker isn't empty
		if (linker.getTagCompound().hasKey("coords"))
		{
			// Get the coordinates in question
			NBTTagCompound nbt = (NBTTagCompound) linker.getTagCompound().getTag("coords");
			Type_CoordEntry coords = new Type_CoordEntry(nbt);
			// Check if these are our own coordinates
			if (coords != this.getMyCoordEntry())
			{
				TileEntity entity = this.worldObj.getTileEntity(coords.getBlockPos());
				if (entity != null && entity instanceof IPowerCrystal)
				{
					// Check to see if the coordinates supplied are in the destinations
					// Meaning we're switching the flow direction
					if (destinations.contains(coords))
					{
						// Make sure we can switch before we switch
						if (canWeSwitch((IPowerCrystal) entity))
						{
							this.switchCoordFunc(coords);
							((IPowerCrystal)entity).switchCoordFunc(this.getMyCoordEntry());
							actionTaken = true;
						}

					}
					// We've repeated a previous action, so we're now undoing it
					else if (sources.contains(coords))
					{
						this.removeCoords(coords, true);
						((IPowerCrystal)entity).removeCoords(this.getMyCoordEntry(), false);
						actionTaken = true;
					}
					// We don't have these coords anywhere, this is a new connection
					else
					{
						this.addCoords(coords, true);
						((IPowerCrystal)entity).addCoords(this.getMyCoordEntry(), false);
						actionTaken = true;
					}
				}
			}
		}
	}
	return actionTaken;
}
private boolean canWeSwitch(IPowerCrystal entity)
{
	return this.canReceivePower() && entity.canSendPower();
}
@Override
public void switchCoordFunc(Type_CoordEntry coords)
{
	if (this.destinations.contains(coords))
	{
		destinations.remove(coords);
		sources.add(coords);
	}
	else
	{
		sources.remove(coords);
		destinations.add(coords);
	}
}


private Type_CoordEntry getMyCoordEntry()
{
	return new Type_CoordEntry(this.worldObj.provider.getDimension(), this.getPos());
}

public Type_CoordEntry getSourceEntry(int i)
{
	if (i >= 0 && i < sources.size())
	{
		return sources.get(i);
	}
	else
	{
		return null;
	}
}
public Type_CoordEntry getDestEntry(int i)
{
	if (i >= 0 && i < destinations.size())
	{
		return destinations.get(i);
	}
	else
	{
		return null;
	}
}

@Override
public List<String> printInventory()
{
	List<String> inventory = new ArrayList<String>();
	for (int i = 0; i < this.getSizeInventory(); i++)
	{
		if (itemStacks[i] != null)
		{
			String line = "Slot " + i + ": " + itemStacks[i].getDisplayName();
			inventory.add(line);
		}
	}
	return inventory;
}
@Override
public List<String> printConnections()
{
	List<String> connections = new ArrayList<String>();
	if (this.canReceivePower())
	{
		connections.add("Sources:");
		for (Type_CoordEntry entry : sources)
		{
			connections.add(entry.printThis());
		}
	}
	if (this.canSendPower())
	{
		connections.add("Destinations:");
		for (Type_CoordEntry entry : destinations)
		{
			connections.add(entry.printThis());
		}
	}
	return connections;
}
@Override
public boolean canSendPower() {
	return true;
	// false if empty
}
@Override
public boolean canReceivePower() {
	return true;
	// false if empty
}
@Override
public void removeCoords(Type_CoordEntry coords, boolean removeFromSource)
{
	Type_CoordEntry locked = new Type_CoordEntry(coords, true);
	if (removeFromSource)
	{
		sources.remove(locked);
		sources.remove(coords);
	}
	else
	{
		destinations.remove(locked);
		destinations.remove(coords);
	}
	markDirty();
}
@Override
public void addCoords(Type_CoordEntry coords, boolean addToSource)
{
	if (addToSource)
	{
		sources.add(coords);
	}
	else
	{
		destinations.add(coords);
	}
	markDirty();
}
//
//  Merge the given item stack with the inventory slots either
//  until the stack is empty or the inventory runs out.
public ItemStack mergeStack(ItemStack stack)
{
	ItemStack returnThisStack = stack.copy();
	for (int i = 0; i < getSizeInventory() && returnThisStack.stackSize > 0; i++)
	{
		// This is the maximum amount we can deposit into each slot
		// based on both this tile entity and the number of items
		// Number of items can't go above the item's max stack size
		// Will never be zero: First is hard-coded, second breaks loop
		int remainingSpace = OAE_Func.getMaxStackToAdd(this, returnThisStack, i);
		if (remainingSpace > 0)
		{
			if (itemStacks[i] == null)
			{
				setInventorySlotContents(i, returnThisStack.splitStack(remainingSpace));
			}
			else if (OAE_Func.canWeStack(itemStacks[i], returnThisStack))
			{
				itemStacks[i].stackSize += remainingSpace;
				returnThisStack.splitStack(remainingSpace);
				markDirty();
			}
		}
	}
	if (returnThisStack.stackSize == 0)
	{
		returnThisStack = null;
	}
	return returnThisStack;
}
@Override
public void readFromNBT(NBTTagCompound compound) {
	super.readFromNBT(compound);

	sources = new ArrayList<Type_CoordEntry>();
	destinations = new ArrayList<Type_CoordEntry>();
	if (compound.hasKey("sources"))
	{
		NBTTagList entryList = (NBTTagList) compound.getTag("sources");
		for (int i = 0; i < entryList.tagCount(); i++)
		{
			NBTTagCompound entryCompound = entryList.getCompoundTagAt(i);
			Type_CoordEntry entry = Type_CoordEntry.readEntryFromNBT(entryCompound);
			sources.add(entry);
		}

		entryList = (NBTTagList) compound.getTag("destinations");
		for (int i = 0; i < entryList.tagCount(); i++)
		{
			NBTTagCompound entryCompound = entryList.getCompoundTagAt(i);
			Type_CoordEntry entry = Type_CoordEntry.readEntryFromNBT(entryCompound);
			destinations.add(entry);
		}
		this.cooldown = compound.getInteger("cooldown");
		entryList = (NBTTagList) compound.getTagList("Items", 10);

		for (int i = 0; i < entryList.tagCount(); i++)
		{
			NBTTagCompound stackTag = entryList.getCompoundTagAt(i);
			int slot = stackTag.getByte("Slot") & 255;
			setInventorySlotContents(slot, ItemStack.loadItemStackFromNBT(stackTag));
		}
	}
}

@Override
public NBTTagCompound writeToNBT(NBTTagCompound compound) {
	// Store sources under 'sources'
	NBTTagList entryList = new NBTTagList();
	for (Type_CoordEntry entry : sources)
	{
		NBTTagCompound entryCompound = new NBTTagCompound();
		entry.writeToNBT(entryCompound);
		entryList.appendTag(entryCompound);
	}
	compound.setTag("sources", entryList);
	// Store destinations under 'destinations'
	entryList = new NBTTagList();
	for (Type_CoordEntry entry : destinations)
	{
		NBTTagCompound entryCompound = new NBTTagCompound();
		entry.writeToNBT(entryCompound);
		entryList.appendTag(entryCompound);
	}
	compound.setTag("destinations", entryList);
	compound.setInteger("cooldown", this.cooldown);
	// Store inventory
	NBTTagList tagList = new NBTTagList();
	for (int i = 0; i < getSizeInventory(); i++)
	{
		if (getStackInSlot(i) != null)
		{
			NBTTagCompound slotTag = new NBTTagCompound();
			slotTag.setByte("Slot", (byte)i);
			getStackInSlot(i).writeToNBT(slotTag);
			tagList.appendTag(slotTag);
		}
	}
	compound.setTag("Items", tagList);
	return super.writeToNBT(compound);

}

@Override
public void update() {
	updateEntity();

}

@Override
public String getName() {
	return null;
}

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

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

@Override
public ItemStack getStackInSlot(int slot) {
	if (slot < 0 || slot >= this.getSizeInventory())
	{
		return null;
	}
	return this.itemStacks[slot];
}

public boolean canAddPartial(ItemStack stack)
{
	for (int i = 0; i < getSizeInventory(); i++)
	{
		if (OAE_Func.isStackEmpty(itemStacks[i]))
		{
			return true;
		}
		else if (OAE_Func.getMaxStackToAdd(this, stack, i) > 0)
		{
			return true;
		}
	}
	return false;
}
@Override
public ItemStack decrStackSize(int slot, int amount) {
	ItemStack stack = getStackInSlot(slot);
	if (stack != null)
	{
		if (stack.stackSize <= amount)
		{
			setInventorySlotContents(slot, null);
			this.markDirty();
		}
		else
		{
			stack = stack.splitStack(amount);
			if (stack.stackSize == 0)
			{
				setInventorySlotContents(slot, null);
			}
			this.markDirty();
		}
	}
	return stack;
}

@Override
public ItemStack removeStackFromSlot(int index) {
	ItemStack stack = getStackInSlot(index);
	setInventorySlotContents(index, null);
	return stack;
}

@Override
public void setInventorySlotContents(int index, ItemStack stack) {
	if (index >= 0 && index < this.itemStacks.length)
	{
		ItemStack newStack = null;
		if (!OAE_Func.isStackEmpty(stack))
		{
			newStack = stack.copy();
			if (stack.stackSize > getInventoryStackLimit())
			{
				newStack.stackSize = getInventoryStackLimit();
			}
		}
		itemStacks[index] = newStack;
		this.markDirty();
	}

}

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

@Override
public boolean isUseableByPlayer(EntityPlayer player) {
	return false;
}

@Override
public void openInventory(EntityPlayer player) {
	// TODO Auto-generated method stub

}

@Override
public void closeInventory(EntityPlayer player) {
	// TODO Auto-generated method stub

}

@Override
public boolean isItemValidForSlot(int index, ItemStack stack) {
	// TODO Auto-generated method stub
	return false;
}

@Override
public int getField(int id) {
	// TODO Auto-generated method stub
	return 0;
}

@Override
public void setField(int id, int value) {
	// TODO Auto-generated method stub

}

@Override
public int getFieldCount() {
	// TODO Auto-generated method stub
	return 0;
}

@Override
public void clear() {
	// TODO Auto-generated method stub

}

@Override
public int acceptPower(int powerInPacket, int orientation) {
	// The energy left over after the orb transfers power
	int leftoverPower = powerInPacket;
	if (!this.canReceivePower())
	{
		return leftoverPower;
	}
	// If we don't have an item to damage, don't bother trying
	if (itemStacks == null || OAE_Func.isStackEmpty(itemStacks[0]))
	{
		return leftoverPower;
	}
	else
	{
		if (itemStacks[0].getItem() instanceof Item_HealingCrystal)
		{
			// Add a third case for orientation == -1
			// If the orientation is the same, charge as much as possible
			if (((Item_HealingCrystal)itemStacks[0].getItem()).getOrientation() == orientation)
			{
				int energyToTransfer = Math.min(powerInPacket, itemStacks[0].getItemDamage());
				itemStacks[0].setItemDamage(itemStacks[0].getItemDamage() - energyToTransfer);
				leftoverPower = powerInPacket - energyToTransfer;
			}
			else // Drain energy from the stack
			{
				int remainingPossibleDamage = itemStacks[0].getMaxDamage() - itemStacks[0].getItemDamage();
				int powerToDrain = Math.min(remainingPossibleDamage, powerInPacket);
				itemStacks[0].setItemDamage(itemStacks[0].getItemDamage() + powerToDrain);
				// Get how much energy we drained and subtract
				leftoverPower -= powerToDrain;
				// If we drained the crystal, break or flip orientation, then charge
				if (leftoverPower > 0)
				{
					// TODO Break if power crystal, flip and charge if other
				}
			}

		}
		return leftoverPower;
	}

}
@Override
public void lockDest(int dimension, BlockPos pos) {
	Type_CoordEntry findThis = new Type_CoordEntry(dimension, pos);
	int index = destinations.indexOf(findThis);
	if (index != -1)
	{
		destinations.set(index, new Type_CoordEntry(findThis, true));
	}

}
@Override
public void unlockDest(int dimension, BlockPos pos) {
	Type_CoordEntry findThis = new Type_CoordEntry(dimension, pos, true);
	int index = destinations.indexOf(findThis);
	if (index != -1)
	{
		destinations.set(index, new Type_CoordEntry(findThis));
	}

}

@Override
public SPacketUpdateTileEntity getUpdatePacket()
{
	NBTTagCompound tag = new NBTTagCompound();
	this.writeToNBT(tag);
	return new SPacketUpdateTileEntity(this.getPos(), 1, tag);
}

@Override
public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity packet)
{
	this.readFromNBT(packet.getNbtCompound());
}
}

 

 

Link to comment
Share on other sites

I found a tutorial that's gotten me nearly all of the way there.  I just have one last problem and I'm not sure why it's happening.

 

The problem I was having was that the block in the world was not getting updated when I modified the itemStacks in the inventory.  I corrected that, or so I thought, because the tile entity correctly shows the new item when I add it.  Problem is, when I remove the item, the tile entity still renders the previous item until I add a new item.  It looks like the problem might be in the dropItems() function, but the code looks right to me.  It's probably something simple, dumb, and/or easily overlooked, so I'm hoping someone spots what I did wrong.

 

[spoiler=TileEntity]

package com.trekkiecub.oddsandends.tileentity;

import java.util.ArrayList;
import java.util.List;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.common.DimensionManager;

import com.trekkiecub.oddsandends.entity.Entity_PowerOrb;
import com.trekkiecub.oddsandends.init.ItemInit;
import com.trekkiecub.oddsandends.items.Item_HealingCrystal;
import com.trekkiecub.oddsandends.util.OAE_Func;
import com.trekkiecub.oddsandends.util.Type_CoordEntry;

public class TileEntity_Sceptre extends TileEntity implements IPowerCrystal, ITickable, IInventory {
private List<Type_CoordEntry> sources = new ArrayList<Type_CoordEntry>();
private List<Type_CoordEntry> destinations = new ArrayList<Type_CoordEntry>();
private ItemStack itemStacks[] = new ItemStack[1];
int cooldown = 0;
int maxCooldown = 30;

/**
 * Fetches the item to render
 * Null if N/A
 * @return The ItemStack to render
 */


public ItemStack getItem()
{
	if (itemStacks == null || OAE_Func.isStackEmpty(itemStacks[0]))
	{
		return new ItemStack(ItemInit.gem_linarite);
	}
	else
	{
		return itemStacks[0].copy();
	}
}

/**
 *  Incoming Power Orb Handling
 */

public int getReceiverOrientation()
{
	if (this.itemStacks == null || OAE_Func.isStackEmpty(itemStacks[0]))
	{
		return Item_HealingCrystal.errorValue;
	}
	else
	{
		return ((Item_HealingCrystal)itemStacks[0].getItem()).getOrientation();
	}
}

/**
 *  Outgoing Power Orb Handling
 */

// Positive return from this
public int getPowerRoom()
{
	if (this.itemStacks == null || OAE_Func.isStackEmpty(itemStacks[0]))
	{
		return 0;
	}
	else
	{
		return itemStacks[0].getItemDamage();
	}
}

public int getInversePowerRoom()
{
	if (this.itemStacks == null || OAE_Func.isStackEmpty(itemStacks[0]))
	{
		return 0;
	}
	else
	{
		return itemStacks[0].getMaxDamage();
	}
}
private void transmitPower(Type_CoordEntry coords)
{
	if (itemStacks == null || OAE_Func.isStackEmpty(itemStacks[0]))
	{
		// do nothing
	}
	else
	{
		if (itemStacks[0].getItem() instanceof Item_HealingCrystal && itemStacks[0].getItemDamage() != itemStacks[0].getMaxDamage())
		{
			// Only if tile entity is IPowerCrystal
			// powerRoom = getPowerRoom();
			// If orientation is the same and we have room, send
			// If orientation is the same and don't have room, don't send
			// If orientation is opposite, send
			BlockPos targetPos = coords.getBlockPos();
			TileEntity targetEntity = this.worldObj.getTileEntity(targetPos);
			if (targetEntity instanceof IPowerCrystal)
			{
				boolean canSend = false;
				int receiver = ((IPowerCrystal)targetEntity).getReceiverOrientation();
				if (receiver == Item_HealingCrystal.errorValue)
				{
					// do nothing
				}
				// If we are able to send anything to this crystal
				// or the receiver is the same type as us
				else if (receiver == -1 || receiver-this.getReceiverOrientation() == 0)
				{
					int room = ((IPowerCrystal)targetEntity).getPowerRoom();
					if (room != 0)
					{
						canSend = true;
					}
				}
				else
				{
					canSend = true;
				}
				if (canSend)
				{
					int energyTargetCanReceive = 0;
					// Restrict energy flow if needed.
					if (receiver == -1 || receiver-this.getReceiverOrientation() == 0)
					{
						energyTargetCanReceive = Math.min(((IPowerCrystal)targetEntity).getPowerRoom(), ((Item_HealingCrystal)itemStacks[0].getItem()).maxPacketSize());
					}
					else
					{
						energyTargetCanReceive = Math.min(((IPowerCrystal)targetEntity).getInversePowerRoom(), ((Item_HealingCrystal)itemStacks[0].getItem()).maxPacketSize());
					}
					int energyToSend = Math.min(energyTargetCanReceive, itemStacks[0].getMaxDamage() - itemStacks[0].getItemDamage());

					// Moonstone default
					int orientation = 0;
					// Set orientation based on reciever's orientation
					if (this.getReceiverOrientation() == -1)
					{
						orientation = ((IPowerCrystal)targetEntity).getReceiverOrientation();
					}
					// Set to sunstone if this is sunstone or receiver is also -1
					if (this.getReceiverOrientation() == 1 || orientation == -1)
					{
						orientation = 1;
					}

					Entity_PowerOrb entity = new Entity_PowerOrb(this.worldObj, this.pos.getX() + 0.5, this.pos.getY() + 0.375, this.pos.getZ() + 0.5);
					entity.setOrientation(orientation);
					float speedMultiplier = ((Item_HealingCrystal)itemStacks[0].getItem()).getTier() * 1.5F;
					speedMultiplier += 1F;
					entity.setThrowableHeading(targetPos.getX() + 0.5 - entity.posX, targetPos.getY() + 0.375 - entity.posY, targetPos.getZ() + 0.5 - entity.posZ, 0.05F * speedMultiplier, 0);
					entity.setEnergy(energyToSend);
					entity.setDestination(targetPos);
					this.worldObj.spawnEntityInWorld(entity);
					itemStacks[0].attemptDamageItem(energyToSend, this.worldObj.rand);
					this.lockDest(coords.getDimension(), coords.getBlockPos());
					this.markDirty();
				}
			}
		}
		else
		{
			// Check for things like ender pearl and quantum-entangled pearls
			// Transmit instantly
		}
	}
}

/**
 * Update Entity
 */


public void updateEntity()
{
	if (!this.worldObj.isRemote)
	{
		cooldown++;
		cooldown = cooldown%maxCooldown;
		if (cooldown == 0 && destinations.size() != 0)
		{
			// Add stuff like a power level check
			for (int i = 0; i < destinations.size(); i++)
			{
				if (!destinations.get(i).isLocked())
				{
					transmitPower(destinations.get(i));
				}
			}
		}
		markDirty();
	}
}

/**
 * Clearing information
 */
public void dropItems()
{
	InventoryHelper.dropInventoryItems(this.worldObj, this.pos, this);
	for (int i = 0; i < this.getInventoryStackLimit(); ++i)
	{
		this.setInventorySlotContents(i, null);
	}
	this.clearConnections();

}
@Override
public void clearConnections()
{
	for (Type_CoordEntry entry : sources)
	{
		TileEntity entity = DimensionManager.getWorld(entry.getDimension()).getTileEntity(entry.getBlockPos());
		if (entity instanceof IPowerCrystal)
		{
			((IPowerCrystal)entity).removeCoords(this.getMyCoordEntry(), false);
		}
	}
	for (Type_CoordEntry entry : destinations)
	{
		TileEntity entity = DimensionManager.getWorld(entry.getDimension()).getTileEntity(entry.getBlockPos());
		if (entity instanceof IPowerCrystal)
		{
			((IPowerCrystal)entity).removeCoords(this.getMyCoordEntry(), true);
		}
	}
	this.sources = new ArrayList<Type_CoordEntry>();
	this.destinations = new ArrayList<Type_CoordEntry>();
}

/**
 * Source/Destination Manipulation
 * Possible Actions:
 *  - Add source if it doesn't exist
 *  - Remove source if it's in sources
 *  - Move from destinations to sources, reversing direction
 */
@Override
public boolean changeConnections(ItemStack linker)
{
	boolean actionTaken = false;
	// Make sure the linker isn't empty
	if (linker.getTagCompound() != null)
	{
		// Again, make sure linker isn't empty
		if (linker.getTagCompound().hasKey("coords"))
		{
			// Get the coordinates in question
			NBTTagCompound nbt = (NBTTagCompound) linker.getTagCompound().getTag("coords");
			Type_CoordEntry coords = new Type_CoordEntry(nbt);
			// Check if these are our own coordinates
			if (coords != this.getMyCoordEntry())
			{
				TileEntity entity = this.worldObj.getTileEntity(coords.getBlockPos());
				if (entity != null && entity instanceof IPowerCrystal)
				{
					// Check to see if the coordinates supplied are in the destinations
					// Meaning we're switching the flow direction
					if (destinations.contains(coords))
					{
						// Make sure we can switch before we switch
						if (canWeSwitch((IPowerCrystal) entity))
						{
							this.switchCoordFunc(coords);
							((IPowerCrystal)entity).switchCoordFunc(this.getMyCoordEntry());
							actionTaken = true;
						}

					}
					// We've repeated a previous action, so we're now undoing it
					else if (sources.contains(coords))
					{
						this.removeCoords(coords, true);
						((IPowerCrystal)entity).removeCoords(this.getMyCoordEntry(), false);
						actionTaken = true;
					}
					// We don't have these coords anywhere, this is a new connection
					else
					{
						this.addCoords(coords, true);
						((IPowerCrystal)entity).addCoords(this.getMyCoordEntry(), false);
						actionTaken = true;
					}
				}
			}
		}
	}
	return actionTaken;
}
private boolean canWeSwitch(IPowerCrystal entity)
{
	return this.canReceivePower() && entity.canSendPower();
}
@Override
public void switchCoordFunc(Type_CoordEntry coords)
{
	if (this.destinations.contains(coords))
	{
		destinations.remove(coords);
		sources.add(coords);
	}
	else
	{
		sources.remove(coords);
		destinations.add(coords);
	}
	markDirty();
}


private Type_CoordEntry getMyCoordEntry()
{
	return new Type_CoordEntry(this.worldObj.provider.getDimension(), this.getPos());
}

public Type_CoordEntry getSourceEntry(int i)
{
	if (i >= 0 && i < sources.size())
	{
		return sources.get(i);
	}
	else
	{
		return null;
	}
}
public Type_CoordEntry getDestEntry(int i)
{
	if (i >= 0 && i < destinations.size())
	{
		return destinations.get(i);
	}
	else
	{
		return null;
	}
}

@Override
public List<String> printInventory()
{
	List<String> inventory = new ArrayList<String>();
	for (int i = 0; i < this.getSizeInventory(); i++)
	{
		if (itemStacks[i] != null)
		{
			String line = "Slot " + i + ": " + itemStacks[i].getDisplayName();
			inventory.add(line);
		}
	}
	return inventory;
}
@Override
public List<String> printConnections()
{
	List<String> connections = new ArrayList<String>();
	if (this.canReceivePower())
	{
		connections.add("Sources:");
		for (Type_CoordEntry entry : sources)
		{
			connections.add(entry.printThis());
		}
	}
	if (this.canSendPower())
	{
		connections.add("Destinations:");
		for (Type_CoordEntry entry : destinations)
		{
			connections.add(entry.printThis());
		}
	}
	return connections;
}
@Override
public boolean canSendPower() {
	return true;
	// false if empty
}
@Override
public boolean canReceivePower() {
	return true;
	// false if empty
}
@Override
public void removeCoords(Type_CoordEntry coords, boolean removeFromSource)
{
	Type_CoordEntry locked = new Type_CoordEntry(coords, true);
	if (removeFromSource)
	{
		sources.remove(locked);
		sources.remove(coords);
	}
	else
	{
		destinations.remove(locked);
		destinations.remove(coords);
	}
	markDirty();
}
@Override
public void addCoords(Type_CoordEntry coords, boolean addToSource)
{
	if (addToSource)
	{
		sources.add(coords);
	}
	else
	{
		destinations.add(coords);
	}
	markDirty();
}
//
//  Merge the given item stack with the inventory slots either
//  until the stack is empty or the inventory runs out.
public ItemStack mergeStack(ItemStack stack)
{
	ItemStack returnThisStack = stack.copy();
	for (int i = 0; i < getSizeInventory() && returnThisStack.stackSize > 0; i++)
	{
		// This is the maximum amount we can deposit into each slot
		// based on both this tile entity and the number of items
		// Number of items can't go above the item's max stack size
		// Will never be zero: First is hard-coded, second breaks loop
		int remainingSpace = OAE_Func.getMaxStackToAdd(this, returnThisStack, i);
		if (remainingSpace > 0)
		{
			if (itemStacks[i] == null)
			{
				setInventorySlotContents(i, returnThisStack.splitStack(remainingSpace));
			}
			else if (OAE_Func.canWeStack(itemStacks[i], returnThisStack))
			{
				itemStacks[i].stackSize += remainingSpace;
				returnThisStack.splitStack(remainingSpace);
				markDirty();
				updateBlock();
			}
		}
	}
	if (returnThisStack.stackSize == 0)
	{
		returnThisStack = null;
	}
	return returnThisStack;
}



@Override
public void update() {
	updateEntity();

}

@Override
public String getName() {
	return null;
}

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

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

@Override
public ItemStack getStackInSlot(int slot) {
	if (slot < 0 || slot >= this.getSizeInventory())
	{
		return null;
	}
	return this.itemStacks[slot];
}

public boolean canAddPartial(ItemStack stack)
{
	for (int i = 0; i < getSizeInventory(); i++)
	{
		if (OAE_Func.isStackEmpty(itemStacks[i]))
		{
			return true;
		}
		else if (OAE_Func.getMaxStackToAdd(this, stack, i) > 0)
		{
			return true;
		}
	}
	return false;
}
@Override
public ItemStack decrStackSize(int slot, int amount) {
	ItemStack stack = getStackInSlot(slot);
	if (stack != null)
	{
		if (stack.stackSize <= amount)
		{
			setInventorySlotContents(slot, null);
		}
		else
		{
			stack = stack.splitStack(amount);
			if (stack.stackSize == 0)
			{
				setInventorySlotContents(slot, null);
			}
		}
		this.markDirty();
		this.updateBlock();
	}
	return stack;
}

@Override
public ItemStack removeStackFromSlot(int index) {
	ItemStack stack = getStackInSlot(index);
	setInventorySlotContents(index, null);
	return stack;
}

@Override
public void setInventorySlotContents(int index, ItemStack stack) {
	if (index >= 0 && index < this.itemStacks.length)
	{
		ItemStack newStack = null;
		if (!OAE_Func.isStackEmpty(stack))
		{
			newStack = stack.copy();
			if (stack.stackSize > getInventoryStackLimit())
			{
				newStack.stackSize = getInventoryStackLimit();
			}
		}
		itemStacks[index] = newStack;
		this.markDirty();
		updateBlock();
	}

}

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

@Override
public boolean isUseableByPlayer(EntityPlayer player) {
	return false;
}

@Override
public void openInventory(EntityPlayer player) {
	// TODO Auto-generated method stub

}

@Override
public void closeInventory(EntityPlayer player) {
	// TODO Auto-generated method stub

}

@Override
public boolean isItemValidForSlot(int index, ItemStack stack) {
	// TODO Auto-generated method stub
	return false;
}

@Override
public int getField(int id) {
	// TODO Auto-generated method stub
	return 0;
}

@Override
public void setField(int id, int value) {
	// TODO Auto-generated method stub

}

@Override
public int getFieldCount() {
	// TODO Auto-generated method stub
	return 0;
}

@Override
public void clear() {
	// TODO Auto-generated method stub

}

@Override
public int acceptPower(int powerInPacket, int orientation) {
	// The energy left over after the orb transfers power
	int leftoverPower = powerInPacket;
	if (!this.canReceivePower())
	{
		return leftoverPower;
	}
	// If we don't have an item to damage, don't bother trying
	if (itemStacks == null || OAE_Func.isStackEmpty(itemStacks[0]))
	{
		return leftoverPower;
	}
	else
	{
		if (itemStacks[0].getItem() instanceof Item_HealingCrystal)
		{
			// Add a third case for orientation == -1
			// If the orientation is the same, charge as much as possible
			if (((Item_HealingCrystal)itemStacks[0].getItem()).getOrientation() == orientation)
			{
				int energyToTransfer = Math.min(powerInPacket, itemStacks[0].getItemDamage());
				itemStacks[0].setItemDamage(itemStacks[0].getItemDamage() - energyToTransfer);
				this.markDirty();
				leftoverPower = powerInPacket - energyToTransfer;
			}
			else // Drain energy from the stack
			{
				int remainingPossibleDamage = itemStacks[0].getMaxDamage() - itemStacks[0].getItemDamage();
				int powerToDrain = Math.min(remainingPossibleDamage, powerInPacket);
				itemStacks[0].setItemDamage(itemStacks[0].getItemDamage() + powerToDrain);
				this.markDirty();
				// Get how much energy we drained and subtract
				leftoverPower -= powerToDrain;
				// If we drained the crystal, break or flip orientation, then charge
				if (leftoverPower > 0)
				{
					// TODO Break if power crystal, flip and charge if other
				}
			}

		}
		return leftoverPower;
	}

}
@Override
public void lockDest(int dimension, BlockPos pos) {
	Type_CoordEntry findThis = new Type_CoordEntry(dimension, pos);
	int index = destinations.indexOf(findThis);
	if (index != -1)
	{
		destinations.set(index, new Type_CoordEntry(findThis, true));
	}
	this.markDirty();

}
@Override
public void unlockDest(int dimension, BlockPos pos) {
	Type_CoordEntry findThis = new Type_CoordEntry(dimension, pos, true);
	int index = destinations.indexOf(findThis);
	if (index != -1)
	{
		destinations.set(index, new Type_CoordEntry(findThis));
	}
	this.markDirty();
}


/**
 * 
 * Syncronization code
 * @return
 */

public void updateBlock()
{
	this.worldObj.notifyBlockUpdate(this.pos, worldObj.getBlockState(pos), worldObj.getBlockState(pos), 3);
}

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

	sources = new ArrayList<Type_CoordEntry>();
	destinations = new ArrayList<Type_CoordEntry>();
	if (compound.hasKey("sources"))
	{
		NBTTagList entryList = (NBTTagList) compound.getTag("sources");
		for (int i = 0; i < entryList.tagCount(); i++)
		{
			NBTTagCompound entryCompound = entryList.getCompoundTagAt(i);
			Type_CoordEntry entry = Type_CoordEntry.readEntryFromNBT(entryCompound);
			sources.add(entry);
		}

		entryList = (NBTTagList) compound.getTag("destinations");
		for (int i = 0; i < entryList.tagCount(); i++)
		{
			NBTTagCompound entryCompound = entryList.getCompoundTagAt(i);
			Type_CoordEntry entry = Type_CoordEntry.readEntryFromNBT(entryCompound);
			destinations.add(entry);
		}
	}
	this.cooldown = compound.getInteger("cooldown");
	this.readInvFromNBT(compound);
}

@Override
public NBTTagCompound writeToNBT(NBTTagCompound compound) {
	// Store sources under 'sources'
	NBTTagList entryList = new NBTTagList();
	for (Type_CoordEntry entry : sources)
	{
		NBTTagCompound entryCompound = new NBTTagCompound();
		entry.writeToNBT(entryCompound);
		entryList.appendTag(entryCompound);
	}
	compound.setTag("sources", entryList);
	// Store destinations under 'destinations'
	entryList = new NBTTagList();
	for (Type_CoordEntry entry : destinations)
	{
		NBTTagCompound entryCompound = new NBTTagCompound();
		entry.writeToNBT(entryCompound);
		entryList.appendTag(entryCompound);
	}
	compound.setTag("destinations", entryList);
	compound.setInteger("cooldown", this.cooldown);
	this.writeInvToNBT(compound);
	return super.writeToNBT(compound);

}

@Override
public SPacketUpdateTileEntity getUpdatePacket()
{
	NBTTagCompound tag = new NBTTagCompound();
	this.writeInvToNBT(tag);
	return new SPacketUpdateTileEntity(this.getPos(), 1, tag);
}

@Override
public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity packet)
{
	readInvFromNBT(packet.getNbtCompound());
}

@Override
public NBTTagCompound getUpdateTag()
    {
	NBTTagCompound tag = super.getUpdateTag();
	readInvFromNBT(tag);
       /*( tag.setInteger("x", this.pos.getX());
        tag.setInteger("y", this.pos.getY());
        tag.setInteger("z", this.pos.getZ());
        */
        return super.getUpdateTag();
    }

@Override
public void handleUpdateTag(NBTTagCompound tag)
    {
	super.handleUpdateTag(tag);
	this.readFromNBT(tag);
    }

public void readInvFromNBT(NBTTagCompound compound)
{
NBTTagList entryList = (NBTTagList) compound.getTagList("Items", 10);

	for (int i = 0; i < entryList.tagCount(); i++)
	{
		NBTTagCompound stackTag = entryList.getCompoundTagAt(i);
		int slot = stackTag.getByte("Slot") & 255;
		setInventorySlotContents(slot, ItemStack.loadItemStackFromNBT(stackTag));
	}
}

public void writeInvToNBT(NBTTagCompound compound)
{
	// Store inventory
			NBTTagList tagList = new NBTTagList();
			for (int i = 0; i < getSizeInventory(); i++)
			{
				if (getStackInSlot(i) != null)
				{
					NBTTagCompound slotTag = new NBTTagCompound();
					slotTag.setByte("Slot", (byte)i);
					getStackInSlot(i).writeToNBT(slotTag);
					tagList.appendTag(slotTag);
				}
			}
			compound.setTag("Items", tagList);
}
}

 

 

Link to comment
Share on other sites

  • 2 weeks later...

Hi

 

This doesn't look right

	@Override
public NBTTagCompound getUpdateTag()
    {
	NBTTagCompound tag = super.getUpdateTag();
	readInvFromNBT(tag);
       /*( tag.setInteger("x", this.pos.getX());
        tag.setInteger("y", this.pos.getY());
        tag.setInteger("z", this.pos.getZ());
        */
        return super.getUpdateTag();    //  <--- should probably be return tag;
  }

 

-TGG

Link to comment
Share on other sites

  • 2 weeks later...

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Ok yeah I think this might be where the problem starts. For starters, I think you can get rid of your RecipeType impl and make it a static constant instead. I'm not 100% sure this will fix it but it's posssible. RuneInscribingRecipe public class RuneInscribingRecipe implements Recipe<SimpleContainer> { public static final RecipeType<RuneInscribingRecipe> RECIPE_TYPE = new RecipeType<>(){}; // .... @Override public RecipeType<?> getType() { return RECIPE_TYPE; } // .... } RuneInscriberMenu private Optional<RecipeHolder<RuneInscribingRecipe>> getCurrentRecipe() { SimpleContainer inventory = new SimpleContainer(2); inventory.setItem(BASE_INPUT_SLOT, this.inventory.getStackInSlot(BASE_INPUT_SLOT)); inventory.setItem(TEMPLATE_INPUT_SLOT, this.inventory.getStackInSlot(TEMPLATE_INPUT_SLOT)); List<RecipeHolder<RuneInscribingRecipe>> list = this.blockEntity.getLevel().getRecipeManager().getRecipesFor(RuneInscribingRecipe.RECIPE_TYPE, inventory, this.blockEntity.getLevel()); if (list.isEmpty()) { return Optional.empty(); } return Optional.of(list.get(0)); }   Also, this here is a little suspicious where you're getting the `this.inventory.getStackInSlot` calls. I'd try and make sure those are what you expect they are with either a Debug line in IDE or print statement SimpleContainer inventory = new SimpleContainer(2); inventory.setItem(BASE_INPUT_SLOT, this.inventory.getStackInSlot(BASE_INPUT_SLOT)); System.out.printf("CHECKING BASE INPUT OF RECIPE: %s\n", this.inventory.getStackInSlot(BASE_INPUT_SLOT)); inventory.setItem(TEMPLATE_INPUT_SLOT, this.inventory.getStackInSlot(TEMPLATE_INPUT_SLOT)); System.out.printf("CHECKING TEMPLATE INPUT OF RECIPE: %s\n", this.inventory.getStackInSlot(TEMPLATE_INPUT_SLOT)); ^ See what the result of those print statements are, make sure they're right
    • Upon testing again after adding them, the game still doesn't crash however the resource packs are still unfortunately broken.
    • Hi! Can someone please point me to the correct FAQ or place? I'm not able do DuckDuckGo myself out of this one. As you can hopefully see, chunks are not rendered. I run a forge server, fresh install on a linux VM. Curseforge on the Win11 client with Embeddium, Oculus and Unbound shader. No mods. Forge 47.2.23 on server & client.  No errors, no crashes, no apparent CPU or RAM issues with the VM. This screenshot was captured while creative, but the same happens when flying in survival. Waiting (floating) for a few minutes sooner or (often) later, lets the missing chunks appear. Usually takes 5-10 minutes.  When on a local game, the chunks appear slowly, but they do appear without pause.   This must be something simple, obvious, but I can't find the correct "search words" to find my way out. "Chunks not loading / rendering" didn't help. Browsing several forums neither. 
    • This is the Forge forums. We only support Forge here. Read the FAQ
    • 1.The game doesn't crash, everything seems normal, but when i insert the designated items into the block entity, the result item does not show up. 2.Yes, I'm using a custom menu, here's the source code:  
  • Topics

×
×
  • Create New...

Important Information

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