diff --git a/data/maps/prefabs01.tmx b/data/maps/prefabs01.tmx index 5a90c29..4a6bdab 100644 --- a/data/maps/prefabs01.tmx +++ b/data/maps/prefabs01.tmx @@ -1,22 +1,27 @@ - + - + - eJztzrERg0AQBMGPAxQFkAdSFEAKOEiZc+YZ8jDO+O6qqXW3NQB47kxR6/wTddbonfZTe6d7W7SnPWrvdO+Kvml/lWdoQzSmXrV3ujdFc2qpvQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3bkBo0MLbA== + eAHt0bENAkEQA8CvA6gC6AOoAmiBBOgcJytdipzOSdZGdjC3bR4BAgQIEOgFXpmY9GsWGoH5h/U2e7qdwCX1azL31s1plwL39B/J3Ge5p94JvFP/JHO/3Zx2KbBLf7/kUO6pdwLH1E9Lzt2cNgECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECfwr8AKNDC2w= - + - eJztzs1pQlEUhdH7hiZam1pFtAp1KrYiIS1Em/CvCI2Zu4UniA1c4a0FH4cz26Xwzn7TJm1rD6Hs0j4d0jGd6s7prGV7z+mS/tI1/VdbxF2vKeUjfaZ+GjS1F3Xb+uX/qbKCh2EaPTWuO6ezVu39St9pmibtpZ5ZmqfF0wUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHdwA0z7FGE= + eAHt0MsNAWEUhuGxdKsNVaAKbEUrIlpAE25FuO19i1lMpoAZieckb45Znd9TFOaXBQ553DGdfvmRf/K2c/7nJV3TLd2TaV5gXZ58ZD/TK73TJ5n2BLqdouilfhqkYTLtCWxrp/e1b5/NCoxyblxp0ux510qBTbmn2bs0T7NyZ5mWBBa5u0yrys5PQ4AAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEWhf4Akz7FGE= - + - eJztzrEJgEAMQNFs4RjuJk6lLmHhEBbu4hUWd9fYGYT3IISk+hGtpcxaZguy7d19pFQwPfvs/tfXIQD8ypwdwKshO4DGmB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVG1QTBmo= + eAHt0AERAAAIAjFbGMP+7azBHSPBsxkjQIAAAQIECBAg0CewfZejH190nTgCBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQaBN4CngARw== - + + + eAHt0LEJwCAURVFnlkyVuESKDJEiu8TCQv8AinAEwWvz4KQ0nrPmVW8Zv9UCgTtsPqHlHIHcZt4w94WWBAgQIECgFzj68CZAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIENhK4Afl2wYk + + + diff --git a/src/saland/GameRegion.cpp b/src/saland/GameRegion.cpp index dbcb4ab..5eaa3b4 100644 --- a/src/saland/GameRegion.cpp +++ b/src/saland/GameRegion.cpp @@ -211,6 +211,7 @@ void GameRegion::Init(int x, int y, const std::string& worldName, bool forceRese } } + TestApplyPrefab(world.tm, 32, 32); MonsterDef batDef; batDef.radius = 16.0f; diff --git a/src/saland/Prefabs.cpp b/src/saland/Prefabs.cpp index e14780c..fb93557 100644 --- a/src/saland/Prefabs.cpp +++ b/src/saland/Prefabs.cpp @@ -27,11 +27,74 @@ https://github.com/salandgame/saland std::vector prefabs; +std::map prefabTileMaps; + +static int GetLayerNumber(const sago::tiled::TileMap& tm, const char* name) { + for (size_t i=0; i < tm.layers.size(); ++i) { + if (tm.layers[i].name == name) { + return i; + } + } + std::cerr << "Failed to find layer: " << name << "\n"; + return -1; +} + +static int32_t translate_tile(const sago::tiled::TileMap& dest, const sago::tiled::TileMap& source, int32_t source_tile) { + if (source_tile == 0) { + return 0; + } + for (size_t i = 0; i < source.tileset.size(); ++i) { + const sago::tiled::TileSet ts = source.tileset.at(i); + std::cerr << "Tile: " << source_tile << " between " << ts.firstgid << " and " << 1024 << "?\n"; + if (ts.firstgid <= source_tile && ts.firstgid+1024 > source_tile) { + std::cerr << "Looking at: " << ts.source << "\n"; + for (size_t j = 0; j < dest.tileset.size(); ++j) { + const sago::tiled::TileSet ts2 = dest.tileset.at(j); + if (ts.source == ts2.source) { + return source_tile - ts.firstgid + ts2.firstgid; + } + } + break; + } + } + return 1; +} + +static void ApplyPrefabLayer(sago::tiled::TileMap& dest, int destX, int destY, const char* destLayer, const Prefab& prefab, const char* sourceLayer) { + const sago::tiled::TileMap& source = prefabTileMaps[prefab.filename]; + int destLayerNumber = GetLayerNumber(dest, destLayer); + int sourceLayerNumber = GetLayerNumber(source, sourceLayer); + if (destLayerNumber < 0 || sourceLayerNumber < 0) { + return; + } + for (int i = 0; i < prefab.width; ++i) { + for (int j = 0; j < prefab.height; ++j) { + int32_t tile = sago::tiled::getTileFromLayer(source, source.layers.at(sourceLayerNumber), prefab.topx+i, prefab.topy+j); + tile = translate_tile(dest, source, tile); + sago::tiled::setTileOnLayerNumber(dest, destLayerNumber, destX+i, destY+j, tile); + } + } +} + +void ApplyPrefab(sago::tiled::TileMap& dest, int destX, int destY, const Prefab& prefab) { + ApplyPrefabLayer(dest, destX, destY, "prefab_ground_1", prefab, "prefab_ground_1"); + ApplyPrefabLayer(dest, destX, destY, "blocking", prefab, "prefab_blocking_1"); + ApplyPrefabLayer(dest, destX, destY, "prefab_blocking_2", prefab, "prefab_blocking_2"); + ApplyPrefabLayer(dest, destX, destY, "prefab_overlay_1", prefab, "prefab_overlay_1"); +} + +void TestApplyPrefab(sago::tiled::TileMap& dest, int destX, int destY) { + if (prefabs.size() == 0) { + return; + } + ApplyPrefab(dest, destX, destY, prefabs.front()); +} void ScanPrefabs(const std::string& filename) { std::string mapFileName = "maps/"+filename+".tmx"; std::string tmx_file = sago::GetFileContent(mapFileName); sago::tiled::TileMap tm = sago::tiled::string2tilemap(tmx_file); + prefabTileMaps[filename] = tm; for (const auto& t : tm.object_groups) { std::cout << "Prefab object group: " << t.name << "\n"; for (const auto& o : t.objects) { @@ -40,7 +103,10 @@ void ScanPrefabs(const std::string& filename) { p.name = o.name; p.topx = o.x/32; p.topy = o.y/32; - std::cout << "Prefab: " << p.name << " " << p.filename << " (" << p.topx << ", " << p.topy << ")\n"; + p.width = (o.x+o.width)/32+1 - p.topx; + p.height = (o.y+o.height)/32+1 - p.topy; + std::cout << "Prefab: " << p.name << " " << p.filename << " (" << p.topx << ", " << p.topy << ", " << p.width << ", " << p.height << ")\n"; + prefabs.push_back(p); } } } \ No newline at end of file diff --git a/src/saland/Prefabs.hpp b/src/saland/Prefabs.hpp index f7b5624..efaf95e 100644 --- a/src/saland/Prefabs.hpp +++ b/src/saland/Prefabs.hpp @@ -23,6 +23,7 @@ https://github.com/salandgame/saland #include #include +#include "../sagotmx/tmx_struct.h" void ScanPrefabs(const std::string& filename); @@ -34,4 +35,6 @@ struct Prefab { int topy = 0; int width = 1; int height = 1; -}; \ No newline at end of file +}; + +void TestApplyPrefab(sago::tiled::TileMap& dest, int destX, int destY); diff --git a/src/saland/model/World.cpp b/src/saland/model/World.cpp index a3b5734..d6645ee 100644 --- a/src/saland/model/World.cpp +++ b/src/saland/model/World.cpp @@ -168,10 +168,33 @@ void World::init_physics(std::shared_ptr& world) { } +static size_t append_layer(sago::tiled::TileMap& tm, const char* name) { + sago::tiled::TileLayer t = createEmptyLayerForMap(tm); + t.name = name; + tm.layers.push_back(t); + return tm.layers.size()-1; +} + +static void object_group_add_group_if_not_exist(sago::tiled::TileMap& tm, const char* name) { + std::vector& object_groups = tm.object_groups; + for (const auto& group : object_groups) { + if (group.name == name) { + std::cout << "Already contains group \"" << name << "\"\n"; + return; + } + } + sago::tiled::TileObjectGroup tog; + tog.name = name; + object_groups.push_back(tog); +} + void World::init(std::shared_ptr& world, const std::string& mapFileName) { blockingLayer = -1; blockingLayer_overlay_1 = -1; + int prefab_layer_ground = -1; + int prefab_blocking_2 = -1; + int prefab_layer_overlay = -1; this->physicsWorld = world; std::string tmx_file = sago::GetFileContent(mapFileName); tm = sago::tiled::string2tilemap(tmx_file); @@ -190,18 +213,30 @@ void World::init(std::shared_ptr& world, const std::string& mapFileName if (tm.layers[i].name == "blocking_overlay_1") { blockingLayer_overlay_1 = i; } + if (tm.layers[i].name == "prefab_ground_1") { + prefab_layer_ground = i; + } + if (tm.layers[i].name == "prefab_overlay_1") { + prefab_layer_overlay = i; + } + if (tm.layers[i].name == "prefab_blocking_2") { + prefab_blocking_2 = i; + } + } + if (prefab_layer_ground == -1) { + append_layer(tm, "prefab_ground_1"); } if (blockingLayer == -1) { - sago::tiled::TileLayer t = createEmptyLayerForMap(tm); - t.name = "blocking"; - tm.layers.push_back(t); - blockingLayer = tm.layers.size()-1; + blockingLayer = append_layer(tm, "blocking"); + } + if (prefab_blocking_2 == -1) { + append_layer(tm, "prefab_blocking_2"); } if (blockingLayer_overlay_1 == -1) { - sago::tiled::TileLayer t = createEmptyLayerForMap(tm); - t.name = "blocking_overlay_1"; - tm.layers.push_back(t); - blockingLayer_overlay_1 = tm.layers.size()-1; + blockingLayer_overlay_1 = append_layer(tm, "blocking_overlay_1"); + } + if (prefab_layer_overlay == -1) { + append_layer(tm, "prefab_overlay_1"); } init_physics(world); protected_tiles.resize(tm.height*tm.width); @@ -221,6 +256,7 @@ void World::init(std::shared_ptr& world, const std::string& mapFileName } } } + object_group_add_group_if_not_exist(tm, "prefab_marking"); const std::vector& object_groups = tm.object_groups; for (const auto& group : object_groups) { for (const auto& item : group.objects) {