Revamp the entire skillset and rebalance everything.

This commit is contained in:
2026-08-24 20:55:56 +02:00
parent 4f51decfca
commit e36fc74a1f
22 changed files with 592 additions and 1207 deletions
@@ -14,26 +14,29 @@ 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 int WIDTH = 220;
private static final int HEIGHT = 240;
private int leftPos;
private int topPos;
private final Minecraft mc = Minecraft.getInstance();
private final Map<String, Button> plusButtons = new HashMap<>();
private String hoveredAttributeKey = null;
public StatsScreen() {
super(Component.literal("Ascend Stats"));
}
private static final String[] ATTRIBUTES = new String[]{
"strength", "agility", "fortitude", "intelligence",
"willpower", "charisma",
"light_scaling", "medium_scaling", "heavy_scaling", "magic_scaling"
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 {
@@ -42,97 +45,141 @@ public class StatsScreen extends Screen {
}
}
@Override
protected void init() {
super.init();
this.leftPos = (this.width - WIDTH) / 2;
this.topPos = (this.height - HEIGHT) / 2;
this.plusButtons.clear();
this.clearWidgets();
int y = topPos + 55;
for (String attr : ATTRIBUTES) {
final String key = attr;
Button plus = Button.builder(Component.literal("+"), (button) -> {
PacketHandler.INSTANCE.sendToServer(new ServerboundSpendPointPacket(key));
})
.bounds(leftPos + WIDTH - 40, y - 6, 30, 18)
.build();
this.addRenderableWidget(plus);
this.plusButtons.put(key, plus);
y += 16;
}
Button done = Button.builder(Component.translatable("gui.done"), (btn) -> onClose())
.bounds(leftPos + WIDTH / 2 - 40, topPos + HEIGHT - 24, 80, 20)
.build();
this.addRenderableWidget(done);
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
public void render(GuiGraphics gui, int mouseX, int mouseY, float partialTicks) {
this.renderBackground(gui);
RenderSystem.enableBlend();
gui.fill(leftPos - 8, topPos - 8, leftPos + WIDTH + 8, topPos + HEIGHT + 8, 0xDD0C0B12);
gui.fill(leftPos - 4, topPos - 4, leftPos + WIDTH + 4, topPos + HEIGHT + 4, 0xE0181422);
gui.fill(leftPos - 4, topPos - 4, leftPos + WIDTH + 4, topPos + 20, 0xFF2A2036);
gui.fill(leftPos - 4, topPos + 20, leftPos + WIDTH + 4, topPos + 21, 0x66FFFFFF);
RenderSystem.disableBlend();
gui.drawCenteredString(this.font, Component.translatable("ascend.stats.title"), this.width / 2, topPos + 6, 0xFFFFFF);
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 (mc.player != null) {
mc.player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
int level = stats.getAscendLevel();
int maxLevel = stats.getMaxAscendLevel();
int xp = stats.getAscendXP();
int xpNext = stats.getXPToNextAscendLevel();
int unspent = stats.getUnspentPoints();
gui.drawString(font, Component.translatable("ascend.stats.level", level, maxLevel), leftPos + 10, topPos + 28, 0xFFE27D);
if (level < maxLevel) {
gui.drawString(font, Component.translatable("ascend.stats.xp", xp, xpNext), leftPos + 10, topPos + 40, 0xB4B4C8);
} else {
gui.drawString(font, Component.translatable("ascend.stats.xp_max"), leftPos + 10, topPos + 40, 0xB4B4C8);
}
int unspentLabelWidth = font.width("Unspent Points: " + unspent);
int unspentX = leftPos + WIDTH - 10 - unspentLabelWidth;
gui.fill(unspentX - 6, topPos + 24, leftPos + WIDTH - 4, topPos + 38, 0x662D3B1E);
gui.drawString(font, Component.translatable("ascend.stats.unspent", unspent),
unspentX, topPos + 28, 0x8CFF8C);
int y = topPos + 64;
for (String key : ATTRIBUTES) {
int attrLevel = stats.getAttributeLevel(key);
int cost = stats.getCostToUpgrade(key);
Component name = Component.translatable("ascend.attribute." + key);
Component label = Component.translatable("ascend.attribute.display", name, attrLevel);
int labelX = leftPos + 10;
gui.drawString(font, label, labelX, y, 0xE6E6F2);
Button plus = plusButtons.get(key);
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) {
plus.setX(leftPos + WIDTH - 40);
plus.setY(y - 6);
plus.active = (unspent >= cost);
plus.setMessage(Component.literal("+" + cost));
int cost = stats.getCostToUpgrade(attribute);
plus.active = stats.getUnspentPoints() >= cost && value < stats.getMaxAttributePoints();
plus.setMessage(value >= stats.getMaxAttributePoints()
? Component.literal("✓") : Component.literal("+"));
}
int labelWidth = font.width(label);
if (mouseX >= labelX && mouseX <= labelX + labelWidth
&& mouseY >= y && mouseY <= y + font.lineHeight) {
hoveredAttributeKey = key;
}
y += 16;
}
});
}
super.render(gui, mouseX, mouseY, partialTicks);
super.render(graphics, mouseX, mouseY, partialTicks);
if (hoveredAttributeKey != null) {
Component tooltip = ATTRIBUTE_TOOLTIPS.get(hoveredAttributeKey);
if (tooltip != null) {
gui.renderTooltip(this.font, tooltip, mouseX, mouseY);
}
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;