Source: Frontend/game/common/game-map/room.mjs

/** @module common/game-map/Room */
import {MIN_SIZE} from "./game-map-const.mjs";
import Corridor from "./corridor.mjs";

/**
 * A room in the maze
 * @prop {number} x X coordinate of the room
 * @prop {number} y Y coordinate of the room
 * @prop {number} width Width coordinate of the room
 * @prop {number} height Height coordinate of the room
 * @prop {string} type Always room
 * @prop {boolean} noMonsters No monsters allowed in this room
 */
export default class Room {
  /**
   * <span style="color: red;">Constructor is private.</span>
   * See GameMap.rooms or GameMap.getRect for instances of Room.
   * @private
   * @param i The index of the room
   * @param x 
   * @param y 
   * @param width 
   * @param height 
   */
  constructor(i, x, y, width, height, mapParams) {
    this._i = i;
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this._params = mapParams;
    this.type = "room";
  
    this._corridors = new Map();
  }

  /**
   * Create a corridor between 2 rooms
   * @private
   */
  _connect(room, corridor) {
    this._corridors.set(room._i, corridor._to(room));
    room._corridors.set(this._i, corridor._to(this));
  }

  /**
   * All corridors connected to this room
   * @return {Corridor[]}
   */
  get corridors() {
    return Array.from(this._corridors.values());
  }

  /**
   * Get the room to the left of this one (if one exists)
   * @return {Room}
   */
  get left() {
    return this._corridors.get(this._i - 1);
  }

  /**
   * Get the room to the right of this one (if one exists)
   * @return {Room}
   */
  get right() {
    return this._corridors.get(this._i + 1);
  }

  /**
   * Get the room above this one (if one exists)
   * @return {Room}
   */
  get above() {
    return this._corridors.get(this._i - this._params.size);
  }

  /**
   * Get the room below this one (if one exists)
   * @return {Room}
   */
  get below() {
    return this._corridors.get(this._i + this._params.size);
  }

  /**
   * Is this room allowed to have monsters
   */
  get noMonsters() {
    return this._corridors.size < 2 || this._i === this._params.spawn;
  }

  /**
   * Convert the room to json
   * @private
   */
  toJSON() {
    let raw = {
      x: this.x / MIN_SIZE,
      y: this.y / MIN_SIZE,
      w: this.width / MIN_SIZE,
      h: this.height / MIN_SIZE,
      r: this._rendererName
    };

    if(this.left) {
      raw.l = this.left.toJSON();
    }

    if(this.above) {
      raw.a = this.above.toJSON();
    }

    return raw;
  }

  /**
   * Convert json into a Room
   * @private
   */
  static _parse(i, rooms, json, mapParams) {
    let room = new Room(
      i,
      json.x * MIN_SIZE,
      json.y * MIN_SIZE,
      json.w * MIN_SIZE,
      json.h * MIN_SIZE,
      mapParams
    );

    if(json.l) {
      room._connect(rooms[i - 1], Corridor._parse(json.l, mapParams));
    }

    if(json.a) {
      room._connect(rooms[i - room._params.size], Corridor._parse(json.a, mapParams));
    }

    room._rendererName = json.r;

    return room;
  }
}