Jump to content

[1.16.5] Beacon Overwrite (Screen Error)


Nyko

Recommended Posts

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 by Nyko
Link to comment
Share on other sites

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

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

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

 

Link to comment
Share on other sites

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 by Beethoven92

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

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 by Beethoven92

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

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?

Link to comment
Share on other sites

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

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

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?

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



×
×
  • Create New...

Important Information

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