From 1e845b14ce363130537b09dbecc0142b42236894 Mon Sep 17 00:00:00 2001 From: Hikari Date: Thu, 19 Mar 2026 21:22:13 -0700 Subject: [PATCH] chore: UI clarity improvements (#84) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Move quest failure explanation to a static note above the quest list (cards now show failure % only) - Show zone unlock requirements (boss + quest) on the Boss and Quest panels, matching the existing Exploration panel behaviour - Display combat power per adventurer on adventurer cards, alongside gold/s and essence/s ✨ This issue was created with help from Hikari~ 🌸 Reviewed-on: https://git.nhcarrigan.com/nhcarrigan/elysium/pulls/84 Co-authored-by: Hikari Co-committed-by: Hikari --- .../src/components/game/adventurerPanel.tsx | 4 ++ apps/web/src/components/game/bossPanel.tsx | 38 +++++++++++++++ apps/web/src/components/game/questPanel.tsx | 48 +++++++++++++++++-- 3 files changed, 87 insertions(+), 3 deletions(-) diff --git a/apps/web/src/components/game/adventurerPanel.tsx b/apps/web/src/components/game/adventurerPanel.tsx index c996374..e6efe97 100644 --- a/apps/web/src/components/game/adventurerPanel.tsx +++ b/apps/web/src/components/game/adventurerPanel.tsx @@ -143,6 +143,10 @@ const AdventurerCard = ({ {" essence/s each"}

} +

+ {formatNumber(adventurer.combatPower)} + {" combat power each"} +

{"×"} diff --git a/apps/web/src/components/game/bossPanel.tsx b/apps/web/src/components/game/bossPanel.tsx index 4b04ff1..e676142 100644 --- a/apps/web/src/components/game/bossPanel.tsx +++ b/apps/web/src/components/game/bossPanel.tsx @@ -267,6 +267,23 @@ const BossPanel = (): JSX.Element => { } const { zones, bosses, quests, autoBoss, prestige: playerPrestige } = state; + + const activeZone = zones.find((zone) => { + return zone.id === activeZoneId; + }); + const zoneIsLocked = activeZone?.status === "locked"; + const unlockBoss = activeZone?.unlockBossId === null + || activeZone?.unlockBossId === undefined + ? undefined + : bosses.find((boss) => { + return boss.id === activeZone.unlockBossId; + }); + const unlockQuest = activeZone?.unlockQuestId === null + || activeZone?.unlockQuestId === undefined + ? undefined + : quests.find((quest) => { + return quest.id === activeZone.unlockQuestId; + }); const zoneBosses = bosses.filter((boss) => { return boss.zoneId === activeZoneId; }); @@ -393,6 +410,27 @@ const BossPanel = (): JSX.Element => { zones={zones} /> + {zoneIsLocked && (unlockBoss !== undefined || unlockQuest !== undefined) + ?
+

{"🔒 This zone is locked. Unlock bosses by:"}

+ {unlockBoss === undefined + ? null + :

+ {"⚔️ Defeat: "} + {unlockBoss.name} +

+ } + {unlockQuest === undefined + ? null + :

+ {"📜 Complete: "} + {unlockQuest.name} +

+ } +
+ : null + } +
{"⚔️ Party DPS"} diff --git a/apps/web/src/components/game/questPanel.tsx b/apps/web/src/components/game/questPanel.tsx index b81c2dc..64b6596 100644 --- a/apps/web/src/components/game/questPanel.tsx +++ b/apps/web/src/components/game/questPanel.tsx @@ -4,6 +4,7 @@ * @license Naomi's Public License * @author Naomi Carrigan */ +/* eslint-disable max-lines -- QuestPanel with sub-component and helper functions */ /* eslint-disable react/no-multi-comp -- QuestCard sub-component is tightly coupled */ /* eslint-disable max-lines-per-function -- Complex component with many render paths */ /* eslint-disable complexity -- Many conditional render paths */ @@ -148,8 +149,7 @@ const QuestCard = ({ &&

{"🎲 "} {String(Math.round((zoneFailureChance[quest.zoneId] ?? 0) * 100))} - {"% failure chance — if failed, the quest resets"} - {" and must be retried."} + {"% failure chance"}

} {quest.status === "available" && quest.lastFailedAt !== undefined @@ -208,7 +208,24 @@ const QuestPanel = (): JSX.Element => { ); } - const { adventurers, autoQuest, quests, zones } = state; + const { adventurers, autoQuest, bosses, quests, zones } = state; + + const activeZone = zones.find((zone) => { + return zone.id === activeZoneId; + }); + const zoneIsLocked = activeZone?.status === "locked"; + const unlockBoss = activeZone?.unlockBossId === null + || activeZone?.unlockBossId === undefined + ? undefined + : bosses.find((boss) => { + return boss.id === activeZone.unlockBossId; + }); + const unlockQuest = activeZone?.unlockQuestId === null + || activeZone?.unlockQuestId === undefined + ? undefined + : quests.find((quest) => { + return quest.id === activeZone.unlockQuestId; + }); let partyCombatPower = 0; for (const adventurer of adventurers) { const contribution = adventurer.combatPower * adventurer.count; @@ -307,6 +324,31 @@ const QuestPanel = (): JSX.Element => { zones={zones} /> + {zoneIsLocked && (unlockBoss !== undefined || unlockQuest !== undefined) + ?
+

{"🔒 This zone is locked. Unlock quests by:"}

+ {unlockBoss === undefined + ? null + :

+ {"⚔️ Defeat: "} + {unlockBoss.name} +

+ } + {unlockQuest === undefined + ? null + :

+ {"📜 Complete: "} + {unlockQuest.name} +

+ } +
+ : null + } + +

+ {"⚠️ If a quest fails, it resets with no rewards — you must retry."} +

+
{visibleQuests.map((quest) => { return (