fix(sanctuary): séparer les statuts du Shop (#32) #60

Merged
koka merged 1 commits from fix/shop-timer-overlap into main 2026-08-29 10:09:05 +00:00
4 changed files with 47 additions and 4 deletions
+9 -1
View File
@@ -62,6 +62,14 @@ tasks.register("questRequestModelSmoke", JavaExec) {
mainClass = "fr.koka99cab.sanctuary26.sanctuary.shop.QuestRequestModelSmoke"
}
tasks.register("shopHeaderLayoutSmoke", JavaExec) {
group = "verification"
description = "Checks that the daily Shop timer and unlocked-offer status cannot overlap."
dependsOn tasks.named("testClasses")
classpath = sourceSets.test.runtimeClasspath
mainClass = "fr.koka99cab.sanctuary26.sanctuary.client.ShopDailyHeaderLayoutSmoke"
}
tasks.register("verifyBlackMarket") {
group = "verification"
description = "Checks the physical sign market, flash Shop, escrow ledger and mailbox delivery."
@@ -212,7 +220,7 @@ tasks.register("verifySanctuary") {
inputs.files(fileTree("tools"))
dependsOn tasks.named("progressionModelSmoke"), tasks.named("serverIdentityModelSmoke"),
tasks.named("shopDeliveryTimingSmoke"), tasks.named("blackMarketModelSmoke"),
tasks.named("questBoardModelSmoke"),
tasks.named("questBoardModelSmoke"), tasks.named("shopHeaderLayoutSmoke"),
tasks.named("verifyBlackMarket")
doLast {
@@ -171,11 +171,13 @@ public final class SanctuaryShopScreen extends Screen {
} else {
if (!operatorPage) {
if (!catalogPage) graphics.text(font, Component.translatable("screen.sanctuary.shop.flash_timer",
flashTimeRemaining(rendered.flashEndsAtEpochMillis())), layout.left(), 53, 0xFFFFD45C);
flashTimeRemaining(rendered.flashEndsAtEpochMillis())), layout.left(),
ShopDailyHeaderLayout.TIMER_Y, 0xFFFFD45C);
drawBalance(graphics);
if (!catalogPage && rendered.nextSlotLevelCost() < 0) graphics.centeredText(font,
Component.translatable("screen.sanctuary.shop.slots_maximum", rendered.visibleOfferSlots(), PAGE_SIZE),
layout.left() + Math.min(240, layout.width() / 2) / 2, 53, 0xFF80E09A);
layout.left() + Math.min(240, layout.width() / 2) / 2,
ShopDailyHeaderLayout.PROGRESS_Y, 0xFF80E09A);
}
if (!operatorPage && !rendered.hasDeliveryBox()) graphics.centeredText(font,
Component.translatable("screen.sanctuary.shop.no_box"), width / 2, 58, 0xFFFF7070);
@@ -293,7 +295,7 @@ public final class SanctuaryShopScreen extends Screen {
private GridLayout gridLayout() {
int panelWidth = Math.max(240, Math.min(720, width - 12));
int left = width / 2 - panelWidth / 2;
int top = 70;
int top = ShopDailyHeaderLayout.GRID_TOP;
int availableHeight = Math.max(174, height - top - 36);
return new GridLayout(left, top, panelWidth, availableHeight);
}
@@ -0,0 +1,17 @@
package fr.koka99cab.sanctuary26.sanctuary.client;
/** Vertical layout reserved for the daily Shop status lines above the offer grid. */
final class ShopDailyHeaderLayout {
static final int TIMER_Y = 53;
static final int PROGRESS_Y = 63;
static final int GRID_TOP = 74;
private ShopDailyHeaderLayout() {
}
static boolean hasSeparatedLines(int fontLineHeight) {
return fontLineHeight > 0
&& TIMER_Y + fontLineHeight <= PROGRESS_Y
&& PROGRESS_Y + fontLineHeight <= GRID_TOP;
}
}
@@ -0,0 +1,16 @@
package fr.koka99cab.sanctuary26.sanctuary.client;
/** Executable smoke coverage for the two-line daily Shop header. */
public final class ShopDailyHeaderLayoutSmoke {
private ShopDailyHeaderLayoutSmoke() {
}
public static void main(String[] args) {
if (!ShopDailyHeaderLayout.hasSeparatedLines(9)) {
throw new AssertionError("Shop timer and unlocked-offer status must occupy separate lines");
}
if (ShopDailyHeaderLayout.hasSeparatedLines(11)) {
throw new AssertionError("Layout check must reject text that would overlap the offer grid");
}
}
}