Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

I have two very similar blocks that inherit from a common block
They have their own EntityBlock, Contains and Screens... all work fine except the Screens, which both blocks open the same one(which belongs to one of them)

I looked EVERYWHERE to understand why that happens, but everything seems to be properly put:
Here's relevant code:


From my registry, the register() just puts them into the DeferredRegister properly, also adding "_container" at the end so all good

		public static final RegistryObject<MenuType<RedstoneTransmitterContainer>> redstone_transmitter = register("redstone_transmitter", RedstoneTransmitterContainer::new);
		public static final RegistryObject<MenuType<RedstoneReceiverContainer>> redstone_receiver = register("redstone_receiver", RedstoneReceiverContainer::new);
		

 

public class RedstoneReceiverBlockEntity extends WirelessBlockEntity {

	public RedstoneReceiverBlockEntity(BlockPos pos, BlockState state) {
		super(Registry.BlockEntities.redstone_receiver.get(), pos, state);
	}
	
}
public class RedstoneTransmitterBlockEntity extends WirelessBlockEntity {
	
	private Location target;
	private boolean interdimensional;
	
	public RedstoneTransmitterBlockEntity(BlockPos pos, BlockState state) {
		super(Registry.BlockEntities.redstone_transmitter.get(), pos, state);
		
		this.target = null;
		this.interdimensional = false;
	}
  
  // .... more stuff this class has //
}

 

public class RedstoneReceiverScreen extends WirelessBlockScreen<RedstoneReceiverContainer> {

	// .. //
  
	public RedstoneReceiverScreen(RedstoneReceiverContainer container, Inventory inventory, Component title) {
		super(container, inventory, title);
		System.out.println("----- ctor receiver screen");
	}
  
  	// ... //
  
 }
public class RedstoneTransmitterScreen extends WirelessBlockScreen<RedstoneTransmitterContainer> {

	public RedstoneTransmitterScreen(RedstoneTransmitterContainer container, Inventory inventory, Component title) {
		super(container, inventory, title);
		System.out.println("----- ctor transmitter screen");
	}

}

 

	@SubscribeEvent
	public static void clientSetup(FMLClientSetupEvent event) {
		PacketHandler.init();
		
		MenuScreens.register(Registry.Containers.redstone_transmitter.get(), RedstoneTransmitterScreen::new);
		MenuScreens.register(Registry.Containers.redstone_receiver.get(), RedstoneReceiverScreen::new);
	}


All seems to  be properly in palce.. yet clicking on the Receiver still shows the Transmitter's GUI, and the Syso says "----- ctor transmitter screen"..

Why is this happening? If there's any other code you want to see let me know

  • Author

Oh PacketHandler is the thing that holds the SimpleChannel I use to send packets to the server, I folllowed a Tutorial and they called it that so I said why not--
the init() method registers the packets(well one packet for now lol)

 

	private static final String VERSION = "0.1.0";
	public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel(new ResourceLocation(Core.MOD_ID, "channel"), () -> VERSION, VERSION::equals, VERSION::equals);
	
	private PacketHandler() {
		
	}
	
	
	public static void init() {
		int index = 0;
		
		CHANNEL.registerMessage(index++, WirelessUpdatePacket.class, WirelessUpdatePacket::encode, WirelessUpdatePacket::decode, WirelessUpdatePacket::handle);
	}

I just put it in the enqueueWork() and it still doesn't work... (wrong screen opened)

Edited by 1Mangomaster1

  • Author

Also wdym the code where I actually open the Menu, in the Block class?

 

	@Override
	public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult) {
		if (level.isClientSide)
			return InteractionResult.SUCCESS;
		BlockEntity blockEntity = level.getBlockEntity(pos);
		if (!(blockEntity instanceof RedstoneReceiverBlockEntity))
			return InteractionResult.SUCCESS;
			
		MenuProvider menu = new SimpleMenuProvider(RedstoneReceiverContainer.getServerContainer((RedstoneReceiverBlockEntity)blockEntity, pos), RedstoneReceiverContainer.TITLE);
		
		NetworkHooks.openGui((ServerPlayer) player, menu);
		return InteractionResult.SUCCESS;
	}
	@Override
	public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult) {
		if (level.isClientSide)
			return InteractionResult.SUCCESS;
		BlockEntity blockEntity = level.getBlockEntity(pos);
		if (!(blockEntity instanceof RedstoneTransmitterBlockEntity))
			return InteractionResult.SUCCESS;
			
		MenuProvider menu = new SimpleMenuProvider(RedstoneTransmitterContainer.getServerContainer((RedstoneTransmitterBlockEntity)blockEntity, pos), RedstoneTransmitterContainer.TITLE);
		
		NetworkHooks.openGui((ServerPlayer) player, menu);
		return InteractionResult.SUCCESS;
	}



