const char* UI_GetTextFromList (int textId, int line) { if (ui_global.sharedData[textId].type != UI_SHARED_LINKEDLISTTEXT) return nullptr; linkedList_t* list = ui_global.sharedData[textId].data.linkedListText; return static_cast<const char*>(LIST_GetByIdx(list, line)); }
TEST_F(GameTest, CountSpawnpoints) { const char* filterId = TEST_GetStringProperty("mapdef-id"); const mapDef_t* md; Cvar_Set("rm_drop", "+craft_drop_herakles"); /* use a known seed to reproduce an error */ unsigned int seed; if (TEST_ExistsProperty("mapdef-seed")) { seed = TEST_GetLongProperty("mapdef-seed"); } else { seed = (unsigned int) time(nullptr); } srand(seed); MapDef_Foreach(md) { if (md->mapTheme[0] == '.') continue; if (filterId && !Q_streq(filterId, md->id)) continue; if (md->aircraft) /* if the mapdef has a list of dropships, let's assume they bring their own spawnpoints */ continue; Com_Printf("testCountSpawnpoints: Mapdef %s (seed %u)\n", md->id, seed); const char* asmName = (const char*)LIST_GetByIdx(md->params, 0); SV_Map(true, md->mapTheme, asmName, false); const int spawnPoints = static_cast<int>(level.num_spawnpoints[TEAM_PHALANX]); Com_Printf("Map: %s Mapdef %s Spawnpoints: %i\n", md->mapTheme, md->id, spawnPoints); ASSERT_TRUE(level.num_spawnpoints[TEAM_PHALANX] >= 12) << "Map " << md->mapTheme << " only " << spawnPoints << " spawnpoints"; } }
/** * @brief Choose a city for terror mission. * @return chosen city in ccs.cities */ static const city_t* CP_ChooseCity (void) { if (ccs.numCities > 0) { const int randnumber = rand() % ccs.numCities; return (city_t*) LIST_GetByIdx(ccs.cities, randnumber); } else { return NULL; } }
/** * @brief Change the skin of the selected actor. */ static void CL_ChangeSkin_f (void) { const int sel = cl_selected->integer; character_t* chr = (character_t*)LIST_GetByIdx(chrDisplayList, sel); if (chr == nullptr) { return; } const int newSkin = CL_FixActorSkinIDX(Cvar_GetInteger("mn_body_skin")); Cvar_SetValue("mn_body_skin", newSkin); /** @todo Get the skin id from the model by using the actorskin id */ /** @todo Or remove skins from models and convert character_t->skin to string */ chr->bodySkin = newSkin; }
/** * @brief This test cycles through the list of map definitions found in the maps.ufo script * and collects some properties of the maps relevant to RMA. */ TEST_F(MapDefStatsTest, DISABLED_MapDefStatistic) { const char* filterId = TEST_GetStringProperty("mapdef-id"); const mapDef_t* md; ASSERT_TRUE(csi.numMDs > 0); MapDef_Foreach(md) { if (md->mapTheme[0] == '.') continue; if (filterId && !Q_streq(filterId, md->id)) continue; const char* asmName = (const char*)LIST_GetByIdx(md->params, 0); SV_PrintAssemblyStats(md->mapTheme, asmName); } }
static void testLinkedList (void) { linkedList_t *list = NULL; const char* data = "SomeDataForTheLinkedList"; const size_t length = strlen(data); linkedList_t *entry; const linkedList_t *entry2; const char *returnedData; entry = LIST_Add(&list, (const byte*)data, length); CU_ASSERT_EQUAL(LIST_Count(list), 1); CU_ASSERT_TRUE(entry != NULL); returnedData = (const char *)LIST_GetByIdx(list, 0); CU_ASSERT_TRUE(returnedData != NULL); entry2 = LIST_ContainsString(list, returnedData); CU_ASSERT_TRUE(entry2 != NULL); CU_ASSERT_EQUAL((const void*)entry2->data, (const void*)returnedData); CU_ASSERT_STRING_EQUAL(entry2->data, returnedData); LIST_RemoveEntry(&list, entry); CU_ASSERT_EQUAL(LIST_Count(list), 0); }
/** * @brief This test cycles through the list of map definitions found in the maps.ufo script * and builds each map with each ufo and every assembly for all valid seeds. * In other words: this a FULL test to check if some seed causes problems in any of the * possible combinations, so it should not be run on the buildserver on a daily basis. */ TEST_F(MapDefMassRMATest, DISABLED_MapDefsMassRMA) { /** You can test a certain assembly by passing "-Dmapdef-id=assembly" to testall. */ const char* filterId = TEST_GetStringProperty("mapdef-id"); const mapDef_t* md; int mapCount = 0; ASSERT_TRUE(csi.numMDs > 0); MapDef_Foreach(md) { if (md->mapTheme[0] == '.') continue; if (filterId && !Q_streq(filterId, md->id)) continue; if (++mapCount <= 0) /* change 0 to n to skip the first n assemblies */ continue; { char* p = md->mapTheme; if (*p == '+') p++; else continue; const char* asmName = (const char*)LIST_GetByIdx(md->params, 0); Com_Printf("\nMap: %s Assembly: %s AssNr: %i\n", p, asmName, mapCount); sv_threads->integer = 0; /* This is tricky. Some maps don't have any ufo on them and thus in the mapdef. * That would cause a LIST_Foreach macro to never run it's body. That's why these * for-loops seem to have two termination conditions. In fact, we have to manually * exit the for-loops if we ran it just once (without ufos nor dropships). */ bool didItOnce = false; linkedList_t* iterDrop; for (iterDrop = md->aircraft; iterDrop || !didItOnce; iterDrop = iterDrop->next) { const char* craft = nullptr; if (iterDrop) craft = (const char*) (iterDrop->data); if (craft) Cvar_Set("rm_drop", "%s", Com_GetRandomMapAssemblyNameForCraft(craft)); else Cvar_Set("rm_drop", "+craft_drop_firebird"); linkedList_t* iterUfo; for (iterUfo = md->ufos; iterUfo || !didItOnce; iterUfo = iterUfo->next) { const char* ufo = nullptr; if (iterUfo) ufo = (const char*) (iterUfo->data); if (ufo) Cvar_Set("rm_ufo", "%s", Com_GetRandomMapAssemblyNameForCraft(ufo)); else Cvar_Set("rm_ufo", "+craft_ufo_scout"); Com_Printf("\nDrop: %s Ufo: %s", craft, ufo); Com_Printf("\nSeed:"); for (int i = 0; i < RMA_HIGHEST_SUPPORTED_SEED; i++) { asmName = nullptr; srand(i); long time = Sys_Milliseconds(); Com_Printf(" %i", i); #if 0 typedef struct skip_info { int seed; char const* map; char const* params; char const* craft; char const* ufo; } skip_info; /* if we have known problems with some combinations, we can skip them */ skip_info const skip_list[] = { /* examples: */ // { 20, "forest", "large", "craft_drop_raptor", 0 }, // { 12, "forest", "large" "craft_drop_herakles", "craft_ufo_harvester" }, { -1, "frozen", "nature_medium",0, 0 }, { 11, "village", "medium", 0, 0 }, { 19, "village", "medium", 0, 0 }, { -1, "village", "medium_noufo", 0, 0 }, { -1, "village", "small", 0, 0 }, }; bool skip = false; for (skip_info const* e = skip_list; e != endof(skip_list); ++e) { if (e->seed >= 0 && i != e->seed) continue; if (e->map && !Q_streq(p, e->map)) continue; if (e->params && !Q_streq(md->params, e->params)) continue; if (e->craft && !Q_streq(craft, e->craft)) continue; if (e->ufo && !Q_streq(ufo, e->ufo)) continue; skip = true; break; } if (skip) continue; #endif /* for ufocrash map, the ufoname is the assemblyame */ if (Q_streq(p, "ufocrash")) asmName = Com_GetRandomMapAssemblyNameForCraft(ufo) + 1; /* +1 = get rid of the '+' */ else asmName = (const char*)LIST_GetByIdx(md->params, 0); char* entityString = SV_GetConfigString(CS_ENTITYSTRING); const int numPlaced = SV_AssembleMap(p, asmName, mapStr, posStr, entityString, i, false); ASSERT_TRUE(numPlaced != 0); time = (Sys_Milliseconds() - time); ASSERT_TRUE(time < 30000); if (time > 10000) Com_Printf("\nMap: %s Assembly: %s Seed: %i tiles: %i ms: %li\n", p, asmName, i, numPlaced, time); } didItOnce = true; if (!iterUfo) break; } if (!iterDrop) break; } } } }
/** * @brief This test cycles through the list of map definitions found in the maps.ufo script * and tries to find surfaces to stand on with no sound assigned to them. * * This test takes too long to be run every time testall is run. So it's set up almost like a game: * After 5 maps (the first of them is fully checked) with missing sounds, the test stops. * If we manage to 'clean' one of those 5 maps, the next map will show up in the next run. */ TEST_F(FootStepTest, DISABLED_MapDefsFootSteps) { const char* filterId = TEST_GetStringProperty("mapdef-id"); const mapDef_t* md; int mapCount = 0; // the number of maps read int badMapCount = 0; const int skipCount = 20; // to skip the first n mapDefs const int badMapCountMax = 25; // # of maps with missing sounds before this test stops const int mapCountMax = 150; // should of cause be higher than skip + bad const int texCountMax = 30; char texNames[texCountMax][MAX_QPATH]; bool done = false; OBJZERO(texNames); ASSERT_TRUE(csi.numMDs > 0); MapDef_Foreach(md) { if (md->mapTheme[0] == '.') continue; if (filterId && !Q_streq(filterId, md->id)) continue; mapCount++; if (mapCount <= skipCount) continue; /* use a known seed to reproduce an error */ unsigned int seed; if (TEST_ExistsProperty("mapdef-seed")) { seed = TEST_GetLongProperty("mapdef-seed"); } else { seed = (unsigned int) time(nullptr); } srand(seed); int count = 0; Com_Printf("testMapDefsFootSteps: Mapdef %s (seed %u)\n", md->id, seed); const char* asmName = (const char*)LIST_GetByIdx(md->params, 0); SV_Map(true, md->mapTheme, asmName); /* now that we have loaded the map, check all cells for walkable places */ GridBox mBox(sv->mapData.mapBox); // test ALL the cells #if !FOOTSTEPS_FULL if (mapCount >= skipCount + 4) { // after the first 4 maps, reduce the testing area const pos3_t center = {148, 128, 0}; mBox.set(center, center); // the box on the map we're testing mBox.expandXY(10); // just test a few cells around the center of the map mBox.maxs[2] = 2; // and 3 levels high } #endif mBox.clipToMaxBoundaries(); for (int x = mBox.getMinX(); x <= mBox.getMaxX() && !done; x++) { for (int y = mBox.getMinY(); y <= mBox.getMaxY() && !done; y++) { for (int z = mBox.getMinZ(); z <= mBox.getMaxZ(); z++) { const int floor = sv->mapData.routing.getFloor(1, x, y, z); if (floor < 0) // if we have a floor in that cell continue; const AABB noBox(vec3_origin, vec3_origin); // we're doing a point-trace const pos3_t cellPos = {(pos_t)x, (pos_t)y, (pos_t)z}; // the cell in question vec3_t from, to; PosToVec(cellPos, from); // the center of the cell VectorCopy(from, to); // also base for the endpoint of the trace from[2] -= UNIT_HEIGHT / 2; // bottom of the cell from[2] += (floor + 2) * QUANT; // add the height of the floor plus 2 QUANTS to[2] -= 2 * UNIT_HEIGHT; // we should really hit the ground with this const trace_t trace = SV_Trace(Line(from, to), noBox, nullptr, MASK_SOLID); if (!trace.surface) continue; const char* snd = SV_GetFootstepSound(trace.surface->name); if (snd) continue; for (int i = 0; i < texCountMax; ++i) { if (!texNames[i][0]) { // found a free slot ? Q_strncpyz(texNames[i], trace.surface->name, sizeof(texNames[i])); count++; break; } if (Q_streq(trace.surface->name, texNames[i])) // already there ? break; } if (count > texCountMax) { done = true; break; // the z-loop } } } } if (!texNames[0][0]) { Com_Printf("In map %s, asm %s: Nothing detected\n", md->mapTheme, asmName); } else { ++badMapCount; for (int i = 0; i < texCountMax; ++i) { if (texNames[i][0]) { Com_Printf("In map %s, asm %s: No sound for: %s\n", md->mapTheme, asmName, texNames[i]); } } } OBJZERO(texNames); SV_ShutdownGameProgs(); if (done || mapCount >= mapCountMax || badMapCount >= badMapCountMax) break; } }