403 lines · 15.3 KB · JavaScript
RawDownload
'use strict' class Input {}setEnumValues(Input, ['left', 'right', 'center', 'forward', 'back', 'action']) class Chapter {}setEnumValues(Chapter, ['act1', 'act2', 'act3', 'act4', 'act5', 'credit']) class Zone {}setEnumValues(Zone, [  'antechannel',  'capsule',  'circular',  'entente',  'forest',  'metamondst',  'nataniev',  'rainre',  'stones',  'studio']) const SealOrder = Object.freeze([  Zone.forest,  Zone.stones,  Zone.rainre,  Zone.metamondst,  Zone.antechannel]) class MazeAxis {}setEnumValues(MazeAxis, ['x', 'y']) class MazeEffect {}setEnumValues(MazeEffect, ['incr', 'decr', 'exit']) const ententeIcons = (function () {  const ententeIcons = new Map()  ententeIcons.set(-1, 'left')  ententeIcons.set(0, 'straight')  ententeIcons.set(1, 'right')  return Object.freeze(ententeIcons)})() const recordsByChapter = (function () {  const recordsByChapter = new Map()  recordsByChapter.set(Chapter.act1, 'music_act1')  recordsByChapter.set(Chapter.act2, 'music_act2')  recordsByChapter.set(Chapter.act3, 'music_act3')  recordsByChapter.set(Chapter.act4, 'music_act4')  recordsByChapter.set(Chapter.act5, 'music_act5')  recordsByChapter.set(Chapter.credit, 'music_credit')  return Object.freeze(recordsByChapter)})() const ambienceByZone = (function () {  const ambienceByZone = new Map()  ambienceByZone.set(Zone.antechannel, 'ambient_antechannel')  ambienceByZone.set(Zone.capsule, 'ambient_capsule')  ambienceByZone.set(Zone.circular, 'ambient_circular')  ambienceByZone.set(Zone.entente, null) // Weird omission, eh?  ambienceByZone.set(Zone.forest, 'ambient_forest')  ambienceByZone.set(Zone.metamondst, 'ambient_metamondst')  ambienceByZone.set(Zone.nataniev, 'ambient_nataniev')  ambienceByZone.set(Zone.rainre, 'ambient_rainre')  ambienceByZone.set(Zone.stones, 'ambient_stones')  ambienceByZone.set(Zone.studio, 'ambient_studio')  return Object.freeze(ambienceByZone)})() class SubjectType {}setEnumValues(SubjectType, ['node', 'puzzle', 'none']) class PuzzleType {}setEnumValues(PuzzleType, ['door', 'terminal']) class Node {  constructor (id, zone, subjects) {    this.id = id    this.zone = zone    this.subjects = subjects    Object.freeze(this)  }} const nodesByID = (function () {  const nodesByID = new Map()   const addNode = (id, zone, subject0, subject1, subject2, subject3) => {    nodesByID.set(      id,      Object.freeze(        new Node(id, zone, [subject0, subject1, subject2, subject3])      )    )  }   const node = (nodeID, orientation, mapIgnore = false) => {    return Object.freeze({      type: SubjectType.node,      nodeID,      orientation,      mapIgnore    })  }   const terminal = puzzleID => {    return Object.freeze({      type: SubjectType.puzzle,      puzzleType: PuzzleType.terminal,      puzzleID    })  }   const door = (    puzzleID,    nodeID,    orientation,    secretNodeID,    secretOrientation  ) => {    return Object.freeze({      type: SubjectType.puzzle,      puzzleType: PuzzleType.door,      puzzleID,      nodeID,      orientation,      alternateNodeID: secretNodeID,      alternateOrientation: secretOrientation    })  }   const secretDoor = (puzzleID, secretNodeID, secretOrientation) => {    return Object.freeze({      type: SubjectType.puzzle,      puzzleType: PuzzleType.door,      puzzleID,      alternateNodeID: secretNodeID,      alternateOrientation: secretOrientation    })  }   const maze = (    subject,    puzzleID,    axis,    effect,    amount,    mazeNodeID,    mazeOrientation  ) => {    return Object.freeze({      nodeID: subject.nodeID,      orientation: subject.orientation,      type: SubjectType.puzzle,      puzzleType: PuzzleType.door,      puzzleID,      axis,      effect,      amount,      alternateNodeID: mazeNodeID,      alternateOrientation: mazeOrientation    })  }   const none = Object.freeze({ type: SubjectType.none })    addNode("fa", Zone.forest, node("fb"), none, door(28, "ea"), none)  addNode("fb", Zone.forest, node("fc"), none, node("fa"), none)  addNode("fc", Zone.forest, node("fk"), node("fj", 2), node("fb"), node("fd", 0))  addNode("fd", Zone.forest, node("fe"), none, node("fc", 1), none)  addNode("fe", Zone.forest, node("ff"), none, node("fd"), terminal(4))  addNode("ff", Zone.forest, node("fg", 1), none, node("fe"), none)  addNode("fg", Zone.forest, node("fl"), node("fh", 0), terminal(1), node("ff", 2))  addNode("fh", Zone.forest, node("fi", 2), none, node("fg", 3), none)  addNode("fi", Zone.forest, node("fh", 2), none, node("fj", 0), none)   addNode("fj", Zone.forest, node("fc", 3), none, node("fi", 0), none)  addNode("fk", Zone.forest, door(25, "ao", 2), none, node("fc"), none)  addNode("fl", Zone.forest, door(3, "sa"), none, node("fg"), node("fm", 0))  addNode("sa", Zone.studio, node("sc"), node("sb"), door(3, "fl"), terminal(2))  addNode("fm", Zone.forest, node("fn"), none, node("fl", 1), none)  addNode("sb", Zone.studio, node("sd"), none, none, node("sa"))  addNode("sd", Zone.studio, node("sg"), door(7, "ci"), node("sb"), node("sc"))  addNode("sc", Zone.studio, node("sf"), node("sd"), node("sa"), none)  addNode("fn", Zone.forest, terminal(31), terminal(2), node("fm"), none)  addNode("se", Zone.studio, none, node("sf"), terminal(5), none)   addNode("sf", Zone.studio, secretDoor(6, "ez", 1), node("sg"), node("sc"), node("se"))  addNode("sg", Zone.studio, terminal(35), none, node("sd"), node("sf"))  addNode("ci", Zone.circular, none, node("ca"), none, node("sd"))  addNode("ca", Zone.circular, node("cb"), terminal(16), node("ch"), door(7, "ci"))  addNode("ch", Zone.circular, node("ca"), none, node("cg"), none)  addNode("cg", Zone.circular, node("ch"), none, node("cf"), door(8, "cl", 2))  addNode("cf", Zone.circular, node("cg"), none, node("ce"), none)  addNode("ce", Zone.circular, node("cf"), none, node("cd"), door(9, "ck", 1))  addNode("cd", Zone.circular, node("ce"), none, node("cc"), none)  addNode("cc", Zone.circular, node("cd"), none, node("cb"), node("cj", 0))   addNode("cb", Zone.circular, node("cc"), none, node("ca"), none)  addNode("cl", Zone.circular, node("cg", 1), none, node("la"), none)  addNode("ck", Zone.circular, none, node("aa"), none, node("ce", 1))  addNode("cj", Zone.circular, terminal(14), none, node("cc", 1), none)  addNode("ey", Zone.entente, terminal(37), none, none, node("le"))  addNode("la", Zone.stones, door(8, "cl", 0), node("lb"), node("lc"), none)  addNode("lc", Zone.stones, node("la"), node("ld"), none, none)  addNode("ld", Zone.stones, node("lb"), node("le"), none, node("lc"))  addNode("lb", Zone.stones, terminal(12), none, node("ld"), node("la"))  const node39Door = door(11, "ra", null, "ey")  addNode("le", Zone.stones, terminal(10), node39Door, node("lf"), node("ld"))   addNode("lf", Zone.stones, node("le"), none, node("lg"), none)  addNode("lg", Zone.stones, node("lf"), none, none, node("lh"))  addNode("lh", Zone.stones, none, node("lg"), node("lj"), node("li"))  addNode("li", Zone.stones, none, node("lh"), none, terminal(35))  addNode("lj", Zone.stones, node("lh"), none, node("lk"), none)  addNode("ra", Zone.rainre, terminal(13), none, terminal(1), node("le"))  addNode("lk", Zone.stones, node("lj"), none, door(15, "ma", 2), none)  addNode("an", Zone.antechannel, none, node("ao"), node("am"), none)  addNode("ao", Zone.antechannel, door(25, "fk", 2), none, node("ap"), node("an"))  addNode("ap", Zone.antechannel, node("ao"), none, terminal(21), node("am"))   addNode("ne", Zone.nataniev, door(40, "nd"), none, terminal(41), none)   addNode("aa", Zone.antechannel, node("ad"), node("ab"), none, door(9, "ck", 3))  addNode("ab", Zone.antechannel, node("ae"), node("ac"), none, node("aa"))  addNode("ad", Zone.antechannel, node("ag"), node("ae"), node("aa"), none)  addNode("ae", Zone.antechannel, terminal(39), node("af"), node("ab"), node("ad"))  addNode("af", Zone.antechannel, node("aj"), none, node("ac"), node("ae"))  addNode("ag", Zone.antechannel, node("ah"), none, node("ad"), none)  addNode("aj", Zone.antechannel, node("ak"), none, node("af"), none)  addNode("ah", Zone.antechannel, node("ai"), none, node("ag"), none)   addNode("ak", Zone.antechannel, node("al"), none, node("af", null, true), none) // Feature, not a bug!  addNode("ai", Zone.antechannel, none, none, node("ah"), door(19, "mk"))  addNode("al", Zone.antechannel, door(26, "am"), none, node("ak"), none)  addNode("mi", Zone.metamondst, node("ml"), node("mj"), none, node("me"))  addNode("nf", Zone.nataniev, node("mi"), none, none, none) // TODO: something interesting  const node65Maze = maze(node("ee"), 42, MazeAxis.y, MazeEffect.exit, 0, "eq", 3)  addNode("ep", Zone.entente, node("ej"), none, node65Maze, none)   addNode("me", Zone.metamondst, node("md"), node("mi"), none, node("mf"))   addNode("mj", Zone.metamondst, terminal(18), door(19, "mk"), none, node("mi"))   addNode("mf", Zone.metamondst, node("mg"), node("me"), none, none)   addNode("mk", Zone.metamondst, none, node("ai"), none, node("mj"))  addNode("ml", Zone.metamondst, node("mm"), none, node("mi"), none)  addNode("md", Zone.metamondst, node("mc"), none, node("me"), none)  addNode("mg", Zone.metamondst, node("mh"), none, node("mf"), none)  addNode("mh", Zone.metamondst, none, none, node("mg"), door(30, "pa"))  addNode("am", Zone.antechannel, node("an"), node("ap"), door(26, "al"), terminal(27))  addNode("mp", Zone.metamondst, node("mo"), none, none, node("mm"))  addNode("pb", Zone.capsule, none, door(33, "na"), node("pa"), none)   addNode("mc", Zone.metamondst, node("ma"), none, node("md"), none)  addNode("mm", Zone.metamondst, node("mn"), node("mp"), node("ml"), none)  addNode("mn", Zone.metamondst, none, node("mo"), node("mm"), terminal(20))  addNode("mo", Zone.metamondst, none, none, node("mp"), node("mn"))  addNode("ac", Zone.antechannel, node("af"), none, terminal(47), node("ab"))  addNode("ma", Zone.metamondst, door(15, "lk", 0), none, node("mc"), node("mb"))  addNode("mb", Zone.metamondst, none, node("ma"), none, terminal(1))  addNode("pa", Zone.capsule, node("pb"), door(30, "mh"), none, node("pc"))  addNode("pc", Zone.capsule, none, node("pa"), none, node("pd"))   const node89Maze = maze(node("eo"), 42, MazeAxis.x, MazeEffect.decr, 1)  addNode("ea", Zone.entente, node89Maze, none, node("eb"), none)  addNode("eb", Zone.entente, node("ea"), none, node("ec"), none)  const node91Maze = maze(node("eo"), 42, MazeAxis.x, MazeEffect.incr, 3, "ed")  addNode("ec", Zone.entente, node("eb"), terminal(23), node91Maze, none)   addNode("ed", Zone.entente, node("ec"), none, node("ee"), none)  addNode("ee", Zone.entente, node("ed"), none, node("ef"), none)  addNode("ef", Zone.entente, node("ee"), none, node("eg"), none)  addNode("eg", Zone.entente, node("ef"), terminal(24), node("eh"), none)  addNode("eh", Zone.entente, node("eg"), none, node("ei"), none)  addNode("ei", Zone.entente, node("eh"), none, node("ej"), none)  addNode("ej", Zone.entente, node("ei"), node("ek"), node("ep"), node("em"))  addNode("ek", Zone.entente, none, node("el"), none, node("ej"))  const node100Maze = maze(node("eg", 2), 42, MazeAxis.y, MazeEffect.decr, 1)  addNode("el", Zone.entente, none, node100Maze, none, node("ek"))  addNode("em", Zone.entente, none, node("ej"), terminal(38), node("en"))  const node102Maze = maze(node("eg", 2), 42, MazeAxis.y, MazeEffect.incr, 4)  addNode("en", Zone.entente, none, node("em"), none, node102Maze)  addNode("eo", Zone.entente, node("ec"), none, node("ea"), none)   addNode("ex", Zone.entente, none, node("eq"), none, node("ew"))  addNode("ew", Zone.entente, none, node("ex"), none, node("ev"))  addNode("ev", Zone.entente, none, node("ew"), none, node("eq"))  addNode("eq", Zone.entente, none, node("ev"), none, node("er"))  addNode("er", Zone.entente, none, node("eq"), none, node("es"))  addNode("es", Zone.entente, none, node("er"), terminal(43), node("et"))  addNode("et", Zone.entente, none, node("es"), none, node("eu"))  addNode("eu", Zone.entente, none, node("et"), none, node("fa", 0))   addNode("na", Zone.nataniev, node("nb"), node("nd"), none, door(33, "pb"))  addNode("nd", Zone.nataniev, node("nc"), terminal(36), door(40, "ne"), node("na"))  addNode("nc", Zone.nataniev, none, none, node("nd"), node("nb"))  addNode("nb", Zone.nataniev, none, node("nc"), node("na"), none)  addNode("ez", Zone.entente, none, none, none, node("sf", 2))   addNode("pd", Zone.capsule, none, node("pc"), none, node("pe")) // was 141  addNode("pe", Zone.capsule, none, node("pd"), none, door(54, "pf", 3)) // was 142  addNode("pf", Zone.capsule, none, door(54, "pe", 1), none, none) // was 143  return Object.freeze(nodesByID)})() const puzzlesByID = (function () {  const puzzlesByID = new Map()   const addPuzzle = puzzle => {    puzzlesByID.set(puzzle.id, Object.freeze(puzzle))  }   const lock = (chapter, seals) => {    return Object.freeze({ chapter, seals })  }   const ententeMazeGoal = Object.freeze(    new Map([[MazeAxis.x, 2], [MazeAxis.y, 17]])  )   const act2Lock = lock(Chapter.act2, [Zone.forest, Zone.rainre])  const act3Lock = lock(Chapter.act3, [Zone.metamondst, Zone.rainre])  const act4Lock = lock(Chapter.act4, [Zone.rainre, Zone.antechannel])   addPuzzle(new ClockTerminal(1))  addPuzzle(new EnergyTerminal(2))  addPuzzle(new EnergyDoor(3, [2]))  addPuzzle(new SealTerminal(4, Zone.forest))  addPuzzle(new StudioTerminal(5, [Zone.stones, Zone.antechannel]))  addPuzzle(new SecretDoor(6))  addPuzzle(new ClockDoor(7, 0))  addPuzzle(new ClockDoor(8, 2))  addPuzzle(new ClockDoor(9, 1))  addPuzzle(new EnergyTerminal(10))  addPuzzle(new SecretEnergyDoor(11, [10], [31]))  addPuzzle(new SealTerminal(12, Zone.stones))  addPuzzle(new SealTerminal(13, Zone.rainre))  addPuzzle(new KillTerminal(14, 50))  addPuzzle(new SealDoor(15, [act2Lock, act4Lock], 1))  addPuzzle(new ProgressTerminal(16))  // We removed puzzle 17 (the illusion puzzle)  addPuzzle(new EnergyTerminal(18))  addPuzzle(new EnergyDoor(19, [18]))  addPuzzle(new SealTerminal(20, Zone.metamondst))  addPuzzle(new SealTerminal(21, Zone.antechannel))  // unused  addPuzzle(new EntenteTerminal(23, MazeAxis.x, ententeMazeGoal))  addPuzzle(new EntenteTerminal(24, MazeAxis.y, ententeMazeGoal))  addPuzzle(new SealDoor(25, [act3Lock], 1))  addPuzzle(new EnergyDoor(26, [27]))  addPuzzle(new EnergyTerminal(27))  addPuzzle(new StudioDoor(28, 1))  // unused  addPuzzle(new StudioDoor(30))  addPuzzle(new EnergyTerminal(31, 1))  // unused  addPuzzle(new EnergyDoor(33, [47]))  addPuzzle(new AudioTerminal(34, 1))  addPuzzle(new AudioTerminal(35, 1))  addPuzzle(new EnergyTerminal(36))  addPuzzle(new SecretTerminal(37))  addPuzzle(new EnergyTerminal(38, 1)) // Entente Fuse  addPuzzle(new EnergyTerminal(39, 1))  addPuzzle(new EndgameDoor(40, [36, 47]))  addPuzzle(new EndgameCredit(41))  addPuzzle(new EntenteDoor(42, ententeMazeGoal))  addPuzzle(new EntenteProgressTerminal(43))  // unused  // unused  // unused  addPuzzle(new EnergyTerminal(47)) // Spare Fuse  // unused  // unused  // unused  // unused  // unused  // unused  addPuzzle(new TimeDoor(54, 15, 7))   return Object.freeze(puzzlesByID)})() const createDefaultState = function () {  const state = {    seals: new Set(),    fuses: new Set(),    clock: 0,    audio: true,    studio: false,    secret: false,    timeDoor: false  }  for (const puzzle of puzzlesByID.values()) {    if (puzzle instanceof EnergyTerminal && puzzle.filledOnNewGame) {      state.fuses.add(puzzle.id)    }  }  return state}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t