Jump to content

[1.15.2] Access tile entity from container


Budschie

Recommended Posts

I've recently tried to add a tile entity with a gui and a container. To add a slot for the tile entity, I need to access it, but I have no idea how...

 

Container:

public class DeepNetherBlastFurnaceContainer extends Container
{
	public static final ContainerType<DeepNetherBlastFurnaceContainer> TYPE = new ContainerType<DeepNetherBlastFurnaceContainer>(DeepNetherBlastFurnaceContainer::new);
	
	PlayerInventory playerInv;
	ItemStackHandler iStackHandler;
	
	public DeepNetherBlastFurnaceContainer(int id, PlayerInventory playerInv, ItemStackHandler teInventory)
	{
		super(TYPE, id);
		
		this.playerInv = playerInv;
		this.iStackHandler = teInventory;
		
		this.addSlot(new SlotItemHandler(iStackHandler, 1, 56, 17));
        this.addSlot(new SlotItemHandler(iStackHandler, 0, 56, 53));
        this.addSlot(new SlotItemHandler(iStackHandler, 2, 116, 35));

        for (int i = 0; i < 3; ++i)
        {
            for (int j = 0; j < 9; ++j)
            {
                this.addSlot(new Slot(playerInv, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
            }
        }

        for (int k = 0; k < 9; ++k)
        {
            this.addSlot(new Slot(playerInv, k, 8 + k * 18, 142));
        }
	}
	
	public DeepNetherBlastFurnaceContainer(int id, PlayerInventory playerInv)
	{
		super(TYPE, id);
		
		this.playerInv = playerInv;
	}

	@Override
	public boolean canInteractWith(PlayerEntity playerIn)
	{
		return true;
	}
	
}

The code to open the container:

	@Override
	public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult p_225533_6_)
	{
		if(!worldIn.isBlockLoaded(pos))
		{
			return ActionResultType.FAIL;
		}
		if(!worldIn.isRemote)
		{
			TileEntity te = worldIn.getTileEntity(pos);
			if(te != null && te instanceof DeepNetherBlastFurnaceTileEntity)
			{
				NetworkHooks.openGui((ServerPlayerEntity) player, ((INamedContainerProvider)te), pos);
			}
		}
		
		return ActionResultType.SUCCESS;
	}

TileEntity:

public class DeepNetherBlastFurnaceTileEntity extends TileEntity implements ICapabilityProvider, INamedContainerProvider
{
	//Code
	@Override
	public Container createMenu(int p_createMenu_1_, PlayerInventory p_createMenu_2_, PlayerEntity p_createMenu_3_)
	{
		return new DeepNetherBlastFurnaceContainer(p_createMenu_1_, p_createMenu_2_, this.inventory);
	}

	@Override
	public ITextComponent getDisplayName()
	{
		return new StringTextComponent("Test String");
	}
}

 

Link to comment
Share on other sites

22 minutes ago, Budschie said:

I need to access it, but I have no idea how...

Pass it in via the constructor. Probably instead of the ItemStackHandler.

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

2 minutes ago, diesieben07 said:

First of all, do not create registry entries (like ContainerType) in static initializers. Use the appropriate registry event or, even better, DeferredRegister.

So, I've changed my registry class a bit, it now looks like this:

Registry class:

@EventBusSubscriber(bus = Bus.MOD)
public class ContainerRegistry
{
	@SubscribeEvent
	public static void registerContainer(RegistryEvent.Register<ContainerType<?>> event)
	{
		IForgeRegistry<ContainerType<?>> registry = event.getRegistry();
		
		registry.register(new ContainerType<DeepNetherBlastFurnaceContainer>(DeepNetherBlastFurnaceContainer::new).setRegistryName(new ResourceLocation(References.MODID, "nether_blast_furnace_container")));
	}
}

 

Container class:

public class DeepNetherBlastFurnaceContainer extends Container
{
	@ObjectHolder(value = References.MODID+":nether_blast_furnace_container")
	public static final ContainerType<DeepNetherBlastFurnaceContainer> TYPE = null;
	
	PlayerInventory playerInv;
	ItemStackHandler iStackHandler;
	
