generated from nhcarrigan/template
fix: adventurer unlocks not applied by force-unlock tool #93
@@ -257,6 +257,37 @@ const applyBossUnlocks = (state: GameState): number => {
|
||||
return count;
|
||||
};
|
||||
|
||||
/**
|
||||
* Unlocks any adventurer tiers that were granted as rewards for completed quests
|
||||
* but are still locked in the player's state.
|
||||
* @param state - The player's current game state (mutated directly).
|
||||
* @returns The number of adventurer tiers that were unlocked.
|
||||
*/
|
||||
const applyAdventurerUnlocks = (state: GameState): number => {
|
||||
let count = 0;
|
||||
const earnedAdventurerIds = new Set<string>();
|
||||
|
||||
for (const quest of state.quests) {
|
||||
if (quest.status !== "completed") {
|
||||
continue;
|
||||
}
|
||||
for (const reward of quest.rewards) {
|
||||
if (reward.type === "adventurer" && reward.targetId !== undefined) {
|
||||
earnedAdventurerIds.add(reward.targetId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const adventurer of state.adventurers) {
|
||||
if (!adventurer.unlocked && earnedAdventurerIds.has(adventurer.id)) {
|
||||
adventurer.unlocked = true;
|
||||
count = count + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
};
|
||||
|
||||
/**
|
||||
* Makes available any exploration areas whose parent zone is now unlocked.
|
||||
* @param state - The player's current game state (mutated directly).
|
||||
@@ -301,6 +332,7 @@ const applyExplorationUnlocks = (state: GameState): number => {
|
||||
const applyForceUnlocks = (
|
||||
state: GameState,
|
||||
): {
|
||||
adventurersUnlocked: number;
|
||||
bossesUnlocked: number;
|
||||
explorationUnlocked: number;
|
||||
questsUnlocked: number;
|
||||
@@ -310,7 +342,14 @@ const applyForceUnlocks = (
|
||||
const questsUnlocked = applyQuestUnlocks(state);
|
||||
const bossesUnlocked = applyBossUnlocks(state);
|
||||
const explorationUnlocked = applyExplorationUnlocks(state);
|
||||
return { bossesUnlocked, explorationUnlocked, questsUnlocked, zonesUnlocked };
|
||||
const adventurersUnlocked = applyAdventurerUnlocks(state);
|
||||
return {
|
||||
adventurersUnlocked,
|
||||
bossesUnlocked,
|
||||
explorationUnlocked,
|
||||
questsUnlocked,
|
||||
zonesUnlocked,
|
||||
};
|
||||
};
|
||||
|
||||
const debugRouter = new Hono<HonoEnvironment>();
|
||||
@@ -330,8 +369,13 @@ debugRouter.post("/force-unlocks", async(context) => {
|
||||
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Prisma stores state as JSON object */
|
||||
const state = gameStateRecord.state as unknown as GameState;
|
||||
|
||||
const { bossesUnlocked, explorationUnlocked, questsUnlocked, zonesUnlocked }
|
||||
= applyForceUnlocks(state);
|
||||
const {
|
||||
adventurersUnlocked,
|
||||
bossesUnlocked,
|
||||
explorationUnlocked,
|
||||
questsUnlocked,
|
||||
zonesUnlocked,
|
||||
} = applyForceUnlocks(state);
|
||||
|
||||
const updatedAt = Date.now();
|
||||
await prisma.gameState.update({
|
||||
@@ -347,6 +391,7 @@ debugRouter.post("/force-unlocks", async(context) => {
|
||||
: computeHmac(JSON.stringify(state), secret);
|
||||
|
||||
return context.json({
|
||||
adventurersUnlocked,
|
||||
bossesUnlocked,
|
||||
explorationUnlocked,
|
||||
questsUnlocked,
|
||||
|
||||
@@ -51,11 +51,15 @@ const DebugPanel = (): JSX.Element => {
|
||||
if (result.explorationUnlocked > 0) {
|
||||
parts.push(`${String(result.explorationUnlocked)} exploration area(s)`);
|
||||
}
|
||||
if (result.adventurersUnlocked > 0) {
|
||||
parts.push(`${String(result.adventurersUnlocked)} adventurer tier(s)`);
|
||||
}
|
||||
const total
|
||||
= result.zonesUnlocked
|
||||
+ result.questsUnlocked
|
||||
+ result.bossesUnlocked
|
||||
+ result.explorationUnlocked;
|
||||
+ result.explorationUnlocked
|
||||
+ result.adventurersUnlocked;
|
||||
const message
|
||||
= parts.length === 0
|
||||
? "Everything looks correct — no missing unlocks were found."
|
||||
|
||||
@@ -558,6 +558,7 @@ interface GameContextValue {
|
||||
* @returns Counts of what was corrected.
|
||||
*/
|
||||
forceUnlocks: ()=> Promise<{
|
||||
adventurersUnlocked: number;
|
||||
bossesUnlocked: number;
|
||||
explorationUnlocked: number;
|
||||
questsUnlocked: number;
|
||||
@@ -2104,6 +2105,7 @@ export const GameProvider = ({
|
||||
localStorage.setItem("elysium_save_signature", data.signature);
|
||||
}
|
||||
return {
|
||||
adventurersUnlocked: data.adventurersUnlocked,
|
||||
bossesUnlocked: data.bossesUnlocked,
|
||||
explorationUnlocked: data.explorationUnlocked,
|
||||
questsUnlocked: data.questsUnlocked,
|
||||
@@ -2116,6 +2118,7 @@ export const GameProvider = ({
|
||||
: "Failed to force unlocks",
|
||||
);
|
||||
return {
|
||||
adventurersUnlocked: 0,
|
||||
bossesUnlocked: 0,
|
||||
explorationUnlocked: 0,
|
||||
questsUnlocked: 0,
|
||||
|
||||
@@ -425,6 +425,11 @@ interface ForceUnlocksResponse {
|
||||
*/
|
||||
explorationUnlocked: number;
|
||||
|
||||
/**
|
||||
* Number of adventurer tiers that were unlocked by this operation.
|
||||
*/
|
||||
adventurersUnlocked: number;
|
||||
|
||||
/**
|
||||
* HMAC-SHA256 signature of the corrected state for anti-cheat chain continuity.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user