fix: tighten codex hint visibility and constants (A-5 polish)
- Hoist MAX_UNDISCOVERED_PER_TIER to module scope (was a local const that expressed game-design intent, not runtime state). - Filter undiscovered slots to those with at least one known ingredient so a fresh player never sees useless `? + ?` cards on high tiers. - Move card-level opacity off the wrapper so the recipe-hint span can stay full-color (especially the craftable-now blue) while sprite + name remain dimmed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -769,12 +769,19 @@ const undiscoveredCardStyle = css`
|
||||
${elementCardBaseStyle}
|
||||
background: ${adaptive.greyBackground};
|
||||
border: 1.5px dashed ${adaptive.grey300};
|
||||
opacity: 0.4;
|
||||
cursor: default;
|
||||
justify-content: center;
|
||||
min-height: 80px;
|
||||
`;
|
||||
|
||||
const undiscoveredDimStyle = css`
|
||||
opacity: 0.45;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
`;
|
||||
|
||||
const spriteWrapStyle = css`
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
@@ -1106,9 +1113,11 @@ const genealogyTextStyle = css`
|
||||
`;
|
||||
|
||||
// ────────────────────────────────────────────────────────────
|
||||
// Tier labels
|
||||
// Tier labels & game design constants
|
||||
// ────────────────────────────────────────────────────────────
|
||||
|
||||
const MAX_UNDISCOVERED_PER_TIER = 6;
|
||||
|
||||
const TIER_LABELS: Record<number, string> = {
|
||||
1: 'Tier 1 — 기본 원소',
|
||||
2: 'Tier 2 — 2차 원소',
|
||||
@@ -1128,6 +1137,7 @@ const elementMap = Object.fromEntries(elementsData.map((el) => [el.id, el]));
|
||||
interface RecipeHint {
|
||||
display: string;
|
||||
craftableNow: boolean;
|
||||
partiallyKnown: boolean;
|
||||
}
|
||||
|
||||
function getRecipeHintForElement(
|
||||
@@ -1148,6 +1158,7 @@ function getRecipeHintForElement(
|
||||
return {
|
||||
display: `${aSym} + ${bSym}`,
|
||||
craftableNow: aDiscovered && bDiscovered && hasA && hasB,
|
||||
partiallyKnown: aDiscovered || bDiscovered,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1323,18 +1334,20 @@ const ElementCard = memo(function ElementCard({
|
||||
if (state === 'undiscovered') {
|
||||
return (
|
||||
<div css={undiscoveredCardStyle}>
|
||||
<div css={spriteWrapStyle}>
|
||||
<div css={idleSpriteWrapperStyle(mood ?? 'awake')}>
|
||||
<CharacterSprite
|
||||
elementId={el.id}
|
||||
elementColor={el.color}
|
||||
tier={el.tier}
|
||||
size={56}
|
||||
state="undiscovered"
|
||||
/>
|
||||
<div css={undiscoveredDimStyle}>
|
||||
<div css={spriteWrapStyle}>
|
||||
<div css={idleSpriteWrapperStyle(mood ?? 'awake')}>
|
||||
<CharacterSprite
|
||||
elementId={el.id}
|
||||
elementColor={el.color}
|
||||
tier={el.tier}
|
||||
size={56}
|
||||
state="undiscovered"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<span css={undiscoveredNameStyle}>???</span>
|
||||
</div>
|
||||
<span css={undiscoveredNameStyle}>???</span>
|
||||
{hint && (
|
||||
<span css={undiscoveredHintStyle(hint.craftableNow)}>{hint.display}</span>
|
||||
)}
|
||||
@@ -1539,8 +1552,6 @@ export function ElementsScreen() {
|
||||
.filter((summary): summary is ActiveBoostSummary => summary !== null && summary.remainingMs > 0)
|
||||
.sort((a, b) => a.remainingMs - b.remainingMs);
|
||||
|
||||
const MAX_UNDISCOVERED_PER_TIER = 6;
|
||||
|
||||
const tierGroups = [1, 2, 3, 4, 5].map((tier) => {
|
||||
const tierElements = elementsData.filter((el) => el.tier === tier);
|
||||
const owned = tierElements.filter((el) => discoveredElementIds.includes(el.id));
|
||||
@@ -1548,6 +1559,7 @@ export function ElementsScreen() {
|
||||
|
||||
const undiscoveredWithHints = undiscovered
|
||||
.map((el) => ({ el, hint: getRecipeHintForElement(el.id, discoveredElementIds, elements) }))
|
||||
.filter(({ hint }) => hint?.partiallyKnown ?? false)
|
||||
.sort((a, b) => {
|
||||
const aCraftable = a.hint?.craftableNow ? 1 : 0;
|
||||
const bCraftable = b.hint?.craftableNow ? 1 : 0;
|
||||
|
||||
Reference in New Issue
Block a user