chore: community feedback fixes and UI improvements (#102)
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 1m3s
CI / Lint, Build & Test (push) Successful in 1m8s

## Summary

Addresses all community feedback tickets from the last deploy, plus several UI improvements made during the same session.

### Bug fixes & balance
- **#97** — Fix auto-adventurer tier priority: sort by combat power instead of current cost so the highest-tier affordable unit is always purchased
- **#98** — Add Dark Templar adventurer (80k CP) to bridge the Volcanic Depths progression wall; rewire upgrade and quest rewards accordingly
- **#99** — Reorder and buff Shadow Assassin (55k CP, level 12) so Witch Coven feels rewarding rather than a regression
- **#100** — Display effective Gold/s (all multipliers applied) in the resource bar
- **#101** — Add Peasant tier 2 (10x, essence) and tier 3 (50x, crystals) upgrades for meaningful late-game scaling

### Other fixes
- Sync game state to server before auto-boss challenges (matching manual challenge behaviour)
- Refresh Discord avatar hash on every game load via bot token so stale CDN URLs are corrected automatically

### UI improvements
- Replace Donate / Discord / Support / View Profile / Edit Profile buttons with a single avatar dropdown menu
- Collapse all resources except Gold into a click-to-toggle dropdown; orange alert dot appears when a hidden resource is capped

## Closes

Closes #97
Closes #98
Closes #99
Closes #100
Closes #101

Reviewed-on: #102
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
This commit was merged in pull request #102.
This commit is contained in:
2026-03-23 16:07:25 -07:00
committed by Naomi Carrigan
parent 7bd6b2d3e3
commit 3ac1d566cb
13 changed files with 698 additions and 191 deletions
+21 -6
View File
@@ -1094,11 +1094,7 @@ export const GameProvider = ({
return adventurer.unlocked && next.resources.gold >= cost;
}).
sort((adventurerA, adventurerB) => {
const costA
= adventurerA.baseCost * Math.pow(1.15, adventurerA.count);
const costB
= adventurerB.baseCost * Math.pow(1.15, adventurerB.count);
return costB - costA;
return adventurerB.combatPower - adventurerA.combatPower;
});
if (bestAdventurer !== undefined) {
const purchaseCost
@@ -1285,7 +1281,26 @@ export const GameProvider = ({
if (availableBoss !== undefined) {
const { id: bossId, name: bossName } = availableBoss;
isAutoBossingReference.current = true;
void challengeBossApi({ bossId }).
const syncBeforeBoss
= stateReference.current !== null && !isSyncingReference.current
? saveGame({
state: stateReference.current,
...signatureReference.current === null
? {}
: { signature: signatureReference.current },
}).then((response) => {
if (response.signature !== undefined) {
signatureReference.current = response.signature;
localStorage.setItem(
"elysium_save_signature",
response.signature,
);
}
})
: Promise.resolve();
void syncBeforeBoss.then(async() => {
return await challengeBossApi({ bossId });
}).
then((result) => {
setState((previous) => {
if (previous === null) {