34 #include "../shared/parse.h" 35 #include "../shared/thread.h" 37 #define ASSEMBLE_THREADS 2 39 #define PRINT_RMA_PROGRESS 0 41 #define SORT_BY_SIZE 1 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 137 typedef struct mToPlace_s {
147 typedef 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;
2167 static 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);
2212 int SV_AssembleMap (
const char* mapTheme,
const char* assembly,
char* asmTiles,
char* asmPos,
char* entityString,
const unsigned int seed,
bool print)
2220 int 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);
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 bool SV_AddMissingTiles_r(MapInfo *map, int rec, int posListCnt, short myPosList[], const Tile *prevTile, int prevX, int prevY)
static int availableTiles[MAX_TILETYPES][2]
Select the next tile to place and place it (recursively)
#define GAPS
the # of different tiles we can store for a gap
static unsigned long tileMask(const char chr)
Convert to tile spec - normalize the characters.
static bool SV_ParseAssembly(MapInfo *map, const char *filename, const char **text, Assembly *a)
Parses an assembly block.
static void SV_GetTilesFromTileSet(const MapInfo *map, const char *filename, const char **text, Assembly *a)
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 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.
static SDL_mutex * mapLock
void Com_SetRandomSeed(unsigned int seed)
static bool SV_TestFilled(const MapInfo *map)
Checks if the map is completely filled.
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
static SDL_cond * mapCond
static bool SV_ParseMapTile(const char *filename, const char **text, MapInfo *map, bool inherit)
Parsed a tile definition out of the ump-files.
static int cmpTileAreaSize(const void *a, const void *b)
static MapInfo * SV_DoMapAssemble(MapInfo *map, const char *assembly, char *asmTiles, char *asmPos, const unsigned int seed, bool print)
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 '+'.
QGL_EXTERN GLsizei const GLvoid * data
const char * getName() const
int FS_LoadFile(const char *path, byte **buffer)
Filenames are relative to the quake search path.
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
void Com_Printf(const char *const fmt,...)
SDL_Thread * Com_CreateThread(int(*fn)(void *), const char *name, void *data=nullptr)
#define TCM
tile code multiplier. For the various debug printfs we want a number that we can easily divide throug...
char inheritBasePath[MAX_QPATH]
static int SV_ParallelSearch(MapInfo *map)
Spawn ASSEMBLE_THREADS threads to try and assemble a map. The first map complete gets returned...
Stores the parsed data for a map tile. (See *.ump files)
unsigned long spec[MAX_TILESIZE][MAX_TILESIZE]
Tile mTile[MAX_TILETYPES]
static void SV_PrepareTilesToPlace(MapInfo *map)
Prepare the list of tiles to place.
static short posTileList[RMA2_MAX_REC][RMA2_MAX_TILEPOS]
array of working random tile positions, 50 recursions
#define Q_strvalid(string)
Assembly assemblies[MAX_MAPASSEMBLIES]
void Com_Error(int code, const char *fmt,...)
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 bool SV_AddMapTiles(MapInfo *map)
Tries to build the map There are 3 categories of tiles:
static const Tile * SV_GetMapTile(const MapInfo *map, const char *tileName)
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
mToPlace_t mToPlace[MAX_TILETYPES]
Stores the Tiles to Place in the map.
static void SV_RemoveTile(MapInfo *map, int *idx, int *pos)
Rebuilds a assembled map up to the previous tile.
static void RandomList(const int n, short *list)
Fills a list with random values between 0 and n.
#define MAX_RANDOM_MAP_HEIGHT
static void SV_RmaPrintMap(const MapInfo *map)
QGL_EXTERN GLuint GLsizei GLsizei * length
#define Q_strncasecmp(s1, s2, n)
static const TileSet * SV_GetMapTileSet(const MapInfo *map, const char *tileSetName)
#define RMA2_MAX_TILEPOS
max # of valid tile/position combinations
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.
Main server include file.
static int SV_GapListReduce(MapInfo *map)
Tries to find tiles that exclude all of their neighbours This is called only once, before recursion starts. So we can safely (ab)use the posTileList space for recursion 1.
static void SV_ParseUMP(const char *name, char *entityString, MapInfo *map, bool inherit)
Parses an ump file that contains the random map definition.
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.
static void SV_TileMaskToString(unsigned long m, char *str)
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
const char * getCurrentAssemblyTitle() const
unsigned long curMap[MAX_RANDOM_MAP_HEIGHT][MAX_RANDOM_MAP_WIDTH]
Stores the alternatives information for the assembled map.
Stores the parsed data of an assembly definition. See *.ump files.
int seeds[MAX_ASSEMBLY_SEEDS]
int Com_GetBlock(const char **text, const char **start)
Get the start and end point of a block in the given text.
static bool SV_ParseMapTileSet(const char *filename, const char **text, MapInfo *map, bool inherit)
Parsed a tileset definition out of the ump-files.
static int minMissingSolids
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. This can also be used to dump the progress of the RMA process.
const char * Com_Parse(const char *data_p[], char *target, size_t size, bool replaceWhitespaces)
Parse a token out of a string.
static int SV_AssemblyThread(void *data)
The main function for the threads that try to create random map assemblies in parallel.
int SV_AssembleMapAndTitle(const char *mapTheme, const char *assembly, char *asmTiles, char *asmPos, char *entityString, const unsigned int seed, bool print, char *asmTitle)
int SV_AssembleMap(const char *mapTheme, const char *assembly, char *asmTiles, char *asmPos, char *entityString, const unsigned int seed, bool print)
cvar_t * sv_rmadisplaythemap
display a character graphic of the tiles placed when RMA2 reaches a dead end.
char mapStr[MAX_TOKEN_CHARS *MAX_TILESTRINGS]
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
char tiles[MAX_TILESETTILES][MAX_VAR]
void Q_strcat(char *dest, size_t destsize, const char *format,...)
Safely (without overflowing the destination buffer) concatenates two strings.
static void SV_DumpPlaced(const MapInfo *map, int pl)
Debug function to dump the map location of a placed tile.
#define MAX_RANDOM_MAP_WIDTH
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.
#define Mem_AllocType(type)
const Assembly * getCurrentAssembly() const
cvar_t * Cvar_Set(const char *varName, const char *value,...)
Sets a cvar value.
#define MAX_ASSEMBLY_SEEDS
#define RMA2_MAX_REC
max # of recursions
mPlaced_t mPlaced[MAX_MAPTILES]
int SV_GetConfigStringLength(int index)
#define MAX_MAPASSEMBLIES
This is a cvar definition. Cvars can be user modified and used in our menus e.g.
cvar_t * Cvar_FindVar(const char *varName)
Searches for a cvar given by parameter.
cvar_t * sv_dumpmapassembly
static void SV_ClearMap(MapInfo *map)
Reset the map to empty state.
void SV_PrintAssemblyStats(const char *mapTheme, const char *asmName)
void setName(const char *mapTheme)
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_AddMissingTiles(MapInfo *map)
Tries to fill the missing tiles of the current map. While the 2010 algo used a 'by chance'-algo...
TileSet tileSets[MAX_TILESETS]
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 const char * SV_GetTileFromTileSet(const MapInfo *map, const char *filename, const char **text, const Assembly *a)
void Com_SkipBlock(const char **text)
Skips a block of {} in our script files.
void FS_FreeFile(void *buffer)
A list of tiles with the same size and neighbouring requirements to randomly pick from...
char posStr[MAX_TOKEN_CHARS *MAX_TILESTRINGS]