Jump to content

how do i detect items in custom GUI slots?


dark2222

Recommended Posts

i am working on an new mod right now and i don't now have to detect the items i put the GUI slots or change them (damaging/enchanting ex)

here are the files i think you will need

container

package com.durabilitytransfer;

import com.durabilitytransfer.slots.basictransferslot1;
import com.durabilitytransfer.slots.basictransferslot2;
import com.durabilitytransfer.slots.basictransferslot3;
import com.durabilitytransfer.titleentitys.TileEntityBasic;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.common.MinecraftForge;

public class ContainerBatic extends Container{
private TileEntityBasic basic;

public ContainerBatic(InventoryPlayer invPlayer, TileEntityBasic basic) {
	this.basic = basic;
	if(basic.canUpdate() != false){
		basic.updateContainingBlockInfo();
	}

	for (int x = 0; x < 9; x++){
		addSlotToContainer(new Slot(invPlayer, x, 8 + 18 * x, 198));
	}
	for (int y = 0; y < 3; y++){
		for(int x = 0; x < 9; x++) {
			addSlotToContainer(new Slot(invPlayer, x + y * 9 + 9, 8 + 18 * x, 140 + y * 18));
		}
	}

	for (int y = 0; y < 1; y++){
		for (int x = 0; x < 1; x++){
			this.addSlotToContainer(new basictransferslot1(basic,  0, 82 + x * 18, 12 + y * 18));
			this.addSlotToContainer(new basictransferslot2(basic,  1, 82 + x * 18, 59 + y * 18));
			this.addSlotToContainer(new basictransferslot3(basic, 2, 8 + x * 18, 120 + y * 18));
		}
	}
}


@Override
public boolean canInteractWith(EntityPlayer entityplayer) {
	return basic.isUseableByPlayer(entityplayer);
}
@Override
public ItemStack transferStackInSlot(EntityPlayer player, int index){
	ItemStack stack = null;
	Slot slot = (Slot) this.inventorySlots.get(index);
	if(slot!=null&&slot.getHasStack()){
		ItemStack slotstack = slot.getStack();
		stack = slotstack.copy();
		if(index<{
			if(!this.mergeItemStack(slotstack,8,this.inventorySlots.size(),false)) return null;
		}else if(!this.getSlot(0).isItemValid(slotstack)||!this.mergeItemStack(slotstack,0,4,false)) return null;
		if(slotstack.stackSize==0){
			slot.putStack((ItemStack) null);
		}else{
			slot.onSlotChanged();
		}
		if(slotstack.stackSize==stack.stackSize) return null;
		slot.onPickupFromSlot(player,slotstack);
	}
	return stack;
}
/**
 * Does the same as mergeItemStack with the same args, except does not
 * actually merge— just returns the number of items that can be merged
 * (usually either stack.stackSize or 0, but can be in between)
 * @param stack
 * @param start
 * @param end
 * @param reverse
 * @return
 */
int dryMerge(ItemStack stack, int start, int end, boolean reverse){
	boolean flag1 = false;
	int i = start;
	if(reverse){
		i = end-1;
	}
	int quantity = stack.stackSize;
	Slot slot;
	ItemStack slotstack;
	if(stack.isStackable()){
		while(stack.stackSize>0&&(!reverse&&i<end||reverse&&i>=start)){
			slot = this.getSlot(i);
			slotstack = slot.getStack();
			if(slotstack!=null&&slotstack.itemID==stack.itemID&&(!stack.getHasSubtypes()||stack.getItemDamage()==slotstack.getItemDamage())&&ItemStack.areItemStackTagsEqual(stack,slotstack)){
				int l = slotstack.stackSize+stack.stackSize;
				if(l<=stack.getMaxStackSize()){
					quantity -= slotstack.stackSize;
				}else if(slotstack.stackSize<stack.getMaxStackSize()){
					quantity -= (stack.getMaxStackSize() - slotstack.stackSize);
				}
			}
			if(reverse) --i;
			else ++i;
		}
	}
	if(stack.stackSize>0){
		if(reverse){
			i = end-1;
		}else{
			i = start;
		}
		while(!reverse&&i<end||reverse&&i>=start){
			slot = (Slot) this.inventorySlots.get(i);
			slotstack = slot.getStack();
			if(slotstack==null){
				quantity = 0;
				break;
			}
			if(reverse){
				--i;
			}else{
				++i;
			}
		}
	}
	return stack.stackSize-quantity;
}

}

 

Tile entity

package com.durabilitytransfer.titleentitys;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
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 TileEntityBasic extends TileEntity implements IInventory{

private ItemStack[] items;

public TileEntityBasic() {
	items = new ItemStack[9];
}

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

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

@Override
public ItemStack decrStackSize(int i, int count) {
	ItemStack itemstack = getStackInSlot(i);

	if(itemstack != null){
		if(itemstack.stackSize <= count){
			setInventorySlotContents(i, null);
		} else {
			itemstack = itemstack.splitStack(count);
			onInventoryChanged();
		}
	}

	return itemstack;
}

@Override
public ItemStack getStackInSlotOnClosing(int i) {
	ItemStack item = getStackInSlot(i);
	setInventorySlotContents(i, null);
	return item;
}

@Override
public void setInventorySlotContents(int i, ItemStack itemstack) {
	items[i] = itemstack;

	if(itemstack != null && itemstack.stackSize > getInventoryStackLimit()) {
		itemstack.stackSize = getInventoryStackLimit();
	}

	onInventoryChanged();

}

@Override
public String getInvName() {
	return "BasicTransfer";
}

@Override
public boolean isInvNameLocalized() {

	return false;
}

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

@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer) {
	return entityplayer.getDistanceSq(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5) <= 64;
}

@Override
public void openChest() {

}

@Override
public void closeChest() {

}

@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack) {
	return itemstack.itemID == Item.swordWood.itemID;
}
@Override
public void writeToNBT(NBTTagCompound compound) {
  super.writeToNBT(compound);

  NBTTagList list = new NBTTagList();

  for(int i = 0; i < getSizeInventory(); i++) {
        ItemStack itemstack = getStackInSlot(i);

        if(itemstack != null) {
          NBTTagCompound item = new NBTTagCompound();

          item.setByte("dtitem", (byte) i);
          itemstack.writeToNBT(item);
          list.appendTag(item);
        }
  }

  compound.setTag("dtitem", list);
}
@Override
public void readFromNBT(NBTTagCompound compound) {
  super.readFromNBT(compound);

  NBTTagList list = compound.getTagList("dtitem");

  for(int i = 0; i < list.tagCount(); i++) {
        NBTTagCompound item = (NBTTagCompound) list.tagAt(i);
        int slot = item.getByte("dtitem");

        if(slot >= 0 && slot < getSizeInventory()) {
          setInventorySlotContents(slot, ItemStack.loadItemStackFromNBT(item));
        }
  }
}
}

