Files
CaseGambling/server/src/caseKeys.js
T
gpatruno 2168998679 prstige
2026-07-18 17:25:56 +02:00

91 lines
2.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/** Base simultaneous opens at key 1 (x10). Each +1 key adds +1 open until x20, then continues +1 per key. */
export const BASE_MAX_OPENS = 10;
/** Keys 110 → next key always costs this many opens. */
export const OPENS_PER_KEY_EARLY = 100;
/** From key 11 onward: cost = OPENS_PER_KEY_EARLY × (keys - 9). */
export const ESCALATION_KEY_THRESHOLD = 11;
export function maxOpensForKeys(keys, openBonus = 0) {
const k = Math.max(1, keys);
const bonus = Math.max(0, Math.floor(Number(openBonus) || 0));
return k + (BASE_MAX_OPENS - 1) + bonus;
}
export function opensRequiredForNextKey(keys, keyOpenReduction = 0) {
const k = Math.max(1, keys);
const base =
k < ESCALATION_KEY_THRESHOLD
? OPENS_PER_KEY_EARLY
: OPENS_PER_KEY_EARLY * (k - (ESCALATION_KEY_THRESHOLD - 2));
const reduction = Math.max(0, Number(keyOpenReduction) || 0);
return Math.max(1, base - reduction);
}
export function serializeKeyProgress(progress, keyOpenReduction = 0, openBonus = 0) {
const keys = progress?.keys ?? 1;
const opensSinceLastKey = progress?.opensSinceLastKey ?? 0;
const totalOpens = progress?.totalOpens ?? 0;
const opensRequired = opensRequiredForNextKey(keys, keyOpenReduction);
return {
keys,
maxOpens: maxOpensForKeys(keys, openBonus),
opensSinceLastKey,
opensRequired,
totalOpens,
};
}
/**
* Apply opens to progress state. Returns updated fields + keysGained.
*/
export function applyOpens(progress, count, keyOpenReduction = 0) {
let keys = Math.max(1, progress.keys ?? 1);
let opensSinceLastKey = progress.opensSinceLastKey ?? 0;
let totalOpens = progress.totalOpens ?? 0;
let keysGained = 0;
opensSinceLastKey += count;
totalOpens += count;
while (opensSinceLastKey >= opensRequiredForNextKey(keys, keyOpenReduction)) {
opensSinceLastKey -= opensRequiredForNextKey(keys, keyOpenReduction);
keys += 1;
keysGained += 1;
}
return { keys, opensSinceLastKey, totalOpens, keysGained };
}
/**
* Rebuild keys/opensSinceLastKey from a lifetime open count (backfill).
* Prestige reduction is ignored here — backfill uses base costs.
*/
export function progressFromTotalOpens(totalOpens) {
let keys = 1;
let remaining = totalOpens;
while (remaining >= opensRequiredForNextKey(keys, 0)) {
remaining -= opensRequiredForNextKey(keys, 0);
keys += 1;
}
return {
keys,
opensSinceLastKey: remaining,
totalOpens,
};
}
export async function getOrCreateProgress(tx, userId, caseId) {
const existing = await tx.caseKeyProgress.findUnique({
where: { userId_caseId: { userId, caseId } },
});
if (existing) return existing;
return tx.caseKeyProgress.create({
data: { userId, caseId, keys: 1, opensSinceLastKey: 0, totalOpens: 0 },
});
}