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

summaryrefslogtreecommitdiff
path: root/source/game/StarDungeonImagePart.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/game/StarDungeonImagePart.cpp
parent6741a057e5639280d85d0f88ba26f000baa58f61 (diff)
everything everywhere
all at once
Diffstat (limited to 'source/game/StarDungeonImagePart.cpp')
-rw-r--r--source/game/StarDungeonImagePart.cpp131
1 files changed, 131 insertions, 0 deletions
diff --git a/source/game/StarDungeonImagePart.cpp b/source/game/StarDungeonImagePart.cpp
new file mode 100644
index 0000000..a3fd417
--- /dev/null
+++ b/source/game/StarDungeonImagePart.cpp
@@ -0,0 +1,131 @@
+#include "StarRoot.hpp"
+#include "StarAssets.hpp"
+#include "StarCasting.hpp"
+#include "StarImage.hpp"
+#include "StarJsonExtra.hpp"
+#include "StarDungeonImagePart.hpp"
+
+namespace Star {
+
+namespace Dungeon {
+
+ void ImagePartReader::readAsset(String const& asset) {
+ auto assets = Root::singleton().assets();
+ m_images.push_back(make_pair(asset, assets->image(asset)));
+ }
+
+ Vec2U ImagePartReader::size() const {
+ if (m_images.empty())
+ return Vec2U{0, 0};
+ return m_images[0].second->size();
+ }
+
+ void ImagePartReader::forEachTile(TileCallback const& callback) const {
+ for (auto const& entry : m_images) {
+ String const& file = entry.first;
+ ImageConstPtr const& image = entry.second;
+ for (size_t y = 0; y < image->height(); y++) {
+ for (size_t x = 0; x < image->width(); x++) {
+
+ Vec2I position(x, y);
+ Vec4B tileColor = image->get(x, y);
+
+ if (auto const& tile = m_tileset->getTile(tileColor)) {
+ bool exitEarly = callback(position, *tile);
+ if (exitEarly)
+ return;
+ } else {
+ throw StarException::format("Dungeon image %s uses unknown tile color: #%02x%02x%02x%02x",
+ file,
+ tileColor[0],
+ tileColor[1],
+ tileColor[2],
+ tileColor[3]);
+ }
+ }
+ }
+ }
+ }
+
+ void ImagePartReader::forEachTileAt(Vec2I pos, TileCallback const& callback) const {
+ for (auto const& entry : m_images) {
+ String const& file = entry.first;
+ ImageConstPtr const& image = entry.second;
+ Vec4B tileColor = image->get(pos.x(), pos.y());
+
+ if (auto const& tile = m_tileset->getTile(tileColor)) {
+ bool exitEarly = callback(pos, *tile);
+ if (exitEarly)
+ return;
+ } else {
+ throw StarException::format("Dungeon image %s uses unknown tile color: #%02x%02x%02x%02x",
+ file,
+ tileColor[0],
+ tileColor[1],
+ tileColor[2],
+ tileColor[3]);
+ }
+ }
+ }
+
+ String connectorColorValue(Vec4B const& color) {
+ return strf("%d,%d,%d,%d", color[0], color[1], color[2], color[3]);
+ }
+
+ Tile variantMapToTile(JsonObject const& tile) {
+ Tile result;
+ if (tile.contains("brush"))
+ result.brushes = Brush::readBrushes(tile.get("brush"));
+ if (tile.contains("rules"))
+ result.rules = Rule::readRules(tile.get("rules"));
+
+ if (tile.contains("connector") && tile.get("connector").toBool()) {
+ auto connector = TileConnector();
+
+ connector.forwardOnly = tile.contains("connectForwardOnly") && tile.get("connectForwardOnly").toBool();
+
+ Json connectorValue = tile.get("value");
+ if (Maybe<Json> value = tile.maybe("connector-value"))
+ connectorValue = value.take();
+
+ if (connectorValue.isType(Json::Type::String))
+ connector.value = connectorValue.toString();
+ else
+ connector.value = connectorColorValue(jsonToVec4B(connectorValue));
+
+ if (tile.contains("direction"))
+ connector.direction = DungeonDirectionNames.getLeft(tile.get("direction").toString());
+
+ result.connector = connector;
+ }
+
+ return result;
+ }
+
+ ImageTileset::ImageTileset(Json const& tileset) {
+ for (Json const& tileDef : tileset.iterateArray()) {
+ Vec4B color = jsonToVec4B(tileDef.get("value"));
+ m_tiles.insert(colorAsInt(color), variantMapToTile(tileDef.toObject()));
+ }
+ }
+
+ Tile const* ImageTileset::getTile(Vec4B color) const {
+ if (color[3] == 0)
+ color = Vec4B(255, 255, 255, 0);
+ if (color[3] != 255)
+ return nullptr;
+ return &m_tiles.get(colorAsInt(color));
+ }
+
+ unsigned ImageTileset::colorAsInt(Vec4B color) const {
+ if ((color[3] != 0) && (color[3] != 255)) {
+ starAssert(false);
+ return 0;
+ }
+ if (color[3] == 0)
+ color = Vec4B(255, 255, 255, 0);
+ return (((unsigned)color[2]) << 16) | (((unsigned)color[1]) << 8) | ((unsigned)color[0]);
+ }
+}
+
+}