Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/utility/map_grep.cpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
commit6352e8e3196f78388b6c771073f9e03eaa612673 (patch)
treee23772f79a7fbc41bc9108951e9e136857484bf4 /source/utility/map_grep.cpp
parent6741a057e5639280d85d0f88ba26f000baa58f61 (diff)
everything everywhere
all at once
Diffstat (limited to 'source/utility/map_grep.cpp')
-rw-r--r--source/utility/map_grep.cpp116
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;
+ }
+}