Build 29095000

This commit is contained in:
Renan LE CARO 2025-04-26 22:40:32 +02:00
parent 096f7d4abd
commit 4c324d211c
27 changed files with 500 additions and 1350 deletions

View file

@ -1,113 +1,123 @@
import {PerkId, RunHistoryItem, UnlockCondition} from "./types";
import {upgrades} from "./loadGameData";
import {hashCode} from "./getLevelBackground";
import {t} from "./i18n/i18n";
import { PerkId, RunHistoryItem, UnlockCondition } from "./types";
import { upgrades } from "./loadGameData";
import { hashCode } from "./getLevelBackground";
import { t } from "./i18n/i18n";
import _hardCodedCondition from './data/unlockConditions.json'
import _hardCodedCondition from "./data/unlockConditions.json";
const hardCodedCondition = _hardCodedCondition as Record<string, UnlockCondition>
const hardCodedCondition = _hardCodedCondition as Record<
string,
UnlockCondition
>;
let excluded: Set<PerkId>;
function isExcluded(id: PerkId) {
if (!excluded) {
excluded = new Set([
"extra_levels",
"extra_life",
"one_more_choice",
"shunt",
"slow_down",
]);
// Avoid excluding a perk that's needed for the required one
upgrades.forEach((u) => {
if (u.requires) excluded.add(u.requires);
});
}
return excluded.has(id);
if (!excluded) {
excluded = new Set([
"extra_levels",
"extra_life",
"one_more_choice",
"shunt",
"slow_down",
]);
// Avoid excluding a perk that's needed for the required one
upgrades.forEach((u) => {
if (u.requires) excluded.add(u.requires);
});
}
return excluded.has(id);
}
export function getLevelUnlockCondition(levelIndex: number, levelName:string):UnlockCondition {
export function getLevelUnlockCondition(
levelIndex: number,
levelName: string,
): UnlockCondition {
if (hardCodedCondition[levelName]) return hardCodedCondition[levelName];
const result: UnlockCondition = {
required: [],
forbidden: [],
minScore: Math.max(-1000 + 100 * levelIndex, 0),
};
if(hardCodedCondition[levelName]) return hardCodedCondition[levelName]
const result :UnlockCondition = {
required:[],
forbidden:[],
minScore : Math.max(-1000 + 100 * levelIndex, 0)
}
if (levelIndex > 20) {
const possibletargets = [...upgrades]
.slice(0, Math.floor(levelIndex / 2))
.filter((u) => !isExcluded(u.id))
.sort((a, b) => hashCode(levelIndex + a.id) - hashCode(levelIndex + b.id))
.map((u) => u.id);
if (levelIndex > 20) {
const possibletargets = [...upgrades]
.slice(0, Math.floor(levelIndex / 2))
.filter((u) => !isExcluded(u.id))
.sort(
(a, b) => hashCode(levelIndex + a.id) - hashCode(levelIndex + b.id),
).map(u => u.id);
const length = Math.min(3, Math.ceil(levelIndex / 30));
result.required = possibletargets.slice(0, length);
result.forbidden = possibletargets.slice(length, length + length);
}
return result
const length = Math.min(3, Math.ceil(levelIndex / 30));
result.required = possibletargets.slice(0, length);
result.forbidden = possibletargets.slice(length, length + length);
}
return result;
}
export function getBestScoreMatching(
history: RunHistoryItem[],
required: PerkId[] = [],
forbidden: PerkId[] = [],
history: RunHistoryItem[],
required: PerkId[] = [],
forbidden: PerkId[] = [],
) {
return Math.max(
0,
...history
.filter(
(r) =>
!required.find((id) => !r?.perks?.[id]) &&
!forbidden.find((id) => r?.perks?.[id]),
)
.map((r) => r.score),
);
return Math.max(
0,
...history
.filter(
(r) =>
!required.find((id) => !r?.perks?.[id]) &&
!forbidden.find((id) => r?.perks?.[id]),
)
.map((r) => r.score),
);
}
export function isLevelLocked(
levelIndex: number,
levelName:string,
history: RunHistoryItem[]){
const {required, forbidden, minScore} = getLevelUnlockCondition(levelIndex, levelName);
return getBestScoreMatching(history, required, forbidden) < minScore
levelIndex: number,
levelName: string,
history: RunHistoryItem[],
) {
const { required, forbidden, minScore } = getLevelUnlockCondition(
levelIndex,
levelName,
);
return getBestScoreMatching(history, required, forbidden) < minScore;
}
export function reasonLevelIsLocked(
levelIndex: number,levelName:string,
history: RunHistoryItem[],
mentionBestScore: boolean,
levelIndex: number,
levelName: string,
history: RunHistoryItem[],
mentionBestScore: boolean,
): null | { reached: number; minScore: number; text: string } {
const {required, forbidden, minScore} = getLevelUnlockCondition(levelIndex, levelName);
const reached = getBestScoreMatching(history, required, forbidden);
let reachedText =
reached && mentionBestScore ? t("unlocks.reached", {reached}) : "";
if (reached >= minScore) {
return null;
} else if (!required.length && !forbidden.length) {
return {
reached,
minScore,
text: t("unlocks.minScore", {minScore}) + reachedText,
};
} else {
return {
reached,
minScore,
text:
t("unlocks.minScoreWithPerks", {
minScore,
required: required.map((u) => upgradeName(u)).join(", "),
forbidden: forbidden.map((u) => upgradeName(u)).join(", "),
}) + reachedText,
};
}
const { required, forbidden, minScore } = getLevelUnlockCondition(
levelIndex,
levelName,
);
const reached = getBestScoreMatching(history, required, forbidden);
let reachedText =
reached && mentionBestScore ? t("unlocks.reached", { reached }) : "";
if (reached >= minScore) {
return null;
} else if (!required.length && !forbidden.length) {
return {
reached,
minScore,
text: t("unlocks.minScore", { minScore }) + reachedText,
};
} else {
return {
reached,
minScore,
text:
t("unlocks.minScoreWithPerks", {
minScore,
required: required.map((u) => upgradeName(u)).join(", "),
forbidden: forbidden.map((u) => upgradeName(u)).join(", "),
}) + reachedText,
};
}
}
export function upgradeName(id:PerkId){
return upgrades.find(u=>u.id==id)!.name
}
export function upgradeName(id: PerkId) {
return upgrades.find((u) => u.id == id)!.name;
}