fix: real-time companion unlocks, persist exploration endsAt, correct auto-prestige formula, and quest balance
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 1m3s
CI / Lint, Build & Test (pull_request) Failing after 1m13s

Closes #191
Closes #205
Closes #206
Closes #212
Closes #214
Closes #216
Closes #224
This commit is contained in:
2026-04-06 13:39:35 -07:00
committed by Naomi Carrigan
parent 69579e166a
commit 99ca3083a1
4 changed files with 82 additions and 14 deletions
+9 -9
View File
@@ -77,7 +77,7 @@ export const defaultQuests: Array<Quest> = [
combatPowerRequired: 500,
description:
"A rogue necromancer has raised an army of skeletons near the city. Silence him before the dead overrun us.",
durationSeconds: 5 * 60,
durationSeconds: 30 * 60,
id: "necromancer_tower",
name: "Necromancer's Tower",
prerequisiteIds: [],
@@ -94,7 +94,7 @@ export const defaultQuests: Array<Quest> = [
combatPowerRequired: 2000,
description:
"An ancient fortress still garrisoned by constructs who don't know the war ended. Clear it out and claim its vaults.",
durationSeconds: 5 * 60,
durationSeconds: 45 * 60,
id: "crumbling_fortress",
name: "The Crumbling Fortress",
prerequisiteIds: [ "necromancer_tower" ],
@@ -111,7 +111,7 @@ export const defaultQuests: Array<Quest> = [
combatPowerRequired: 8000,
description:
"A vast library sealed for centuries whose contents have warped and grown hostile. The knowledge within is priceless.",
durationSeconds: 10 * 60,
durationSeconds: 60 * 60,
id: "cursed_library",
name: "The Cursed Library",
prerequisiteIds: [ "crumbling_fortress" ],
@@ -127,7 +127,7 @@ export const defaultQuests: Array<Quest> = [
combatPowerRequired: 30_000,
description:
"The legendary lair of Pyraxis the Undying. Few who enter return — those who do are rich beyond imagining.",
durationSeconds: 15 * 60,
durationSeconds: 90 * 60,
id: "dragon_lair",
name: "Dragon's Lair",
prerequisiteIds: [ "cursed_library" ],
@@ -545,7 +545,7 @@ export const defaultQuests: Array<Quest> = [
rewards: [
{ amount: 3_000_000_000_000, type: "gold" },
{ amount: 1_500_000_000, type: "essence" },
{ amount: 12_000_000, type: "crystals" },
{ amount: 0, type: "crystals" },
],
status: "locked",
zoneId: "abyssal_trench",
@@ -561,7 +561,7 @@ export const defaultQuests: Array<Quest> = [
rewards: [
{ amount: 10_000_000_000_000, type: "gold" },
{ amount: 5_000_000_000, type: "essence" },
{ amount: 30_000_000, type: "crystals" },
{ amount: 0, type: "crystals" },
],
status: "locked",
zoneId: "abyssal_trench",
@@ -577,7 +577,7 @@ export const defaultQuests: Array<Quest> = [
rewards: [
{ amount: 30_000_000_000_000, type: "gold" },
{ amount: 15_000_000_000, type: "essence" },
{ amount: 60_000_000, type: "crystals" },
{ amount: 0, type: "crystals" },
],
status: "locked",
zoneId: "abyssal_trench",
@@ -593,7 +593,7 @@ export const defaultQuests: Array<Quest> = [
rewards: [
{ amount: 100_000_000_000_000, type: "gold" },
{ amount: 50_000_000_000, type: "essence" },
{ amount: 120_000_000, type: "crystals" },
{ amount: 0, type: "crystals" },
{ targetId: "abyss_diver_1", type: "upgrade" },
],
status: "locked",
@@ -610,7 +610,7 @@ export const defaultQuests: Array<Quest> = [
rewards: [
{ amount: 400_000_000_000_000, type: "gold" },
{ amount: 200_000_000_000, type: "essence" },
{ amount: 400_000_000, type: "crystals" },
{ amount: 0, type: "crystals" },
],
status: "locked",
zoneId: "abyssal_trench",
+3 -3
View File
@@ -191,17 +191,17 @@ exploreRouter.post("/start", async(context) => {
}
const now = Date.now();
// eslint-disable-next-line stylistic/no-mixed-operators -- duration * 1000 is clear
const endsAt = now + explorationArea.durationSeconds * 1000;
area.status = "in_progress";
area.startedAt = now;
area.endsAt = endsAt;
await prisma.gameState.update({
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Prisma requires object */
data: { state: state as object, updatedAt: now },
where: { discordId },
});
// eslint-disable-next-line stylistic/no-mixed-operators -- duration * 1000 is clear
const endsAt = now + explorationArea.durationSeconds * 1000;
const response: ExploreStartResponse = {
areaId,
endsAt,