git repos / saland

commit c7c0d165

Poul Sander · 2021-04-05 16:02
c7c0d165726c9f187b29dde393bd00d51788ff11 patch · browse files
parent 9b0ac03f28d47ce7ed79680684e466c440863775

Started to add prefabs

Changed files

M data/maps/prefabs01.tmx before
M src/saland/GameRegion.cpp before
M src/saland/Prefabs.cpp before
M src/saland/Prefabs.hpp before
M src/saland/model/World.cpp before
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 @@
<?xml version="1.0" encoding="UTF-8"?>
-<map version="1.2" tiledversion="1.3.2" orientation="orthogonal" renderorder="right-down" compressionlevel="-1" width="100" height="100" tilewidth="32" tileheight="32" infinite="0" nextlayerid="5" nextobjectid="4">
+<map version="1.2" tiledversion="1.3.2" orientation="orthogonal" renderorder="right-down" compressionlevel="0" width="100" height="100" tilewidth="32" tileheight="32" infinite="0" nextlayerid="6" nextobjectid="4">
<tileset firstgid="1" source="city_outside.tsx"/>
- <layer id="1" name="ground_1" width="100" height="100">
+ <layer id="1" name="prefab_ground_1" width="100" height="100">
<data encoding="base64" compression="zlib">
- eJztzrERg0AQBMGPAxQFkAdSFEAKOEiZc+YZ8jDO+O6qqXW3NQB47kxR6/wTddbonfZTe6d7W7SnPWrvdO+Kvml/lWdoQzSmXrV3ujdFc2qpvQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3bkBo0MLbA==
+ eAHt0bENAkEQA8CvA6gC6AOoAmiBBOgcJytdipzOSdZGdjC3bR4BAgQIEOgFXpmY9GsWGoH5h/U2e7qdwCX1azL31s1plwL39B/J3Ge5p94JvFP/JHO/3Zx2KbBLf7/kUO6pdwLH1E9Lzt2cNgECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECfwr8AKNDC2w=
</data>
</layer>
- <layer id="2" name="blocking_1" width="100" height="100">
+ <layer id="2" name="prefab_blocking_1" width="100" height="100">
<data encoding="base64" compression="zlib">
- eJztzs1pQlEUhdH7hiZam1pFtAp1KrYiIS1Em/CvCI2Zu4UniA1c4a0FH4cz26Xwzn7TJm1rD6Hs0j4d0jGd6s7prGV7z+mS/tI1/VdbxF2vKeUjfaZ+GjS1F3Xb+uX/qbKCh2EaPTWuO6ezVu39St9pmibtpZ5ZmqfF0wUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHdwA0z7FGE=
+ eAHt0MsNAWEUhuGxdKsNVaAKbEUrIlpAE25FuO19i1lMpoAZieckb45Znd9TFOaXBQ553DGdfvmRf/K2c/7nJV3TLd2TaV5gXZ58ZD/TK73TJ5n2BLqdouilfhqkYTLtCWxrp/e1b5/NCoxyblxp0ux510qBTbmn2bs0T7NyZ5mWBBa5u0yrys5PQ4AAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEWhf4Akz7FGE=
</data>
</layer>
- <layer id="3" name="overlay_1" width="100" height="100">
+ <layer id="5" name="prefab_blocking_2" width="100" height="100">
<data encoding="base64" compression="zlib">
- eJztzrEJgEAMQNFs4RjuJk6lLmHhEBbu4hUWd9fYGYT3IISk+hGtpcxaZguy7d19pFQwPfvs/tfXIQD8ypwdwKshO4DGmB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVG1QTBmo=
+ eAHt0AERAAAIAjFbGMP+7azBHSPBsxkjQIAAAQIECBAg0CewfZejH190nTgCBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQaBN4CngARw==
</data>
</layer>
- <objectgroup id="4" name="marking_prefab">
+ <layer id="3" name="prefab_overlay_1" width="100" height="100">
+ <data encoding="base64" compression="zlib">
+ eAHt0LEJwCAURVFnlkyVuESKDJEiu8TCQv8AinAEwWvz4KQ0nrPmVW8Zv9UCgTtsPqHlHIHcZt4w94WWBAgQIECgFzj68CZAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIENhK4Afl2wYk
+ </data>
+ </layer>
+ <objectgroup id="4" name="prefab_marking">
<object id="1" name="basic_house" type="prefab" x="112" y="16" width="129" height="317"/>
<object id="2" name="statue_1" type="prefab" x="38" y="69" width="22" height="51"/>
<object id="3" name="statue_2" type="prefab" x="38" y="200" width="22" height="47"/>
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<Prefab> prefabs;
+std::map<std::string, sago::tiled::TileMap> 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 <string>
#include <vector>
+#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<b2World>& 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<sago::tiled::TileObjectGroup>& 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<b2World>& 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<b2World>& 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<b2World>& world, const std::string& mapFileName
}
}
}
+ object_group_add_group_if_not_exist(tm, "prefab_marking");
const std::vector<sago::tiled::TileObjectGroup>& object_groups = tm.object_groups;
for (const auto& group : object_groups) {
for (const auto& item : group.objects) {