Jump to content

Recommended Posts

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

Posted (edited)

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
Posted

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

Posted (edited)
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
Posted (edited)

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
Posted (edited)

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
Posted (edited)

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
Posted

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())

Posted

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

Posted

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);
		

 

Posted (edited)

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
Posted

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

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