A dark, mysterious five-act ARG built around hidden archives and forgotten witnesses.

Commit 0d24b835

0d24b8359f5aMerged

Fenria-Aspen <[email protected]> · 1 month ago · 1 file · +1 added

Description

Fix puzzle submissions and hint buttons at runtime

Details

Commit
0d24b8359f5a
Parent
7a48ce452cb7

assets/js/puzzle-fixes.jsaddedView file

1+// Runtime fixes for puzzle forms and hints.
2+(function () {
3+ function findPuzzle(id) {
4+ for (const act of Acts.data) {
5+ const puzzle = act.sections.find(section => section.id === id);
6+ if (puzzle) return puzzle;
7+ }
8+ return null;
9+ }
10+
11+ Acts.checkPuzzle = function (puzzleId, answer) {
12+ const puzzle = findPuzzle(puzzleId);
13+ const form = document.querySelector(`.puzzle-form[data-puzzle-id="${puzzleId}"]`);
14+ if (!puzzle || !form) return;
15+ const result = form.querySelector('.puzzle-result');
16+ const input = form.querySelector('input');
17+ const normalize = value => String(value || '').trim().toUpperCase().replace(/[^A-Z0-9 ]/g, '').replace(/\s+/g, ' ');
18+ const accepted = [puzzle.answer, ...(puzzle.alternate_answers || [])].map(normalize);
19+
20+ if (accepted.includes(normalize(answer))) {
21+ result.textContent = `✓ ${puzzle.successMessage || 'Correct.'}`;
22+ result.className = 'puzzle-result success';
23+ input.disabled = true;
24+ form.querySelector('button[type="submit"]').disabled = true;
25+ GameState.solvePuzzle(puzzleId);
26+ (puzzle.rewards || []).forEach(reward => {
27+ if (reward.type === 'item') GameState.addItem(reward.id, { name: reward.name, description: reward.description, icon: '📦' });
28+ if (reward.type === 'evidence') GameState.addEvidence(reward.id, { title: reward.name, description: reward.description });
29+ if (reward.type === 'unlock') GameState.unlockSection(reward.section);
30+ });
31+ const fill = document.querySelector('.progress-fill');
32+ if (fill) fill.style.width = `${GameState.getCompletion()}%`;
33+ } else {
34+ result.textContent = '✗ INCORRECT. Try again.';
35+ result.className = 'puzzle-result error';
36+ GameState.recordAttempt(puzzleId, answer);
37+ input.value = '';
38+ input.focus();
39+ }
40+ };
41+
42+ Acts.showHint = function (puzzleId) {
43+ const puzzle = findPuzzle(puzzleId);
44+ const form = document.querySelector(`.puzzle-form[data-puzzle-id="${puzzleId}"]`);
45+ if (!puzzle || !form || !puzzle.hints) return;
46+ Acts.attemptCount = Acts.attemptCount || {};
47+ const index = Math.min(Acts.attemptCount[puzzleId] || 0, puzzle.hints.length - 1);
48+ const result = form.querySelector('.puzzle-result');
49+ result.textContent = `💡 ${puzzle.hints[index]}`;
50+ result.className = 'puzzle-result hint';
51+ Acts.attemptCount[puzzleId] = index + 1;
52+ };
53+})();