static void testVisFlags (void) { const char *mapName = "test_game"; if (FS_CheckFile("maps/%s.bsp", mapName) != -1) { edict_t *ent; int num; /* the other tests didn't call the server shutdown function to clean up */ OBJZERO(*sv); SV_Map(true, mapName, NULL); num = 0; ent = NULL; while ((ent = G_EdictsGetNextLivingActorOfTeam(ent, TEAM_ALIEN))) { const teammask_t teamMask = G_TeamToVisMask(ent->team); const bool visible = ent->visflags & teamMask; char *visFlagsBuf = Mem_StrDup(Com_UnsignedIntToBinary(ent->visflags)); char *teamMaskBuf = Mem_StrDup(Com_UnsignedIntToBinary(teamMask)); CU_ASSERT_EQUAL(ent->team, TEAM_ALIEN); UFO_CU_ASSERT_TRUE_MSG(visible, va("visflags: %s, teamMask: %s", visFlagsBuf, teamMaskBuf)); Mem_Free(visFlagsBuf); Mem_Free(teamMaskBuf); num++; } SV_ShutdownGameProgs(); CU_ASSERT_TRUE(num > 0); } else { UFO_CU_FAIL_MSG(va("Map resource '%s.bsp' for test is missing.", mapName)); } }
/** * @brief Parses one key and value for an entity from the current tokens * @sa parsedToken * @sa GetToken * @sa ParseEntity * @sa ParseMapEntity */ epair_t* ParseEpair (int entNum) { StripTrailingWhitespaces(parsedToken); const char* key = Mem_StrDup(parsedToken); GetToken(); StripTrailingWhitespaces(parsedToken); const char* value = Mem_StrDup(parsedToken); return AddEpair(key, value, entNum); }
void SetKeyValue (entity_t* ent, const char* key, const char* value) { for (epair_t* ep = ent->epairs; ep; ep = ep->next) if (Q_streq(ep->key, key)) { ep->value = Mem_StrDup(value); return; } epair_t* e = AddEpair(Mem_StrDup(key), Mem_StrDup(value), -1); e->next = ent->epairs; ent->epairs = e; }
void SetKeyValue (entity_t* ent, const char* key, const char* value) { epair_t* ep; for (ep = ent->epairs; ep; ep = ep->next) if (Q_streq(ep->key, key)) { ep->value = Mem_StrDup(value); return; } ep = Mem_AllocType(epair_t); ep->next = ent->epairs; ent->epairs = ep; ep->key = Mem_StrDup(key); ep->value = Mem_StrDup(value); }
/** * @brief Register an actorskin name * @return The id where the actorskin is registered */ int R_ModAllocateActorSkin (const char* name) { if (r_numActorSkinName >= lengthof(r_actorSkinNames)) return -1; r_actorSkinNames[r_numActorSkinName] = Mem_StrDup(name); return r_numActorSkinName++; }
/** * @brief Reads the tiles and position config strings and convert them into a * linked list that holds the imagename (mapname), the x and the y position * (screencoordinates) * @param[in] tiles The configstring with the tiles (map tiles) * @param[in] pos The position string, only used in case of random map assembly * @sa UI_DrawRadar * @sa R_ModBeginLoading */ static void UI_BuildRadarImageList (const char *tiles, const char *pos) { const float mapMidX = cl.mapData->getWidthX() * 0.5; const float mapMidY = (cl.mapData->mapMax[1] + cl.mapData->mapMin[1]) * 0.5; /* load tiles */ while (tiles) { int i; vec3_t sh; char name[MAX_VAR]; hudRadarImage_t *image; /* get tile name */ const char *token = Com_Parse(&tiles); if (!tiles) { /* finish */ return; } /* get base path */ if (token[0] == '-') { Q_strncpyz(radar.base, token + 1, sizeof(radar.base)); continue; } /* get tile name */ if (token[0] == '+') token++; Com_sprintf(name, sizeof(name), "%s%s", radar.base, token); image = &radar.images[radar.numImages++]; image->name = Mem_StrDup(name); image->isTile = pos && pos[0]; if (!image->isTile) /* it is a single background image*/ return; /* get grid position and add a tile */ for (i = 0; i < 3; i++) { token = Com_Parse(&pos); if (!pos) Com_Error(ERR_DROP, "UI_BuildRadarImageList: invalid positions\n"); sh[i] = atoi(token); } image->gridX = sh[0]; image->gridY = sh[1]; image->mapX = mapMidX + sh[0] * UNIT_SIZE; image->mapY = mapMidY + sh[1] * UNIT_SIZE; Com_Printf("radar %s %dx%d\n", name, image->gridX, image->gridY); if (radar.gridMin[0] > sh[0]) radar.gridMin[0] = sh[0]; if (radar.gridMin[1] > sh[1]) radar.gridMin[1] = sh[1]; } }
/** * @brief Sets the cvar value back to the old value * @param cvar The cvar to reset */ void Cvar_Reset (cvar_t* cvar) { char* str; if (cvar->oldString == nullptr) return; str = Mem_StrDup(cvar->oldString); Cvar_Set(cvar->name, "%s", str); Mem_Free(str); }
void UI_RadioButton_SetValue (uiNode_t* node, const char* value) { /* This is a special case: we have a situation where the node already has a value reference (either being float or cvar). We now want to replace this value reference by a new cvar. So we first need to free the existing reference, then create new cvar reference (just a string starting with '*cvar' and store it. */ Mem_Free(*(void**)(EXTRADATA(node).string)); *(void**)EXTRADATA(node).string= Mem_StrDup(value); uiRadioButtonNode* b=static_cast<uiRadioButtonNode*>(node->behaviour->manager.get()); b->onActivate(node); }
TEST_F(GameTest, VisFlags) { const char* mapName = "test_game"; ASSERT_NE(-1, FS_CheckFile("maps/%s.bsp", mapName)) << "Map resource '" << mapName << ".bsp' for test is missing."; int num; SV_Map(true, mapName, nullptr); num = 0; Actor* actor = nullptr; while ((actor = G_EdictsGetNextLivingActorOfTeam(actor, TEAM_ALIEN))) { const teammask_t teamMask = G_TeamToVisMask(actor->getTeam()); const bool visible = actor->visflags & teamMask; char* visFlagsBuf = Mem_StrDup(Com_UnsignedIntToBinary(actor->visflags)); char* teamMaskBuf = Mem_StrDup(Com_UnsignedIntToBinary(teamMask)); ASSERT_EQ(actor->getTeam(), TEAM_ALIEN); ASSERT_TRUE(visible) << "visflags: " << visFlagsBuf << ", teamMask: " << teamMaskBuf; Mem_Free(visFlagsBuf); Mem_Free(teamMaskBuf); num++; } ASSERT_TRUE(num > 0) << "No alien actors found"; }
/** * @brief Calculate some radar values that won't change during a mission * @note Called for every new map (client_state_t is wiped with every * level change) */ static void UI_InitRadar (const uiNode_t* node) { int i, j; const vec3_t offset = {MAP_SIZE_OFFSET, MAP_SIZE_OFFSET, MAP_SIZE_OFFSET}; float distAB, distBC; vec2_t gridSize; /**< Size of the whole grid (in tiles units) */ vec2_t nodepos; vec2_t min; vec2_t max; UI_FreeRadarImages(); UI_BuildRadarImageList(CL_GetConfigString(CS_TILES), CL_GetConfigString(CS_POSITIONS)); UI_GetNodeAbsPos(node, nodepos); radar.x = nodepos[0] + node->box.size[0] / 2; radar.y = nodepos[1] + node->box.size[1] / 2; /* only check once per map whether all the needed images exist */ for (j = 0; j < radar.numImages; j++) { hudRadarImage_t* tile = &radar.images[j]; /* map_mins, map_maxs */ for (i = 0; i < PATHFINDING_HEIGHT; i++) { char imagePath[MAX_QPATH]; const image_t* image; if (!UI_CheckRadarImage(tile->name, i + 1)) { if (i == 0) { /* there should be at least one level */ Com_Printf("No radar images for map: '%s'\n", tile->name); radar.numImages = 0; return; } continue; } Com_sprintf(imagePath, sizeof(imagePath), "radars/%s_%i", tile->name, i + 1); tile->path[i] = Mem_StrDup(imagePath); tile->maxlevel++; image = R_FindImage(va("pics/%s", tile->path[i]), it_pic); tile->width = image->width; tile->height = image->height; if (tile->isTile) { tile->gridWidth = round(image->width / 94.0f); tile->gridHeight = round(image->height / 94.0f); tile->mapWidth = tile->gridWidth * 8 * UNIT_SIZE; tile->mapHeight = tile->gridHeight * 8 * UNIT_SIZE; } else { tile->mapX = cl.mapData->mapBox.getMinX(); tile->mapY = cl.mapData->mapBox.getMinY(); tile->mapWidth = cl.mapData->mapBox.getWidthX(); tile->mapHeight = cl.mapData->mapBox.getWidthY(); } } if (tile->isTile) { tile->mapY = cl.mapData->mapBox.getMaxY() - tile->mapY - tile->mapHeight; } } /* center tiles into the minMap/maxMap */ Vector2Copy(cl.mapData->mapBox.maxs, min); Vector2Copy(cl.mapData->mapBox.mins, max); for (j = 0; j < radar.numImages; j++) { hudRadarImage_t* tile = &radar.images[j]; if (tile->mapX < min[0]) min[0] = tile->mapX; if (tile->mapY < min[1]) min[1] = tile->mapY; if (tile->mapX + tile->mapWidth > max[0]) max[0] = tile->mapX + tile->mapWidth; if (tile->mapY + tile->mapHeight > max[1]) max[1] = tile->mapY + tile->mapHeight; } /* compute translation */ min[0] = cl.mapData->mapBox.getMinX() + (cl.mapData->mapBox.getWidthX() - (max[0] - min[0])) * 0.5 - min[0]; min[1] = cl.mapData->mapBox.getMinY() + (cl.mapData->mapBox.getWidthY() - (max[1] - min[1])) * 0.5 - min[1]; for (j = 0; j < radar.numImages; j++) { hudRadarImage_t* tile = &radar.images[j]; tile->mapX += min[0]; tile->mapY += min[1]; } /* get the three points of the triangle */ VectorSubtract(cl.mapData->mapBox.mins, offset, radar.a); VectorAdd(cl.mapData->mapBox.maxs, offset, radar.c); VectorSet(radar.b, radar.c[0], radar.a[1], 0); distAB = (Vector2Dist(radar.a, radar.b) / UNIT_SIZE); distBC = (Vector2Dist(radar.b, radar.c) / UNIT_SIZE); UI_GetRadarWidth(node, gridSize); /* get the dimensions for one grid field on the radar map */ radar.gridWidth = radar.w / distAB; radar.gridHeight = radar.h / distBC; /* shift the x and y values according to their grid width/height and * their gridX and gridY position */ { const float radarLength = std::max(1.0f, fabsf(gridSize[0])); const float radarHeight = std::max(1.0f, fabsf(gridSize[1])); /* image grid relations */ const float gridFactorX = radar.w / radarLength; const float gridFactorY = radar.h / radarHeight; for (j = 0; j < radar.numImages; j++) { hudRadarImage_t* image = &radar.images[j]; image->x = (image->gridX - radar.gridMin[0]) * gridFactorX; image->y = radar.h - (image->gridY - radar.gridMin[1]) * gridFactorY - image->height; } } /* now align the screen coordinates like it's given by the node */ radar.x -= (radar.w / 2); radar.y -= (radar.h / 2); }
/* ================= EndDMLevel The timelimit or fraglimit has been exceeded ================= */ void EndDMLevel () { char *s, *t, *f; static const char *seps = " ,\n\r"; // stay on same level flag if (DeathmatchFlags.dfSameLevel.IsEnabled()) { BeginIntermission (CreateTargetChangeLevel (Level.ServerLevelName.CString())); return; } if (!Level.ForceMap.IsNullOrEmpty()) { BeginIntermission (CreateTargetChangeLevel (Level.ForceMap.CString())); return; } // see if it's in the map list if (*CvarList[CV_MAPLIST].StringValue()) { s = Mem_StrDup(CvarList[CV_MAPLIST].StringValue()); f = NULL; t = strtok(s, seps); while (t != NULL) { if (Q_stricmp(t, Level.ServerLevelName.CString()) == 0) { // it's in the list, go to the next one t = strtok(NULL, seps); if (t == NULL) { // end of list, go to first one if (f == NULL) // there isn't a first one, same level BeginIntermission (CreateTargetChangeLevel (Level.ServerLevelName.CString()) ); else BeginIntermission (CreateTargetChangeLevel (f) ); } else BeginIntermission (CreateTargetChangeLevel (t) ); QDelete s; return; } if (!f) f = t; t = strtok(NULL, seps); } free(s); } if (!Level.NextMap.IsNullOrEmpty()) // go to a specific map BeginIntermission (CreateTargetChangeLevel (Level.NextMap.CString()) ); else { // search for a changelevel CTargetChangeLevel *Entity = CC_FindByClassName<CTargetChangeLevel, EF_BASE> (NULL, "target_changelevel"); if (!Entity) { // the map designer didn't include a changelevel, // so create a fake ent that goes back to the same level BeginIntermission (CreateTargetChangeLevel (Level.ServerLevelName.CString()) ); return; } BeginIntermission (Entity); } }
static linkedList_t *LIST_AllocateString(char const* data, linkedList_t* const next = 0) { return LIST_AllocateEntry(Mem_StrDup(data), next); }
/** * @brief Parsed map entites and brushes * @sa ParseBrush * @param[in] filename The map filename * @param[in] entityString The body of the entity we are parsing */ static bool ParseMapEntity (const char* filename, const char* entityString) { entity_t* mapent; const char* entName; static int worldspawnCount = 0; int notCheckOrFix = !(config.performMapCheck || config.fixMap); if (Q_strnull(GetToken())) return false; if (*parsedToken != '{') Sys_Error("ParseMapEntity: { not found"); if (num_entities == MAX_MAP_ENTITIES) Sys_Error("num_entities == MAX_MAP_ENTITIES (%i)", num_entities); mapent = &entities[num_entities++]; OBJZERO(*mapent); mapent->firstbrush = nummapbrushes; mapent->numbrushes = 0; do { if (Q_strnull(GetToken())) Sys_Error("ParseMapEntity: EOF without closing brace"); if (*parsedToken == '}') break; if (*parsedToken == '{') ParseBrush(mapent, filename); else { epair_t* e = ParseEpair(num_entities); e->next = mapent->epairs; mapent->epairs = e; } } while (true); GetVectorForKey(mapent, "origin", mapent->origin); entName = ValueForKey(mapent, "classname"); /* offset all of the planes and texinfo if needed */ if (IsInlineModelEntity(entName) && VectorNotEmpty(mapent->origin)) AdjustBrushesForOrigin(mapent); if (num_entities == 1 && !Q_streq("worldspawn", entName)) Sys_Error("The first entity must be worldspawn, it is: %s", entName); if (notCheckOrFix && Q_streq("func_group", entName)) { /* group entities are just for editor convenience * toss all brushes into the world entity */ MoveBrushesToWorld(mapent); num_entities--; } else if (IsInlineModelEntity(entName)) { if (mapent->numbrushes == 0 && notCheckOrFix) { Com_Printf("Warning: %s has no brushes assigned (entnum: %i)\n", entName, num_entities); num_entities--; } } else if (Q_streq("worldspawn", entName)) { worldspawnCount++; if (worldspawnCount > 1) Com_Printf("Warning: more than one %s in one map\n", entName); const char* text = entityString; do { const char* token = Com_Parse(&text); if (Q_strnull(token)) break; const char* key = Mem_StrDup(token); token = Com_Parse(&text); if (Q_strnull(token)) break; const char* value = Mem_StrDup(token); epair_t* e = AddEpair(key, value, num_entities); e->next = mapent->epairs; mapent->epairs = e; } while (true); } return true; }