	public DeepNetherBlastFurnaceContainer(int id, PlayerInventory playerInv, ItemStackHandler teInventory)
	{
		super(TYPE, id);
		
		this.playerInv = playerInv;
		this.iStackHandler = teInventory;
		
		this.addSlot(new SlotItemHandler(iStackHandler, 1, 56, 17));
        this.addSlot(new SlotItemHandler(iStackHandler, 0, 56, 53));
        this.addSlot(new SlotItemHandler(iStackHandler, 2, 116, 35));

        for (int i = 0; i < 3; ++i)
        {
            for (int j = 0; j < 9; ++j)
            {
                this.addSlot(new Slot(playerInv, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
            }
        }

        for (int k = 0; k < 9; ++k)
        {
            this.addSlot(new Slot(playerInv, k, 8 + k * 18, 142));
        }
	}
	
	public DeepNetherBlastFurnaceContainer(int id, PlayerInventory playerInv)
	{
		super(TYPE, id);
		
		this.playerInv = playerInv;
	}

	@Override
	public boolean canInteractWith(PlayerEntity playerIn)
	{
		return true;
	}
	
}

I've did some debugging too, and the problem seems to be that the constructor without the ItemStackHandler gets called on the client side.

Link to comment
Share on other sites

19 minutes ago, diesieben07 said:

You need to create a proper IContainerFactory for your container. Which constructor gets called is entirely controlled by your code, so if the wrong one gets called then your code is wrong.

I've now implemented IContainerFactory , parsed the block pos into the custom packet buffer, and now it seemed to work:

IContainerFactory implementation:

registry.register(new ContainerType<DeepNetherBlastFurnaceContainer>(new IContainerFactory<DeepNetherBlastFurnaceContainer>()
		{

			@Override
			public DeepNetherBlastFurnaceContainer create(int windowId, PlayerInventory inv, PacketBuffer data)
			{
				if(data != null)
				{
					BlockPos tePos = new BlockPos(data.readInt(), data.readInt(), data.readInt());
					TileEntity te = Minecraft.getInstance().world.getTileEntity(tePos);
					
					if(te != null && te instanceof DeepNetherBlastFurnaceTileEntity)
					{
						return new DeepNetherBlastFurnaceContainer(windowId, inv, ((DeepNetherBlastFurnaceTileEntity)te));
					}
				}
				
				return new DeepNetherBlastFurnaceContainer(windowId, inv);
			}
			
		}).setRegistryName(new ResourceLocation(References.MODID, "nether_blast_furnace_container")));

Block Class:

	@Override
	public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult p_225533_6_)
	{
		if(!worldIn.isBlockLoaded(pos))
		{
			return ActionResultType.FAIL;
		}
		if(!worldIn.isRemote)
		{
			TileEntity te = worldIn.getTileEntity(pos);
			if(te != null && te instanceof DeepNetherBlastFurnaceTileEntity)
			{
				NetworkHooks.openGui((ServerPlayerEntity) player, ((INamedContainerProvider)te), new Consumer<PacketBuffer>()
				{

					@Override
					public void accept(PacketBuffer t)
					{
						t.writeInt(pos.getX());
						t.writeInt(pos.getY());
						t.writeInt(pos.getZ());
					}
				});
			}
		}
		
		return ActionResultType.SUCCESS;
	}

Thanks.

Link to comment
Share on other sites

Howdy

Containers, TileEntity, and ContainerScreen synchronisation has a few traps, you might find the working examples in this tutorial project useful (mbe30, mbe31)

https://github.com/TheGreyGhost/MinecraftByExample

 

The main trap is: your server-side Container will access the TileEntity, but your client side should not, otherwise you will probably get synchronisation problems because your client-side container is getting two copies of information: one via the container update packets, and one via tile-entity update packets.

 

This page also has more background information

http://greyminecraftcoder.blogspot.com/2020/04/containers-1144.html

-TGG

Edited by TheGreyGhost
clarification
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

