324 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			324 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.client.gui.screens.inventory;
 | |
| 
 | |
| import com.google.common.collect.Lists;
 | |
| import java.util.List;
 | |
| import java.util.Optional;
 | |
| import net.fabricmc.api.EnvType;
 | |
| import net.fabricmc.api.Environment;
 | |
| import net.minecraft.client.gui.Gui;
 | |
| import net.minecraft.client.gui.GuiGraphics;
 | |
| import net.minecraft.client.gui.components.AbstractButton;
 | |
| import net.minecraft.client.gui.components.AbstractWidget;
 | |
| import net.minecraft.client.gui.components.Tooltip;
 | |
| import net.minecraft.client.gui.narration.NarrationElementOutput;
 | |
| import net.minecraft.client.renderer.RenderPipelines;
 | |
| import net.minecraft.core.Holder;
 | |
| import net.minecraft.network.chat.CommonComponents;
 | |
| import net.minecraft.network.chat.Component;
 | |
| import net.minecraft.network.chat.MutableComponent;
 | |
| import net.minecraft.network.protocol.game.ServerboundSetBeaconPacket;
 | |
| import net.minecraft.resources.ResourceLocation;
 | |
| import net.minecraft.world.effect.MobEffect;
 | |
| import net.minecraft.world.entity.player.Inventory;
 | |
| import net.minecraft.world.inventory.AbstractContainerMenu;
 | |
| import net.minecraft.world.inventory.BeaconMenu;
 | |
| import net.minecraft.world.inventory.ContainerListener;
 | |
| import net.minecraft.world.item.ItemStack;
 | |
| import net.minecraft.world.item.Items;
 | |
| import net.minecraft.world.level.block.entity.BeaconBlockEntity;
 | |
| import org.jetbrains.annotations.Nullable;
 | |
| 
 | |
| @Environment(EnvType.CLIENT)
 | |
