diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
---|---|---|
committer | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
commit | 6352e8e3196f78388b6c771073f9e03eaa612673 (patch) | |
tree | e23772f79a7fbc41bc9108951e9e136857484bf4 /source/utility/map_grep.cpp | |
parent | 6741a057e5639280d85d0f88ba26f000baa58f61 (diff) |
everything everywhere
all at once
Diffstat (limited to 'source/utility/map_grep.cpp')
-rw-r--r-- | source/utility/map_grep.cpp | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/source/utility/map_grep.cpp b/source/utility/map_grep.cpp new file mode 100644 index 0000000..03083e0 --- /dev/null +++ b/source/utility/map_grep.cpp @@ -0,0 +1,116 @@ +#include "StarFile.hpp" +#include "StarLogging.hpp" +#include "StarRootLoader.hpp" +#include "StarDungeonTMXPart.hpp" + +using namespace Star; +using namespace Star::Dungeon; + +typedef String TileName; +typedef pair<String, String> TileProperty; + +typedef MVariant<TileName, TileProperty> MatchCriteria; + +struct SearchParameters { + MatchCriteria criteria; +}; + +typedef function<void(String, Vec2I)> MatchReporter; + +String const MapFilenameSuffix = ".json"; + +Maybe<String> matchTile(SearchParameters const& search, Tiled::Tile const& tile) { + Tiled::Properties const& properties = tile.properties; + if (search.criteria.is<TileName>()) { + if (auto tileName = properties.opt<String>("//name")) + if (tileName->regexMatch(search.criteria.get<TileName>())) + return tileName; + } else { + String propertyName; + String matchValue; + tie(propertyName, matchValue) = search.criteria.get<TileProperty>(); + if (auto propertyValue = properties.opt<String>(propertyName)) + if (propertyValue->regexMatch(matchValue)) + return properties.opt<String>("//name").value("?"); + } + return {}; +} + +void grepTileLayer(SearchParameters const& search, TMXMapPtr map, TMXTileLayerPtr tileLayer, MatchReporter callback) { + tileLayer->forEachTile(map.get(), + [&](Vec2I pos, Tile const& tile) { + if (auto tileName = matchTile(search, static_cast<Tiled::Tile const&>(tile))) + callback(*tileName, pos); + return false; + }); +} + +void grepObjectGroup(SearchParameters const& search, TMXObjectGroupPtr objectGroup, MatchReporter callback) { + for (auto object : objectGroup->objects()) { + if (auto tileName = matchTile(search, object->tile())) + callback(*tileName, object->pos()); + } +} + +void grepMap(SearchParameters const& search, String file) { + auto map = make_shared<TMXMap>(Json::parseJson(File::readFileString(file))); + + for (auto tileLayer : map->tileLayers()) + grepTileLayer(search, map, tileLayer, [&](String const& tileName, Vec2I const& pos) { + coutf("%s: %s: %s @ %s\n", file, tileLayer->name(), tileName, pos); + }); + + for (auto objectGroup : map->objectGroups()) + grepObjectGroup(search, objectGroup, [&](String const& tileName, Vec2I const& pos) { + coutf("%s: %s: %s @ %s\n", file, objectGroup->name(), tileName, pos); + }); +} + +void grepDirectory(SearchParameters const& search, String directory) { + for (pair<String, bool> entry : File::dirList(directory)) { + if (entry.second) + grepDirectory(search, File::relativeTo(directory, entry.first)); + else if (entry.first.endsWith(MapFilenameSuffix)) + grepMap(search, File::relativeTo(directory, entry.first)); + } +} + +void grepPath(SearchParameters const& search, String path) { + if (File::isFile(path)) { + grepMap(search, path); + } else if (File::isDirectory(path)) { + grepDirectory(search, path); + } +} + +MatchCriteria parseMatchCriteria(String const& criteriaStr) { + if (criteriaStr.contains("=")) { + StringList parts = criteriaStr.split('=', 1); + return make_pair(parts[0], parts[1]); + } + return TileName(criteriaStr); +} + +int main(int argc, char* argv[]) { + try { + RootLoader rootLoader({{}, {}, {}, LogLevel::Warn, false, {}}); + rootLoader.setSummary("Search Tiled map files for specific materials or objects."); + rootLoader.addArgument("MaterialId|ObjectName|Property=Value", OptionParser::Required); + rootLoader.addArgument("JsonMapFile", OptionParser::Multiple); + + RootUPtr root; + OptionParser::Options options; + tie(root, options) = rootLoader.commandInitOrDie(argc, argv); + + SearchParameters search = {parseMatchCriteria(options.arguments[0])}; + StringList files = options.arguments.slice(1); + + for (auto file : files) + grepPath(search, file); + + return 0; + } catch (std::exception const& e) { + cerrf("exception caught: %s\n", outputException(e, true)); + return 1; + } +} |