2025-04-07 14:08:48 +02:00
|
|
|
import { GameState } from "./types";
|
|
|
|
import { asyncAlert } from "./asyncAlert";
|
|
|
|
import { t } from "./i18n/i18n";
|
|
|
|
import {
|
|
|
|
getLevelUnlockCondition,
|
|
|
|
levelsListHTMl,
|
|
|
|
max_levels,
|
|
|
|
pickedUpgradesHTMl,
|
|
|
|
reasonLevelIsLocked,
|
|
|
|
} from "./game_utils";
|
|
|
|
import { getCreativeModeWarning, getHistory } from "./gameOver";
|
|
|
|
import { pause } from "./game";
|
|
|
|
import { allLevels, icons } from "./loadGameData";
|
2025-04-08 14:03:38 +02:00
|
|
|
import { firstWhere } from "./pure_functions";
|
|
|
|
import { getSettingValue, getTotalScore } from "./settings";
|
2025-04-07 14:08:48 +02:00
|
|
|
|
|
|
|
export async function openScorePanel(gameState: GameState) {
|
|
|
|
pause(true);
|
|
|
|
|
|
|
|
await asyncAlert({
|
|
|
|
title: t("score_panel.title", {
|
|
|
|
score: gameState.score,
|
|
|
|
level: gameState.currentLevel + 1,
|
|
|
|
max: max_levels(gameState),
|
|
|
|
}),
|
|
|
|
|
|
|
|
content: [
|
|
|
|
getCreativeModeWarning(gameState),
|
|
|
|
pickedUpgradesHTMl(gameState),
|
|
|
|
levelsListHTMl(gameState, gameState.currentLevel),
|
|
|
|
getNearestUnlockHTML(gameState),
|
|
|
|
gameState.rerolls
|
|
|
|
? t("score_panel.rerolls_count", { rerolls: gameState.rerolls })
|
|
|
|
: "",
|
|
|
|
],
|
|
|
|
allowClose: true,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getNearestUnlockHTML(gameState: GameState) {
|
2025-04-07 15:25:58 +02:00
|
|
|
if (gameState.creative) return "";
|
2025-04-08 14:03:38 +02:00
|
|
|
const unlocked = new Set(getSettingValue("breakout_71_unlocked_levels", []));
|
|
|
|
const firstUnlockable = firstWhere(allLevels, (l, li) => {
|
|
|
|
if (unlocked.has(l.name)) return;
|
|
|
|
const reason = reasonLevelIsLocked(li, getHistory(), false);
|
|
|
|
if (!reason) return;
|
2025-04-07 14:08:48 +02:00
|
|
|
|
2025-04-08 14:03:38 +02:00
|
|
|
const { minScore, forbidden, required } = getLevelUnlockCondition(li);
|
|
|
|
const missing = required.filter((u) => !gameState?.perks?.[u.id]);
|
|
|
|
// we can't have a forbidden perk
|
|
|
|
if (forbidden.find((u) => gameState?.perks?.[u.id])) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// All required upgrades need to be unlocked
|
|
|
|
if (missing.find((u) => u.threshold > getTotalScore())) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
l,
|
|
|
|
li,
|
|
|
|
minScore,
|
|
|
|
forbidden,
|
|
|
|
required,
|
|
|
|
missing,
|
|
|
|
reason,
|
|
|
|
};
|
|
|
|
});
|
2025-04-07 14:08:48 +02:00
|
|
|
|
|
|
|
if (!firstUnlockable) return "";
|
|
|
|
let missingPoints = firstUnlockable.minScore - gameState.score;
|
|
|
|
let missingUpgrades = firstUnlockable.missing.map((u) => u.name).join(", ");
|
|
|
|
|
|
|
|
const title =
|
|
|
|
(missingUpgrades &&
|
|
|
|
t("score_panel.get_upgrades_to_unlock", {
|
|
|
|
missingUpgrades,
|
|
|
|
points: missingPoints,
|
|
|
|
level: firstUnlockable.l.name,
|
|
|
|
})) ||
|
2025-04-08 14:03:38 +02:00
|
|
|
t("score_panel.score_to_unlock", {
|
|
|
|
points: missingPoints,
|
2025-04-07 14:08:48 +02:00
|
|
|
level: firstUnlockable.l.name,
|
|
|
|
});
|
|
|
|
|
|
|
|
return `
|
|
|
|
<p>${t("score_panel.close_to_unlock")}</p>
|
|
|
|
<div class="upgrade used">
|
|
|
|
${icons[firstUnlockable.l.name]}
|
|
|
|
<p>
|
|
|
|
<strong>${title}</strong>
|
|
|
|
${firstUnlockable.reason?.text}
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
`;
|
|
|
|
}
|