| public class BeaconScreen extends AbstractContainerScreen<BeaconMenu> {
 | |
| 	private static final ResourceLocation BEACON_LOCATION = ResourceLocation.withDefaultNamespace("textures/gui/container/beacon.png");
 | |
| 	static final ResourceLocation BUTTON_DISABLED_SPRITE = ResourceLocation.withDefaultNamespace("container/beacon/button_disabled");
 | |
| 	static final ResourceLocation BUTTON_SELECTED_SPRITE = ResourceLocation.withDefaultNamespace("container/beacon/button_selected");
 | |
| 	static final ResourceLocation BUTTON_HIGHLIGHTED_SPRITE = ResourceLocation.withDefaultNamespace("container/beacon/button_highlighted");
 | |
| 	static final ResourceLocation BUTTON_SPRITE = ResourceLocation.withDefaultNamespace("container/beacon/button");
 | |
| 	static final ResourceLocation CONFIRM_SPRITE = ResourceLocation.withDefaultNamespace("container/beacon/confirm");
 | |
| 	static final ResourceLocation CANCEL_SPRITE = ResourceLocation.withDefaultNamespace("container/beacon/cancel");
 | |
| 	private static final Component PRIMARY_EFFECT_LABEL = Component.translatable("block.minecraft.beacon.primary");
 | |
| 	private static final Component SECONDARY_EFFECT_LABEL = Component.translatable("block.minecraft.beacon.secondary");
 | |
| 	private final List<BeaconScreen.BeaconButton> beaconButtons = Lists.<BeaconScreen.BeaconButton>newArrayList();
 | |
| 	@Nullable
 | |
| 	Holder<MobEffect> primary;
 | |
| 	@Nullable
 | |
| 	Holder<MobEffect> secondary;
 | |
| 
 | |
| 	public BeaconScreen(BeaconMenu menu, Inventory playerInventory, Component title) {
 | |
| 		super(menu, playerInventory, title);
 | |
| 		this.imageWidth = 230;
 | |
| 		this.imageHeight = 219;
 | |
| 		menu.addSlotListener(new ContainerListener() {
 | |
| 			@Override
 | |
| 			public void slotChanged(AbstractContainerMenu containerToSend, int dataSlotIndex, ItemStack stack) {
 | |
| 			}
 | |
| 
 | |
| 			@Override
 | |
| 			public void dataChanged(AbstractContainerMenu containerMenu, int dataSlotIndex, int value) {
 | |
| 				BeaconScreen.this.primary = menu.getPrimaryEffect();
 | |
| 				BeaconScreen.this.secondary = menu.getSecondaryEffect();
 | |
| 			}
 | |
| 		});
 | |
| 	}
 | |
| 
 | |
| 	private <T extends AbstractWidget & BeaconScreen.BeaconButton> void addBeaconButton(T beaconButton) {
 | |
| 		this.addRenderableWidget(beaconButton);
 | |
| 		this.beaconButtons.add(beaconButton);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected void init() {
 | |
| 		super.init();
 | |
| 		this.beaconButtons.clear();
 | |
| 		this.addBeaconButton(new BeaconScreen.BeaconConfirmButton(this.leftPos + 164, this.topPos + 107));
 | |
| 		this.addBeaconButton(new BeaconScreen.BeaconCancelButton(this.leftPos + 190, this.topPos + 107));
 | |
| 
 | |
| 		for (int i = 0; i <= 2; i++) {
 | |
| 			int j = ((List)BeaconBlockEntity.BEACON_EFFECTS.get(i)).size();
 | |
| 			int k = j * 22 + (j - 1) * 2;
 | |
| 
 | |
| 			for (int l = 0; l < j; l++) {
 | |
| 				Holder<MobEffect> holder = (Holder<MobEffect>)((List)BeaconBlockEntity.BEACON_EFFECTS.get(i)).get(l);
 | |
| 				BeaconScreen.BeaconPowerButton beaconPowerButton = new BeaconScreen.BeaconPowerButton(
 | |
| 					this.leftPos + 76 + l * 24 - k / 2, this.topPos + 22 + i * 25, holder, true, i
 | |
| 				);
 | |
| 				beaconPowerButton.active = false;
 | |
| 				this.addBeaconButton(beaconPowerButton);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		int i = 3;
 | |
| 		int j = ((List)BeaconBlockEntity.BEACON_EFFECTS.get(3)).size() + 1;
 | |
| 		int k = j * 22 + (j - 1) * 2;
 | |
| 
 | |
| 		for (int l = 0; l < j - 1; l++) {
 | |
| 			Holder<MobEffect> holder = (Holder<MobEffect>)((List)BeaconBlockEntity.BEACON_EFFECTS.get(3)).get(l);
 | |
| 			BeaconScreen.BeaconPowerButton beaconPowerButton = new BeaconScreen.BeaconPowerButton(
 | |
| 				this.leftPos + 167 + l * 24 - k / 2, this.topPos + 47, holder, false, 3
 | |
| 			);
 | |
| 			beaconPowerButton.active = false;
 | |
| 			this.addBeaconButton(beaconPowerButton);
 | |
| 		}
 | |
| 
 | |
| 		Holder<MobEffect> holder2 = (Holder<MobEffect>)((List)BeaconBlockEntity.BEACON_EFFECTS.get(0)).get(0);
 | |
| 		BeaconScreen.BeaconPowerButton beaconPowerButton2 = new BeaconScreen.BeaconUpgradePowerButton(
 | |
| 			this.leftPos + 167 + (j - 1) * 24 - k / 2, this.topPos + 47, holder2
 | |
| 		);
 | |
| 		beaconPowerButton2.visible = false;
 | |
| 		this.addBeaconButton(beaconPowerButton2);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void containerTick() {
 | |
| 		super.containerTick();
 | |
| 		this.updateButtons();
 | |
| 	}
 | |
| 
 | |
| 	void updateButtons() {
 | |
| 		int i = this.menu.getLevels();
 | |
| 		this.beaconButtons.forEach(beaconButton -> beaconButton.updateStatus(i));
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected void renderLabels(GuiGraphics guiGraphics, int mouseX, int mouseY) {
 | |
| 		guiGraphics.drawCenteredString(this.font, PRIMARY_EFFECT_LABEL, 62, 10, -2039584);
 | |
| 		guiGraphics.drawCenteredString(this.font, SECONDARY_EFFECT_LABEL, 169, 10, -2039584);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected void renderBg(GuiGraphics guiGraphics, float partialTick, int mouseX, int mouseY) {
 | |
| 		int i = (this.width - this.imageWidth) / 2;
 | |
| 		int j = (this.height - this.imageHeight) / 2;
 | |
| 		guiGraphics.blit(RenderPipelines.GUI_TEXTURED, BEACON_LOCATION, i, j, 0.0F, 0.0F, this.imageWidth, this.imageHeight, 256, 256);
 | |
| 		guiGraphics.renderItem(new ItemStack(Items.NETHERITE_INGOT), i + 20, j + 109);
 | |
| 		guiGraphics.renderItem(new ItemStack(Items.EMERALD), i + 41, j + 109);
 | |
| 		guiGraphics.renderItem(new ItemStack(Items.DIAMOND), i + 41 + 22, j + 109);
 | |
| 		guiGraphics.renderItem(new ItemStack(Items.GOLD_INGOT), i + 42 + 44, j + 109);
 | |
| 		guiGraphics.renderItem(new ItemStack(Items.IRON_INGOT), i + 42 + 66, j + 109);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
 | |
| 		super.render(guiGraphics, mouseX, mouseY, partialTick);
 | |
| 		this.renderTooltip(guiGraphics, mouseX, mouseY);
 | |
| 	}
 | |
| 
 | |
| 	@Environment(EnvType.CLIENT)
 | |
| 	interface BeaconButton {
 | |
| 		void updateStatus(int beaconTier);
 | |
| 	}
 | |
| 
 | |
| 	@Environment(EnvType.CLIENT)
 | |
| 	class BeaconCancelButton extends BeaconScreen.BeaconSpriteScreenButton {
 | |
| 		public BeaconCancelButton(final int x, final int y) {
 | |
| 			super(x, y, BeaconScreen.CANCEL_SPRITE, CommonComponents.GUI_CANCEL);
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void onPress() {
 | |
| 			BeaconScreen.this.minecraft.player.closeContainer();
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void updateStatus(int beaconTier) {
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Environment(EnvType.CLIENT)
 | |
| 	class BeaconConfirmButton extends BeaconScreen.BeaconSpriteScreenButton {
 | |
| 		public BeaconConfirmButton(final int x, final int y) {
 | |
| 			super(x, y, BeaconScreen.CONFIRM_SPRITE, CommonComponents.GUI_DONE);
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void onPress() {
 | |
| 			BeaconScreen.this.minecraft
 | |
| 				.getConnection()
 | |
| 				.send(new ServerboundSetBeaconPacket(Optional.ofNullable(BeaconScreen.this.primary), Optional.ofNullable(BeaconScreen.this.secondary)));
 | |
| 			BeaconScreen.this.minecraft.player.closeContainer();
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void updateStatus(int beaconTier) {
 | |
| 			this.active = BeaconScreen.this.menu.hasPayment() && BeaconScreen.this.primary != null;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Environment(EnvType.CLIENT)
 | |
| 	class BeaconPowerButton extends BeaconScreen.BeaconScreenButton {
 | |
| 		private final boolean isPrimary;
 | |
| 		protected final int tier;
 | |
| 		private Holder<MobEffect> effect;
 | |
| 		private ResourceLocation sprite;
 | |
| 
 | |
| 		public BeaconPowerButton(final int x, final int y, final Holder<MobEffect> effect, final boolean isPrimary, final int tier) {
 | |
| 			super(x, y);
 | |
| 			this.isPrimary = isPrimary;
 | |
| 			this.tier = tier;
 | |
| 			this.setEffect(effect);
 | |
| 		}
 | |
| 
 | |
| 		protected void setEffect(Holder<MobEffect> effect) {
 | |
| 			this.effect = effect;
 | |
| 			this.sprite = Gui.getMobEffectSprite(effect);
 | |
| 			this.setTooltip(Tooltip.create(this.createEffectDescription(effect), null));
 | |
| 		}
 | |
| 
 | |
| 		protected MutableComponent createEffectDescription(Holder<MobEffect> effect) {
 | |
| 			return Component.translatable(effect.value().getDescriptionId());
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void onPress() {
 | |
| 			if (!this.isSelected()) {
 | |
| 				if (this.isPrimary) {
 | |
| 					BeaconScreen.this.primary = this.effect;
 | |
| 				} else {
 | |
| 					BeaconScreen.this.secondary = this.effect;
 | |
| 				}
 | |
| 
 | |
| 				BeaconScreen.this.updateButtons();
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		protected void renderIcon(GuiGraphics guiGraphics) {
 | |
| 			guiGraphics.blitSprite(RenderPipelines.GUI_TEXTURED, this.sprite, this.getX() + 2, this.getY() + 2, 18, 18);
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void updateStatus(int beaconTier) {
 | |
| 			this.active = this.tier < beaconTier;
 | |
| 			this.setSelected(this.effect.equals(this.isPrimary ? BeaconScreen.this.primary : BeaconScreen.this.secondary));
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		protected MutableComponent createNarrationMessage() {
 | |
| 			return this.createEffectDescription(this.effect);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Environment(EnvType.CLIENT)
 | |
| 	abstract static class BeaconScreenButton extends AbstractButton implements BeaconScreen.BeaconButton {
 | |
| 		private boolean selected;
 | |
| 
 | |
| 		protected BeaconScreenButton(int x, int y) {
 | |
| 			super(x, y, 22, 22, CommonComponents.EMPTY);
 | |
| 		}
 | |
| 
 | |
| 		protected BeaconScreenButton(int x, int y, Component message) {
 | |
| 			super(x, y, 22, 22, message);
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
 | |
| 			ResourceLocation resourceLocation;
 | |
| 			if (!this.active) {
 | |
| 				resourceLocation = BeaconScreen.BUTTON_DISABLED_SPRITE;
 | |
| 			} else if (this.selected) {
 | |
| 				resourceLocation = BeaconScreen.BUTTON_SELECTED_SPRITE;
 | |
| 			} else if (this.isHoveredOrFocused()) {
 | |
| 				resourceLocation = BeaconScreen.BUTTON_HIGHLIGHTED_SPRITE;
 | |
| 			} else {
 | |
| 				resourceLocation = BeaconScreen.BUTTON_SPRITE;
 | |
| 			}
 | |
| 
 | |
| 			guiGraphics.blitSprite(RenderPipelines.GUI_TEXTURED, resourceLocation, this.getX(), this.getY(), this.width, this.height);
 | |
| 			this.renderIcon(guiGraphics);
 | |
| 		}
 | |
| 
 | |
| 		protected abstract void renderIcon(GuiGraphics guiGraphics);
 | |
| 
 | |
| 		public boolean isSelected() {
 | |
| 			return this.selected;
 | |
| 		}
 | |
| 
 | |
| 		public void setSelected(boolean selected) {
 | |
| 			this.selected = selected;
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void updateWidgetNarration(NarrationElementOutput narrationElementOutput) {
 | |
| 			this.defaultButtonNarrationText(narrationElementOutput);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Environment(EnvType.CLIENT)
 | |
| 	abstract static class BeaconSpriteScreenButton extends BeaconScreen.BeaconScreenButton {
 | |
| 		private final ResourceLocation sprite;
 | |
| 
 | |
| 		protected BeaconSpriteScreenButton(int x, int y, ResourceLocation sprite, Component message) {
 | |
| 			super(x, y, message);
 | |
| 			this.sprite = sprite;
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		protected void renderIcon(GuiGraphics guiGraphics) {
 | |
| 			guiGraphics.blitSprite(RenderPipelines.GUI_TEXTURED, this.sprite, this.getX() + 2, this.getY() + 2, 18, 18);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Environment(EnvType.CLIENT)
 | |
| 	class BeaconUpgradePowerButton extends BeaconScreen.BeaconPowerButton {
 | |
| 		public BeaconUpgradePowerButton(final int x, final int y, final Holder<MobEffect> effect) {
 | |
| 			super(x, y, effect, false, 3);
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		protected MutableComponent createEffectDescription(Holder<MobEffect> effect) {
 | |
| 			return Component.translatable(effect.value().getDescriptionId()).append(" II");
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void updateStatus(int beaconTier) {
 | |
| 			if (BeaconScreen.this.primary != null) {
 | |
| 				this.visible = true;
 | |
| 				this.setEffect(BeaconScreen.this.primary);
 | |
| 				super.updateStatus(beaconTier);
 | |
| 			} else {
 | |
| 				this.visible = false;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 |