Also important to notice, while the same screen opens for them both, the title IS different between the blocks...

  • Author
public class RedstoneReceiverContainer extends WirelessBlockContainer {

	public static final TextComponent TITLE = new TextComponent("Receiver Menu");
	
	public RedstoneReceiverContainer(int id, Inventory inventory) {
		super(Registry.Containers.redstone_receiver.get(), id, inventory);
	}
	public RedstoneReceiverContainer(int id, Inventory inventory, BlockPos pos, RedstoneReceiverBlockEntity blockEntity) {
		super(Registry.Containers.redstone_receiver.get(), id, inventory, pos, blockEntity);
	}

	public static MenuConstructor getServerContainer(RedstoneReceiverBlockEntity blockEntity, BlockPos pos) {
		return (id, inventory, player) -> new RedstoneReceiverContainer(id, inventory, pos, blockEntity);
	}
	
	@Override
	public boolean stillValid(Player player) {
		return stillValid(containerAccess, player, Registry.Blocks.redstone_receiver.get());
	}
	
}
public class RedstoneTransmitterContainer extends WirelessBlockContainer {

	public static final TextComponent TITLE = new TextComponent("Transmitter Menu");
	
	public RedstoneTransmitterContainer(int id, Inventory inventory) {
		super(Registry.Containers.redstone_transmitter.get(), id, inventory);
	}
	public RedstoneTransmitterContainer(int id, Inventory inventory, BlockPos pos, RedstoneTransmitterBlockEntity blockEntity) {
		super(Registry.Containers.redstone_transmitter.get(), id, inventory, pos, blockEntity);
	}

	public static MenuConstructor getServerContainer(RedstoneTransmitterBlockEntity blockEntity, BlockPos pos) {
		return (id, inventory, player) -> new RedstoneTransmitterContainer(id, inventory, pos, blockEntity);
	}
	
	@Override
	public boolean stillValid(Player player) {
		return stillValid(containerAccess, player, Registry.Blocks.redstone_transmitter.get());
	}
	
}

 

Edited by 1Mangomaster1

  • Author

Give me some time and I'll build it, is there a private-messaging system or do I send that over here?

 

Edited by 1Mangomaster1

  • Author

I THINK I FOUND OUT!

I found a trace in my old code(back when I was only working on a single block) when I don't use the given menu type but just this block... I can't believe I missed that, I didn't send it because it is now in an abtract class I did not even think to look at

Thank you!

 

public abstract class WirelessBlockContainer extends AbstractContainerMenu {

	private static WirelessBlockEntity BLOCK_ENTITY;
	
	
	private WirelessBlockEntity blockEntity;
	protected final ContainerLevelAccess containerAccess;
	
	public WirelessBlockContainer(MenuType<? extends WirelessBlockContainer> menuType, int id, Inventory inventory) {
		this(menuType, id, inventory, BlockPos.ZERO, BLOCK_ENTITY);
	}
	public WirelessBlockContainer(MenuType<? extends WirelessBlockContainer> menuType, int id, Inventory inventory, BlockPos pos, WirelessBlockEntity blockEntity) {
		super(Registry.Containers.redstone_transmitter.get(), id);
		
		this.containerAccess = ContainerLevelAccess.create(inventory.player.level, pos);
		this.blockEntity = blockEntity;
		BLOCK_ENTITY = blockEntity;
	}
	
	public WirelessBlockEntity getBlockEntity() {
		return blockEntity;
	}
		
}

That second constructor.... whoopsies

