|  | dirs = {
  "up-left": "Northwest",
  "up": "North",
  "up-right": "Northeast",
  "left": "West",
  "right": "East",
  "down-left": "Southwest",
  "down": "South",
  "down-right": "Southeast",
  "ascend": "Up",
  "descend": "Down"
}
function initWorld(worldChoice, state) {
  state.world = worlds[worldChoice];
  initRoomState(state);
}
function initRoomState(state) {
  console.log(state.world);
  state.player.rooms = {};
  Object.entries(state.world).forEach(([key, val]) => {
    state.player.rooms[key] = {};
  });
}
function showActionDescription(desc) {
  const descHolder = document.querySelector("#desc");
  descHolder.textContent = desc;
}
function removeActionDescription() {
  const descHolder = document.querySelector("#desc");
  descHolder.textContent = "";
}
function moveToRoom(src, exit, dest, state) {
  console.log(state)
  const room = state.world[dest];
  if (exit.hooks) {
    for (let hook of exit.hooks) {
      if (!hook(room, exit, state)) {
        return;
      }
    }
  }
  if (room.hooks) {
    for (let hook of room.hooks) {
      if (!hook(room, state)) {
        return;
      }
    }
  }
  state.world[dest].move(state.world[dest], state);
  updateRoom(dest, state);
}
function goToRoom(dest, state) {
  const room = state.world[dest];
  if (room.hooks) {
    for (let hook of room.hooks) {
      if (!hook(room, state)) {
        return;
      }
    }
  }
  updateRoom(dest, state);
}
function updateRoom(dest, state) {
  const room = state.world[dest];
  if (!state.player.rooms[dest.id]) {
    state.player.rooms[dest.id] = {};
  }
  const areaName = document.querySelector("#area-name");
  const areaDesc = document.querySelector("#area-desc");
  areaName.textContent = room.name;
  areaDesc.textContent = room.desc;
  const moveHolder = document.querySelector("#move-holder");
  moveHolder.innerHTML = "";
  Object.entries(dirs).forEach(([dir, name]) => {
    const button = document.createElement("button");
    button.classList.add("move-button")
    button.id = "move-" + dir;
    button.classList.add("disabled");
    button.setAttribute("disabled", "true");
    button.textContent = dirs[dir];
    moveHolder.appendChild(button);
  });
  if (room.exits) {
    Object.entries(room.exits).forEach(([dir, exit]) => {
      const button = document.querySelector("#move-" + dir);
      const dest = state.world[exit.target];
      // don't even show an exit if this fails!
      if (exit.show) {
        if (!exit.show.every(cond => cond(room, state))) {
          return;
        }
      }
      button.textContent = dest.name;
      // if any condition fails, don't enable/add a listener
      if (exit.conditions) {
        if (!exit.conditions.every(cond => cond(room,state))) {
          return;
        }
      }
      button.classList.remove("disabled");
      button.removeAttribute("disabled");
      button.addEventListener("click", () => {
        // todo: log
        moveToRoom(room, exit, exit.target, state);
      })
    });
  }
  const actionHolder = document.querySelector("#actions");
  actionHolder.innerHTML = "";
  if (room.actions) {
    room.actions.forEach(action => {
      const button = document.createElement("button");
      button.classList.add("action-button");
      if (action.show) {
        if (!action.show.every(cond => cond(room, state))) {
          return;
        }
      }
      button.textContent = action.name;
      actionHolder.appendChild(button);
      if (action.conditions) {
        if (!action.conditions.every(cond => cond(room, state))) {
          button.classList.add("disabled");
          button.setAttribute("disabled", "true");
          return;
        }
      }
      button.addEventListener("click", () => {
        action.execute(room, state);
        updateRoom(room.id, state);
      });
      button.addEventListener("mouseenter", () => {
        showActionDescription(action.desc);
      });
      button.addEventListener("mouseleave", () => {
        removeActionDescription();
      });
    });
  }
}
worlds = {
  "demo": {
    "Home": {
      "id": "Home",
      "name": "Home",
      "desc": "Where the wifi autoconnects",
      "move": (room, state) => {
        print(["You go back to your living room"]);
      },
      "actions": [
        {
          "name": "Squint",
          "desc": "Squint in a very aggressive manner",
          "execute": (room, state) => {
            state.player.rooms[room.id].squinted = true;
            print(["You stare at the wall and notice a secret door. But where is the key?"]);
          }
        },
        {
          "name": "Find Keys",
          "desc": "Find your keys",
          "execute": (room, state) => {
            state.player.items.keys.push("Locked Room");
            print(["You found your keys under the couch cushions"]);
          },
          "show": [
            (room, state) => {
              return state.player.rooms[room.id].squinted;
            },
            (room, state) => {
              return !state.player.items.keys.includes("Locked Room");
            }
          ]
        }
      ],
      "exits": {
        "up": {
          "target": "Locked Room",
          "desc": "It's locked!",
          "conditions": [
            (room, state) => {
              return state.player.items.keys.includes("Locked Room");
            }
          ],
          "show": [
            (room, state) => {
              console.log(room);
              return state.player.rooms[room.id].squinted;
            }
          ]
        }
      },
      "hooks": [
        (room, state) => {
          print(["This is a test of the hooks"]);
          return true;
        }
      ]
    },
    "Locked Room": {
      "id": "Locked Room",
      "name": "Locked Room",
      "desc": "Super seecret",
      "move": (room, state) => {
        print(["You enter the locked room. wowie!"]);
      },
      "exits": {
        "down": {
          "target": "Home",
          "desc": "Back to home",
          "hooks": [
            (room, exit, state) => {
              print(["Potato"]);
              console.log(room);
              console.log(exit);
              console.log(state);
              return true;
            }
          ]
        }
      }
    }
  }
}
 |