i also have 3 custom slot classes for my Block slots that look like this

package com.durabilitytransfer.slots;

import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;

public class basictransferslot1 extends Slot{


public basictransferslot1(IInventory par1iInventory, int par2, int par3, int par4) {
	super(par1iInventory, par2, par3, par4);
}

@Override
    public boolean isItemValid(ItemStack par1ItemStack)
    {
        return par1ItemStack.itemID == Item.swordWood.itemID;
    }
    
}

Link to comment
Share on other sites

the itemstack array in the tileentity symboles your Slots.

Use onUpdate() in the tileentity and check your inventory and change the item how much you want.

Thanks for the tip, can i still check what slot the item are in? Have 3 diffrent slots and i need to do diffrent stuff on all slots

 

Sorry if some words are spell wrong i am on ipad in school

Link to comment
Share on other sites

Each index in the array is a different Slot. You are defining which slot is which index when you construct your Slots. You pass it an index variable, that is the index in the array.

So i can tell it what slot by the slot id i gave the specefic slot?

 

Sorry i ask so much just trying to understand as much as i can before getting home for school xD

Link to comment
Share on other sites

In your Inventory (in this case: the TileEntity) you have the

getStackInSlot

and

setInventorySlotContents

methods. These take a slot index. Usually that maps directly to an array of ItemStacks, so

getStackInSlot(0)

will return the first element in the array:

itemStacks[0]

.

Now in your container you have something like

new Slot(id, x, y)

. Now that slot will display the stack which is available via

getStackInSlot(id)

resp.

itemStacks[id]

.

i have tryed a cuble things but i can't get it to run

EDIT-

i can't find any onUpdate

Link to comment
Share on other sites

I don't know how to explain it more clearly. There is ONE index for each slot. It's the index of the ItemStack in your ItemStack array.

i understand that and i tryed to make a code my problem is that my code is not running/executing

EDIT-

wait... am i suppose to do this in the container or tile entity? (right now i tryed in tile entity)

