| 15 | { |
| 16 | |
| 17 | void InitialGameStateExtractor::extractCityMap(GameState &state, UString fileName, |
| 18 | UString tilePrefix, sp<City> city) const |
| 19 | { |
| 20 | UString map_prefix = "xcom3/ufodata/"; |
| 21 | unsigned int sizeX = 100; |
| 22 | unsigned int sizeY = 100; |
| 23 | unsigned int sizeZ = 10; |
| 24 | Vec3<unsigned int> fullSize(140, 140, 13); |
| 25 | |
| 26 | // We want a predictable RNG state to generate the 'same' random grass each time |
| 27 | Xorshift128Plus<uint32_t> rng{}; |
| 28 | |
| 29 | auto inFile = fw().data->fs.open(map_prefix + fileName); |
| 30 | if (!inFile) |
| 31 | { |
| 32 | LogError("Failed to open \"%s\"", fileName); |
| 33 | } |
| 34 | auto fileSize = inFile.size(); |
| 35 | |
| 36 | unsigned int expectedFileSize = sizeX * sizeY * sizeZ * 2; |
| 37 | |
| 38 | if (fileSize != expectedFileSize) |
| 39 | { |
| 40 | LogError("Unexpected filesize %zu - expected %u", fileSize, expectedFileSize); |
| 41 | } |
| 42 | |
| 43 | city->size = {fullSize.x, fullSize.y, fullSize.z}; |
| 44 | |
| 45 | int tileIndex = 0; |
| 46 | |
| 47 | for (unsigned int y = 0; y < fullSize.y; y++) |
| 48 | { |
| 49 | for (unsigned int x = 0; x < fullSize.x; x++) |
| 50 | { |
| 51 | uint16_t idx; |
| 52 | if (fileName == "alienmap") |
| 53 | { |
| 54 | idx = 5; |
| 55 | } |
| 56 | else |
| 57 | { |
| 58 | // NOTE: uniform_int_distribution would give a 'better' distribution here, but |
| 59 | // doesn't give the same result over different platforms (tested: x86_64 gcc 5.4.0 |
| 60 | // and x64 msvc 2015u3) |
| 61 | // range {169,172} |
| 62 | auto off = rng() % 4; |
| 63 | idx = 169 + off; |
| 64 | } |
| 65 | |
| 66 | auto tileName = |
| 67 | format("%s%s%u", SceneryTileType::getPrefix(), tilePrefix, (unsigned)idx); |
| 68 | |
| 69 | city->initial_tiles[Vec3<int>{x, y, 1}] = {&state, tileName}; |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | for (unsigned int z = 0; z < sizeZ; z++) |
| 74 | { |