Edited by 1Mangomaster1

  • Author

I didn't find another way to transfer the Block Entity... I saw a tutorial make it static but does nothing with it, just saying it is needed.. so I thought "nah it does nothing", then I noticed that even tho you supply the game with the second constructor it defaults to the first one which has no BlockEntity inserted into it, and I just didn't realize how am I gonna do that, when I thought "maybe that's why this static thing is needed", and... it works.

Is there a better way of making it?? I sure hope so

Basically what I found out is that even tho I supply an object made with the second constructor(look at getServerContainer() at the Transmitter and Receiver containers)
All it does is takes its type and generates a new object from the first constructor(that has to look like that for registration), which has no BlockEntity input... that was my way around it

Edited by 1Mangomaster1

  • Author

I just edited my last message, sorry I wasn't clear, plus, it did work to me so far.. the BLOCK_ENTITY saves the last blockEntity inserted from the second constructor. The idea is I know the first constructor is called right after the second one(as explained I give a supplier of an object made in the second constructor.. for a weird reason it just takes it, gets its type and makes a new one with the first one...)
I use it to then call the second constructor with the BLOCK_ENTITY as the blockEntity, which is the last one made, called from the second constructor of that same container

Edited by 1Mangomaster1

  • Author

Hold up.. it seems I was wrong about this, I just looked at NetworkHooks again... However for some reason not using this static object makes my BlockEntity always be null and for some reason the first constructor is always called altho the second one is supplied(again, look at the Transmitter and Receiver getServerContainer())

  • Author

I am passing it to my constructor, as you can see the second constructor, it cannot be passed in the first one because the register requires a specific container constructor to register it, which does only accepts a menuType, id and inventory...

I did debugged and found out that my second constructor is called right before the first one is called again for reasons I don't understand.. so that was my way around it.. idrk how to do it otherwise without having blockEntity is null

  • Author

So far I registered it that way..

 

		public static final DeferredRegister<BlockEntityType<?>> BLOCK_ENTITIES = DeferredRegister.create(ForgeRegistries.BLOCK_ENTITIES, Core.MOD_ID);
		
		
		private static final <T extends BlockEntity> RegistryObject<BlockEntityType<T>> register(final String name, final BlockEntitySupplier<T> supplier, RegistryObject<? extends Block> block) {
			return BLOCK_ENTITIES.register(name + "_block_entity", () -> BlockEntityType.Builder.of(supplier, block.get()).build(null));
		}
		
		public static final RegistryObject<BlockEntityType<RedstoneTransmitterBlockEntity>> redstone_transmitter = register("redstone_transmitter", RedstoneTransmitterBlockEntity::new, Blocks.redstone_transmitter);
		public static final RegistryObject<BlockEntityType<RedstoneReceiverBlockEntity>> redstone_receiver = register("redstone_receiver", RedstoneReceiverBlockEntity::new, Blocks.redstone_receiver);
		

 

  • Author

Oh shit I did idk why I was too focused on the whole BLOCk_ENTITY thing I completely forgot we talked about containers loll

For containers I just..

 

		public static final DeferredRegister<MenuType<?>> CONTAINERS = DeferredRegister.create(ForgeRegistries.CONTAINERS, Core.MOD_ID);
		
		private static final <T extends AbstractContainerMenu> RegistryObject<MenuType<T>> register(final String name, final MenuSupplier<T> supplier) {
			return CONTAINERS.register(name + "_container", () -> new MenuType<>(supplier));
		}
		
		public static final RegistryObject<MenuType<RedstoneTransmitterContainer>> redstone_transmitter = register("redstone_transmitter", RedstoneTransmitterContainer::new);
		public static final RegistryObject<MenuType<RedstoneReceiverContainer>> redstone_receiver = register("redstone_receiver", RedstoneReceiverContainer::new);
		

Is this a wrong way of doing it?

Edited by 1Mangomaster1

  • Author

Ok, I am now registering the way you suggest, using the buffer to get the position, so I assume the constructor is where I read things... where do I write the data tho? because rn I am getting an error trying to read the pos that there's no pos... and Containers don't have save() and load() methdos like the BlockEntities...

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...

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.