Link to comment
Share on other sites

... am i suppose to do this in the container or tile entity? (right now i tryed in tile entity)

Define "this".

am i suppose to do the detect/check on the tile entity or container?

so far i try'd in tile entity to detect it but nothing worked

so i am trying to make it in the container

Link to comment
Share on other sites

You ask (author) some strange questions lately - it's almost like you are lazy (lol) :)

If you don't understand how TileEntity works in container and when and what is called I suggest opening:

BlockFurncae.class

ContainerFurnace.class

FurnaceRecipes.class

TileEntityFurnace.class

Then go through code and in every method add System.out.println() on beggining and end, also before and after any method that is called by that method (see for what it asks, when, and what is the return).

eg.: in onUpdate() in TileEntity write something like:

public void updateEntity()
    {
        boolean flag = this.furnaceBurnTime > 0;
        boolean flag1 = false;
System.out.println("Starting Updating Entity")
        if (this.furnaceBurnTime > 0)
        {
System.out.println("Furnace is burning...")
            --this.furnaceBurnTime;
        }
else System.out.println("Not burning")

        if (!this.worldObj.isRemote)
        {
System.out.println("Checking if furnace is not burning and if not, and also there is fuel continue")
            if (this.furnaceBurnTime == 0 && this.canSmelt())
            {
                this.currentItemBurnTime = this.furnaceBurnTime = getItemBurnTime(this.furnaceItemStacks[1]);

 

Same goes to this.furnaceItemStacks[1] - if you add nice System.out.println() to it and put something in it you will figure out how it works.

I am not helping here much (sorry) but belive me, if you want to have ability to code advanced stuff in future this will help very much (takes about few hours to figure out, but then you KNOW the code).

 

And hit about this.furnaceItemStacks[] - when you are adding slots in your Container class this will be an array with size equal to how many slots you add. Let's have look:

//In Container  I have defined my slots like this
public static final int FUEL[] = {0};
public static final int INPUT[] = {1,2,3,4,5,6};
public static final int OUTPUT[] = {7,8,9,10,11,12};
//Now in my TileEntity it's
ArrayOfItemStacks = new ItemStack[13];
//Now ArrayOfItemStacks is a array {0,1,2,3,4,5,6,7,8,9,10,11,12}; where every ID is refering to those in Container.class

Can't describe it more clearly :C

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

You ask (author) some strange questions lately - it's almost like you are lazy (lol) :)

If you don't understand how TileEntity works in container and when and what is called I suggest opening:

BlockFurncae.class

ContainerFurnace.class

FurnaceRecipes.class

TileEntityFurnace.class

Then go through code and in every method add System.out.println() on beggining and end, also before and after any method that is called by that method (see for what it asks, when, and what is the return).

eg.: in onUpdate() in TileEntity write something like:

public void updateEntity()
    {
        boolean flag = this.furnaceBurnTime > 0;
        boolean flag1 = false;
System.out.println("Starting Updating Entity")
        if (this.furnaceBurnTime > 0)
        {
System.out.println("Furnace is burning...")
            --this.furnaceBurnTime;
        }
else System.out.println("Not burning")

        if (!this.worldObj.isRemote)
        {
System.out.println("Checking if furnace is not burning and if not, and also there is fuel continue")
            if (this.furnaceBurnTime == 0 && this.canSmelt())
            {
                this.currentItemBurnTime = this.furnaceBurnTime = getItemBurnTime(this.furnaceItemStacks[1]);

 

Same goes to this.furnaceItemStacks[1] - if you add nice System.out.println() to it and put something in it you will figure out how it works.

I am not helping here much (sorry) but belive me, if you want to have ability to code advanced stuff in future this will help very much (takes about few hours to figure out, but then you KNOW the code).

 

And hit about this.furnaceItemStacks[] - when you are adding slots in your Container class this will be an array with size equal to how many slots you add. Let's have look:

//In Container  I have defined my slots like this
public static final int FUEL[] = {0};
public static final int INPUT[] = {1,2,3,4,5,6};
public static final int OUTPUT[] = {7,8,9,10,11,12};
//Now in my TileEntity it's
ArrayOfItemStacks = new ItemStack[13];
//Now ArrayOfItemStacks is a array {0,1,2,3,4,5,6,7,8,9,10,11,12}; where every ID is refering to those in Container.class

Can't describe it more clearly :C

will not say that i am lazy bekos i am trying to make it work as i am waiting for response

i just ask so much bekos i can't find any tuts on it + i don't now that much java (learning that as i go more advanced)

and i use that system println trick and right now i am trying to get wooden sword to work but i all times get a error

(about ItemStack[] don't work with int)

 

Link to comment
Share on other sites

Dude... ItemStack is not ant int, it's an OBJECT (java type).

If yo uwant to eg. get specific block you do not write:

ItemStack[1000]

but:

ItemStack[MyMod.Sword]

well as i sad i learn as do it right now and i just learned that it is a object

and btw if i try to do that it want to change the items to a int so i don't think i am doing it right

here is my container is i try to code in

package com.durabilitytransfer;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.event.ForgeSubscribe;

import com.durabilitytransfer.slots.basictransferslot1;
import com.durabilitytransfer.slots.basictransferslot2;
import com.durabilitytransfer.slots.basictransferslot3;
import com.durabilitytransfer.titleentitys.TileEntityBasic;

public class ContainerBatic extends Container{
private TileEntityBasic basic;

public ContainerBatic(InventoryPlayer invPlayer, TileEntityBasic basic) {
	this.basic = basic;
	boolean a = true;
		test(basic);

	for (int x = 0; x < 9; x++){
		addSlotToContainer(new Slot(invPlayer, x, 8 + 18 * x, 198));
	}
	for (int y = 0; y < 3; y++){
		for(int x = 0; x < 9; x++) {
			addSlotToContainer(new Slot(invPlayer, x + y * 9 + 9, 8 + 18 * x, 140 + y * 18));
		}
	}

	for (int y = 0; y < 1; y++){
		for (int x = 0; x < 1; x++){
			this.addSlotToContainer(new basictransferslot1(basic,  0, 82 + x * 18, 12 + y * 18));
			this.addSlotToContainer(new basictransferslot2(basic,  1, 82 + x * 18, 59 + y * 18));
			this.addSlotToContainer(new basictransferslot3(basic, 2, 8 + x * 18, 120 + y * 18));
		}
	}
}
                                                                       
public static void test(TileEntityBasic basic){ <---- this is the code i am working on
	System.out.println("starting1");
	if(basic.getStackInSlot(0) == ItemStack[item.swordWood]){
		System.out.println("test");

	}else{
		System.out.println("broke");

	}
}


@Override
public boolean canInteractWith(EntityPlayer entityplayer) {
	return basic.isUseableByPlayer(entityplayer);
}
@Override
public ItemStack transferStackInSlot(EntityPlayer player, int index){
	ItemStack stack = null;
	Slot slot = (Slot) this.inventorySlots.get(index);
	if(slot!=null&&slot.getHasStack()){
		ItemStack slotstack = slot.getStack();
		stack = slotstack.copy();
		if(index<{
			if(!this.mergeItemStack(slotstack,8,this.inventorySlots.size(),false)) return null;
		}else if(!this.getSlot(0).isItemValid(slotstack)||!this.mergeItemStack(slotstack,0,4,false)) return null;
		if(slotstack.stackSize==0){
			slot.putStack((ItemStack) null);
		}else{
			slot.onSlotChanged();
		}
		if(slotstack.stackSize==stack.stackSize) return null;
		slot.onPickupFromSlot(player,slotstack);
	}
	return stack;
}
/**
 * Does the same as mergeItemStack with the same args, except does not
 * actually merge— just returns the number of items that can be merged
 * (usually either stack.stackSize or 0, but can be in between)
 * @param stack
 * @param start
 * @param end
 * @param reverse
 * @return
 */
int dryMerge(ItemStack stack, int start, int end, boolean reverse){
	boolean flag1 = false;
	int i = start;
	if(reverse){
		i = end-1;
	}
	int quantity = stack.stackSize;
	Slot slot;
	ItemStack slotstack;
	if(stack.isStackable()){
		while(stack.stackSize>0&&(!reverse&&i<end||reverse&&i>=start)){
			slot = this.getSlot(i);
			slotstack = slot.getStack();
			if(slotstack!=null&&slotstack.itemID==stack.itemID&&(!stack.getHasSubtypes()||stack.getItemDamage()==slotstack.getItemDamage())&&ItemStack.areItemStackTagsEqual(stack,slotstack)){
				int l = slotstack.stackSize+stack.stackSize;
				if(l<=stack.getMaxStackSize()){
					quantity -= slotstack.stackSize;
				}else if(slotstack.stackSize<stack.getMaxStackSize()){
					quantity -= (stack.getMaxStackSize() - slotstack.stackSize);
				}
			}
			if(reverse) --i;
			else ++i;
		}
	}
	if(stack.stackSize>0){
		if(reverse){
			i = end-1;
		}else{
			i = start;
		}
		while(!reverse&&i<end||reverse&&i>=start){
			slot = (Slot) this.inventorySlots.get(i);
			slotstack = slot.getStack();
			if(slotstack==null){
				quantity = 0;
				break;
			}
			if(reverse){
				--i;
			}else{
				++i;
			}
		}
	}
	return stack.stackSize-quantity;
}
}

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hi, I want to make a client-only mod, everything is ok, but when I use shaders, none of the textures rendered in RenderLevelStageEvent nor the crow entity model are rendered, I want them to be visible, because it's a horror themed mod Here is how i render the crow model in the CrowEntityRenderer<CrowEntity>, by the time i use this method, i know is not the right method but i don't think this is the cause of the problem, the renderType i'm using is entityCutout @Override public void render(CrowEntity p_entity, float entityYaw, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight) { super.render(p_entity, entityYaw, partialTick, poseStack, bufferSource, packedLight); ClientEventHandler.getClient().crow.renderToBuffer(poseStack, bufferSource.getBuffer(ClientEventHandler.getClient().crow .renderType(TEXTURE)), packedLight, OverlayTexture.NO_OVERLAY, Utils.rgb(255, 255, 255)); } Here renderLevelStage @Override public void renderWorld(RenderLevelStageEvent e) { horrorEvents.draw(e); } Here is how i render every event public void draw(RenderLevelStageEvent e) { for (HorrorEvent event : currentHorrorEvents) { event.tick(e.getPartialTick()); event.draw(e); } } Here is how i render the crow model on the event @Override public void draw(RenderLevelStageEvent e) { if(e.getStage() == RenderLevelStageEvent.Stage.AFTER_ENTITIES) { float arcProgress = getArcProgress(0.25f); int alpha = (int) Mth.lerp(arcProgress, 0, 255); int packedLight = LevelRenderer.getLightColor(Minecraft.getInstance().level, blockPos); VertexConsumer builder = ClientEventHandler.bufferSource.getBuffer(crow); Crow<CreepyBirdHorrorEvent> model = ClientEventHandler .getClient().crow; model.setupAnim(this); RenderHelper.renderModelInWorld(model, position, offset, e.getCamera(), e.getPoseStack(), builder, packedLight, OverlayTexture.NO_OVERLAY, alpha); builder = ClientEventHandler.bufferSource.getBuffer(eyes); RenderHelper.renderModelInWorld(model, position, offset, e.getCamera(), e.getPoseStack(), builder, 15728880, OverlayTexture.NO_OVERLAY, alpha); } } How i render the model public static void renderModelInWorld(Model model, Vector3f pos, Vector3f offset, Camera camera, PoseStack matrix, VertexConsumer builder, int light, int overlay, int alpha) { matrix.pushPose(); Vec3 cameraPos = camera.getPosition(); double finalX = pos.x - cameraPos.x + offset.x; double finalY = pos.y - cameraPos.y + offset.y; double finalZ = pos.z - cameraPos.z + offset.z; matrix.pushPose(); matrix.translate(finalX, finalY, finalZ); matrix.mulPose(Axis.XP.rotationDegrees(180f)); model.renderToBuffer(matrix, builder, light, overlay, Utils .rgba(255, 255, 255, alpha)); matrix.popPose(); matrix.popPose(); } Thanks in advance
    • Here's the link: https://mclo.gs/7L5FibL Here's the link: https://mclo.gs/7L5FibL
    • Also the mod "Connector Extras" modifies Reach-entity-attributes and can cause fatal errors when combined with ValkrienSkies mod. Disable this mod and continue to use Syntra without it.
    • Hi everyone. I was trying modify the vanilla loot of the "short_grass" block, I would like it drops seeds and vegetal fiber (new item of my mod), but I don't found any guide or tutorial on internet. Somebody can help me?
    • On 1.20.1 use ValkrienSkies mod version 2.3.0 Beta 1. I had the same issues as you and it turns out the newer beta versions have tons of unresolved incompatibilities. If you change the version you will not be required to change the versions of eureka or any other additions unless prompted at startup. This will resolve Reach-entity-attributes error sound related error and cowardly errors.
  • Topics

  • Who's Online (See full list)

×
×
  • Create New...

Important Information

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