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

Download ZIP
assets/js/puzzle-fixes.js 53 lines · 2.4 KB · javascript
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
})();