fix: unlock exploration areas when their zone is unlocked by boss kill or quest (#161)

applyBossResult and the tick engine both updated zone status to "unlocked"
but never propagated that unlock to state.exploration.areas, leaving all
areas in the new zone permanently locked until force-unlock was used.
Both code paths now map over exploration areas and set any locked area
whose zone just became unlocked to "available" in the same state update.
This commit is contained in:
2026-03-31 10:35:36 -07:00
committed by Naomi Carrigan
parent a09280470e
commit 3735cff23f
2 changed files with 39 additions and 0 deletions
+21
View File
@@ -53,6 +53,7 @@ import {
transcend as transcendApi, transcend as transcendApi,
} from "../api/client.js"; } from "../api/client.js";
import { CODEX_ENTRIES } from "../data/codex.js"; import { CODEX_ENTRIES } from "../data/codex.js";
import { EXPLORATION_AREAS } from "../data/explorations.js";
import { RECIPES } from "../data/recipes.js"; import { RECIPES } from "../data/recipes.js";
import { import {
RESOURCE_CAP, RESOURCE_CAP,
@@ -116,6 +117,9 @@ const applyBossResult = (
}). }).
filter(Boolean), filter(Boolean),
); );
const newlyUnlockedZoneIds = new Set(unlockedZones.map((z) => {
return z.id;
}));
const challengeUpdate const challengeUpdate
= previous.dailyChallenges === undefined = previous.dailyChallenges === undefined
@@ -216,6 +220,23 @@ const applyBossResult = (
? { ...u, unlocked: true } ? { ...u, unlocked: true }
: u; : u;
}), }),
...newlyUnlockedZoneIds.size === 0 || previous.exploration === undefined
? {}
: {
exploration: {
...previous.exploration,
areas: previous.exploration.areas.map((area) => {
const areaDefinition = EXPLORATION_AREAS.find((definition) => {
return definition.id === area.id;
});
return areaDefinition !== undefined
&& newlyUnlockedZoneIds.has(areaDefinition.zoneId)
&& area.status === "locked"
? { ...area, status: "available" as const }
: area;
}),
},
},
}; };
} }
+18
View File
@@ -21,6 +21,7 @@ import {
getActiveCompanionBonus, getActiveCompanionBonus,
} from "@elysium/types"; } from "@elysium/types";
import { EQUIPMENT_SETS } from "../data/equipmentSets.js"; import { EQUIPMENT_SETS } from "../data/equipmentSets.js";
import { EXPLORATION_AREAS } from "../data/explorations.js";
import { updateChallengeProgress } from "../utils/dailyChallenges.js"; import { updateChallengeProgress } from "../utils/dailyChallenges.js";
/** /**
@@ -753,6 +754,23 @@ export const applyTick = (
...updatedDailyChallenges === undefined ...updatedDailyChallenges === undefined
? {} ? {}
: { dailyChallenges: updatedDailyChallenges }, : { dailyChallenges: updatedDailyChallenges },
...newlyUnlockedZoneIds.size === 0 || state.exploration === undefined
? {}
: {
exploration: {
...state.exploration,
areas: state.exploration.areas.map((area) => {
const areaDefinition = EXPLORATION_AREAS.find((definition) => {
return definition.id === area.id;
});
return areaDefinition !== undefined
&& newlyUnlockedZoneIds.has(areaDefinition.zoneId)
&& area.status === "locked"
? { ...area, status: "available" as const }
: area;
}),
},
},
adventurers: updatedAdventurers, adventurers: updatedAdventurers,
bosses: updatedBosses, bosses: updatedBosses,
equipment: updatedEquipmentReference, equipment: updatedEquipmentReference,