Jump to content

Recommended Posts

Posted

Hey there,

 

I have made a super TileEntity class for the machines in my mod, and now want to make a super Container class, but I am having some trouble. This is one of the many Container classes that I have at the moment:

package com.nr.mod.container;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import com.nr.mod.blocks.tileentities.TileEntityElectrolyser;
import com.nr.mod.crafting.ElectrolyserRecipes;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

public class ContainerElectrolyser extends Container {
public TileEntityElectrolyser entity;
public int lastCookTime;
public int lastEnergy;
public int lastEU;
public int lastSU;
  
public ContainerElectrolyser(InventoryPlayer inventory, TileEntityElectrolyser tileentity) {
	this.entity = tileentity;
	addSlotToContainer(new Slot(tileentity, 0, 41, 43));
	addSlotToContainer(new SlotBlockedInventory(tileentity, 1, 134, 15));
	addSlotToContainer(new SlotBlockedInventory(tileentity, 2, 134, 35));
	addSlotToContainer(new SlotBlockedInventory(tileentity, 3, 134, 55));
	addSlotToContainer(new SlotBlockedInventory(tileentity, 4, 134, 75));
	this.addSlotToContainer(new Slot(tileentity, 5, 31, 20));
	this.addSlotToContainer(new Slot(tileentity, 6, 51, 20));
	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 9; j++) {
			addSlotToContainer(new Slot(inventory, j + i * 9 + 9, 8 + j * 18, 92 + i * 18));
		}
	}
	for (int i = 0; i < 9; i++) {
		addSlotToContainer(new Slot(inventory, i, 8 + i * 18, 150));
	}
}
  
public void addCraftingToCrafters(ICrafting icrafting) {
	super.addCraftingToCrafters(icrafting);
	icrafting.sendProgressBarUpdate(this, 0, this.entity.cookTime);
}
  
public void detectAndSendChanges() {
	super.detectAndSendChanges();
	for (int i = 0; i < this.crafters.size(); i++) {
		ICrafting icrafting = (ICrafting)this.crafters.get(i);
		if (this.lastCookTime != this.entity.cookTime) {
			icrafting.sendProgressBarUpdate(this, 0, this.entity.cookTime);
		}
		icrafting.sendProgressBarUpdate(this, 200, this.entity.energyStorage.getEnergyStored());
		icrafting.sendProgressBarUpdate(this, 201, this.entity.energyStorage.getEnergyStored() >> 16);
		icrafting.sendProgressBarUpdate(this, 100, this.entity.energyUpgrade);
		icrafting.sendProgressBarUpdate(this, 101, this.entity.energyUpgrade >> 16);
		icrafting.sendProgressBarUpdate(this, 102, this.entity.speedUpgrade);
		icrafting.sendProgressBarUpdate(this, 103, this.entity.speedUpgrade >> 16);
	}
	this.lastCookTime = this.entity.cookTime;
}
  
@SideOnly(Side.CLIENT)
public void updateProgressBar(int slot, int value) {
	super.updateProgressBar(slot, value);
	if (slot == 0) {this.entity.cookTime = value;}
	if (slot == 200) {this.lastEnergy = this.upcastShort(value);}
	if (slot == 201) {this.entity.energy = this.lastEnergy | value << 16;}
	if (slot == 100) {this.lastEU = this.upcastShort(value);}
	if (slot == 101) {this.entity.energyUpgrade = this.lastEU | value << 16;}
	if (slot == 102) {this.lastSU = this.upcastShort(value);}
	if (slot == 103) {this.entity.speedUpgrade = this.lastSU | value << 16;}
}
  
private int upcastShort(int input) {
	if (input < 0) input += 65536;
	return input;
}

public ItemStack transferStackInSlot(EntityPlayer player, int clickedSlotNumber) {
	ItemStack itemstack = null;
	Slot slot = (Slot)this.inventorySlots.get(clickedSlotNumber);
	if ((slot != null) && (slot.getHasStack())) {
		ItemStack itemstack1 = slot.getStack();
		itemstack = itemstack1.copy();
		if (clickedSlotNumber == 1 || clickedSlotNumber == 2 || clickedSlotNumber == 3 || clickedSlotNumber == 4) {
			if (!mergeItemStack(itemstack1, 7, 43, true)) {
				return null;
			}
			slot.onSlotChange(itemstack1, itemstack);
		}
		else if(clickedSlotNumber > 6) {
			if (TileEntityElectrolyser.isSpeedUpgrade(itemstack1)) {
				if (!this.mergeItemStack(itemstack1, 5, 6, false)) {
					return null;
				}
			}
			else if (TileEntityElectrolyser.isEnergyUpgrade(itemstack1)) {
				if (!this.mergeItemStack(itemstack1, 6, 7, false)) {
					return null;
				}
			}
			else if (ElectrolyserRecipes.instance().validInput(itemstack1)) {
				if (!mergeItemStack(itemstack1, 0, 1, false)) {
					return null;
				}
			}
			else if ((clickedSlotNumber >= 7) && (clickedSlotNumber < 34)) {
				if (!mergeItemStack(itemstack1, 34, 43, false)) {
					return null;
				}
			}
			else if ((clickedSlotNumber >= 34) && (clickedSlotNumber < 43) && (!mergeItemStack(itemstack1, 7, 34, false))) {
				return null;
			}
		}
		else if (!mergeItemStack(itemstack1, 7, 43, false)) {
			return null;
		}
		if (itemstack1.stackSize == 0) {
			slot.putStack((ItemStack)null);
		}
		else {
			slot.onSlotChanged();
		}
		if (itemstack1.stackSize == itemstack.stackSize) {
			return null;
		}
		slot.onPickupFromSlot(player, itemstack1);
	}
	return itemstack;
}

public boolean canInteractWith(EntityPlayer var1) {
	return this.entity.isUseableByPlayer(var1);
}
}

 

The problem I am having is as follows:

 

Line 15: I define 'entity' as a certain machine TileEntity, and one of the arguments is that TileEntity - how can I make a super constructor if one of the arguments is different each time?

 

Could I perhaps use the argument 'ISidedInventory inventory' instead, and then cast tileentity to the TileEntity I want?

 

Thanks for any help in advance :)

Posted

Use generics, or just use your 'super tile entity' class as the parameter type.

 

Keep in mind that you will only be able to use methods / fields from that type, so if any of your tile entity classes have special methods or fields, they will not be accessible without casting to that type.

 

What you're trying is really only useful if there is a lot of common behavior and you don't need it to do anything specific based on the actual class involved.

Posted

Thanks for the quick reply - yes, there are a lot of common features as they are essentially all standard RF-using machines, and the tile entity class handles different numbers of inputs/outputs (it doesn't work perfectly but it is getting less buggy). Thanks for the link to that tutorial too - I'll take a look through it and work it out from there ;)

Posted

Just quickly as an example without generics - if, in my super, I have

public TileEntityElectrolyser entity;

and TileEntityElectrolyser extends TileEntityMachine, then can I have TileEntityMachine as the constructor parameter:

public ContainerMachine(InventoryPlayer inventory, TileEntityMachine tileentity) {

and use the following in the constructor?

this.entity = (TileEntityElectrolyser) tileentity;

Posted

That's not generics, that's simple inheritance (which should be fine for your purposes), but you CAN NOT cast to the specific tile entity class. That defeats the whole point.

 

If you need a container that has access to methods / fields specific to your TileEntityElectrolyser class, make a container specifically for that class - the container can extend your super container, and take the specific TileEntityElectrolyser as a constructor parameter.

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.