Added Quests and Real Settings (yay)

This commit is contained in:
2026-07-11 09:53:19 +02:00
parent 596612880b
commit d3fc829dee
12 changed files with 666 additions and 150 deletions
@@ -0,0 +1,156 @@
package de.fullrisk.citrusDev.UI;
import io.wispforest.owo.ui.component.UIComponents;
import io.wispforest.owo.ui.container.FlowLayout;
import io.wispforest.owo.ui.container.UIContainers;
import io.wispforest.owo.ui.core.*;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.FontDescription;
import de.fullrisk.citrusDev.client.PlaytimeTracker;
import java.util.List;
public class QuestsPanel {
private static final int ACCENT = 0xbaff86;
private record QuestData(String title, String description, int requiredPlaytime) {
boolean isUnlocked() {
return PlaytimeTracker.getCurrentPlaytimeSeconds() >= requiredPlaytime;
}
}
public static void build(FlowLayout content, int contentWidth, int contentHeight) {
List<QuestData> quests = quests();
int playtime = PlaytimeTracker.getCurrentPlaytimeSeconds();
int maxPlaytime = 360;
int progress = Math.min(playtime * 100 / maxPlaytime, 100);
int barWidth = contentWidth - 8;
long unlockedCount = quests.stream().filter(QuestData::isUnlocked).count();
// --- status row: playtime + percentage ---
FlowLayout statusBar = UIContainers.horizontalFlow(Sizing.fixed(barWidth), Sizing.fixed(20));
statusBar.gap(4);
statusBar.padding(Insets.of(4));
statusBar.verticalAlignment(VerticalAlignment.CENTER);
statusBar.horizontalAlignment(HorizontalAlignment.LEFT);
statusBar.surface(MyScreen.GLASS_PANEL);
statusBar.child(UIComponents.label(Component.literal("Playtime: " + formatPlaytime(playtime)))
.color(Color.ofRgb(0xFFFFFF)));
statusBar.child(UIComponents.spacer());
statusBar.child(UIComponents.label(Component.literal(progress + "%"))
.color(Color.ofRgb(ACCENT)));
content.child(statusBar);
// --- progress bar ---
FlowLayout barBg = UIContainers.horizontalFlow(Sizing.fixed(barWidth), Sizing.fixed(6));
barBg.surface(Surface.flat(0x30FFFFFF).and(Surface.outline(0x30FFFFFF)));
barBg.horizontalAlignment(HorizontalAlignment.LEFT);
barBg.gap(0);
barBg.padding(Insets.of(0));
int fillWidth = Math.max(barWidth * progress / 100, progress > 0 ? 2 : 0);
FlowLayout barFill = UIContainers.horizontalFlow(Sizing.fixed(fillWidth), Sizing.fixed(6));
barFill.surface(Surface.flat(0xFF000000 | ACCENT));
barBg.child(barFill);
content.child(barBg);
// --- unlocked count summary ---
FlowLayout summaryRow = UIContainers.horizontalFlow(Sizing.fixed(barWidth), Sizing.content());
summaryRow.padding(Insets.of(3, 0, 2, 2));
summaryRow.child(UIComponents.label(
Component.literal("Quests " + unlockedCount + "/" + quests.size())
.withStyle(style -> style.withFont(new FontDescription.Resource(MyScreen.MC_FIVE))))
.color(Color.ofRgb(0xa3a3ac)));
content.child(summaryRow);
// --- quest list (scrollable) ---
FlowLayout questList = UIContainers.verticalFlow(Sizing.fixed(barWidth), Sizing.content());
questList.gap(3);
questList.padding(Insets.of(2, 0, 2, 2));
for (QuestData quest : quests) {
questList.child(buildQuestEntry(quest, contentWidth));
}
int usedHeight = 20 + 6 + 18 + 6; // statusBar + barBg + summaryRow + gaps
int scrollHeight = contentHeight - usedHeight;
var scrollArea = UIContainers.verticalScroll(
Sizing.fixed(barWidth),
Sizing.fixed(scrollHeight),
questList
);
content.child(scrollArea);
}
private static String formatPlaytime(int seconds) {
int hours = seconds / 3600;
int minutes = (seconds % 3600) / 60;
int secs = seconds % 60;
if (hours > 0) {
return hours + "h " + minutes + "m " + secs + "s";
} else if (minutes > 0) {
return minutes + "m " + secs + "s";
} else {
return secs + "s";
}
}
private static List<QuestData> quests() {
return List.of(
new QuestData("First Steps", "Play for 5 minutes", 300),
new QuestData("Getting Started", "Play for 30 minutes", 1800),
new QuestData("Dedicated Player", "Play for 1 hour", 3600),
new QuestData("Veteran", "Play for 3 hours", 10800)
);
}
private static FlowLayout buildQuestEntry(QuestData quest, int contentWidth) {
boolean unlocked = quest.isUnlocked();
int entryWidth = contentWidth - 12;
FlowLayout row = UIContainers.horizontalFlow(Sizing.fixed(entryWidth), Sizing.fixed(32));
row.gap(6);
row.padding(Insets.of(4));
row.verticalAlignment(VerticalAlignment.CENTER);
row.horizontalAlignment(HorizontalAlignment.LEFT);
row.surface(unlocked
? Surface.flat(0x1AFFFFFF).and(Surface.outline(0x30 << 24 | ACCENT))
: Surface.flat(0x12000000));
FlowLayout iconBox = UIContainers.verticalFlow(Sizing.fixed(12), Sizing.fixed(12));
iconBox.surface(unlocked
? Surface.flat(0xFF000000 | ACCENT)
: Surface.flat(0x40FFFFFF));
iconBox.horizontalAlignment(HorizontalAlignment.CENTER);
iconBox.verticalAlignment(VerticalAlignment.CENTER);
iconBox.child(UIComponents.label(Component.literal(unlocked ? "" : ""))
.color(Color.ofRgb(0x1c1c1c)));
row.child(iconBox);
FlowLayout textStack = UIContainers.verticalFlow(Sizing.fixed(entryWidth - 24), Sizing.content());
textStack.gap(1);
textStack.horizontalAlignment(HorizontalAlignment.LEFT);
textStack.verticalAlignment(VerticalAlignment.TOP);
var titleLabel = UIComponents.label(Component.literal(quest.title())
.withStyle(style -> style.withFont(new FontDescription.Resource(MyScreen.MC_FIVE))))
.color(Color.ofRgb(unlocked ? 0xFFFFFF : 0x797b86));
textStack.child(titleLabel);
var descLabel = UIComponents.label(Component.literal(quest.description()))
.color(Color.ofRgb(0xa3a3ac))
.maxWidth(entryWidth - 24);
textStack.child(descLabel);
row.child(textStack);
return row;
}
}