    • 浦和单身妈妈故事℡BCGAME55·COM◇浦和单身妈妈旅行格斗浦和单身妈妈指导台球单身妈妈系统跆拳道单身妈妈Kakao Talk[本社文之电讯@JBOX7]浦和单身妈妈位置定具浦和单身妈妈总经销摔跤单身妈妈聚会信息滑雪单人妈联谊会[总经销文之Kakao Talk JBOWN] 浦和单人妈位置定具广告巡回赛[浦和拳击广告] 乌拉瓦单身妈妈推荐的足球单身妈妈Instagram E体育单身妈妈Kakao Talk [体育总公司]乌拉瓦单身妈妈招聘广告 篮球乌拉瓦单身妈妈Instagram 跆拳道单身妈妈总经销 匹克球 单身妈妈故事[TOTO总公司咨询]乌拉瓦单身妈妈推特举重乌拉瓦单身母亲推荐 扔铅球 单打游戏 野洞 Nordic Single Mom YouTube[TOTOTO总经总经销 购买]乌拉瓦单身母亲系统篮球乌拉瓦做标枪弹射枪,验证,橄榄球运动。 LINE柔道Urawa单身妈妈地址足球单身妈妈度假村摔跤单身妈妈最新地址[赛马总经销]Urawa单身妈妈LINE F1大奖赛Urawa单身妈妈巡回赛 单身妈妈巡回赛 跳马单身妈妈营业招集[BCGAME BC游戏总经销咨询] 设置通知 推荐 订阅 点赞
    • 東南アジアロット業者ºBCGAME33·COM♥ベナンロト動画東南アジアセネガルロト戦略[本社お問い合わせテレJBOX7]東南アジアロト◑‡戦略セネガルロト遊び場東南アジアカザフスタン東南アジアロト競技[総販お問い合わせカカオトークJBOX7]東南アジアロト♨↘旅行クラウンカジノロト動画東南アジアノルウェー東南アジアロト映像[各種オフィコミュニティ制作]南東アロット♩♨カジノパブクウェートロットゲーム南東ア エティオ·ドンア·ロット旅行[マーケティングお問い合わせ]南東アロット♧&クープーン·セント·キッツ·ロット·運動南東アリア·トーリーグ [カジノ本社] ポルトガル ロトリーグ ☞← 方法 ゲンティングハイランドカジノロット映像 東南アジアブルガリア東南アジアロト放送 [ト本社お問い合わせ]東南アジアロト★◁コミュニティボツワナロトサイト東南アジアバハマ東南アジアロトクープン[トト総販購入]東南アジアロト▼◈検証シエラレオネロトカジノパブ東南アジアカザフスタン東南アジアロトコミュニティ[カジノ総販]南東アロト◁↓ゲーム場カタールロット方法 南東アアルジェリア南東アロット業者[大和本社]南東アロット↕ 도박賭博場クラウンカジノロットサイト南東ア レバカラ総販]南東アロットゲームセンター [バカラ総販]南東アロット総販売動画募集 [BCGAMEBCゲーム総販お問い合わせ] お知らせ設定おすすめ購読いいですね
    • 前桥按摩女孩推荐♩BCGAME55·COM△前桥按摩女孩网站掰手腕前桥按摩女孩网站调整按摩女孩网站推荐单杠按摩女孩链接[本社咨询的Tele @JBOX7]前桥按摩女孩网站排球前桥按摩女孩Telegram按摩女孩旅行壁球场度假村[总经销的Kakao Talk JBOX7]诱导前桥鞍马女聚会制作长跑腿运动信息] [赌场总公司] 前桥按摩女孩验证环 前桥按摩女孩总经销 美式足球按摩女孩系列 掷铅球 按摩女孩广播 [体育总公司] 前桥按摩女孩巡回 滑雪 前桥按摩女孩故事 拳击按摩女孩视频 短柄墙球 按摩女孩新地址[TOTO总公司咨询] 前桥按摩女郎聚会信息 跳远 跳远 按摩女郎店募集创投标枪广告 世界杯 按摩天猫女足世界杯 按摩天猫队 按摩天猫队 按摩天猫队购买棒球] 按摩女郎所在网络游戏《按摩女郎故事》[BAKARA总经销]前桥按摩女郎同好会 真实前桥按摩女郎故事 击剑 推荐 壁球按摩女郎登录[赛马总经销]前桥按摩女郎社区骑马前桥按摩女郎故事 推荐 台球按摩女郎旅游[BCGAME BC游戏总经销 推荐 订阅 点赞]
    • 全世界LAPTツアー◎BCGAME33·COM↖シリアLAPTトーナメント全世界ポルトガルLAPTバカラパブ[本社お問い合わせテレJBOX7]全世界LAPT◇️カジノパブフィリピンLAPT戦略全世界ボリビア全世界LAPT本社[総販お問い合わせカカオトークJBOX7]全世界LAPT▒⊙住所アリアカジノLAPT検証全世界グレナダ全世界LAPT募集[各種オフィコミュニティ制作] 全界LAPT ↗▥コミュニティデンマークLAPTトーナメント 世界スペイン 全界 LAPPTARP TOOMALE お問い合わせ [マーケティング] キャッシュゲーム 全世界 南欧 全世界 LAPT ホールダンパブ [スポーツ本社] 全世界 LAPT @℡アドレス トリニダード LAPTカジノパブ 全世界 ボリビア 全世界 LAPT サイト [TOTO本社お問い合わせ] 全世界 LAPT ▣‡試合 マルタ LAPT 賭博場 全世界カザフスタン 全世界 LAPT映像[TOTOTO DANGIF] [TOTO DANGIF LAPT™□住所] 世界中のオーストラリア 世界のLAT中継 [カジノ総販] 世界中のLAPT☜㏂中継マルタ ルクセンブルク中継 旅行 全世界イエメン 全世界LAPT賭博場 [競馬総販]アイランドLAPT本社マルタLAPTバカラパブ [BCGAMEBCゲーム総販お問い合わせ] お知らせ設定おすすめ購読いいですね
    • hey, i would like to highlight a specific slot in a chest for example: when a player opens a chest that has an item that has the name "god sword" it will highlight the slot of "god sword". i already have my code to search for the items in chest then only issue is that i don't know how to highlight the item. would appreciate any help / suggestions. thanks.
  • Topics

×
×
  • Create New...

Important Information

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