#pragma once // ----------------------------------------------------------------------------- // Проект: всё, что отличает одну игру на Tile2D от другой. // // Движок не знает ни одного имени содержимого. Он знает, что у проекта есть // каталог сущностей, набор комнат, вид отображения и кривая глубины, — а какие // именно твари, комнаты и числа за этим стоят, читается из project.txt. // // Отсюда правило, которое легко нарушить и трудно заметить: НИ ОДИН путь к // содержимому не может быть зашит в код движка. Раньше движок сам искал // assets/rooms и assets/catalog, то есть в нём было зашито имя ровно одной // игры; такой «движок» работает с одним проектом и притворяется общим. // // Формат — построчный `ключ значение`, как у комнат и каталога. Причина та же: // файл лежит в git, правится руками и обязан читаться в diff. // // name DESCENT // view iso # iso | topdown // rooms rooms # каталог с *.room, относительно проекта // catalog catalog/entities.txt // startdepth 1 // danger 3.0 2.2 0.10 # база, линейный рост, квадратичный хвост // density 0.05 1.5 # прирост за этаж, упор // loot 2 4 3 # база, этажей на +1 предмет, этажей на тир // sight 0.035 0.60 # сжатие за этаж, нижний упор // xp 0.15 # прирост множителя опыта за этаж // themes 1 4 8 13 # с какого этажа начинается каждая тема // ----------------------------------------------------------------------------- #include #include #include "engine/progression.h" #include "engine/projection.h" struct Project { std::string dir; // корень проекта std::string name = "UNTITLED"; ViewMode view = ViewMode::ISO_2_1; // Пути уже склеены с корнем проекта: вызывающему не приходится знать, // относительно чего они были записаны. std::string roomsDir; std::string catalogPath; int startDepth = 1; FloorCurve curve; // false — проект не читается; err объясняет, чего именно не хватает. bool Load(const std::string& projectDir, std::string* err = nullptr); // Поставить проект на движок: вид отображения и кривую глубины. Отдельно от // Load намеренно — прочитать манифест, чтобы показать его в списке, и // ПЕРЕКЛЮЧИТЬ на него движок это разные действия. void Apply() const; }; // Где искать проект. wanted — либо путь к каталогу проекта, либо просто имя // (тогда ищется projects/<имя>). Пусто — берётся переменная окружения // TILE2D_PROJECT, а если и её нет — единственный найденный проект. // // Поиск идёт от текущего каталога вверх: запуск из корня репозитория и запуск // из build/bin одинаково рабочие, и это не должно требовать ключей. std::string FindProjectDir(const std::string& wanted = {}); // Имена проектов, которые видны отсюда, — для сообщения об ошибке и для списка // в редакторе. «Проект не найден» без ответа на «а какие есть» бесполезно. std::vector AvailableProjects();