37#define ASSEMBLE_THREADS 2
39#define PRINT_RMA_PROGRESS 0
44#define RMA2_MAX_REC 64
57#define RMA2_MAX_TILEPOS 1700
65#define MAX_RANDOM_MAP_WIDTH 32
66#define MAX_RANDOM_MAP_HEIGHT 32
76#define MAX_MAPASSEMBLIES 32
79#define MAX_TILETYPES 128
80#define MAX_TILESETS 16
81#define MAX_TILESETTILES 16
82#define MAX_TILESIZE 16
83#define MAX_FIXEDTILES 64
102#define MAX_ASSEMBLY_SEEDS 32
137typedef struct mToPlace_s {
147typedef struct mPlaced_s {
188 Q_strncpyz(this->name, mapTheme,
sizeof(this->name));
207 for (
i = 0;
i < n;
i++)
210 for (
i = 0;
i < n;
i++) {
211 const short r = rand() % (
i + (n -
i));
212 const short t = list[r];
218#define ALL_TILES (0xfffffffeUL)
219#define IS_SOLID(x) ((x)&1UL)
251 else if (chr >=
'1' && chr <=
'5')
252 return 1UL << (chr -
'0');
253 else if (chr >=
'a' && chr <=
'z')
254 return 1UL << (chr -
'a' + 6);
255 else if (chr >=
'A' && chr <=
'Z')
256 return 1UL << (chr -
'A' + 6);
275 for (
i = 1;
i < 6;
i++) {
281 for (
i = 6;
i < 32;
i++) {
283 str[j] =
'a' - 6 +
i;
307 screen[
i][rb + 1] =
'|';
308 screen[
i][rb + 2] = 0;
316 const char* tn = tile->
id + 1;
318 if (!strncmp(tn,
"craft_", 6))
320 for (ty = 0; ty < tile->
h; ty++) {
321 for (tx = 0; tx < tile->
w; tx++) {
323 int cbX =
ACW * (mp->
x + tx);
324 int cbY =
ACH * (mp->
y + ty);
325 char flags[33] = {0,};
328 for (j = 0; j <
ACW - 1; j++) {
330 screen[cbY +
ACH - 1][cbX + 1 + j] = tn[j];
338 for (j = 0; j <
ACW - 1; j++) {
340 screen[cbY +
ACH - 2][cbX + 1 + j] = flags[j];
348 for (j = 0; j <
ACH; j++)
349 screen[cbY + j][cbX] =
'!';
352 for (j = 0; j <
ACH; j++)
353 screen[cbY + j][cbX +
ACW] =
'!';
356 for (j = 1; j <
ACW; j++)
357 screen[cbY][cbX + j] =
'-';
360 for (j = 1; j <
ACW; j++)
361 screen[cbY +
ACH][cbX + j] =
'-';
370 int height = mAsm->
height;
371 int width = mAsm->
width;
372 for (cy = 0; cy <= height; cy++) {
373 for (cx = 0; cx <= width; cx++) {
375 const int cbX =
ACW * (cx);
376 const int cbY =
ACH * (cy);
377 char flags2[33] = {0,};
382 for (j = 0; j <
ACW - 1; j++) {
384 screen[cbY +
ACH - 2][cbX + 1 + j] = flags2[j];
393 const char* underscores =
"_________________________________________________________________________\n";
397 int h =
ACH * (height + 1);
398 for (
i = h;
i >=
ACH;
i--)
431 const char* errhead =
"SV_ParseMapTileSet: Unexpected end of file (";
457 if (token[0] !=
'}') {
478 }
while (token[0] !=
'}');
490 const char* errhead =
"SV_ParseMapTile: Unexpected end of file (";
522 target->
w = atoi(token);
527 target->
h = atoi(token);
531 *text = strchr(*text,
'}');
536 for (
int y = target->
h - 1; y >= 0; y--)
537 for (
int x = 0; x < target->
w; x++) {
539 if (!*text || *token ==
'}') {
540 Com_Printf(
"SV_ParseMapTile: Bad tile desc in '%s' - not enough entries for size\n", target->
id);
541 *text = strchr(*text,
'}') + 1;
544 target->
spec[y][x] = 0UL;
545 for (
int i = 0; token[
i];
i++) {
556 Com_Printf(
"SV_ParseMapTile: Bad tile desc in '%s' - too many entries for size\n", target->
id);
581 if (!text || token[0] ==
'}')
588 if (cvar->
string[0] !=
'+') {
589 Com_Printf(
"SV_ParseAssembly: warning - cvar '%s' value doesn't seem to be a valid tile id '%s' - set to default '%s'\n",
592 if (token[0] !=
'+' && !strchr(token,
'/'))
602 const char* tokenTile = strrchr(token,
'/');
604 const char* cvarTile = cvar->
string + 1;
606 const char* tileId = map->
mTile[
i].
id;
607 const char* tileName = strrchr(tileId,
'/');
608 if (tileName && strstr(tileName, cvarTile) && !
Q_strncasecmp(tileId, token, tokenTile - token))
618 const char* errhead =
"SV_GetTileFromTileSet: Unexpected end of file (";
629 if (tileSet ==
nullptr)
632 random = rand() % tileSet->
numTiles;
633 return tileSet->
tiles[random];
646 const char* errhead =
"SV_ParseAssemblySeeds: Unexpected end of file (";
654 Com_Printf(
"SV_ParseAssemblySeeds: Expected '{' for seed of assembly '%s' (%s)\n", a->
id,
filename);
660 if (!*text || token[0] ==
'}')
674 const char* errhead =
"SV_GetTilesFromTileSet: Unexpected end of file (";
684 if (tileSet ==
nullptr)
689 if (!text || *token ==
'}')
691 if (!strstr(token,
" "))
693 sscanf(token,
"%i %i", &min, &max);
695 Com_Error(
ERR_DROP,
"SV_GetTilesFromTilesSet: Error in assembly %s (min is bigger than max for tileset %s)",
filename, tileSet->
id);
699 for (
int i = max, j = min;
i > 0; --
i) {
700 const int random = rand() % tileSet->
numTiles;
702 if (tile !=
nullptr) {
703 const ptrdiff_t tileIdx = tile - map->
mTile;
729 const char* errhead =
"SV_ParseAssembly: Unexpected end of file (";
748 if (!*text || *token !=
'{')
754 if (!text || *token ==
'}')
765 }
else if (
Q_streq(token,
"multiplayer")) {
776 const ptrdiff_t
i = t - map->
mTile;
784 }
else if (
Q_streq(token,
"size")) {
793 }
else if (
Q_streq(token,
"seeds")) {
797 }
else if (
Q_streq(token,
"grid")) {
803 sscanf(token,
"%i %i", &a->
dx, &a->
dy);
806 }
else if (
Q_streq(token,
"tileset")) {
810 }
else if (
Q_streq(token,
"fix")) {
818 if (token[0] ==
'*') {
820 if (token ==
nullptr)
822 }
else if (
Q_streq(token,
"tileset")) {
828 const ptrdiff_t
i = t - map->
mTile;
837 sscanf(token,
"%i %i", &x, &y);
839 Com_Error(
ERR_DROP,
"SV_ParseAssembly: Error, invalid fixed coordinates given for x (%i) boundaries are: [0:%i] (%s).",
842 Com_Error(
ERR_DROP,
"SV_ParseAssembly: Error, invalid fixed coordinates given for y (%i) - boundaries are: [0:%i] (%s).",
853 }
else if (token[0] ==
'*') {
855 if (token ==
nullptr)
860 if (tile !=
nullptr) {
861 const ptrdiff_t
i = tile - map->
mTile;
864 if (!text || *token ==
'}')
867 if (!strstr(token,
" "))
870 sscanf(token,
"%i %i", &x, &y);
903 *mapAlts &= tileAlts;
912 unsigned long* mp = &map->
curMap[0][0];
929 const unsigned long* spec =
nullptr;
930 const unsigned long*
m =
nullptr;
934 assert(x % mAsm->
dx == 0);
935 assert(y % mAsm->
dy == 0);
942 if (x + tile->
w > mAsm->
width + 2 || y + tile->
h > mAsm->
height + 2)
944 unsigned long combined;
947 spec = &tile->
spec[1][1];
949 combined = (*m) & (*spec);
950 if (
IS_SOLID(combined) || !combined)
954 spec = &tile->
spec[0][0];
956 for (ty = 0; ty < tile->
h; ty++) {
957 for (tx = 0; tx < tile->
w; tx++, spec++,
m++) {
958 combined = (*m) & (*spec);
961 if (
IS_SOLID(combined) || !combined)
981 for (y = 1; y < mAsm->
height + 1; y++)
982 for (x = 1; x < mAsm->
width + 1; x++)
996 const int h = mAsm->
height;
997 const int w = mAsm->
width;
1002 for (y = h; y >= 1; y--) {
1003 for (x = 1; x < w + 1; x++) {
1004 const int dx = x - placed->
x;
1005 const int dy = y - placed->
y;
1007 if (dx >= 0 && dx < placed->tile->w && dy >= 0 && dy < placed->tile->h &&
1035 assert(x % mAsm->
dx == 0);
1036 assert(y % mAsm->
dy == 0);
1040 for (ty = 0; ty < tile->
h; ty++)
1041 for (tx = 0; tx < tile->
w; tx++) {
1098 for (ty = 0; ty < tile->
h; ty++) {
1099 for (tx = 0; tx < tile->
w; tx++) {
1146 Com_Printf(
"Map info - tiles used: %s\n", asmTiles);
1147 Com_Printf(
"Map info - tiles pos: %s\n", asmPos);
1163 const int pos = tileCode /
TCM;
1164 const int ti = tileCode %
TCM;
1165 const int posX = pos % mapW;
1166 const int posY = pos / mapW;
1168 const Tile* tile = mToPlace[ti].
tile;
1170 return tile->
spec[mapY - posY][mapX - posX];
1188 static int callCnt = 0;
1190 const int mapW = mAsm->
width;
1194 int availableTilesCnt = 0;
1200 int prevMaxX = 0, prevMaxY = 0;
1202 prevMaxX = prevX + prevTile->
w - 1;
1203 prevMaxY = prevY + prevTile->
h - 1;
1207 for (
i = 0;
i < posListCnt;
i++) {
1208 const int pos = myPosList[
i] /
TCM;
1209 const int ti = myPosList[
i] %
TCM;
1210 const int x = pos % mapW;
1211 const int y = pos / mapW;
1213 if (mToPlace[ti].cnt >= mToPlace[ti].max)
1216 const Tile* cTile = mToPlace[ti].
tile;
1220 if (x > prevMaxX || y > prevMaxY || prevX > x + cTile->
w - 1 || prevY > y + cTile->
h - 1)
1225 ok =
SV_FitTile(map, mToPlace[ti].tile, x, y);
1234 for (k = 0; k < availableTilesCnt; k++) {
1240 if (k >= availableTilesCnt) {
1243 availableTilesCnt++;
1251 for (y = 1; y < mAsm->
height + 1; y++) {
1252 for (x = 1; x < mAsm->
width + 1; x++)
1262 for (
i = 0;
i < availableTilesCnt;
i++) {
1264 const int allowed = mToPlace[ti].
max - mToPlace[ti].
cnt;
1266 const int remaining = std::min(allowed, possible);
1267 solids += remaining * mToPlace[ti].
tile->
area;
1269 if (solids < gapCount) {
1271 const int missing = gapCount - solids;
1281 for (
i = 0;
i < j;
i++) {
1284 const int x = pos % mapW;
1285 const int y = pos / mapW;
1286 const Tile* tile = mToPlace[ti].
tile;
1288 for (ty = 0; ty < tile->
h; ty++) {
1289 for (tx = 0; tx < tile->
w; tx++) {
1291 gapList[x + tx][y + ty][0] += 1;
1292 int cnt =
gapList[x + tx][y + ty][0];
1301 for (y = 1; y < mAsm->
height + 1; y++) {
1302 for (x = 1; x < mAsm->
width + 1; x++) {
1315 for (y = 1; y < mAsm->
height + 1; y++) {
1316 for (x = 1; x < mAsm->
width + 1; x++) {
1328 unsigned nonLineFlags = (~lineFlags) ^ 1L;
1331 for (; line >= 0; line--) {
1332 for (g = 1; g <=
GAPS; g++) {
1333 for (y = 1; y < mAsm->
height + 1; y++) {
1334 for (x = 1; x < mAsm->
width + 1; x++) {
1337 if (line && (map->
curMap[y][x] & nonLineFlags))
1339 for (h = 1; h <= g; h++) {
1340 const int tc =
gapList[x][y][h];
1341 const int pos = tc /
TCM;
1342 const int ti = tc %
TCM;
1343 const int px = pos % mapW;
1344 const int py = pos / mapW;
1346 SV_AddTile(map, mToPlace[ti].tile, px, py, ti, pos);
1347#if PRINT_RMA_PROGRESS
1349 Com_Printf(
"GAPS: %i rec: %i chances: %i calls: %i\n",
GAPS, rec, j, callCnt);
1376 for (
i = 0;
i < j;
i++) {
1379 const int x = pos % mapW;
1380 const int y = pos / mapW;
1382 SV_AddTile(map, mToPlace[ti].tile, x, y, ti, pos);
1403 const int mapW = mAsm->
width;
1408 for (y = 1; y < mAsm->
height + 1; y++) {
1409 for (x = 1; x < mAsm->
width + 1; x++)
1417 for (
int i = 0;
i < tilePosListCnt;
i++) {
1423 for (
int ty = 0; ty < tile->
h; ty++) {
1424 for (
int tx = 0; tx < tile->
w; tx++) {
1426 gapList[x + tx][y + ty][0] += 1;
1427 const int cnt =
gapList[x + tx][y + ty][0];
1436 for (y = 1; y < mAsm->
height + 1; y++) {
1437 for (x = 1; x < mAsm->
width + 1; x++) {
1482 for (h = 1; h <=
gapList[nx][ny][0]; h++) {
1483 const int tc2 =
gapList[nx][ny][h];
1486 if (flags1 & flags2) {
1503 const int mapW = mAsm->
width;
1504 const int mapH = mAsm->
height;
1509 for (y = 1; y < mapH + 1; y++) {
1510 for (x = 1; x < mapW + 1; x++) {
1515 for (g = 1; g <=
gapList[x][y][0]; g++) {
1516 const int tc1 =
gapList[x][y][g];
1551#if PRINT_RMA_PROGRESS
1552 char mapStr[10000] = {0};
1553 char posStr[10000] = {0};
1574 static int attempts = 0;
1576 const int mapSize = mAsm->
size;
1577 const int mapW = mAsm->
width;
1592 int i, j, k, offs, num, n = 0;
1593 for (
i = 0;
i < mapSize;
i++) {
1594 const int x = posList[
i] % mapW;
1595 const int y = posList[
i] / mapW;
1598 if (x % mAsm->
dx != 0 || y % mAsm->
dy != 0) {
1605 offs = rand() % num;
1606 for (k = offs; k < num + offs; k++) {
1607 const int ti = tilenumList[k % num];
1609 if (mToPlace[ti].cnt >= mToPlace[ti].max)
1611 if (
SV_FitTile(map, mToPlace[ti].tile, x, y)) {
1618#if PRINT_RMA_PROGRESS
1626 bool eliminated =
true;
1627 while (eliminated) {
1631 for (
i = 0;
i < n;
i++) {
1643 for (
int x = 0; x < mAsm->
width + 1; x++){
1644 for (
int y = 0; y < mAsm->
height + 1; y++){
1647 for (j = 0; j <= cnt + 3; j++) {
1661 for (j = 0; j <
m; j++) {
1664 for (
i = 0;
i < n;
i++) {
1703 const int mapW = mAsm->
width;
1704 const int mapSize = mAsm->
size;
1713#if PRINT_RMA_PROGRESS
1714 char mapStr[10000] = {0};
1715 char posStr[10000] = {0};
1723 while (idx < numToPlace) {
1724 while (mToPlace[idx].cnt < mToPlace[idx].min) {
1725 for (; pos < mapSize; pos++) {
1726 const int x = prList[pos] % mapW;
1727 const int y = prList[pos] / mapW;
1729 if (SDL_SemValue(
mapSem) != 1) {
1735 if ((x % mAsm->
dx != 0) || (y % mAsm->
dy != 0))
1738 if (
SV_FitTile(map, mToPlace[idx].tile, x, y)) {
1740 SV_AddTile(map, mToPlace[idx].tile, x, y, idx, pos);
1741#if PRINT_RMA_PROGRESS
1755 if (!mToPlace[idx].cnt)
1772 if (pos < mapSize) {
1779 Com_Error(
ERR_DROP,
"SV_AddMapTiles: Impossible to assemble map '%s' with assembly '%s'\n",
1782 Com_Printf(
"SV_AddMapTiles: Impossible to assemble map '%s' with assembly '%s' - retry with another seed\n",
1846 if (SDL_SemTryWait(
mapSem) != 0)
1889 static int timeout = 5000;
1899 assert(
mapSem ==
nullptr);
1900 mapSem = SDL_CreateSemaphore(1);
1903 for (
i = 0;
i < threadno;
i++) {
1905 memcpy(maps[
i], map,
sizeof(*map));
1911 Com_Printf(
"SV_ParallelSearch: timeout at %i ms, restarting\n", timeout);
1914 if (SDL_SemTryWait(
mapSem) != 0) {
1919 for (
i = 0;
i < threadno;
i++) {
1920 SDL_WaitThread(threads[
i],
nullptr);
1925 for (
i = 0;
i < threadno;
i++) {
1926 memcpy(maps[
i], map,
sizeof(*map));
1935 for (
i = 0;
i < threadno;
i++) {
1936 if (SDL_GetThreadID(threads[
i]) ==
threadID) {
1937 memcpy(map, maps[
i],
sizeof(*map));
1940 SDL_WaitThread(threads[
i],
nullptr);
1945 SDL_DestroySemaphore(
mapSem);
1969 const char* text, *token;
1978 text = (
const char*)
buf;
1984 if (
Q_streq(token,
"extends")) {
1987 Com_Printf(
"SV_ParseUMP: Nested extends in %s 'extends %s' ignored\n",
filename, token);
1990 }
else if (
Q_streq(token,
"base")) {
1996 }
else if (
Q_streq(token,
"line")) {
1998 const char* p = token;
2004 }
else if (
Q_streq(token,
"tileset")) {
2009 }
else if (
Q_streq(token,
"worldspawn")) {
2010 const char* start =
nullptr;
2016 if (
length >= worldSpawnLength)
2017 Com_Printf(
"SV_ParseUMP: worldspawn is too big - only %i characters are allowed", worldSpawnLength);
2021 }
else if (
Q_streq(token,
"tile")) {
2026 }
else if (
Q_streq(token,
"assembly")) {
2035 }
else if (token[0] ==
'{') {
2036 Com_Printf(
"SV_ParseUMP: Skipping unknown block\n");
2038 text = strchr(text,
'}') + 1;
2088 const int oldCount = map->
retryCnt;
2090 if (oldCount < map->retryCnt && mAsm->
numSeeds > 0) {
2100 unsigned int seedUsed;
2113 Com_Printf(
"Picked seed: %i for <%s>\n", seedUsed, assembly);
2119 seedUsed = rand() % 50;
2167static MapInfo*
SV_AssembleMap_ (
const char* mapTheme,
const char* assembly,
char* asmTiles,
char* asmPos,
char* entityString,
const unsigned int seed,
bool print)
2203 Com_Printf(
"SV_AssembleMap: Map assembly '%s' not found\n", assembly);
2212int SV_AssembleMap (
const char* mapTheme,
const char* assembly,
char* asmTiles,
char* asmPos,
char* entityString,
const unsigned int seed,
bool print)
2220int SV_AssembleMapAndTitle (
const char* mapTheme,
const char* assembly,
char* asmTiles,
char* asmPos,
char* entityString,
const unsigned int seed,
bool print,
char* asmTitle)
2232 char mapAsmName[80];
2233 const char* p = mapTheme;
2243 if (asmName && asmName[0]) {
2251 Com_Printf(
"testMapDefStatistic: Map assembly '%s' not found\n", asmName);
2260 for (
int k = 0; k < theMap->
numToPlace; k++) {
2265 Com_sprintf(mapAsmName,
sizeof(mapAsmName),
"%s %s", p, asmName);
Stores the parsed data of an assembly definition. See *.ump files.
int seeds[MAX_ASSEMBLY_SEEDS]
void setName(const char *mapTheme)
unsigned long curMap[MAX_RANDOM_MAP_HEIGHT][MAX_RANDOM_MAP_WIDTH]
Stores the alternatives information for the assembled map.
mToPlace_t mToPlace[MAX_TILETYPES]
Stores the Tiles to Place in the map.
const char * getCurrentAssemblyTitle() const
const Assembly * getCurrentAssembly() const
TileSet tileSets[MAX_TILESETS]
mPlaced_t mPlaced[MAX_MAPTILES]
Assembly assemblies[MAX_MAPASSEMBLIES]
char inheritBasePath[MAX_QPATH]
Tile mTile[MAX_TILETYPES]
const char * getName() const
Stores the parsed data for a map tile. (See *.ump files).
unsigned long spec[MAX_TILESIZE][MAX_TILESIZE]
A list of tiles with the same size and neighbouring requirements to randomly pick from.
char tiles[MAX_TILESETTILES][MAX_VAR]
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
void Com_Error(int code, const char *fmt,...)
void Com_SetRandomSeed(unsigned int seed)
void Com_Printf(const char *const fmt,...)
cvar_t * Cvar_Set(const char *varName, const char *value,...)
Sets a cvar value.
cvar_t * Cvar_FindVar(const char *varName)
Searches for a cvar given by parameter.
int FS_LoadFile(const char *path, byte **buffer)
Filenames are relative to the quake search path.
void FS_FreeFile(void *buffer)
#define Mem_AllocType(type)
const char * Com_Parse(const char *data_p[], char *target, size_t size, bool replaceWhitespaces)
Parse a token out of a string.
void Com_SkipBlock(const char **text)
Skips a block of {} in our script files.
int Com_GetBlock(const char **text, const char **start)
Get the start and end point of a block in the given text.
Shared parsing functions.
QGL_EXTERN GLsizei const GLvoid * data
QGL_EXTERN GLuint GLsizei GLsizei * length
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
const char * Com_EParse(const char **text, const char *errhead, const char *errinfo, char *target, size_t size)
Parsing function that prints an error message when there is no text in the buffer.
Main server include file.
cvar_t * sv_rmadisplaythemap
display a character graphic of the tiles placed when RMA2 reaches a dead end.
int SV_GetConfigStringLength(int index)
cvar_t * sv_dumpmapassembly
#define Q_strvalid(string)
#define Q_strncasecmp(s1, s2, n)
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
void Q_strcat(char *dest, size_t destsize, const char *format,...)
Safely (without overflowing the destination buffer) concatenates two strings.
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
This is a cvar definition. Cvars can be user modified and used in our menus e.g.
#define RMA2_MAX_REC
max # of recursions
static const TileSet * SV_GetMapTileSet(const MapInfo *map, const char *tileSetName)
int SV_AssembleMapAndTitle(const char *mapTheme, const char *assembly, char *asmTiles, char *asmPos, char *entityString, const unsigned int seed, bool print, char *asmTitle)
static short posTileList[RMA2_MAX_REC][RMA2_MAX_TILEPOS]
array of working random tile positions, 50 recursions
static MapInfo * SV_AssembleMap_(const char *mapTheme, const char *assembly, char *asmTiles, char *asmPos, char *entityString, const unsigned int seed, bool print)
Assembles a "random" map and parses the *.ump files for assembling the "random" maps and places the '...
static void SV_RemoveTile(MapInfo *map, int *idx, int *pos)
Rebuilds a assembled map up to the previous tile.
static int cmpTileAreaSize(const void *a, const void *b)
static const Tile * SV_GetMapTile(const MapInfo *map, const char *tileName)
#define MAX_RANDOM_MAP_HEIGHT
#define TCM
tile code multiplier. For the various debug printfs we want a number that we can easily divide throug...
static void SV_GetTilesFromTileSet(const MapInfo *map, const char *filename, const char **text, Assembly *a)
static bool SV_AddMissingTiles(MapInfo *map)
Tries to fill the missing tiles of the current map. While the 2010 algo used a 'by chance'-algo,...
static const char * SV_GetCvarToken(const MapInfo *map, const Assembly *a, const char *token, const char *filename, const char **text, const char *errhead)
Tries to extract a tile name from a cvar - the cvar value must start with a '+'.
#define MAX_MAPASSEMBLIES
static bool SV_TestFilled(const MapInfo *map)
Checks if the map is completely filled.
static void SV_DumpPlaced(const MapInfo *map, int pl)
Debug function to dump the map location of a placed tile.
static void SV_RmaPrintMap(const MapInfo *map)
static int SV_AssemblyThread(void *data)
The main function for the threads that try to create random map assemblies in parallel.
static void SV_ClearMap(MapInfo *map)
Reset the map to empty state.
static const char * SV_GetTileFromTileSet(const MapInfo *map, const char *filename, const char **text, const Assembly *a)
static bool SV_GapCheckNeighbour(MapInfo *map, int tc1, int mapW, int mapH, int nx, int ny)
Find a tile that meets the requirements of tc1 at a given pos.
static void SV_TileMaskToString(unsigned long m, char *str)
static int minMissingSolids
static unsigned long SV_GapGetFlagsAtAbsPos(MapInfo *map, int tileCode, int mapW, int mapX, int mapY)
get the specs of a tile at map-x/y if it was placed where tileCode indicates
static void SV_PrepareTilesToPlace(MapInfo *map)
Prepare the list of tiles to place.
void SV_PrintAssemblyStats(const char *mapTheme, const char *asmName)
static int SV_ParallelSearch(MapInfo *map)
Spawn ASSEMBLE_THREADS threads to try and assemble a map. The first map complete gets returned....
#define MAX_ASSEMBLY_SEEDS
static void SV_CombineAlternatives(unsigned long *mapAlts, const unsigned long tileAlts)
Combines the alternatives/connection info of a map with a tile and sets the rating.
static MapInfo * SV_DoMapAssemble(MapInfo *map, const char *assembly, char *asmTiles, char *asmPos, const unsigned int seed, bool print)
static unsigned long tileMask(const char chr)
Convert to tile spec - normalize the characters.
static SDL_cond * mapCond
static int SV_GapListReduce(MapInfo *map)
Tries to find tiles that exclude all of their neighbours This is called only once,...
static void RandomList(const int n, short *list)
Fills a list with random values between 0 and n.
#define GAPS
the # of different tiles we can store for a gap
static short gapList[MAX_RANDOM_MAP_HEIGHT][MAX_RANDOM_MAP_HEIGHT][GAPS+1]
for every x/y we can store the tiles that can cover that place here
static bool SV_ParseAssemblySeeds(MapInfo *map, const char *filename, const char **text, Assembly *a)
Parses a list of working seeds to assemble this rma assembly.
static bool SV_ParseMapTileSet(const char *filename, const char **text, MapInfo *map, bool inherit)
Parsed a tileset definition out of the ump-files.
static SDL_mutex * mapLock
#define RMA2_MAX_TILEPOS
max # of valid tile/position combinations
static bool SV_GapListBuild(MapInfo *map, int tilePosListCnt)
Builds a list of map positions (gaps) and the tiles that can cover them.
static bool SV_AddMapTiles(MapInfo *map)
Tries to build the map There are 3 categories of tiles:
static bool SV_AddMissingTiles_r(MapInfo *map, int rec, int posListCnt, short myPosList[], const Tile *prevTile, int prevX, int prevY)
int SV_AssembleMap(const char *mapTheme, const char *assembly, char *asmTiles, char *asmPos, char *entityString, const unsigned int seed, bool print)
#define MAX_RANDOM_MAP_WIDTH
static int availableTiles[MAX_TILETYPES][2]
Select the next tile to place and place it (recursively).
static bool SV_FitTile(const MapInfo *map, const Tile *tile, const int x, const int y)
Checks if a given map-tile fits into the empty space (in a given location) of a map.
static void SV_BuildMapStrings(const MapInfo *map, char *asmTiles, char *asmPos, bool print)
Creates the mapstrings as known from the ufoconsole.log and optionally prints them....
static bool SV_ParseMapTile(const char *filename, const char **text, MapInfo *map, bool inherit)
Parsed a tile definition out of the ump-files.
static void SV_ParseUMP(const char *name, char *entityString, MapInfo *map, bool inherit)
Parses an ump file that contains the random map definition.
static bool SV_ParseAssembly(MapInfo *map, const char *filename, const char **text, Assembly *a)
Parses an assembly block.
static void SV_AddTile(MapInfo *map, const Tile *tile, int x, int y, int idx, int pos)
Adds a new map-tile to an assembled map. Also adds the tile to the placed-tiles list.
char posStr[MAX_TOKEN_CHARS *MAX_TILESTRINGS]
char mapStr[MAX_TOKEN_CHARS *MAX_TILESTRINGS]
SDL_Thread * Com_CreateThread(int(*fn)(void *), const char *name, void *data=nullptr)