generated from nhcarrigan/template
feat: v0.6.0 balance pass, quest-gated bosses, and achievement fixes
This commit is contained in:
@@ -8,11 +8,11 @@
|
||||
type AchievementConditionType =
|
||||
| "totalGoldEarned"
|
||||
| "totalClicks"
|
||||
| "bossesDefeated"
|
||||
| "questsCompleted"
|
||||
| "adventurerTotal"
|
||||
| "prestigeCount"
|
||||
| "equipmentOwned";
|
||||
| "equipmentOwned"
|
||||
| "uniqueQuestsCompleted"
|
||||
| "uniqueBossesDefeated";
|
||||
|
||||
interface AchievementCondition {
|
||||
type: AchievementConditionType;
|
||||
|
||||
@@ -55,6 +55,12 @@ interface Boss {
|
||||
*/
|
||||
zoneId: string;
|
||||
|
||||
/**
|
||||
* ID of the quest that must be completed before this boss becomes
|
||||
* available. `null`/`undefined` means no quest gate applies.
|
||||
*/
|
||||
unlockQuestId?: string | null;
|
||||
|
||||
/**
|
||||
* One-time runestone bounty awarded on first-ever defeat.
|
||||
*/
|
||||
@@ -66,6 +72,14 @@ interface Boss {
|
||||
* bounty is never re-awarded in subsequent runs.
|
||||
*/
|
||||
bountyRunestonesClaimed?: boolean;
|
||||
|
||||
/**
|
||||
* Whether this boss has ever been defeated, across all prestige/
|
||||
* transcendence/apotheosis resets. Used by achievements that require
|
||||
* defeating every distinct boss, since `status` alone only reflects
|
||||
* the current run.
|
||||
*/
|
||||
everDefeated?: boolean;
|
||||
}
|
||||
|
||||
export type { Boss, BossStatus };
|
||||
|
||||
@@ -87,7 +87,7 @@ const COMPANIONS: Array<Companion> = [
|
||||
id: "wren",
|
||||
name: "Wren",
|
||||
title: "Hedge Witch",
|
||||
unlock: { threshold: 500, type: "lifetimeQuests" },
|
||||
unlock: { threshold: 250, type: "lifetimeQuests" },
|
||||
},
|
||||
{
|
||||
bonus: { type: "bossDamage", value: 0.2 },
|
||||
@@ -117,7 +117,7 @@ const COMPANIONS: Array<Companion> = [
|
||||
id: "kael",
|
||||
name: "Kael",
|
||||
title: "Battle Mage",
|
||||
unlock: { threshold: 720, type: "lifetimeBosses" },
|
||||
unlock: { threshold: 500, type: "lifetimeBosses" },
|
||||
},
|
||||
{
|
||||
bonus: { type: "questTime", value: 0.3 },
|
||||
@@ -127,7 +127,7 @@ const COMPANIONS: Array<Companion> = [
|
||||
id: "zuri",
|
||||
name: "Zuri",
|
||||
title: "Chrono Weaver",
|
||||
unlock: { threshold: 950, type: "lifetimeQuests" },
|
||||
unlock: { threshold: 500, type: "lifetimeQuests" },
|
||||
},
|
||||
{
|
||||
bonus: { type: "passiveGold", value: 0.75 },
|
||||
|
||||
@@ -40,6 +40,13 @@ interface Equipment {
|
||||
*/
|
||||
owned: boolean;
|
||||
|
||||
/**
|
||||
* Whether the player has ever acquired this item, across all runs — never reset.
|
||||
* Optional for backwards compatibility with saves persisted before this field
|
||||
* existed; readers should fall back to `owned` when it is absent.
|
||||
*/
|
||||
everOwned?: boolean;
|
||||
|
||||
/**
|
||||
* Whether this item is currently equipped (only one per type can be equipped).
|
||||
*/
|
||||
|
||||
@@ -60,7 +60,7 @@ const DEFAULT_PROFILE_SETTINGS: ProfileSettings = {
|
||||
enableNotifications: false,
|
||||
enablePrestigeAnnouncements: true,
|
||||
enableSounds: false,
|
||||
numberFormat: "suffix",
|
||||
numberFormat: "scientific",
|
||||
showAchievementsUnlocked: true,
|
||||
showAdventurersRecruited: true,
|
||||
showApotheosis: true,
|
||||
|
||||
@@ -61,6 +61,14 @@ interface Quest {
|
||||
* Unix timestamp of the most recent failed attempt (if any).
|
||||
*/
|
||||
lastFailedAt?: number;
|
||||
|
||||
/**
|
||||
* Whether this quest has ever been completed, across all prestige/
|
||||
* transcendence/apotheosis resets. Used by achievements that require
|
||||
* completing every distinct quest, since `status` alone only reflects
|
||||
* the current run.
|
||||
*/
|
||||
everCompleted?: boolean;
|
||||
}
|
||||
|
||||
export type { Quest, QuestReward, QuestRewardType, QuestStatus };
|
||||
|
||||
@@ -35,8 +35,8 @@ describe("computeUnlockedCompanionIds", () => {
|
||||
expect(result).toContain("finn");
|
||||
});
|
||||
|
||||
it("unlocks wren at 500 lifetime quests", () => {
|
||||
const result = computeUnlockedCompanionIds({ ...baseParams, lifetimeQuestsCompleted: 500 });
|
||||
it("unlocks wren at 250 lifetime quests", () => {
|
||||
const result = computeUnlockedCompanionIds({ ...baseParams, lifetimeQuestsCompleted: 250 });
|
||||
expect(result).toContain("finn");
|
||||
expect(result).toContain("wren");
|
||||
});
|
||||
@@ -57,15 +57,15 @@ describe("computeUnlockedCompanionIds", () => {
|
||||
expect(result).not.toContain("sera");
|
||||
});
|
||||
|
||||
it("unlocks kael at 720 lifetime bosses", () => {
|
||||
const result = computeUnlockedCompanionIds({ ...baseParams, lifetimeBossesDefeated: 720 });
|
||||
it("unlocks kael at 500 lifetime bosses", () => {
|
||||
const result = computeUnlockedCompanionIds({ ...baseParams, lifetimeBossesDefeated: 500 });
|
||||
expect(result).toContain("kael");
|
||||
expect(result).toContain("lyra");
|
||||
expect(result).toContain("aldric");
|
||||
});
|
||||
|
||||
it("unlocks zuri at 950 lifetime quests", () => {
|
||||
const result = computeUnlockedCompanionIds({ ...baseParams, lifetimeQuestsCompleted: 950 });
|
||||
it("unlocks zuri at 500 lifetime quests", () => {
|
||||
const result = computeUnlockedCompanionIds({ ...baseParams, lifetimeQuestsCompleted: 500 });
|
||||
expect(result).toContain("zuri");
|
||||
});
|
||||
|
||||
@@ -96,8 +96,8 @@ describe("computeUnlockedCompanionIds", () => {
|
||||
|
||||
it("unlocks multiple companions simultaneously", () => {
|
||||
const result = computeUnlockedCompanionIds({
|
||||
lifetimeBossesDefeated: 720,
|
||||
lifetimeQuestsCompleted: 950,
|
||||
lifetimeBossesDefeated: 500,
|
||||
lifetimeQuestsCompleted: 500,
|
||||
lifetimeGoldEarned: 1e18,
|
||||
prestigeCount: 10,
|
||||
transcendenceCount: 5,
|
||||
|
||||
@@ -24,7 +24,7 @@ describe("DEFAULT_PROFILE_SETTINGS", () => {
|
||||
expect(DEFAULT_PROFILE_SETTINGS.enableNotifications).toBe(false);
|
||||
});
|
||||
|
||||
it("defaults numberFormat to suffix", () => {
|
||||
expect(DEFAULT_PROFILE_SETTINGS.numberFormat).toBe("suffix");
|
||||
it("defaults numberFormat to scientific", () => {
|
||||
expect(DEFAULT_PROFILE_SETTINGS.numberFormat).toBe("scientific");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user