Nyko Posted March 2, 2021 Share Posted March 2, 2021 (edited) hey i'm new to minecraft modding, but have been programming more or less good java for some time now. I've read the forge doc and a few topics here in the forum about overwriting and changing vanilla elements. which helped me to overwrite the beacon, but now I have an error that I cannot explain to myself. the beacon works so far (block, item, container, tileentity- / render). only something is wrong with the screen when I put an activation item in the slot and press the Confirm button, the screen is closed and the item drops, and I don't get any effects. what i find strange about it i have taken over the minecraft code of the screen directly and have not changed anything. this is the screen class: public class ModBeaconScreen extends ContainerScreen<ModBeaconContainer> { private static final ResourceLocation BEACON_GUI_TEXTURES = new ResourceLocation("textures/gui/container/beacon.png"); private static final ITextComponent field_243334_B = new TranslationTextComponent("block.minecraft.beacon.primary"); private static final ITextComponent field_243335_C = new TranslationTextComponent("block.minecraft.beacon.secondary"); private ModBeaconScreen.ConfirmButton beaconConfirmButton; private boolean buttonsNotDrawn; private Effect primaryEffect; private Effect secondaryEffect; public ModBeaconScreen(ModBeaconContainer container, PlayerInventory playerInventory, ITextComponent title) { super(container, playerInventory, title); this.xSize = 230; this.ySize = 219; container.addListener(new IContainerListener() { @Override public void sendAllContents(Container containerToSend, NonNullList<ItemStack> itemsList) { } @Override public void sendSlotContents(Container containerToSend, int slotInd, ItemStack stack) { } @Override public void sendWindowProperty(Container containerIn, int varToUpdate, int newValue) { ModBeaconScreen.this.primaryEffect = container.func_216967_f(); ModBeaconScreen.this.secondaryEffect = container.func_216968_g(); ModBeaconScreen.this.buttonsNotDrawn = true; } }); } @Override protected void init() { super.init(); this.beaconConfirmButton = this.addButton(new ModBeaconScreen.ConfirmButton(this.guiLeft + 164, this.guiTop + 107)); this.addButton(new ModBeaconScreen.CancelButton(this.guiLeft + 190, this.guiTop + 107)); this.buttonsNotDrawn = true; this.beaconConfirmButton.active = false; } @Override public void tick() { super.tick(); int i = this.container.func_216969_e(); if (this.buttonsNotDrawn && i >= 0) { this.buttonsNotDrawn = false; for (int j = 0; j <= 2; ++j) { int k = BeaconTileEntity.EFFECTS_LIST[j].length; int l = k * 22 + (k - 1) * 2; for (int i1 = 0; i1 < k; ++i1) { Effect effect = BeaconTileEntity.EFFECTS_LIST[j][i1]; ModBeaconScreen.PowerButton beaconscreen$powerbutton = new ModBeaconScreen.PowerButton( this.guiLeft + 76 + i1 * 24 - l / 2, this.guiTop + 22 + j * 25, effect, true); this.addButton(beaconscreen$powerbutton); if (j >= i) { beaconscreen$powerbutton.active = false; } else if (effect == this.primaryEffect) { beaconscreen$powerbutton.setSelected(true); } } } int k1 = BeaconTileEntity.EFFECTS_LIST[3].length + 1; int l1 = k1 * 22 + (k1 - 1) * 2; for (int i2 = 0; i2 < k1 - 1; ++i2) { Effect effect1 = BeaconTileEntity.EFFECTS_LIST[3][i2]; ModBeaconScreen.PowerButton beaconscreen$powerbutton2 = new ModBeaconScreen.PowerButton( this.guiLeft + 167 + i2 * 24 - l1 / 2, this.guiTop + 47, effect1, false); this.addButton(beaconscreen$powerbutton2); if (3 >= i) { beaconscreen$powerbutton2.active = false; } else if (effect1 == this.secondaryEffect) { beaconscreen$powerbutton2.setSelected(true); } } if (this.primaryEffect != null) { ModBeaconScreen.PowerButton beaconscreen$powerbutton1 = new ModBeaconScreen.PowerButton( this.guiLeft + 167 + (k1 - 1) * 24 - l1 / 2, this.guiTop + 47, this.primaryEffect, false); this.addButton(beaconscreen$powerbutton1); if (3 >= i) { beaconscreen$powerbutton1.active = false; } else if (this.primaryEffect == this.secondaryEffect) { beaconscreen$powerbutton1.setSelected(true); } } } this.beaconConfirmButton.active = this.container.func_216970_h() && this.primaryEffect != null; } @Override protected void drawGuiContainerForegroundLayer(MatrixStack matrixStack, int x, int y) { drawCenteredString(matrixStack, this.font, field_243334_B, 62, 10, 14737632); drawCenteredString(matrixStack, this.font, field_243335_C, 169, 10, 14737632); for (Widget widget : this.buttons) { if (widget.isHovered()) { widget.renderToolTip(matrixStack, x - this.guiLeft, y - this.guiTop); break; } } } @Override @SuppressWarnings("deprecation") protected void drawGuiContainerBackgroundLayer(MatrixStack matrixStack, float partialTicks, int x, int y) { RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); this.minecraft.getTextureManager().bindTexture(BEACON_GUI_TEXTURES); int i = (this.width - this.xSize) / 2; int j = (this.height - this.ySize) / 2; this.blit(matrixStack, i, j, 0, 0, this.xSize, this.ySize); this.itemRenderer.zLevel = 100.0F; this.itemRenderer.renderItemAndEffectIntoGUI(new ItemStack(Items.NETHERITE_INGOT), i + 20, j + 109); this.itemRenderer.renderItemAndEffectIntoGUI(new ItemStack(Items.EMERALD), i + 41, j + 109); this.itemRenderer.renderItemAndEffectIntoGUI(new ItemStack(Items.DIAMOND), i + 41 + 22, j + 109); this.itemRenderer.renderItemAndEffectIntoGUI(new ItemStack(Items.GOLD_INGOT), i + 42 + 44, j + 109); this.itemRenderer.renderItemAndEffectIntoGUI(new ItemStack(Items.IRON_INGOT), i + 42 + 66, j + 109); this.itemRenderer.zLevel = 0.0F; } @Override public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { this.renderBackground(matrixStack); super.render(matrixStack, mouseX, mouseY, partialTicks); this.renderHoveredTooltip(matrixStack, mouseX, mouseY); } abstract static class Button extends AbstractButton { private boolean selected; protected Button(int x, int y) { super(x, y, 22, 22, StringTextComponent.EMPTY); } @Override @SuppressWarnings("deprecation") public void renderButton(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { Minecraft.getInstance().getTextureManager().bindTexture(ModBeaconScreen.BEACON_GUI_TEXTURES); RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); int j = 0; if (!this.active) { j += this.width * 2; } else if (this.selected) { j += this.width * 1; } else if (this.isHovered()) { j += this.width * 3; } this.blit(matrixStack, this.x, this.y, j, 219, this.width, this.height); this.func_230454_a_(matrixStack); } protected abstract void func_230454_a_(MatrixStack p_230454_1_); public boolean isSelected() { return this.selected; } public void setSelected(boolean selectedIn) { this.selected = selectedIn; } } class CancelButton extends ModBeaconScreen.SpriteButton { public CancelButton(int x, int y) { super(x, y, 112, 220); } @Override public void onPress() { ModBeaconScreen.this.minecraft.player.connection.sendPacket(new CCloseWindowPacket(ModBeaconScreen.this.minecraft.player.openContainer.windowId)); ModBeaconScreen.this.minecraft.displayGuiScreen((Screen) null); } @Override public void renderToolTip(MatrixStack matrixStack, int mouseX, int mouseY) { ModBeaconScreen.this.renderTooltip(matrixStack, DialogTexts.GUI_CANCEL, mouseX, mouseY); } } class ConfirmButton extends ModBeaconScreen.SpriteButton { public ConfirmButton(int x, int y) { super(x, y, 90, 220); } @Override public void onPress() { ModBeaconScreen.this.minecraft.getConnection().sendPacket(new CUpdateBeaconPacket(Effect.getId(ModBeaconScreen.this.primaryEffect), Effect.getId(ModBeaconScreen.this.secondaryEffect))); ModBeaconScreen.this.minecraft.player.connection.sendPacket(new CCloseWindowPacket(ModBeaconScreen.this.minecraft.player.openContainer.windowId)); ModBeaconScreen.this.minecraft.displayGuiScreen((Screen) null); } @Override public void renderToolTip(MatrixStack matrixStack, int mouseX, int mouseY) { ModBeaconScreen.this.renderTooltip(matrixStack, DialogTexts.GUI_DONE, mouseX, mouseY); } } class PowerButton extends ModBeaconScreen.Button { private final Effect effect; private final TextureAtlasSprite field_212946_c; private final boolean field_212947_d; private final ITextComponent field_243336_e; public PowerButton(int x, int y, Effect p_i50827_4_, boolean p_i50827_5_) { super(x, y); this.effect = p_i50827_4_; this.field_212946_c = Minecraft.getInstance().getPotionSpriteUploader().getSprite(p_i50827_4_); this.field_212947_d = p_i50827_5_; this.field_243336_e = this.func_243337_a(p_i50827_4_, p_i50827_5_); } private ITextComponent func_243337_a(Effect p_243337_1_, boolean p_243337_2_) { IFormattableTextComponent iformattabletextcomponent = new TranslationTextComponent(p_243337_1_.getName()); if (!p_243337_2_ && p_243337_1_ != Effects.REGENERATION) { iformattabletextcomponent.appendString(" II"); } return iformattabletextcomponent; } @Override public void onPress() { if (!this.isSelected()) { if (this.field_212947_d) { ModBeaconScreen.this.primaryEffect = this.effect; } else { ModBeaconScreen.this.secondaryEffect = this.effect; } ModBeaconScreen.this.buttons.clear(); ModBeaconScreen.this.children.clear(); ModBeaconScreen.this.init(); ModBeaconScreen.this.tick(); } } @Override public void renderToolTip(MatrixStack matrixStack, int mouseX, int mouseY) { ModBeaconScreen.this.renderTooltip(matrixStack, this.field_243336_e, mouseX, mouseY); } @Override protected void func_230454_a_(MatrixStack p_230454_1_) { Minecraft.getInstance().getTextureManager().bindTexture(this.field_212946_c.getAtlasTexture().getTextureLocation()); blit(p_230454_1_, this.x + 2, this.y + 2, this.getBlitOffset(), 18, 18, this.field_212946_c); } } abstract static class SpriteButton extends ModBeaconScreen.Button { private final int u; private final int v; protected SpriteButton(int x, int y, int u, int v) { super(x, y); this.u = u; this.v = v; } @Override protected void func_230454_a_(MatrixStack p_230454_1_) { this.blit(p_230454_1_, this.x + 2, this.y + 2, this.u, this.v, 18, 18); } } } my english is unfortunately not good which is why i use a online translator Edited March 2, 2021 by Nyko Quote Link to comment Share on other sites More sharing options...
Beethoven92 Posted March 2, 2021 Share Posted March 2, 2021 The beacon container uses a proximity check to see if the player is near enough to open the container..unfortunately this check is hardcoded to only work with the vanilla Blocks.BEACON. So if you created your own beacon block this will be different from the vanilla one, and the proximity check will always fail leading to the behavior you described above. You need to override canInteractWith in your ModBeaconContainer (which i suppose directly inherits from the BeaconContainer class?) and allow interaction with your own Beacon block Quote Check out the port of the BetterEnd fabric mod (WIP): https://www.curseforge.com/minecraft/mc-mods/betterend-forge-port Link to comment Share on other sites More sharing options...
Nyko Posted March 3, 2021 Author Share Posted March 3, 2021 8 hours ago, Beethoven92 said: You need to override canInteractWith in your ModBeaconContainer (which i suppose directly inherits from the BeaconContainer class?) and allow interaction with your own Beacon block I have already overwritten this method: This is my container class (there is the method you mean, or is there another one): private final IInventory tileBeacon = new Inventory(1) { @Override public boolean isItemValidForSlot(int index, ItemStack stack) { return stack.getItem().isIn(ItemTags.BEACON_PAYMENT_ITEMS); } @Override public int getInventoryStackLimit() { return 1; } }; private final ModBeaconContainer.BeaconSlot beaconSlot; private final IWorldPosCallable worldPosCallable; private final IIntArray field_216972_f; public ModBeaconContainer(int id, IInventory p_i50099_2_, PacketBuffer extraData) { this(id, p_i50099_2_, new IntArray(3), IWorldPosCallable.DUMMY); } public ModBeaconContainer(int id, IInventory inventory, IIntArray p_i50100_3_, IWorldPosCallable worldPosCallable) { super(ModContainerType.BEACON.get(), id); assertIntArraySize(p_i50100_3_, 3); this.field_216972_f = p_i50100_3_; this.worldPosCallable = worldPosCallable; this.beaconSlot = new ModBeaconContainer.BeaconSlot(this.tileBeacon, 0, 136, 110); this.addSlot(this.beaconSlot); this.trackIntArray(p_i50100_3_); for (int k = 0; k < 3; ++k) { for (int l = 0; l < 9; ++l) { this.addSlot(new Slot(inventory, l + k * 9 + 9, 36 + l * 18, 137 + k * 18)); } } for (int i1 = 0; i1 < 9; ++i1) { this.addSlot(new Slot(inventory, i1, 36 + i1 * 18, 195)); } } @Override public void onContainerClosed(PlayerEntity playerIn) { super.onContainerClosed(playerIn); if (!playerIn.world.isRemote) { ItemStack itemstack = this.beaconSlot.decrStackSize(this.beaconSlot.getSlotStackLimit()); if (!itemstack.isEmpty()) { playerIn.dropItem(itemstack, false); } } } @Override public boolean canInteractWith(PlayerEntity playerIn) { return true; } @Override public void updateProgressBar(int id, int data) { super.updateProgressBar(id, data); this.detectAndSendChanges(); } @Override public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) { ItemStack itemstack = ItemStack.EMPTY; Slot slot = this.inventorySlots.get(index); if (slot != null && slot.getHasStack()) { ItemStack itemstack1 = slot.getStack(); itemstack = itemstack1.copy(); if (index == 0) { if (!this.mergeItemStack(itemstack1, 1, 37, true)) { return ItemStack.EMPTY; } slot.onSlotChange(itemstack1, itemstack); } else if (this.mergeItemStack(itemstack1, 0, 1, false)) { return ItemStack.EMPTY; } else if (index >= 1 && index < 28) { if (!this.mergeItemStack(itemstack1, 28, 37, false)) { return ItemStack.EMPTY; } } else if (index >= 28 && index < 37) { if (!this.mergeItemStack(itemstack1, 1, 28, false)) { return ItemStack.EMPTY; } } else if (!this.mergeItemStack(itemstack1, 1, 37, false)) { return ItemStack.EMPTY; } if (itemstack1.isEmpty()) { slot.putStack(ItemStack.EMPTY); } else { slot.onSlotChanged(); } if (itemstack1.getCount() == itemstack.getCount()) { return ItemStack.EMPTY; } slot.onTake(playerIn, itemstack1); } return itemstack; } @OnlyIn(Dist.CLIENT) public int func_216969_e() { return this.field_216972_f.get(0); } @Nullable @OnlyIn(Dist.CLIENT) public Effect func_216967_f() { return Effect.get(this.field_216972_f.get(1)); } @Nullable @OnlyIn(Dist.CLIENT) public Effect func_216968_g() { return Effect.get(this.field_216972_f.get(2)); } public void func_216966_c(int p_216966_1_, int p_216966_2_) { if (this.beaconSlot.getHasStack()) { this.field_216972_f.set(1, p_216966_1_); this.field_216972_f.set(2, p_216966_2_); this.beaconSlot.decrStackSize(1); } } @OnlyIn(Dist.CLIENT) public boolean func_216970_h() { return !this.tileBeacon.getStackInSlot(0).isEmpty(); } public IWorldPosCallable getWorldPosCallable() { return worldPosCallable; } class BeaconSlot extends Slot { public BeaconSlot(IInventory inventoryIn, int index, int xIn, int yIn) { super(inventoryIn, index, xIn, yIn); } @Override public boolean isItemValid(ItemStack stack) { return stack.getItem().isIn(ItemTags.BEACON_PAYMENT_ITEMS); } @Override public int getSlotStackLimit() { return 1; } } Quote Link to comment Share on other sites More sharing options...
Beethoven92 Posted March 3, 2021 Share Posted March 3, 2021 (edited) I apologize...i misread the part where you say that your custom beacon inventory actually opens fine! Yeah, the proximity check is doing its job, the problem seems to be that when pressing the confirm button you are sending a vanilla CUpdateBeaconPacket, then handled by the server, which will check if your open container is a BeaconContainer. It would be helpful to see the complete code you have, please post a link to your repository Edited March 3, 2021 by Beethoven92 Quote Check out the port of the BetterEnd fabric mod (WIP): https://www.curseforge.com/minecraft/mc-mods/betterend-forge-port Link to comment Share on other sites More sharing options...
Nyko Posted March 3, 2021 Author Share Posted March 3, 2021 4 hours ago, Beethoven92 said: please post a link to your repository this is the repository of my mod https://github.com/Nyko-y/Nyko/tree/master/VanillaEdit/src/main/java/net/nyko Quote Link to comment Share on other sites More sharing options...
Beethoven92 Posted March 3, 2021 Share Posted March 3, 2021 (edited) Yep, thats the problem your ModBeaconContainer is not a BeaconContainer, so the check that server does when handling the beacon packet always fails. This means your confirm button does basically nothing more than just closing the gui Edited March 3, 2021 by Beethoven92 Quote Check out the port of the BetterEnd fabric mod (WIP): https://www.curseforge.com/minecraft/mc-mods/betterend-forge-port Link to comment Share on other sites More sharing options...
Nyko Posted March 4, 2021 Author Share Posted March 4, 2021 11 hours ago, Beethoven92 said: This means your confirm button does basically nothing more than just closing the gui what do I have to change so that the button works correctly or can I remove the CUpdateBeaconPacket? Quote Link to comment Share on other sites More sharing options...
Beethoven92 Posted March 4, 2021 Share Posted March 4, 2021 If your custom beacon container has the same function as the vanilla container why not just having your container inherit from the BeaconContainer class (keep in mind that you would still need to override the proximity check)? This way the server side check when using the confirm button won't fail Quote Check out the port of the BetterEnd fabric mod (WIP): https://www.curseforge.com/minecraft/mc-mods/betterend-forge-port Link to comment Share on other sites More sharing options...
Nyko Posted March 4, 2021 Author Share Posted March 4, 2021 1 hour ago, Beethoven92 said: If your custom beacon container has the same function as the vanilla container why not just having your container inherit from the BeaconContainer class I changed that 1 hour ago, Beethoven92 said: still need to override the proximity check which method? what do I have to overwrite? Quote Link to comment Share on other sites More sharing options...
Beethoven92 Posted March 4, 2021 Share Posted March 4, 2021 The method is canInteractWith 1 Quote Check out the port of the BetterEnd fabric mod (WIP): https://www.curseforge.com/minecraft/mc-mods/betterend-forge-port Link to comment Share on other sites More sharing options...
Nyko Posted March 4, 2021 Author Share Posted March 4, 2021 2 hours ago, Beethoven92 said: The method is canInteractWith okay since i probably misunderstood something. I thought I had to override another method thanks now it works Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.