from enum import IntEnum, auto
from .generated import data_pb2 as data_pb2
from .items import SYMBOL_ITEMS
from typing import TYPE_CHECKING, NamedTuple
from .options import VictoryCondition, ShuffleLetters, CyanDoorBehavior
if TYPE_CHECKINGpre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */#include <google/protobuf/message.h>
#include <google/protobuf/text_format.h>
#include <algorithm>
#include <cstdint>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <map>
#include <optional>
#include <sstream>
#include <string>
#include "container.h"
#include "proto/data.pb.h"
#include "proto/human.pb.h"
#include "util/ids_yaml_format.h"
namespace com::fourisland::lingo2_archipelago {
namespace {
template <typename T>
T ReadMessageFromFile(const std::string& path) {
std::cout << "Processing " << path << std::endl;
std::ifstream file(path);
std::stringstream buffer;
buffer << file.rdbuf();
T message;
google::protobuf::TextFormat::ParseFromString(buffer.str(), &message);
return message;
}
class DataPacker {
public:
DataPacker(const std::string& mapdir, const std::string& outputpath)
: mapdir_(mapdir), outputpath_(outputpath) {}
void Run() {
std::filesystem::path datadir_path = mapdir_;
ProcessConnectionsFile(datadir_path / "connections.txtpb", std::nullopt);
ProcessMaps(datadir_path);
ProcessProgressivesFile(datadir_path / "progressives.txtpb");
ProcessDoorGroupsFile(datadir_path / "door_groups.txtpb");
ProcessGlobalMetadataFile(datadir_path / "metadata.txtpb");
ProcessIdsFile(datadir_path / "ids.yaml");
{
std::ofstream outputfile(outputpath_);
container_.all_objects().SerializeToOstream(&outputfile);
}
/*std::string output;
google::protobuf::TextFormat::PrintToString(container_.all_objects(),
&output);
std::cout << output << std::endl;*/
}
private:
void ProcessMaps(std::filesystem::path path) {
std::filesystem::path maps_dir = path / "maps";
for (auto const& dir_entry :
std::filesystem::directory_iterator(maps_dir)) {
ProcessMap(dir_entry.path());
}
}
void ProcessMap(std::filesystem::path path) {
std::string map_name = path.filename().string();
ProcessMapMetadataFile(path / "metadata.txtpb", map_name);
ProcessConnectionsFile(path / "connections.txtpb", map_name);
ProcessDoorsFile(path / "doors.txtpb", map_name);
ProcessRooms(path / "rooms", map_name);
}
void ProcessMapMetadataFile(std::filesystem::path path,
const std::string& map_name) {
if (!std::filesystem::exists(path)) {
return;
}
auto metadata = ReadMessageFromFile<HumanMap>(path.string());
uint64_t map_id = container_.FindOrAddMap(map_name);
Map& map = *container_.all_objects().mutable_maps(map_id);
if (metadata.has_display_name()) {
map.set_display_name(metadata.display_name());
}
}
void ProcessRooms(std::filesystem::path path,
const std::string& current_map_name) {
for (auto const& dir_entry : std::filesystem::directory_iterator(path)) {
auto room = ReadMessageFromFile<HumanRoom>(dir_entry.path().string());
ProcessRoom(room, current_map_name);
}
}
void ProcessRoom(const HumanRoom& h_room,
const std::string& current_map_name) {
uint64_t room_id =
container_.FindOrAddRoom(current_map_name, h_room.name(), std::nullopt);
Room& room = *container_.all_objects().mutable_rooms(room_id);
// room.set_display_name(h_room.display_name());
if (h_room.has_panel_display_name()) {
room.set_panel_display_name(h_room.panel_display_name());
}
for (const HumanPanel& h_panel : h_room.panels()) {
room.add_panels(ProcessPanel(h_panel, current_map_name, room.name()));
}
for (const HumanPainting& h_painting : h_room.paintings()) {
room.add_paintings(
ProcessPainting(h_painting, current_map_name, room.name()));
}
for (const HumanPort& h_port : h_room.ports()) {
room.add_ports(ProcessPort(h_port, current_map_name, room.name()));
}
for (const HumanLetter& h_letter : h_room.letters()) {
room.add_letters(ProcessLetter(h_letter, current_map_name, room.name()));
}
for (const HumanMastery& h_mastery : h_room.masteries()) {
room.add_masteries(
ProcessMastery(h_mastery, current_map_name, room.name()));
}
for (const HumanKeyholder& h_keyholder : h_room.keyholders()) {
room.add_keyholders(
ProcessKeyholder(h_keyholder, current_map_name, room.name()));
}
for (const HumanEnding& h_ending : h_room.endings()) {
room.add_endings(ProcessEnding(h_ending, current_map_name, room.name()));
}
}
uint64_t ProcessPanel(const HumanPanel& h_panel,
const std::string& current_map_name,
const std::string& current_room_name) {
uint64_t panel_id =
container_.FindOrAddPanel(current_map_name, current_room_name,
h_panel.name(), std::nullopt, std::nullopt);
PanelData& panel = *container_.all_objects().mutable_panels(panel_id);
panel.set_path(h_panel.path());
panel.set_clue(h_panel.clue());
panel.set_answer(h_panel.answer());
std::copy(
h_panel.symbols().begin(), h_panel.symbols().end(),
google::protobuf::RepeatedFieldBackInserter(panel.mutable_symbols()));
std::copy(
h_panel.proxies().begin(), h_panel.proxies().end(),
google::protobuf::RepeatedFieldBackInserter(panel.mutable_proxies()));
if (h_panel.has_required_door()) {
std::optional<std::string> map_name =
h_panel.required_door().has_map()
? std::optional<std::string>(h_panel.required_door().map())
: std::nullopt;
panel.set_required_door(container_.FindOrAddDoor(
map_name, h_panel.required_door().name(), current_map_name));
}
if (h_panel.has_required_room()) {
std::optional<std::string> map_name =
h_panel.required_room().has_map()
? std::optional<std::string>(h_panel.required_room().map())
: std::nullopt;
panel.set_required_room(container_.FindOrAddRoom(
map_name, h_panel.required_room().name(), current_map_name));
}
if (h_panel.has_display_name()) {
panel.set_display_name(h_panel.display_name());
}
return panel_id;
}
uint64_t ProcessPainting(const HumanPainting& h_painting,
const std::string& current_map_name,
const std::string& current_room_name) {
uint64_t painting_id = container_.FindOrAddPainting(
current_map_name, current_room_name, h_painting.name(), std::nullopt,
std::nullopt);
PaintingData& painting =
*container_.all_objects().mutable_paintings(painting_id);
painting.set_path(h_painting.path());
painting.set_display_name(h_painting.display_name());
painting.set_orientation(h_painting.orientation());
// Setting this explicitly because the Godot protobuf doesn't support
// custom defaults.
painting.set_gravity(h_painting.gravity());
if (h_painting.has_move()) {
painting.set_move(h_painting.move());
}
if (h_painting.has_enter_only()) {
painting.set_enter_only(h_painting.enter_only());
}
if (h_painting.has_exit_only()) {
painting.set_exit_only(h_painting.exit_only());
}
if (h_painting.has_required_door()) {
std::optional<std::string> map_name =
h_painting.required_door().has_map()
? std::optional<std::string>(h_painting.required_door().map())
: std::nullopt;
painting.set_required_door(container_.FindOrAddDoor(
map_name, h_painting.required_door().name(), current_map_name));
}
return painting_id;
}
uint64_t ProcessPort(const HumanPort& h_port,
const std::string& current_map_name,
const std::string& current_room_name) {
uint64_t port_id =
container_.FindOrAddPort(current_map_name, current_room_name,
h_port.name(), std::nullopt, std::nullopt);
Port& port = *container_.all_objects().mutable_ports(port_id);
port.set_path(h_port.path());
port.set_display_name(h_port.display_name());
if (h_port.no_shuffle()) {
port.set_no_shuffle(h_port.no_shuffle());
} else {
*port.mutable_destination() = h_port.destination();
port.set_rotation(h_port.rotation());
}
// Setting this explicitly because the Godot protobuf doesn't support
// custom defaults.
port.set_gravity(h_port.gravity());
if (h_port.has_required_door()) {
std::optional<std::string> map_name =
h_port.required_door().has_map()
? std::optional<std::string>(h_port.required_door().map())
: std::nullopt;
port.set_required_door(container_.FindOrAddDoor(
map_name, h_port.required_door().name(), current_map_name));
}
return port_id;
}
uint64_t ProcessLetter(const HumanLetter& h_letter,
const std::string& current_map_name,
const std::string& current_room_name) {
uint64_t letter_id =
container_.FindOrAddLetter(h_letter.key(), h_letter.level2());
Letter& letter = *container_.all_objects().mutable_letters(letter_id);
letter.set_room_id(container_.FindOrAddRoom(
current_map_name, current_room_name, std::nullopt));
letter.set_path(h_letter.path());
return letter_id;
}
uint64_t ProcessMastery(const HumanMastery& h_mastery,
const std::string& current_map_name,
const std::string& current_room_name) {
uint64_t mastery_id = container_.FindOrAddMastery(
current_map_name, current_room_name, h_mastery.name(), std::nullopt,
std::nullopt);
Mastery& mastery = *container_.all_objects().mutable_masteries(mastery_id);
mastery.set_path(h_mastery.path());
return mastery_id;
}
uint64_t ProcessKeyholder(const HumanKeyholder& h_keyholder,
const std::string& current_map_name,
const std::string& current_room_name) {
uint64_t keyholder_id = container_.FindOrAddKeyholder(
current_map_name, current_room_name, h_keyholder.name(), std::nullopt,
std::nullopt);
KeyholderData& keyholder =
*container_.all_objects().mutable_keyholders(keyholder_id);
keyholder.set_path(h_keyholder.path());
if (h_keyholder.has_key()) {
keyholder.set_key(h_keyholder.key());
}
return keyholder_id;
}
uint64_t ProcessEnding(const HumanEnding& h_ending,
const std::string& current_map_name,
const std::string& current_room_name) {
uint64_t ending_id = container_.FindOrAddEnding(h_ending.name());
Ending& ending = *container_.all_objects().mutable_endings(ending_id);
ending.set_room_id(container_.FindOrAddRoom(
current_map_name, current_room_name, std::nullopt));
ending.set_path(h_ending.path());
return ending_id;
}
void ProcessDoorsFile(std::filesystem::path path,
const std::string& current_map_name) {
if (!std::filesystem::exists(path)) {
return;
}
auto doors = ReadMessageFromFile<HumanDoors>(path.string());
for (const HumanDoor& door : doors.doors()) {
ProcessDoor(door, current_map_name);
}
}
void ProcessDoor(const HumanDoor& h_door,
const std::string& current_map_name) {
uint64_t door_id =
container_.FindOrAddDoor(current_map_name, h_door.name(), std::nullopt);
Door& door = *container_.all_objects().mutable_doors(door_id);
if (h_door.has_location_room()) {
door.set_room_id(container_.FindOrAddRoom(
current_map_name, h_door.location_room(), std::nullopt));
Room& room = *container_.all_objects().mutable_rooms(door.room_id());
room.add_doors(door_id);
}
std::copy(
h_door.receivers().begin(), h_door.receivers().end(),
google::protobuf::RepeatedFieldBackInserter(door.mutable_receivers()));
std::copy(
h_door.senders().begin(), h_door.senders().end(),
google::protobuf::RepeatedFieldBackInserter(door.mutable_senders()));
for (const PaintingIdentifier& pi : h_door.move_paintings()) {
std::optional<std::string> map_name =
pi.has_map() ? std::optional<std::string>(pi.map()) : std::nullopt;
door.add_move_paintings(container_.FindOrAddPainting(
map_name, pi.room(), pi.name(), current_map_name, std::nullopt));
}
for (const PanelIdentifier& pi : h_door.panels()) {
ProxyIdentifier* proxy = door.add_panels();
std::optional<std::string> map_name =
pi.has_map() ? std::optional<std::string>(pi.map()) : std::nullopt;
proxy->set_panel(container_.FindOrAddPanel(
map_name, pi.room(), pi.name(), current_map_name, std::nullopt));
if (pi.has_answer()) {
proxy->set_answer(pi.answer());
}
}
for (const KeyholderIdentifier& ki : h_door.keyholders()) {
KeyholderAnswer* answer = door.add_keyholders();
std::optional<std::string> map_name =
ki.has_map() ? std::optional<std::string>(ki.map()) : std::nullopt;
answer->set_keyholder(container_.FindOrAddKeyholder(
map_name, ki.room(), ki.name(), current_map_name, std::nullopt));
if (ki.has_key()) {
answer->set_key(ki.key());
}
}
for (const RoomIdentifier& ri : h_door.rooms()) {
std::optional<std::string> map_name =
ri.has_map() ? std::optional<std::string>(ri.map()) : std::nullopt;
door.add_rooms(
container_.FindOrAddRoom(map_name, ri.name(), current_map_name));
}
for (const DoorIdentifier& di : h_door.doors()) {
std::optional<std::string> map_name =
di.has_map() ? std::optional<std::string>(di.map()) : std::nullopt;
door.add_doors(
container_.FindOrAddDoor(map_name, di.name(), current_map_name));
}
for (const std::string& ending_name : h_door.endings()) {
door.add_endings(container_.FindOrAddEnding(ending_name));
}
if (h_door.has_control_center_color()) {
door.set_control_center_color(h_door.control_center_color());
}
if (h_door.has_complete_at()) {
door.set_complete_at(h_door.complete_at());
}
door.set_type(h_door.type());
if (h_door.has_location_name()) {
door.set_location_name(h_door.location_name());
}
if (h_door.has_double_letters()) {
door.set_double_letters(h_door.double_letters());
}
}
void ProcessConnectionsFile(std::filesystem::path path,
std::optional<std::string> current_map_name) {
if (!std::filesystem::exists(path)) {
return;
}
auto connections = ReadMessageFromFile<HumanConnections>(path.string());
for (const HumanConnection& connection : connections.connections()) {
ProcessConnection(connection, current_map_name);
}
}
void ProcessConnection(const HumanConnection& human_connection,
const std::optional<std::string>& current_map_name) {
Connection f_connection;
if (human_connection.has_from_room()) {
f_connection.set_from_room(container_.FindOrAddRoom(
std::nullopt, human_connection.from_room(), current_map_name));
} else if (human_connection.has_from()) {
ProcessSingleConnection(human_connection.from(), current_map_name,
f_connection);
}
Connection r_connection;
r_connection.set_to_room(f_connection.from_room());
if (human_connection.has_to_room()) {
r_connection.set_from_room(container_.FindOrAddRoom(
std::nullopt, human_connection.to_room(), current_map_name));
} else if (human_connection.has_to()) {
ProcessSingleConnection(human_connection.to(), current_map_name,
r_connection);
}
f_connection.set_to_room(r_connection.from_room());
if (human_connection.has_door()) {
std::optional<std::string> map_name =
human_connection.door().has_map()
? std::optional<std::string>(human_connection.door().map())
: std::nullopt;
uint64_t door_id = container_.FindOrAddDoor(
map_name, human_connection.door().name(), current_map_name);
f_connection.set_required_door(door_id);
r_connection.set_required_door(door_id);
}
if (human_connection.has_roof_access()) {
f_connection.set_roof_access(human_connection.roof_access());
r_connection.set_roof_access(human_connection.roof_access());
}
if (human_connection.has_purple_ending()) {
f_connection.set_purple_ending(human_connection.purple_ending());
r_connection.set_purple_ending(human_connection.purple_ending());
}
if (human_connection.has_cyan_ending()) {
f_connection.set_cyan_ending(human_connection.cyan_ending());
r_connection.set_cyan_ending(human_connection.cyan_ending());
}
container_.AddConnection(f_connection);
if (!human_connection.oneway()) {
container_.AddConnection(r_connection);
}
}
void ProcessSingleConnection(
const HumanConnection::Endpoint& endpoint,
const std::optional<std::string>& current_map_name,
Connection& connection) {
if (endpoint.has_room()) {
std::optional<std::string> map_name =
endpoint.room().has_map()
? std::optional<std::string>(endpoint.room().map())
: std::nullopt;
connection.set_from_room(container_.FindOrAddRoom(
map_name, endpoint.room().name(), current_map_name));
} else if (endpoint.has_painting()) {
std::optional<std::string> map_name =
endpoint.painting().has_map()
? std::optional<std::string>(endpoint.painting().map())
: std::nullopt;
std::string room_name;
if (!endpoint.painting().has_room()) {
std::cout << "Missing room name for painting "
<< endpoint.painting().name() << std::endl;
room_name = "default";
} else {
room_name = endpoint.painting().room();
}
connection.set_from_room(
container_.FindOrAddRoom(map_name, room_name, current_map_name));
connection.set_painting(container_.FindOrAddPainting(
map_name, room_name, endpoint.painting().name(), current_map_name,
std::nullopt));
} else if (endpoint.has_port()) {
std::optional<std::string> map_name =
endpoint.port().has_map()
? std::optional<std::string>(endpoint.port().map())
: std::nullopt;
std::string room_name;
if (!endpoint.port().has_room()) {
std::cout << "Missing room name for port " << endpoint.port().name()
<< std::endl;
room_name = "default";
} else {
room_name = endpoint.port().room();
}
connection.set_from_room(
container_.FindOrAddRoom(map_name, room_name, current_map_name));
connection.set_port(
container_.FindOrAddPort(map_name, room_name, endpoint.port().name(),
current_map_name, std::nullopt));
} else if (endpoint.has_panel()) {
std::optional<std::string> map_name =
endpoint.panel().has_map()
? std::optional<std::string>(endpoint.panel().map())
: std::nullopt;
std::string room_name;
if (!endpoint.panel().has_room()) {
std::cout << "Missing room name for panel " << endpoint.panel().name()
<< std::endl;
room_name = "default";
} else {
room_name = endpoint.panel().room();
}
connection.set_from_room(
container_.FindOrAddRoom(map_name, room_name, current_map_name));
connection.mutable_panel()->set_panel(container_.FindOrAddPanel(
map_name, room_name, endpoint.panel().name(), current_map_name,
std::nullopt));
if (endpoint.panel().has_answer()) {
connection.mutable_panel()->set_answer(endpoint.panel().answer());
}
}
}
void ProcessProgressivesFile(std::filesystem::path path) {
if (!std::filesystem::exists(path)) {
return;
}
auto h_progs = ReadMessageFromFile<HumanProgressives>(path.string());
for (const HumanProgressive& h_prog : h_progs.progressives()) {
ProcessProgressive(h_prog);
}
}
void ProcessProgressive(const HumanProgressive& h_prog) {
uint64_t prog_id = container_.FindOrAddProgressive(h_prog.name());
Progressive& prog = *container_.all_objects().mutable_progressives(prog_id);
for (const DoorIdentifier& di : h_prog.doors()) {
uint64_t door_id =
container_.FindOrAddDoor(di.map(), di.name(), std::nullopt);
prog.add_doors(door_id);
}
}
void ProcessDoorGroupsFile(std::filesystem::path path) {
if (!std::filesystem::exists(path)) {
return;
}
auto h_groups = ReadMessageFromFile<HumanDoorGroups>(path.string());
for (const HumanDoorGroup& h_group : h_groups.door_groups()) {
ProcessDoorGroup(h_group);
}
}
void ProcessDoorGroup(const HumanDoorGroup& h_group) {
uint64_t group_id = container_.FindOrAddDoorGroup(h_group.name());
DoorGroup& group = *container_.all_objects().mutable_door_groups(group_id);
group.set_type(h_group.type());
for (const DoorIdentifier& di : h_group.doors()) {
uint64_t door_id =
container_.FindOrAddDoor(di.map(), di.name(), std::nullopt);
group.add_doors(door_id);
}
}
void ProcessGlobalMetadataFile(std::filesystem::path path) {
if (!std::filesystem::exists(path)) {
return;
}
auto h_metadata = ReadMessageFromFile<HumanGlobalMetadata>(path.string());
container_.all_objects().set_version(h_metadata.version());
}
void ProcessIdsFile(std::filesystem::path path) {
auto ids = ReadIdsFromYaml(path.string());
for (const auto& [map_name, map] : ids.maps()) {
for (const auto& [door_name, ap_id] : map.doors()) {
uint64_t door_id =
container_.FindOrAddDoor(map_name, door_name, std::nullopt);
container_.all_objects().mutable_doors(door_id)->set_ap_id(ap_id);
}
for (const auto& [room_name, room] : map.rooms()) {
for (const auto& [panel_name, ap_id] : room.panels()) {
uint64_t panel_id = container_.FindOrAddPanel(
map_name, room_name, panel_name, std::nullopt, std::nullopt);
container_.all_objects().mutable_panels(panel_id)->set_ap_id(ap_id);
}
for (const auto& [mastery_name, ap_id] : room.masteries()) {
uint64_t mastery_id = container_.FindOrAddMastery(
map_name, room_name, mastery_name, std::nullopt, std::nullopt);
container_.all_objects()
.mutable_masteries(mastery_id)
->set_ap_id(ap_id);
}
for (const auto& [keyholder_name, ap_id] : room.keyholders()) {
uint64_t keyholder_id = container_.FindOrAddKeyholder(
map_name, room_name, keyholder_name, std::nullopt, std::nullopt);
container_.all_objects()
.mutable_keyholders(keyholder_id)
->set_ap_id(ap_id);
}
}
}
auto& specials = *container_.all_objects().mutable_special_ids();
for (const auto& [tag, id] : ids.special()) {
specials[tag] = id;
}
for (const auto& [letter_name, ap_id] : ids.letters()) {
uint64_t letter_id = container_.FindLetterByName(letter_name);
container_.all_objects().mutable_letters(letter_id)->set_ap_id(ap_id);
}
for (const auto& [ending_name, ap_id] : ids.endings()) {
uint64_t ending_id = container_.FindOrAddEnding(ending_name);
container_.all_objects().mutable_endings(ending_id)->set_ap_id(ap_id);
}
for (const auto& [prog_name, ap_id] : ids.progressives()) {
uint64_t prog_id = container_.FindOrAddProgressive(prog_name);
container_.all_objects().mutable_progressives(prog_id)->set_ap_id(ap_id);
}
for (const auto& [group_name, ap_id] : ids.door_groups()) {
uint64_t group_id = container_.FindOrAddDoorGroup(group_name);
container_.all_objects().mutable_door_groups(group_id)->set_ap_id(ap_id);
}
}
std::string mapdir_;
std::string outputpath_;
Container container_;
};
} // namespace
} // namespace com::fourisland::lingo2_archipelago
int main(int argc, char** argv) {
if (argc != 3) {
std::cout << "Incorrect argument count." << std::endl;
std::cout << "Usage: datapacker [path to map directory] [output file]"
<< std::endl;
return 1;
}
std::string mapdir = argv[1];
std::string outputpath = argv[2];
com::fourisland::lingo2_archipelago::DataPacker data_packer(mapdir,
outputpath);
data_packer.Run();
return 0;
}