package com.thebrokenrail.sorcerycraft.client.block; import com.mojang.blaze3d.systems.RenderSystem; import com.thebrokenrail.sorcerycraft.block.CastingTableContainer; import com.thebrokenrail.sorcerycraft.packet.SelectSpellC2SPacket; import com.thebrokenrail.sorcerycraft.spell.Spell; import com.thebrokenrail.sorcerycraft.spell.SpellTag; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.screen.ingame.ContainerScreen; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.item.ItemStack; import net.minecraft.text.Text; import net.minecraft.text.TranslatableText; import net.minecraft.util.Identifier; import net.minecraft.util.math.MathHelper; @Environment(EnvType.CLIENT) public class CastingTableScreen extends ContainerScreen { private static final Identifier TEXTURE = new Identifier("textures/gui/container/villager2.png"); private int selectedIndex; private int indexStartOffset; private boolean scrolling; public CastingTableScreen(CastingTableContainer container, PlayerInventory inventory, Text title) { super(container, inventory, title); containerWidth = 276; } @Override protected void drawForeground(int mouseX, int mouseY) { int j = containerHeight - 94; font.draw(title.asFormattedString(), (float) (49 + this.containerWidth / 2 - font.getStringWidth(title.asFormattedString()) / 2), 6.0F, 4210752); font.draw(playerInventory.getDisplayName().asFormattedString(), 107.0F, (float) j, 4210752); String spells = new TranslatableText("container.sorcerycraft.spells").getString(); font.draw(spells, (float) (5 - font.getStringWidth(spells) / 2 + 48), 6.0F, 4210752); renderXPCost(); } @Override protected void drawBackground(float delta, int mouseX, int mouseY) { RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); assert minecraft != null; minecraft.getTextureManager().bindTexture(TEXTURE); int i = (width - containerWidth) / 2; int j = (height - containerHeight) / 2; blit(i, j, this.getBlitOffset(), 0.0F, 0.0F, containerWidth, containerHeight, 256, 512); } @Override public void render(int mouseX, int mouseY, float delta) { renderBackground(); super.render(mouseX, mouseY, delta); drawMouseoverTooltip(mouseX, mouseY); renderScrollbar(); renderItems(); for (WidgetButtonPage button : buttons) { if (button.isHovered()) { button.renderToolTip(mouseX, mouseY); } button.visible = button.index < container.getRecipes().length; if (button.visible) { Spell spell = container.getRecipes()[button.getIndex() + indexStartOffset]; button.setMessage(SpellTag.getTranslatedSpell(spell.getID(), spell.getLevel()).getString()); button.setFocused((button.getIndex() + indexStartOffset) == selectedIndex); } } } private void renderScrollbar() { Spell[] spells = container.getRecipes(); assert minecraft != null; minecraft.getTextureManager().bindTexture(TEXTURE); int i = (width - containerWidth) / 2; int j = (height - containerHeight) / 2; int k = spells.length + 1 - 7; if (k > 1) { int l = 139 - (27 + (k - 1) * 139 / k); int m = 1 + l / k + 139 / k; int o = Math.min(113, indexStartOffset * m); if (this.indexStartOffset == k - 1) { o = 113; } blit(i + 94, j + 18 + o, getBlitOffset(), 0.0F, 199.0F, 6, 27, 256, 512); } else { blit(i + 94, j + 18, getBlitOffset(), 6.0F, 199.0F, 6, 27, 256, 512); } } private void renderItems() { int i = (width - containerWidth) / 2; int j = (height - containerHeight) / 2; int k = j + 16 + 1; Spell[] spells = container.getRecipes(); for (int x = 0; x < spells.length; x++) { if (!canScroll(spells.length) || (x >= indexStartOffset && x < 7 + indexStartOffset)) { ItemStack itemStack = spells[x].getItemCost(); itemRenderer.zOffset = 100.0F; int n = k + 2; itemRenderer.renderGuiItem(itemStack, i + 5 + 68, n); itemRenderer.renderGuiItemOverlay(font, itemStack, i + 5 + 68, n); itemRenderer.zOffset = 0.0F; k += 20; } } } private void renderXPCost() { if (container.getRecipes().length > 0) { int i = container.getRecipes()[selectedIndex].getXPCost(); int j = 8453920; assert minecraft != null; assert minecraft.player != null; String string = new TranslatableText("container.repair.cost", i).getString(); if (!container.canTakeResult(playerInventory.player)) { j = 16736352; } int x2 = containerWidth - 8; int x1 = x2 - font.getStringWidth(string); fill(x1, 65, x2, 77, 1325400064); font.drawWithShadow(string, (float) x1, 67.0F, j); } } private boolean canScroll(int listSize) { return listSize > 7; } @Override public boolean mouseScrolled(double d, double e, double amount) { int i = container.getRecipes().length; if (this.canScroll(i)) { int j = i - 7; indexStartOffset = (int) ((double) indexStartOffset - amount); indexStartOffset = MathHelper.clamp(indexStartOffset, 0, j); } return true; } @Override public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { int i = container.getRecipes().length; if (scrolling) { int j = y + 18; int k = j + 139; int l = i - 7; float f = ((float) mouseY - (float) j - 13.5F) / ((float) (k - j) - 27.0F); f = f * (float)l + 0.5F; indexStartOffset = MathHelper.clamp((int) f, 0, l); return true; } else { return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); } } @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { scrolling = false; int i = (width - containerWidth) / 2; int j = (height - containerHeight) / 2; if (this.canScroll(container.getRecipes().length) && mouseX > (double)(i + 94) && mouseX < (double) (i + 94 + 6) && mouseY > (double) (j + 18) && mouseY <= (double) (j + 18 + 139 + 1)) { scrolling = true; } return super.mouseClicked(mouseX, mouseY, button); } private void syncRecipeIndex() { container.setIndex(selectedIndex); assert minecraft != null; SelectSpellC2SPacket.send(minecraft, selectedIndex); } private final WidgetButtonPage[] buttons = new WidgetButtonPage[7]; @Override protected void init() { super.init(); int i = (width - containerWidth) / 2; int j = (height - containerHeight) / 2; int k = j + 16 + 2; for (int l = 0; l < 7; ++l) { buttons[l] = addButton(new WidgetButtonPage(i + 5, k, l, (buttonWidget) -> { selectedIndex = ((WidgetButtonPage) buttonWidget).getIndex() + indexStartOffset; syncRecipeIndex(); })); k += 20; } } @Environment(EnvType.CLIENT) private class WidgetButtonPage extends ButtonWidget { final int index; public WidgetButtonPage(int i, int j, int k, PressAction pressAction) { super(i, j, 89, 20, "", pressAction); index = k; visible = false; } @Override public void setFocused(boolean state) { super.setFocused(state); } public int getIndex() { return this.index; } public void renderToolTip(int mouseX, int mouseY) { if (isHovered && container.getRecipes().length > index + indexStartOffset && mouseX > this.x + 65) { ItemStack itemStack = container.getRecipes()[index + indexStartOffset].getItemCost(); if (!itemStack.isEmpty()) { renderTooltip(itemStack, mouseX, mouseY); } } } @Override public void drawCenteredString(TextRenderer textRenderer, String str, int ignored, int y, int color) { drawString(textRenderer, str, x + 5, y, color); } } }