#include #include #include #include #include #include #include #include #include #include #include #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 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"); 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(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(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 map_name = h_panel.required_door().has_map() ? std::optional(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 map_name = h_panel.required_room().has_map() ? std::optional(h_panel.required_room().
#include "godot_processor.h"

#include <filesystem>
#include <iostream>
#include <memory>
#include <set>

#include "structs.h"
#include "util/godot_scene.h"

namespace com::fourisland::lingo2_archipelago {

namespace {

static const std::set<std::string> kImportantNodeTypes = {
    "res://objects/nodes/panel.tscn", "res://objects/nodes/worldport.tscn",
    "res://objects/nodes/keyHolder.tscn",
    "res://objects/nodes/collectable.tscn"};

class GodotProcessor {
 public:
  GodotProcessor(const std::string& repodir, CollectedInfo& info)
      : repodir_(repodir), info_(info) {}

  void Run() {
    for (auto& [map_name, map_info] : info_.maps) {
      ProcessMap(map_name, map_info);
    }
  }

  void ProcessMap(const std::string& map_name, MapInfo& map_info) {
    std::filesystem::path scene_path = std::filesystem::path(repodir_) /
                                       "objects" / "scenes" /
                                       (map_name + ".tscn");
    std::string scene_path_str = scene_path.string();
    std::cout << "Processing " << scene_path_str << std::endl;

    GodotScene scene = ReadGodotSceneFromFile(scene_path_str);
    for (const GodotNode& node : scene.GetNodes()) {
      ProcessMapNode(scene, node, map_info);
    }
  }

  void ProcessMapNode(const GodotScene& scene, const GodotNode& node,
                      MapInfo& map_info) {
    if (std::holds_alternative<GodotExtResourceRef>(node.instance_type)) {
      const GodotExtResourceRef& ext_resource_ref =
          std::get<GodotExtResourceRef>(node.instance_type);
      const GodotExtResource* ext_resource =
          scene.GetExtResource(ext_resource_ref.id);

      if (ext_resource != nullptr &&
          (kImportantNodeTypes.count(ext_resource->path) ||
           ext_resource->path.starts_with("res://objects/meshes/paintings/"))) {
        map_info.game_nodes[node.GetPath()].defined = true;
      }
    }
  }

 private:
  std::string repodir_;
  CollectedInfo& info_;
};

}  // namespace

void ProcessGodotData(const std::string& repodir, CollectedInfo& info) {
  GodotProcessor godot_processor(repodir, info);
  godot_processor.Run();
}

}  // namespace com::fourisland::lingo2_archipelago