Files
Ascend/src/main/java/net/fretux/ascend/client/screen/StatsScreen.java
T

188 lines
8.8 KiB
Java

package net.fretux.ascend.client.screen;
import com.mojang.blaze3d.systems.RenderSystem;
import net.fretux.ascend.network.PacketHandler;
import net.fretux.ascend.network.ServerboundSpendPointPacket;
import net.fretux.ascend.player.PlayerStatsProvider;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import java.util.HashMap;
import java.util.Map;
public class StatsScreen extends Screen {
private static final int WIDTH = 480;
private static final int HEIGHT = 266;
private static final int PADDING = 12;
private static final int COLUMN_GAP = 8;
private static final int CARD_GAP = 4;
private static final int CARD_HEIGHT = 40;
private static final int CARDS_TOP = 64;
private static final int CARD_WIDTH = (WIDTH - PADDING * 2 - COLUMN_GAP) / 2;
private static final String[] ATTRIBUTES = {
"vigor", "mind", "strength", "agility",
"intelligence", "willpower", "charisma", "arcane"
};
private static final Map<String, Integer> ATTRIBUTE_COLORS = Map.of(
"vigor", 0xFFD85C5C,
"mind", 0xFF6699E8,
"strength", 0xFFD78445,
"agility", 0xFF71C988,
"intelligence", 0xFF9A7BE8,
"willpower", 0xFF79B9C8,
"charisma", 0xFFE28AB8,
"arcane", 0xFFC878E0
);
private static final Map<String, Component> ATTRIBUTE_TOOLTIPS = new HashMap<>();
static {
for (String key : ATTRIBUTES) {
ATTRIBUTE_TOOLTIPS.put(key, Component.translatable("ascend.attribute." + key + ".desc"));
}
}
private final Minecraft minecraft = Minecraft.getInstance();
private final Map<String, Button> plusButtons = new HashMap<>();
private int leftPos;
private int topPos;
private String hoveredAttributeKey;
public StatsScreen() {
super(Component.translatable("ascend.stats.title"));
}
@Override
protected void init() {
super.init();
leftPos = (width - WIDTH) / 2;
topPos = (height - HEIGHT) / 2;
plusButtons.clear();
clearWidgets();
for (int index = 0; index < ATTRIBUTES.length; index++) {
String attribute = ATTRIBUTES[index];
int column = index % 2;
int row = index / 2;
int cardX = leftPos + PADDING + column * (CARD_WIDTH + COLUMN_GAP);
int cardY = topPos + CARDS_TOP + row * (CARD_HEIGHT + CARD_GAP);
Button plus = Button.builder(Component.literal("+"), button ->
PacketHandler.INSTANCE.sendToServer(new ServerboundSpendPointPacket(attribute)))
.bounds(cardX + CARD_WIDTH - 30, cardY + 5, 22, 18)
.build();
addRenderableWidget(plus);
plusButtons.put(attribute, plus);
}
addRenderableWidget(Button.builder(Component.translatable("gui.done"), button -> onClose())
.bounds(leftPos + WIDTH / 2 - 45, topPos + HEIGHT - 24, 90, 18)
.build());
}
@Override
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
renderBackground(graphics);
drawWindow(graphics);
hoveredAttributeKey = null;
if (minecraft.player != null) {
minecraft.player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
drawProgression(graphics, stats.getAscendLevel(), stats.getMaxAscendLevel(),
stats.getAscendXP(), stats.getXPToNextAscendLevel(), stats.getKnowledge(), stats.getUnspentPoints());
for (int index = 0; index < ATTRIBUTES.length; index++) {
String attribute = ATTRIBUTES[index];
int column = index % 2;
int row = index / 2;
int cardX = leftPos + PADDING + column * (CARD_WIDTH + COLUMN_GAP);
int cardY = topPos + CARDS_TOP + row * (CARD_HEIGHT + CARD_GAP);
int value = stats.getAttributeLevel(attribute);
boolean hovered = mouseX >= cardX && mouseX < cardX + CARD_WIDTH
&& mouseY >= cardY && mouseY < cardY + CARD_HEIGHT;
drawAttributeCard(graphics, attribute, value, stats.getMaxAttributePoints(), cardX, cardY, hovered);
if (hovered) hoveredAttributeKey = attribute;
Button plus = plusButtons.get(attribute);
if (plus != null) {
int cost = stats.getCostToUpgrade(attribute);
plus.active = stats.getUnspentPoints() >= cost && value < stats.getMaxAttributePoints();
plus.setMessage(value >= stats.getMaxAttributePoints()
? Component.literal("✓") : Component.literal("+"));
}
}
});
}
super.render(graphics, mouseX, mouseY, partialTicks);
if (hoveredAttributeKey != null) {
graphics.renderTooltip(font, ATTRIBUTE_TOOLTIPS.get(hoveredAttributeKey), mouseX, mouseY);
}
}
private void drawWindow(GuiGraphics graphics) {
RenderSystem.enableBlend();
graphics.fill(leftPos - 6, topPos - 6, leftPos + WIDTH + 6, topPos + HEIGHT + 6, 0xCC07070C);
graphics.fill(leftPos - 3, topPos - 3, leftPos + WIDTH + 3, topPos + HEIGHT + 3, 0xFF30253C);
graphics.fill(leftPos, topPos, leftPos + WIDTH, topPos + HEIGHT, 0xF016131E);
graphics.fill(leftPos, topPos, leftPos + WIDTH, topPos + 20, 0xFF2A2036);
graphics.fill(leftPos, topPos + 20, leftPos + WIDTH, topPos + 21, 0xFF655275);
RenderSystem.disableBlend();
graphics.drawCenteredString(font, title, leftPos + WIDTH / 2, topPos + 6, 0xFFF4EAFB);
}
private void drawProgression(GuiGraphics graphics, int level, int maxLevel, int xp, int xpNext,
int knowledge, int unspent) {
int panelX = leftPos + PADDING;
int panelY = topPos + 26;
int panelWidth = WIDTH - PADDING * 2;
graphics.fill(panelX, panelY, panelX + panelWidth, panelY + 31, 0xAA211C29);
graphics.fill(panelX, panelY, panelX + 3, panelY + 31, 0xFFCFB060);
graphics.drawString(font, Component.translatable("ascend.stats.level", level, maxLevel),
panelX + 9, panelY + 5, 0xFFFFDF78, false);
graphics.drawString(font, Component.translatable("ascend.stats.knowledge", knowledge),
panelX + 112, panelY + 5, 0xFFA9C7FF, false);
Component points = Component.translatable("ascend.stats.unspent", unspent);
int pointsWidth = font.width(points);
int pointsX = panelX + panelWidth - pointsWidth - 9;
graphics.fill(pointsX - 5, panelY + 2, panelX + panelWidth - 4, panelY + 16, 0x663D623D);
graphics.drawString(font, points, pointsX, panelY + 5, unspent > 0 ? 0xFF87F58D : 0xFF9D9D9D, false);
int barX = panelX + 9;
int barY = panelY + 20;
int barWidth = panelWidth - 18;
graphics.fill(barX, barY, barX + barWidth, barY + 5, 0xFF0C0A10);
double progress = level >= maxLevel || xpNext <= 0 ? 1.0 : Math.min(1.0, (double) xp / xpNext);
graphics.fill(barX + 1, barY + 1, barX + 1 + (int) ((barWidth - 2) * progress), barY + 4, 0xFF8E68C3);
Component xpLabel = level >= maxLevel ? Component.translatable("ascend.stats.xp_max")
: Component.translatable("ascend.stats.xp", xp, xpNext);
graphics.drawCenteredString(font, xpLabel, barX + barWidth / 2, barY - 2, 0xFFC9C1D0);
}
private void drawAttributeCard(GuiGraphics graphics, String attribute, int value, int maximum,
int x, int y, boolean hovered) {
int accent = ATTRIBUTE_COLORS.getOrDefault(attribute, 0xFFFFFFFF);
graphics.fill(x, y, x + CARD_WIDTH, y + CARD_HEIGHT, hovered ? 0xE0332B3D : 0xC925202F);
graphics.fill(x, y, x + 3, y + CARD_HEIGHT, accent);
graphics.fill(x + 3, y, x + CARD_WIDTH, y + 1, hovered ? 0x667F6B8C : 0x334C4057);
graphics.drawString(font, Component.translatable("ascend.attribute." + attribute),
x + 9, y + 7, 0xFFF1ECF4, false);
Component valueLabel = Component.literal(value + " / " + maximum);
int valueX = x + CARD_WIDTH - 38 - font.width(valueLabel);
graphics.drawString(font, valueLabel, valueX, y + 7, value >= maximum ? 0xFFFFD66B : 0xFFC9C1D0, false);
graphics.drawString(font, Component.translatable("ascend.attribute." + attribute + ".short"),
x + 9, y + 26, 0xFF9F98A8, false);
}
@Override
public boolean isPauseScreen() {
return false;
}
}