Jump to content

RInventor7

Members
  • Posts

    87
  • Joined

  • Last visited

Everything posted by RInventor7

  1. Since all other custom packets ware working and are working, and I have never had this type of an error before I think my network is working perfectly fine and it must be registered. And the message is registered like that: INSTANCE.messageBuilder(MyS2CMessage.class, messageID++, NetworkDirection.PLAY_TO_CLIENT) .encoder(MyS2CMessage::encode).decoder(MyS2CMessage::new) .consumerMainThread(MyS2CMessage::handle).add(); Maybe something else is wrong? It crashes the server anyway when I try to play the sound by sending the custom packet. Server crash report.
  2. Sending now the packet to client in order to play the sounds. if (!level.isClientSide()) { //Send msg to client with filename and position ModNetwork.INSTANCE.send(PacketDistributor.ALL.noArg(), new MyS2CMessage(pos, filename)); } This works fine on singleplayer, but on multiplayer I’ll get a server error: [Server thread/ERROR] [ne.mi.ne.si.IndexedMessageCodec/SIMPLENET]: Received invalid message com.rinventor.mymod.util.sound.MyS2CMessage on channel mymod:network Here’s my S2C Packet class. Maybe I’m doing something wrong (again)? package com.rinventor.mymod.util.sound; import java.util.function.Supplier; import com.rinventor.mymod.MyMod; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundSource; import net.minecraft.world.level.Level; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.network.NetworkEvent; public class MyS2CMessage { public final BlockPos pos; public final String filename; public MyS2CMessage(BlockPos pos, String data) { this.pos = pos; this.filename = data; } public MyS2CMessage(FriendlyByteBuf buffer) { this(buffer.readBlockPos(), buffer.readUtf()); } public void encode(FriendlyByteBuf buffer) { buffer.writeBlockPos(this.pos); buffer.writeUtf(this.filename); } public static void handle(MyS2CMessage msg, Supplier<NetworkEvent.Context> ctx) { ctx.get().enqueueWork(() -> // Make sure it's only executed on the physical client DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> MyMessageClient.handlePacket(msg, ctx)) ); ctx.get().setPacketHandled(true); } public class MyMessageClient { @SuppressWarnings("resource") public static void handlePacket(MyS2CMessage msg, Supplier<NetworkEvent.Context> ctx) { Level level = Minecraft.getInstance().level; BlockPos pos = msg.pos; if (level.isLoaded(pos)) { int x = pos.getX(); int y = pos.getY(); int z = pos.getZ(); level.playLocalSound(x, y, z, new SoundEvent(new ResourceLocation(MyMod.MOD_ID + ":" + msg.filename)), SoundSource.AMBIENT, 1, 1, false); } } } }
  3. I have my own world based configuration file (.txt) which contains more than a minecraft’s configuration file could store, like custom object arrays and etc. I would just like to save and read from this file and store the file in the world folder (not in the configs folder what i managed to do at the moment). The reason for this is that then all the players on server would access the same file. Otherwise all players would have separate files on their computers which leads to data desync on server for the players?? I tried to fix this by implementing SavedData but now all the data between client and server is desynchronized. And SavedData can’t store custom object arrays? So for me the only option seems to be my custom configuration file which is always in-sync... idk... Any better ideas??
  4. Thanks, didn’t think of a custom packet myself. So I run the following code only on client? ResourceLocation resource1 = new ResourceLocation(MyMod.MOD_ID + ":" + filename); SoundEvent se1 = new SoundEvent(resource1); entity.playSound(se1, 1.0f, 1.0f); And then send a packet to server? Or I should run that code on server and send a packet to the client? Entity sound playing happens on client, does it? Or do I need to run this code in the packet handle function as well? Sorry, but I’m confused. It works, but only on server-side? I have a custom screen that reads and sets some data that is saved in my SavedData instance. Since the screen is client-side only then MinecraftServer is null and accessing the SavedData will crash the game. How to fix that? (I don’t want to send a lot of custom packets back and forth)
  5. Yes, already tried. Well the reading is the problem. Reading and playing the sound like this ResourceLocation resource1 = new ResourceLocation(MyMod.MOD_ID + ":" + filename); SoundEvent se1 = new SoundEvent(resource1); entity.playSound(se1, 1.0f, 1.0f); will kick from the server saying that java.lang.IllegalArgumentException: Can't find id for 'net.minecraft.sounds.SoundEvent@937bd60' in map Registry[ResourceKey[minecraft:root / minecraft:sound_event] (Experimental)] Should I read and play the sound file somehow differently? I’m kinda clueless.
  6. Thanks. That works now. I’m basically trying to solve this other issue. Since I wish the player to hear my sound on server as well without registering them and without knowing their file names, I created a custom sound player. Since texture packs can be different for all players on server I decided that the sound files should be in the world folder, which should be the same for all the player playing on the same server. I just need my custom sound player to be able to find the world folder and locate the files to play them.
  7. Thanks for the solution. 1) Since I am making my mod interact with some other files located in the world folder I would still like to be able to somehow get the path to that folder (using Java.io.file) if possible. 2) For data saving I tried to use the SavedData. But I can’t get it working. Here’s my saved data class: package com.rinventor.ptmmod.util; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.MinecraftServer; import net.minecraft.world.level.saveddata.SavedData; public class PTMSavedData extends SavedData { private int test = 0; public int getTest() { return this.test; } public void setTest(int test) { this.test = test; this.setDirty(); } public static PTMSavedData create() { return new PTMSavedData(); } public static PTMSavedData load(CompoundTag tag) { PTMSavedData data = create(); data.test = tag.getInt("test"); return data; } public CompoundTag save(CompoundTag tag) { tag.putInt("test", test); return tag; } public static void manage(MinecraftServer server) { server.overworld().getDataStorage().computeIfAbsent(PTMSavedData::load, PTMSavedData::create, "ptm-file"); } } This should be correct? Now I have problems reading and writing the data. When world closes I’m trying to save some data, but it doesn’t even create .dat file. I’m probably doing it incorrectly: PTMSavedData.manage(event.getLevel().getServer()); PTMSavedData data = PTMSavedData.create(); data.setTest(9); And since it doesn’t create the file, it can’t read anything and will default the test int to 0. When I’m reading it (maybe also incorrectly?) PTMSavedData.manage(level.getServer()); PTMSavedData data = new PTMSavedData(); int testInt = data.getTest(); What am I doing wrong? Thanks.
  8. Hi! I would like to read/save a text file to world folder. But I don’t know how to get the world/level name as a string nor how to get a world’s directory (current world, where the player is in). I managed to get the world name in singleplayer and only on server like this String worldName = level.toString().substring(level.toString().indexOf("[")+1).replace("]", ""); There’s probably a method that would do that and return me the name even on client and multiplayer. Does anybody have any ideas or suggestions? Thanks.
  9. Hi! My mod contains some custom sounds, that work perfectly fine, because they’re properly registered. I have a custom block entity. On right click it open a screen with textbox where you can type in a name (e.g. snd1). The player/mod user has a custom texture pack containing the sound file named snd1 and a proper sounds.json containing an entry for snd1. A custom entity should now in some situations play the custom sound which name has been entered by player. At the moment the code I use for an entity to play the sound looks like this: (the filename it gets from the block entity) ResourceLocation resource1 = new ResourceLocation(MyMod.MOD_ID + ":" + filename); SoundEvent se1 = new SoundEvent(resource1); entity.playSound(se1, 1.0f, 1.0f); It works fine in singleplayer. As soon as I test it on server it kicks the player when it tries to play the sound and gives the following error: java.lang.IllegalArgumentException: Can't find id for 'net.minecraft.sounds.SoundEvent@937bd60' in map Registry[ResourceKey[minecraft:root / minecraft:sound_event] (Experimental)] See full debug log. Registering the sounds with DeferredRegister during RegistryEvent is not possible because I do not know how many sounds will the player have and what their names would be. What can I do to get it working on the server? Is it even possible? Thanks in advance.
  10. The rotating works perfectly. Thank you. However, setting the RenderType to ENTITYBLOCK_ANIMATED makes the default model invisible which is good, but it makes my rendered model also invisible. If I do not set the RenderType it renders still 2 models in 1. I can render one model (for example a block of glass) and rotate it, but if I render my block I either get 2 models in 1 or nothing. Is it possible to somehow only render 1 model (the one that I render myself) of my block? Maybe it is possible to somehow re-render the original model with rotation instead of rendering a new model with correct rotation? My block has 5 different states which are defined by the blockstate.json and an IntegerProperty. I’m just trying to rotate the block without using the FACING property because then i’d have to make two json models of all the 5 states (one straight and the other at 45 deg angle) and then rotate them. So the whole idea is to use custom renderer to reduce model files from 20 to 5.
  11. Hi! I have a working block entity renderer, but there’s 2 problems with it, that I can’t figure out how to solve. All I wish to do is to rotate the block by 45 degrees. Of course angles can be 0, 45, 90, 135, 180 etc. @OnlyIn(Dist.CLIENT) public class MyBlockRender implements BlockEntityRenderer<MyBlockBlockEntity> { BlockRenderDispatcher blockRenderer = Minecraft.getInstance().getBlockRenderer(); public MyBlockRender(BlockEntityRendererProvider.Context renderManager) { super(); blockRenderer = renderManager.getBlockRenderDispatcher(); } @Override public void render(MyBlockBlockEntity be, float partialTicks, PoseStack poseStack, MultiBufferSource bufferSource, int combinedLight, int combinedOverlay) { BlockState bs = be.getBlockState(); poseStack.pushPose(); poseStack.translate(0.0, 1.5, 0.0); float f = PTMBlock.getRotationInDeg(bs); poseStack.mulPose(Vector3f.YP.rotationDegrees(f)); blockRenderer.renderSingleBlock(bs, poseStack, bufferSource, combinedLight, OverlayTexture.NO_OVERLAY, ModelData.EMPTY, RenderType.cutout()); poseStack.popPose(); } } 1) As my code indicates I move the model up. This immediately will indicate that it renders 2 blocks in 1. How can I stop the original renderer because otherwise (if no translation) it will render 2 models in one and if I rotate the model 45 degrees only my rendered model is at the correct angle. 2) Using poseStack.mulPose(Vector3f.YP.rotationDegrees(45f)) is messing up the model location. I want the model to be inside the bounding box but it’s rotated half a block on the side (depending on the angle). Does it got to do something with the actual block model.json or do i just have to use the translate function to center the model?
  12. Thanks for the replay. You just saved me from a lot of extra work. Thank you so much! The following code works (at least I can now see the something rendered in game): package com.rinventor.mymod.entities.render.block; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Vector3f; import com.rinventor.mymod.objects.blockentities.MyBlockBlockEntity; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.BlockRenderDispatcher; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @OnlyIn(Dist.CLIENT) public class MyBlockRender implements BlockEntityRenderer<MyBlockBlockEntity> { public MyBlockRender(BlockEntityRendererProvider.Context renderManager) { super(); } @Override public void render(MyBlockBlockEntity be, float partialTicks, PoseStack poseStack, MultiBufferSource bufferSource, int combinedLight, int combinedOverlay) { BlockRenderDispatcher blockRenderer = Minecraft.getInstance().getBlockRenderer(); BlockState blockstate = be.getBlockState(); poseStack.pushPose(); float f1 = 45.0F; poseStack.mulPose(new Vector3f().rotationDegrees(f1)); blockRenderer.renderSingleBlock(blockstate, poseStack, bufferSource, combinedLight, OverlayTexture.NO_OVERLAY, be.getModelData(), RenderType.cutout()); poseStack.popPose(); } }
  13. Hi! I managed to make a custom block entity render for my block entity. The renderer is correctly registered and it runs on every tick as it should be. The problem is that it’s not doing anything I have set it to do. What am I doing wrong? I just wish to move the block model, scale it smaller and rotate it 45 degrees. Thanks in advance. package com.rinventor.transportmod.entities.render.block; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Vector3f; import com.rinventor.transportmod.core.base.PTMBlock; import com.rinventor.transportmod.core.init.ModBlocks; import com.rinventor.transportmod.objects.blockentities.MyBlockEntity; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @OnlyIn(Dist.CLIENT) public class MyBlockRender implements BlockEntityRenderer<MyBlockEntity> { public MyBlockRender(BlockEntityRendererProvider.Context renderManager) { super(); } @Override public void render(MyBlockEntity be, float partialTicks, PoseStack poseStack, MultiBufferSource bufferSource, int combinedLight, int combinedOverlay) { BlockState blockstate = be.getBlockState(); poseStack.pushPose(); if (blockstate.getBlock() == ModBlocks.MY_BLOCK.get()) { float f1 = 45.0F; poseStack.mulPose(Vector3f.YP.rotationDegrees(f1)); poseStack.translate(0.5D, 0.5D, 0.5D); poseStack.scale(-0.6666667F, -0.6666667F, -0.6666667F); } poseStack.popPose(); } }
  14. The blockstate.json doesn’t accept values such as 22.5 and 45. After searching around for few hours and trying to understand how Minecraft sign block works, I came to conclusion that in order to rotate the block by 22.5 increments you would have to create a custom renderer.
  15. Hi! I have a custom block. Now I wanted it to have rotations like standing sign block has. Added IntegerProperty for rotations and all rotations work perfectly fine except the block model. The rotation changes according to the placement (as it should be), but instead of the correct block model I see purple and black squared block. Created the block model with Blockbench, and I think my blockstate.json is also correct: { "variants": { "rotation=0": { "model": "mymodid:block/my_block", "y": 0 }, "rotation=1": { "model": "mymodid:block/my_block", "y": 22.5 }, "rotation=2": { "model": "mymodid:block/my_block", "y": 45 }, "rotation=3": { "model": "mymodid:block/my_block", "y": 67.5 }, "rotation=4": { "model": "mymodid:block/my_block", "y": 90 }, "rotation=5": { "model": "mymodid:block/my_block", "y": 112.5 }, "rotation=6": { "model": "mymodid:block/my_block", "y": 135 }, "rotation=7": { "model": "mymodid:block/my_block", "y": 157.5 }, "rotation=8": { "model": "mymodid:block/my_block", "y": 180 }, "rotation=9": { "model": "mymodid:block/my_block", "y": 202.5 }, "rotation=10": { "model": "mymodid:block/my_block", "y": 225 }, "rotation=11": { "model": "mymodid:block/my_block", "y": 247.5 }, "rotation=12": { "model": "mymodid:block/my_block", "y": 270 }, "rotation=13": { "model": "mymodid:block/my_block", "y": 292.5 }, "rotation=14": { "model": "mymodid:block/my_block", "y": 315 }, "rotation=15": { "model": "mymodid:block/my_block", "y": 337.5 } } } Why is it not working? What am I doing wrong this time? Thanks.
  16. Hi! I'm trying to send some custom network packets from server to client. The packets are sent but I have some problems handling them on client. To avoid arbitrary chuck generation I'm trying to use level#hasChunckAt(pos). It's deprected. Is this the correct thing to use or should I use something else? And it doesn't execute the code in client because I can get the ServerLevel but I need ClientLevel? How can I get it working? Thanks. import java.util.function.Supplier; import com.rinventor.transportmod.core.base.PTMDbg; import net.minecraft.core.BlockPos; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.world.level.Level; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.network.NetworkEvent; public class InformationScreenSyncMessage { public final BlockPos pos; public final String data; public InformationScreenSyncMessage(BlockPos pos, String data) { this.pos = pos; this.data = data; } public InformationScreenSyncMessage(FriendlyByteBuf buffer) { this(buffer.readBlockPos(), buffer.readUtf()); } public void encode(FriendlyByteBuf buffer) { buffer.writeBlockPos(this.pos); buffer.writeUtf(this.data); } public static void handle(InformationScreenSyncMessage msg, Supplier<NetworkEvent.Context> ctx) { ctx.get().enqueueWork(() -> // Make sure it's only executed on the physical client DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> InformationScreenClient.handlePacket(msg, ctx)) ); ctx.get().setPacketHandled(true); } public class InformationScreenClient { @SuppressWarnings("deprecation") public static void handlePacket(InformationScreenSyncMessage msg, Supplier<NetworkEvent.Context> ctx) { Level level = ctx.get().getSender().getLevel(); BlockPos pos = msg.pos; if (level.hasChunkAt(pos)) { if (level.getBlockEntity(pos) instanceof InformationScreenBlockEntity be) { be.data = msg.data; } } } } }
  17. Hi! I have made a custom boolean gamerule. After restating the game though the gamerule is not synced between server and client. Am I registring my gamerule correctly? And how to sync it? Thanks. @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) public class ModGameRules { public static final GameRules.Key<GameRules.BooleanValue> REAL_DAYLIGHT = GameRules.register("realDaylight", GameRules.Category.UPDATES, create(true)); @SuppressWarnings("unchecked") public static Type<GameRules.BooleanValue> create(boolean defaultValue) { try { Method createGameruleMethod = ObfuscationReflectionHelper.findMethod(GameRules.BooleanValue.class, "m_46250_", boolean.class); createGameruleMethod.setAccessible(true); return (Type<GameRules.BooleanValue>) createGameruleMethod.invoke(GameRules.BooleanValue.class, defaultValue); } catch (Exception e) { e.printStackTrace(); } return null; } }
  18. Hi! I have a custom entity that moves around. I can make the entity itself glowing but the surroundings are still not lit when it's night time. If I add a custom invisible light emitting block above the entity everything will be lit around the entity. Now, since the entity moves around it adds the light-emitting blocks int front of it and removes them from behind as it moves. Is there an easier way to do the same thing without the light-emmiting blocks. Is there some lighting system/function maybe built into Minecraft that would be usable in my case? Thanks.
  19. Everything actually worked. It was synced, I was just printing out and display the wrong variable on the screen.
  20. I added the functions to sync on block update but the value is still empty string on client. So the screen's EditBox just shows empty string. When I have written something to the EditBox it will send packet to the server just before closing the screen with the value. Packet handle function on server: public static void set(LevelAccessor world, BlockPos pos, String name) { if (world.getBlockEntity(pos) instanceof StationBlockEntity be) { be.getPersistentData().putString("StationName", name); be.setChanged(); if (world instanceof Level level) { BlockState state = PTMBlock.getBlockState(world, pos.getX(), pos.getY(), pos.getZ()); level.sendBlockUpdated(pos, state, state, 2); } } } And the syncing function in my block entity class: @Override public void load(CompoundTag tag) { super.load(tag); this.name = tag.getString("StationName"); } @Override public void saveAdditional(CompoundTag tag) { super.saveAdditional(tag); tag.putString("StationName", this.name); } @Override public void handleUpdateTag(CompoundTag tag) { load(tag); } @Override public CompoundTag getUpdateTag() { CompoundTag tag = new CompoundTag(); tag.putString("StationName", this.name); return tag; } @Override public Packet<ClientGamePacketListener> getUpdatePacket() { return ClientboundBlockEntityDataPacket.create(this); } @Override public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt) { this.load(pkt.getTag()); } So why is this value still not synced with client? Am I missing something? It's not synced after I reload the world!
  21. Hey. I have created a custom Block entity, which on right click opens a screen. The screen has only 1 EditBox. I now want to save the EditBox value (String) and load it back every time I open the screen again. I've managed to do achieve half of that. When I close the world and open it and open the screen again the EditBox is empty and the BlockEntity has no idea what the String value is. For saving the value I overrided the saveAdditional and Load methods in my BlockEntity class. Why this thing happens? Am I doing something wrong? Thanks. Here's the block entity class code package com.rinventor.transportmod.objects.blockentities.station; import com.rinventor.transportmod.core.init.ModBlockEntities; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.Connection; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.world.WorldlyContainer; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.ContainerData; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; public class StationBlockEntity extends BlockEntity implements WorldlyContainer { private String name; public StationBlockEntity(BlockPos position, BlockState state) { super(ModBlockEntities.STATION_ENTITY.get(), position, state); } @Override public void load(CompoundTag nbt) { super.load(nbt); this.name = nbt.getString("StationName"); } @Override public void saveAdditional(CompoundTag nbt) { super.saveAdditional(nbt); nbt.putString("StationName", this.name); } @Override public ClientboundBlockEntityDataPacket getUpdatePacket() { return ClientboundBlockEntityDataPacket.create(this); } @Override public CompoundTag getUpdateTag() { return this.saveWithFullMetadata(); } @Override public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt) { this.load(pkt.getTag()); } }
  22. I have a custom entity that is animated using GeckoLib. Is it possible to display/render text on that entity's side for example, and how to do that? Thanks.
  23. Thanks, that did the trick. Everything works fine, but it renders the dirt background for some reason. I want to render my own texture and it actually does render below the dirt background. Is there any way to stop the dirt background from rendering? Here's my code: package com.rinventor....; import java.util.ArrayList; import java.util.List; import javax.annotation.Nullable; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.rinventor.transportmod.MyMod; import com.rinventor.transportmod.core.init.ModNetwork; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiComponent; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.ObjectSelectionList; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; public class CScreen8 extends AbstractContainerScreen<CMenu8> { private final Player entity; private final Component data; private CScreen8.LinesList list; String line; List<String> lines; public CScreen8(CMenu8 container, Inventory inventory, Component text) { super(container, inventory, text); this.entity = container.entity; this.imageWidth = 320; this.imageHeight = 240; this.data = text; this.line = ""; this.lines = new ArrayList<String>(List.of("A", "B", "C")); } private static final ResourceLocation texture = new ResourceLocation(MyMod.MOD_ID + ":textures/cmenu.png"); @Override public void render(PoseStack ms, int mouseX, int mouseY, float partialTicks) { this.renderBackground(ms); super.render(ms, mouseX, mouseY, partialTicks); this.renderTooltip(ms, mouseX, mouseY); this.list.render(ms, mouseX, mouseY, partialTicks); } @Override protected void renderBg(PoseStack ms, float partialTicks, int gx, int gy) { RenderSystem.setShaderColor(1, 1, 1, 1); RenderSystem.setShaderTexture(0, texture); GuiComponent.blit(ms, this.leftPos, this.topPos, 0, 0, imageWidth, 198, imageWidth, imageHeight); } @Override public boolean keyPressed(int key, int b, int c) { if (key == 256) { this.minecraft.player.closeContainer(); return true; } return super.keyPressed(key, b, c); } @Override protected void renderLabels(PoseStack ps, int mouseX, int mouseY) { String id = "menu1.transport"; String id = data.getString().trim(); this.font.draw(ps, Component.translatable(id).getString(), 7, 7, -16711792); } @SuppressWarnings("resource") @Override public void onClose() { super.onClose(); Minecraft.getInstance().keyboardHandler.setSendRepeatsToGui(false); } @Override public void init() { super.init(); this.minecraft.keyboardHandler.setSendRepeatsToGui(true); this.list = new CScreen8.LinesList(); this.addWidget(this.list); this.addRenderableWidget(new Button(leftPos + imageWidth - 24, topPos + 4, 20, 20, Component.literal("<-"), e -> { ModNetwork.INSTANCE.sendToServer(new CScreenButtonMessage(7, "")); CScreenButtonMessage.handleButtonAction(entity, 7, ""); })); } @OnlyIn(Dist.CLIENT) class LinesList extends ObjectSelectionList<CScreen8.LinesList.Entry> { LinesList() { super(CScreen8.this.minecraft, CScreen8.this.width-150, CScreen8.this.height-150, 50, CScreen8.this.height - 37, 16); for (String l : CScreen8.this.lines) { this.addEntry(new CScreen8.LinesList.Entry(l)); } } protected boolean isFocused() { return CScreen8.this.getFocused() == this; } public void setSelected(@Nullable CScreen8.LinesList.Entry entry) { super.setSelected(entry); if (entry != null) { CScreen8.this.line = entry.line; } // AFTER SELECTED -> // ModNetwork.INSTANCE.sendToServer(new CScreenButtonMessage(0, "test")); // CScreenButtonMessage.handleButtonAction(entity, 0, "test"); } @OnlyIn(Dist.CLIENT) class Entry extends ObjectSelectionList.Entry<CScreen8.LinesList.Entry> { final String line; public Entry(String entry) { this.line = entry; } public Component getNarration() { return Component.translatable("narrator.select", this.line); } public void render(PoseStack p_95802_, int p_95803_, int p_95804_, int p_95805_, int p_95806_, int p_95807_, int p_95808_, int p_95809_, boolean p_95810_, float p_95811_) { GuiComponent.drawString(p_95802_, CScreen8.this.font, this.line, p_95805_ + 5, p_95804_ + 2, 16777215); } public boolean mouseClicked(double p_95798_, double p_95799_, int p_95800_) { if (p_95800_ == 0) { LinesList.this.setSelected(this); return true; } else { return false; } } } } }
  24. Hi! I have a custom block entity, which has a screen. I have managed to get the EditBox and a CheckBox working. Now I want to add a scrollable list of strings where the player can choose between options and finally select one, which would then open another screen according to the selection made by the player. How to achieve this long list with a scrollbar that would open another screen after selecting? What GUI component should I use for that? And are there any examples available somewhere? Thanks in advance.
  25. Yes but that has a limit of 16 pixels up or down. I need it to be 23 down. But there's probably no way of overriding the 16 pixel limit, is there?
×
×
  • Create New...

Important Information

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