about summary refs log tree commit diff stats
path: root/data/maps/the_bearer/README
blob: 815833b7fceb8522392e355b03ee7dfe24f8b5ff (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
This map is a bit of a mess. The top areas should make sense but the bottom area
is confusing because of the fact that many panels can be seen from multiple
places in the grid, and it is intended for you to solve them through the
transparent doors. The approach to this is threefold.

1. Panels that can be solved without opening any doors are all in the Entry
   region. This includes the two panels physically accessible from the warp
   hallways, as well as the two panels each that can be seen while standing next
   to those panels, for a total of six panels in the Entry region (plus the two
   that are actually upstairs).
2. The part of the grid behind where you enter is actually completely linear.
   There is one region for each grid square in this area, except for the middle
   two in the orange row. The regions are named after the positions you stand
   in, not the panels at those positions in the grid. Instead, each region
   contains the panel you can see from that position. This is why the two middle
   orange grid squares do not have regions, because they are solvable from the
   red row and entering the regions does nothing.
3. For the rest of the grid, each panel is visible from two other grid
   positions. To handle this, there is a region for every grid position you can
   stand in, and a region for every panel. The standing regions are connected to
   each adjacent grid square using event doors, and there is a oneway connection
   from each standing region into the panel regions for each panel that can be
   seen from that standing position.
244' href='#n244'>244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
#include "container.h"

#include <iostream>

#include "util/naming.h"

namespace com::fourisland::lingo2_archipelago {

uint64_t Container::FindOrAddMap(std::string map_name) {
  auto it = map_id_by_name_.find(map_name);

  if (it == map_id_by_name_.end()) {
    uint64_t new_id = all_objects_.maps_size();
    Map* map = all_objects_.add_maps();
    map->set_id(new_id);
    map->set_name(map_name);

    map_id_by_name_[map_name] = new_id;

    return new_id;
  } else {
    return it->second;
  }
}

uint64_t Container::FindOrAddRoom(std::optional<std::string> map_name,
                                  std::string room_name,
                                  std::optional<std::string> map_fallback) {
  if (!map_name) {
    if (!map_fallback) {
      std::cout << "No map name provided for " << room_name << std::endl;
      map_name = "global";
    } else {
      map_name = map_fallback;
    }
  }

  auto& map_container = room_id_by_map_room_names_[*map_name];
  auto it = map_container.find(room_name);
  if (it == map_container.end()) {
    uint64_t new_id = all_objects_.rooms_size();
    Room* room = all_objects_.add_rooms();
    room->set_id(new_id);
    room->set_map_id(FindOrAddMap(*map_name));
    room->set_name(room_name);

    map_container[room_name] = new_id;

    return new_id;
  } else {
    return it->second;
  }
}

uint64_t Container::FindOrAddPainting(
    std::optional<std::string> map_name, std::optional<std::string> room_name,
    std::string painting_name, std::optional<std::string> map_fallback,
    std::optional<std::string> room_fallback) {
  if (!map_name) {
    if (!map_fallback) {
      std::cout << "No map name provided for " << painting_name << std::endl;
      map_name = "global";
    } else {
      map_name = map_fallback;
    }
  }

  if (!room_name) {
    if (!room_fallback) {
      std::cout << "No room name provided for " << painting_name << std::endl;
      room_name = "global";
    } else {
      room_name = room_fallback;
    }
  }

  auto& room_container =
      painting_id_by_map_room_painting_names_[*map_name][*room_name];
  auto it = room_container.find(painting_name);
  if (it == room_container.end()) {
    uint64_t new_id = all_objects_.paintings_size();
    Painting* painting = all_objects_.add_paintings();
    painting->set_id(new_id);
    painting->set_room_id(FindOrAddRoom(map_name, *room_name, std::nullopt));
    painting->set_name(painting_name);

    room_container[painting_name] = new_id;

    return new_id;
  } else {
    return it->second;
  }
}

uint64_t Container::FindOrAddPort(std::optional<std::string> map_name,
                                  std::optional<std::string> room_name,
                                  std::string port_name,
                                  std::optional<std::string> map_fallback,
                                  std::optional<std::string> room_fallback) {
  if (!map_name) {
    if (!map_fallback) {
      std::cout << "No map name provided for " << port_name << std::endl;
      map_name = "global";
    } else {
      map_name = map_fallback;
    }
  }

  if (!room_name) {
    if (!room_fallback) {
      std::cout << "No room name provided for " << port_name << std::endl;
      room_name = "global";
    } else {
      room_name = room_fallback;
    }
  }

  auto& room_container = port_id_by_map_room_port_names_[*map_name][*room_name];
  auto it = room_container.find(port_name);
  if (it == room_container.end()) {
    uint64_t new_id = all_objects_.ports_size();
    Port* port = all_objects_.add_ports();
    port->set_id(new_id);
    port->set_room_id(FindOrAddRoom(map_name, *room_name, std::nullopt));
    port->set_name(port_name);

    room_container[port_name] = new_id;

    return new_id;
  } else {
    return it->second;
  }
}

uint64_t Container::FindOrAddPanel(std::optional<std::string> map_name,
                                   std::optional<std::string> room_name,
                                   std::string panel_name,
                                   std::optional<std::string> map_fallback,
                                   std::optional<std::string> room_fallback) {
  if (!map_name) {
    if (!map_fallback) {
      std::cout << "No map name provided for " << panel_name << std::endl;
      map_name = "global";
    } else {
      map_name = map_fallback;
    }
  }

  if (!room_name) {
    if (!room_fallback) {
      std::cout << "No room name provided for " << panel_name << std::endl;
      room_name = "global";
    } else {
      room_name = room_fallback;
    }
  }

  auto& room_container =
      panel_id_by_map_room_panel_names_[*map_name][*room_name];
  auto it = room_container.find(panel_name);
  if (it == room_container.end()) {
    uint64_t new_id = all_objects_.panels_size();
    Panel* panel = all_objects_.add_panels();
    panel->set_id(new_id);
    panel->set_room_id(FindOrAddRoom(map_name, *room_name, std::nullopt));
    panel->set_name(panel_name);

    room_container[panel_name] = new_id;

    return new_id;
  } else {
    return it->second;
  }
}

uint64_t Container::FindOrAddLetter(std::string key, bool double_) {
  std::string letter_name = GetLetterName(key, double_);

  auto it = letter_id_by_name_.find(letter_name);
  if (it == letter_id_by_name_.end()) {
    uint64_t new_id = all_objects_.letters_size();
    Letter* letter = all_objects_.add_letters();
    letter->set_id(new_id);
    letter->set_key(key);

    if (double_) {
      letter->set_double_(double_);
    }

    letter_id_by_name_[letter_name] = new_id;

    return new_id;
  } else {
    return it->second;
  }
}

uint64_t Container::FindLetterByName(std::string letter_name) {
  auto it = letter_id_by_name_.find(letter_name);
  if (it == letter_id_by_name_.end()) {
    std::cout << "Could not find letter by name: " << letter_name << std::endl;
    exit(2);
  } else {
    return it->second;
  }
}

uint64_t Container::FindOrAddMastery(std::optional<std::string> map_name,
                                     std::optional<std::string> room_name,
                                     std::string mastery_name,
                                     std::optional<std::string> map_fallback,
                                     std::optional<std::string> room_fallback) {
  if (!map_name) {
    if (!map_fallback) {
      std::cout << "No map name provided for " << mastery_name << std::endl;
      map_name = "global";
    } else {
      map_name = map_fallback;
    }
  }

  if (!room_name) {
    if (!room_fallback) {
      std::cout << "No room name provided for " << mastery_name << std::endl;
      room_name = "global";
    } else {
      room_name = room_fallback;
    }
  }

  auto& room_container =
      mastery_id_by_map_room_mastery_names_[*map_name][*room_name];
  auto it = room_container.find(mastery_name);
  if (it == room_container.end()) {
    uint64_t new_id = all_objects_.masteries_size();
    Mastery* mastery = all_objects_.add_masteries();
    mastery->set_id(new_id);
    mastery->set_room_id(FindOrAddRoom(map_name, *room_name, std::nullopt));
    mastery->set_name(mastery_name);

    room_container[mastery_name] = new_id;

    return new_id;
  } else {
    return it->second;
  }
}

uint64_t Container::FindOrAddKeyholder(
    std::optional<std::string> map_name, std::optional<std::string> room_name,
    std::string keyholder_name, std::optional<std::string> map_fallback,
    std::optional<std::string> room_fallback) {
  if (!map_name) {
    if (!map_fallback) {
      std::cout << "No map name provided for " << keyholder_name << std::endl;
      map_name = "global";
    } else {
      map_name = map_fallback;
    }
  }

  if (!room_name) {
    if (!room_fallback) {
      std::cout << "No room name provided for " << keyholder_name << std::endl;
      room_name = "global";
    } else {
      room_name = room_fallback;
    }
  }

  auto& room_container =
      keyholder_id_by_map_room_keyholder_names_[*map_name][*room_name];
  auto it = room_container.find(keyholder_name);
  if (it == room_container.end()) {
    uint64_t new_id = all_objects_.keyholders_size();
    Keyholder* keyholder = all_objects_.add_keyholders();
    keyholder->set_id(new_id);
    keyholder->set_room_id(FindOrAddRoom(map_name, *room_name, std::nullopt));
    keyholder->set_name(keyholder_name);

    room_container[keyholder_name] = new_id;

    return new_id;
  } else {
    return it->second;
  }
}

uint64_t Container::FindOrAddDoor(std::optional<std::string> map_name,
                                  std::string door_name,
                                  std::optional<std::string> map_fallback) {
  if (!map_name) {
    if (!map_fallback) {
      std::cout << "No map name provided for " << door_name << std::endl;
      map_name = "global";
    } else {
      map_name = map_fallback;
    }
  }

  auto& map_container = door_id_by_map_door_names_[*map_name];
  auto it = map_container.find(door_name);
  if (it == map_container.end()) {
    uint64_t new_id = all_objects_.doors_size();
    Door* door = all_objects_.add_doors();
    door->set_id(new_id);
    door->set_map_id(FindOrAddMap(*map_name));
    door->set_name(door_name);

    map_container[door_name] = new_id;

    return new_id;
  } else {
    return it->second;
  }
}

void Container::AddConnection(const Connection& connection) {
  *all_objects_.add_connections() = connection;
}

}  // namespace com::fourisland::lingo2_archipelago