Beispiel #1
0
/** ============================================================================
 *  @func   LIST_GetHead
 *
 *  @desc   Pops the head off the list and returns a pointer to it.
 *
 *  @modif  None
 *  ============================================================================
 */
EXPORT_API
DSP_STATUS
LIST_GetHead (IN List * list, OUT ListElement ** headElement)
{
    DSP_STATUS status = DSP_SOK ;

    TRC_2ENTER ("LIST_GetHead", list, headElement) ;

    DBC_Require (list != NULL) ;
    DBC_Require (headElement != NULL) ;

    if ((list == NULL) || (headElement == NULL)) {
        status = DSP_EINVALIDARG ;
        SET_FAILURE_REASON ;
    }
    else {
        if (LIST_IsEmpty (list)) {
            *headElement = NULL ;
        }
        else {
            *headElement = list->head.next ;
            list->head.next = (*headElement)->next ;
            (*headElement)->next->prev = &list->head ;
        }
    }

    TRC_1LEAVE ("LIST_GetHead", status) ;

    return status ;
}
Beispiel #2
0
/** ============================================================================
 *  @func   LIST_Next
 *
 *  @desc   Returns a pointer to the next element of the list, or NULL if
 *          the next element is the head of the list or the list is empty.
 *
 *  @modif  None
 *  ============================================================================
 */
EXPORT_API
DSP_STATUS
LIST_Next (IN  List *          list,
           IN  ListElement *   currentElement,
           OUT ListElement **  nextElement)
{
    DSP_STATUS status = DSP_SOK ;

    TRC_3ENTER ("LIST_Next", list, currentElement, nextElement) ;

    DBC_Require (list != NULL) ;
    DBC_Require (currentElement != NULL) ;
    DBC_Require (nextElement != NULL) ;

    if (   (list == NULL)
        || (currentElement == NULL)
        || (nextElement == NULL)) {
        status = DSP_EINVALIDARG ;
        SET_FAILURE_REASON ;
    }
    else {
        *nextElement = NULL ;           /* prime the variable */
        if (!LIST_IsEmpty (list)) {
            if (currentElement->next != &list->head) {
                *nextElement = currentElement->next ;
            }
        }
    }

    TRC_1LEAVE ("LIST_Next", status) ;

    return status ;
}
Beispiel #3
0
/** ============================================================================
 *  @func   LIST_First
 *
 *  @desc   Returns a pointer to the first element of the list, or NULL if
 *          the list is empty.
 *
 *  @modif  None
 *  ============================================================================
 */
EXPORT_API
DSP_STATUS
LIST_First (IN List * list, OUT ListElement ** element)
{
    DSP_STATUS      status = DSP_SOK ;

    TRC_2ENTER ("LIST_First", list, element) ;

    DBC_Require (list != NULL) ;

    if ((list == NULL) || (element == NULL)) {
        status = DSP_EINVALIDARG ;
        SET_FAILURE_REASON ;
    }
    else {
        if (!LIST_IsEmpty (list)) {
            *element  = list->head.next ;
        }
        else {
            *element = NULL ;
        }
    }

    TRC_1LEAVE ("LIST_First", status) ;

    return status ;
}
Beispiel #4
0
/** ============================================================================
 *  @func   LIST_RemoveElement
 *
 *  @desc   Removes (unlinks) the given element from the list, if the list is
 *          not empty.  Does not free the list element.
 *
 *  @modif  None
 *  ============================================================================
 */
EXPORT_API
DSP_STATUS
LIST_RemoveElement (IN List * list, IN ListElement * element)
{
    DSP_STATUS status = DSP_SOK ;

    TRC_2ENTER ("LIST_RemoveElement", list, element) ;

    DBC_Require (list != NULL) ;
    DBC_Require (element != NULL) ;

    if ((list == NULL) || (element == NULL)) {
        status = DSP_EINVALIDARG ;
        SET_FAILURE_REASON ;
    }
    else {
        if (!LIST_IsEmpty (list)) {
            element->prev->next = element->next ;
            element->next->prev = element->prev ;

            /* set elem fields to NULL to prevent illegal references */
            element->next = NULL ;
            element->prev = NULL ;
        }
        else {
            status = DSP_EINVALIDARG ;
            SET_FAILURE_REASON ;
        }
    }

    TRC_1LEAVE ("LIST_RemoveElement", status) ;

    return status ;
}
Beispiel #5
0
/** ============================================================================
 *  @func   LIST_PutTail
 *
 *  @desc   Adds the specified element to the tail of the list.
 *
 *  @modif  None
 *  ============================================================================
 */
EXPORT_API
DSP_STATUS
LIST_PutTail (IN List * list, IN ListElement * element)
{
    DSP_STATUS status = DSP_SOK ;

    TRC_2ENTER ("LIST_PutTail", list, element) ;

    DBC_Require (list != NULL) ;
    DBC_Require (element != NULL) ;

    if ((list == NULL) || (element == NULL)) {
        status = DSP_EINVALIDARG ;
        SET_FAILURE_REASON ;
    }
    else {
        element->prev       = list->head.prev ;
        element->next       = &list->head ;
        list->head.prev     = element ;
        element->prev->next = element ;
    }

    DBC_Assert (   (DSP_SUCCEEDED (status) && (!LIST_IsEmpty (list)))
                || (DSP_FAILED (status)));

    TRC_1LEAVE ("LIST_PutTail", status) ;

    return status ;
}
Beispiel #6
0
/** ============================================================================
 *  @func   LIST_InsertBefore
 *
 *  @desc   Insert the element before the existing element.
 *
 *  @modif  None
 *  ============================================================================
 */
EXPORT_API
DSP_STATUS
LIST_InsertBefore (IN  List *          list,
                   IN  ListElement *   insertElement,
                   IN  ListElement *   existingElement)
{
    DSP_STATUS status = DSP_SOK ;

    TRC_3ENTER ("LIST_InsertBefore", list, insertElement, existingElement) ;

    DBC_Require(list != NULL) ;
    DBC_Require(insertElement != NULL) ;
    DBC_Require(existingElement != NULL) ;

    if (   (list ==  NULL)
        || (insertElement == NULL)
        || (existingElement == NULL)) {
        status = DSP_EINVALIDARG ;
        SET_FAILURE_REASON ;
    }
    else {
        existingElement->prev->next = insertElement ;
        insertElement->prev         = existingElement->prev ;
        insertElement->next         = existingElement ;
        existingElement->prev       = insertElement ;
    }

    DBC_Assert (   (DSP_SUCCEEDED (status) && (!LIST_IsEmpty (list)))
                || (DSP_FAILED (status)));

    TRC_1LEAVE ("LIST_InsertBefore", status) ;

    return status ;
}
Beispiel #7
0
/** ============================================================================
 *  @func   LIST_SearchElement
 *
 *  @desc   This function searchs for a element in the List.
 *
 *  @modif  None.
 *  ============================================================================
 */
EXPORT_API
DSP_STATUS
LIST_SearchElement (IN  List *         list,
                    IN  Pvoid          data,
                    OUT ListElement ** elem,
                    IN  ListMatchFunc  matchFunc)
{
    DSP_STATUS          status = DSP_SOK ;
    ListElement *       temp   = NULL    ;
    ListElement *       temp1  = NULL    ;
    Bool                found  = FALSE   ;

    DBC_Require (list != NULL) ;
    DBC_Require (elem != NULL) ;
    DBC_Require (matchFunc != NULL) ;

    if ((list == NULL) || (elem == NULL)) {
        status = DSP_EINVALIDARG ;
        SET_FAILURE_REASON ;
    }
    else {
        if (LIST_IsEmpty (list)) {
            status = DSP_EINVALIDARG ;
            SET_FAILURE_REASON ;
        }

        if (DSP_SUCCEEDED (status)) {
            status = LIST_First (list, &temp) ;
            if (DSP_SUCCEEDED (status)) {
                while ((found == FALSE) && (temp != NULL)) {
                    if ((*matchFunc) (temp, data) == TRUE) {
                        found = TRUE ;
                    }
                    else {
                        temp1 = temp ;
                        LIST_Next (list, temp1, &temp) ;
                    }
                }

                if (found == TRUE) {
                    *elem = temp ;
                }
                else {
                    *elem = NULL ;
                    status = DSP_ENOTFOUND ;
                    SET_FAILURE_REASON ;
                }
            }
            else {
                SET_FAILURE_REASON ;
            }
        }
    }

    return status ;
}
Beispiel #8
0
static void testTeamDefsModelScriptData (void)
{
	int i;
	linkedList_t *armourPaths = NULL;

	for (i = 0; i < csi.numTeamDefs; i++) {
		int j;
		const teamDef_t *teamDef = &csi.teamDef[i];
		if (!teamDef->armour)
			continue;

		for (j = 0; j < csi.numODs; j++) {
			const objDef_t *od = INVSH_GetItemByIDX(j);
			if (!INV_IsArmour(od))
				continue;

			/* not for this team */
			if (!CHRSH_IsArmourUseableForTeam(od, teamDef))
				continue;

			if (!LIST_ContainsString(armourPaths, od->armourPath))
				LIST_AddString(&armourPaths, od->armourPath);
		}

		UFO_CU_ASSERT_TRUE_MSG(!LIST_IsEmpty(armourPaths), va("no armour definitions found for team %s - but armour is set to true",
				teamDef->id));

		LIST_Foreach(armourPaths, char const, armourPath) {
			int l;

			for (l = NAME_NEUTRAL; l < NAME_LAST; l++) {
				/* no models for this gender */
				if (!teamDef->numModels[l])
					continue;

				CU_ASSERT_PTR_NOT_NULL_FATAL(teamDef->models[l]);

				for (linkedList_t const* list = teamDef->models[l]; list; list = list->next) {
					teamDef_t::model_t const& m = *static_cast<teamDef_t::model_t const*>(list->data);

					UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s/%s", m.path, m.body)), va("%s does not exist in models/%s (teamDef: %s)",
							m.body, m.path, teamDef->id));
					UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s%s/%s", m.path, armourPath, m.body)), va("%s does not exist in models/%s%s (teamDef: %s)",
							m.body, m.path, armourPath, teamDef->id));

					UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s/%s", m.path, m.head)), va("%s does not exist in models/%s (teamDef: %s)",
							m.head, m.path, teamDef->id));
					UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s%s/%s", m.path, armourPath, m.head)), va("%s does not exist in models/%s%s (teamDef: %s)",
							m.head, m.path, armourPath, teamDef->id));
				}
			}
		}

		LIST_Delete(&armourPaths);
	}
Beispiel #9
0
int LIST_NumOfObjs(t_List *p_List)
{
    t_List *p_Tmp;
    int    numOfObjs = 0;

    if (!LIST_IsEmpty(p_List))
        LIST_FOR_EACH(p_Tmp, p_List)
            numOfObjs++;

    return numOfObjs;
}
Beispiel #10
0
/**
 * @brief Callback every time the parent window is closed (pop from the active window stack)
 */
void uiCvarNode::onWindowClosed (uiNode_t* node)
{
    cvar_t* var;

    var = Cvar_FindVar(node->name);
    if (var == nullptr)
        return;

    cvarChangeListener_t* l = var->changeListener;
    while (l) {
        if (l->exec == UI_CvarListenerNodeCallback) {
            LIST_Remove(reinterpret_cast<linkedList_t**>(&l->data), node);
            if (LIST_IsEmpty(static_cast<linkedList_t*>(l->data))) {
                Cvar_UnRegisterChangeListener(node->name, UI_CvarListenerNodeCallback);
            }
            break;
        }
        l = l->next;
    }
}
Beispiel #11
0
void GameTest::testCountSpawnpointsForMapInMultiplayerMode(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft, const char *ufo)
{
	if (verbose) {
		std::cout << "[          ] adding test parameter: gamemode multiplayer" << std::endl;
		Com_Printf("CountSpawnpoints - adding test parameter: gamemode multiplayer\n");
	}

	if (LIST_IsEmpty(md->gameTypes)) {
		ADD_FAILURE() << "Error: Multiplayer enabled, but no gametypes defined in mapdef " << md->id;
		Com_Printf("CountSpawnpoints - error: Multiplayer enabled, but no gametypes defined in mapdef.\n");
		return;
	}

	if (md->teams < 1) {
		ADD_FAILURE() << "Error: Multiplayer enabled, but number of teams is " << md->teams;
		Com_Printf("CountSpawnpoints - error: Multiplayer enabled, but number of teams is %i.\n", md->teams);
		return;
	}

	/* Set initial values. */
	/* Load map in multiplayer mode. */
	Cvar_Set("sv_maxclients", DOUBLEQUOTE(MAX_CLIENTS));
	/* It seems, because of reaction-fire limitations we cannot spawn more than 128 actors total. */
	Cvar_Set("sv_maxsoldiersperteam", "12");
	Cvar_Set("ai_multiplayeraliens", "64");
	Cvar_Set("ai_numcivilians", "16");

	Com_Printf("CountSpawnpoints - loading map: mode multiplayer mapdef %s map %s assembly %s dropship %s ufo %s\n", md->id, md->mapTheme, asmName, aircraft, ufo);
	long time = Sys_Milliseconds();

	try {
		SV_Map(true, md->mapTheme, asmName, true);
	} catch (comDrop_t&) {
		ADD_FAILURE() << "Error: Failed to load assembly " << asmName << " from mapdef " << md->id << ", map "
			<< md->mapTheme << " aircraft: " << aircraft << ", ufo: " << ufo << " => multiplayer mode.";
			Com_Printf("CountSpawnpoints - error: Multiplayer enabled, but no gametypes defined in mapdef.\n");
		Com_Printf("CountSpawnpoints - error: Failed to load map.\n");
		SV_ShutdownGameProgs();
		return;
	}

	time = Sys_Milliseconds() - time;
	Com_Printf("CountSpawnpoints - result: %li ms\n", time);
	SV_ShutdownGameProgs();
	mapCount++;

	/* Print report to log. */
	Com_Printf("CountSpawnpoints - map: mode multiplayer\n");
	Com_Printf("CountSpawnpoints - map: mapdef %s\n", md->id);
	Com_Printf("CountSpawnpoints - map: map %s\n", md->mapTheme);
	Com_Printf("CountSpawnpoints - map: assembly %s\n", asmName);
	Com_Printf("CountSpawnpoints - map: aircraft %s \n", aircraft);
	Com_Printf("CountSpawnpoints - map: ufo %s\n", ufo);

	/* Check if one of the gametypes available in the mapdef defines a coop mode,
	   in which case we will need aliens on the map. */
	int coop = 0;
	/* The number of alien spawnpoints required on the map. In PvP gamemodes this is zero,
	   while in coop games we check for the number given as 'maxaliens' in the mapdef. */
	int minAliens = 0;
	/* The number of player spawnpoints required for each team is determined
	   by the value of sv_maxsoldiersperteam given in the gametype def. */
	int minMP = 0;

	/* Count spawnpoints for TEAM_CIVILIAN. */
	const int spawnCivs = static_cast<int>(level.num_spawnpoints[TEAM_CIVILIAN]);
	Com_Printf("CountSpawnpoints - count spawnpoints: civilian %i\n", spawnCivs);

	/* Find the highest numbers for alien and player spawnpoints needed in the map. */
	LIST_Foreach(md->gameTypes, const char, gameType) {
		for (int i = 0; i < csi.numGTs; i++) {
			const gametype_t* gt = &csi.gts[i];
			if (!Q_streq(gt->id, gameType))
				continue;
			const cvarlist_t* list = gt->cvars;
			for (int j = 0; j < gt->num_cvars; j++, list++) {
				if (Q_streq(list->name, "ai_multiplayeraliens")) {
					coop = std::max(coop, atoi(list->value));
				} else if (Q_streq(list->name, "sv_maxsoldiersperteam")) {
					minMP = std::max(minMP, atoi(list->value));
				}
			}
		}
	}

	/* If the mapdef does not define a coop mode, we do not need aliens. */
	if (coop)
		minAliens = std::min(md->maxAliens, testCountSpawnpointsGetNumteamValueForUFO(ufo));

	const int startTeam = TEAM_CIVILIAN + 1;
	/* For every single mp team defined in the mapdef - check if there are enough spawnpoints available. */
	for (int currTeamNum = startTeam; currTeamNum < startTeam + md->teams; ++currTeamNum) {
		if (currTeamNum > TEAM_MAX_HUMAN) {
			ADD_FAILURE() << "Error: Mapdef " << md->id << " has too many teams set.";
			Com_Printf("CountSpawnpoints - error: Too many teams set.\n");
			break;
		}
		const int spawnTeam = static_cast<int>(level.num_spawnpoints[currTeamNum]);
		/* Make gtest report back in case there are not enough spawnpoints available for the team. */
		EXPECT_GE(spawnTeam, minMP) << "Error: Assembly " << asmName << " from mapdef " << md->id << ", map " << md->mapTheme
			<< "(aircraft: " << aircraft << ", ufo: " << ufo << ") in multiplayer mode: Only " << spawnTeam
			<< " spawnpoints for team " << currTeamNum << " but " << minMP << " expected.";
		/* Log the result. */
		Com_Printf("CountSpawnpoints - count spawnpoints: player team/needs/found %i/%i/%i\n", currTeamNum, minMP, spawnTeam);
		if (spawnTeam < minMP)
			Com_Printf("CountSpawnpoints - error: missing spawnpoints - player team/needs/found %i/%i/%i\n", currTeamNum, minMP, spawnTeam);

	}
	if (minAliens) {
		const int spawnAliens = static_cast<int>(level.num_spawnpoints[TEAM_ALIEN]);
		/* Make gtest report back in case there are not enough alien spawnpoints available. */
		EXPECT_GE(spawnAliens, minAliens) << "Assembly " << asmName << " from mapdef " << md->id << ", map " << md->mapTheme
			<< "(aircraft: " << aircraft << ", ufo: " << ufo << ") in multiplayer mode defines at least one coop game mode,"
			<< " but does not have enough alien spawn positions for that. We expect at least " << minAliens
			<< " spawn positions for aliens, the map provides " << spawnAliens << ".";
		/* Log the result. */
		Com_Printf("CountSpawnpoints - count spawnpoints: alien needs/found %i/%i\n", minAliens, spawnAliens);
		if (spawnAliens < minAliens)
			Com_Printf("CountSpawnpoints - error: missing spawnpoints - alien needs/found %i/%i\n", minAliens, spawnAliens);
	}

	SV_ShutdownGameProgs();
}
static void testTeamDefsModelScriptData (void)
{
	int i;
	linkedList_t *armourPaths = NULL;

	for (i = 0; i < csi.numTeamDefs; i++) {
		int j;
		const teamDef_t *teamDef = &csi.teamDef[i];
		if (!teamDef->armour)
			continue;

		for (j = 0; j < csi.numODs; j++) {
			const objDef_t *od = INVSH_GetItemByIDX(j);
			if (!INV_IsArmour(od))
				continue;

			/* not for this team */
			if (!CHRSH_IsArmourUseableForTeam(od, teamDef))
				continue;

			if (!LIST_ContainsString(armourPaths, od->armourPath))
				LIST_AddString(&armourPaths, od->armourPath);
		}

		UFO_CU_ASSERT_TRUE_MSG(!LIST_IsEmpty(armourPaths), va("no armour definitions found for team %s - but armour is set to true",
				teamDef->id));

		LIST_Foreach(armourPaths, char const, armourPath) {
			nametypes_t l;

			for (l = NAME_NEUTRAL; l < NAME_LAST; l++) {
				linkedList_t *list = teamDef->models[l];
				int k;

				/* no models for this gender */
				if (!teamDef->numModels[l])
					continue;

				CU_ASSERT_PTR_NOT_NULL(list);
				for (k = 0; k < teamDef->numModels[l]; k++) {
					const char *path;

					CU_ASSERT_PTR_NOT_NULL_FATAL(list);
					path = (const char*)list->data;
					/* body */
					list = list->next;
					CU_ASSERT_PTR_NOT_NULL_FATAL(list);
					UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s/%s", path, list->data)), va("%s does not exist in models/%s (teamDef: %s)",
							list->data, path, teamDef->id));
					UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s%s/%s", path, armourPath, list->data)), va("%s does not exist in models/%s%s (teamDef: %s)",
							list->data, path, armourPath, teamDef->id));

					list = list->next;
					CU_ASSERT_PTR_NOT_NULL_FATAL(list);
					/* head */
					UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s/%s", path, list->data)), va("%s does not exist in models/%s (teamDef: %s)",
							list->data, path, teamDef->id));
					UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s%s/%s", path, armourPath, list->data)), va("%s does not exist in models/%s%s (teamDef: %s)",
							list->data, path, armourPath, teamDef->id));

					/* skip skin */
					/** @todo check that the skin is valid for the given model */
					list = list->next;
					CU_ASSERT_PTR_NOT_NULL_FATAL(list);

					/* new path */
					list = list->next;
				}
			}
		}

		LIST_Delete(&armourPaths);
	}
Beispiel #13
0
/**
 * @sa CL_ParseScriptFirst
 */
static void CP_ParseAlienTeam (const char *name, const char **text)
{
	const char *errhead = "CP_ParseAlienTeam: unexpected end of file (alienteam ";
	const char *token;
	int i;
	alienTeamCategory_t *alienCategory;

	/* get it's body */
	token = Com_Parse(text);

	if (!*text || *token != '{') {
		Com_Printf("CP_ParseAlienTeam: alien team category \"%s\" without body ignored\n", name);
		return;
	}

	if (ccs.numAlienCategories >= ALIENCATEGORY_MAX) {
		Com_Printf("CP_ParseAlienTeam: maximum number of alien team category reached (%i)\n", ALIENCATEGORY_MAX);
		return;
	}

	/* search for category with same name */
	for (i = 0; i < ccs.numAlienCategories; i++)
		if (Q_streq(name, ccs.alienCategories[i].id))
			break;
	if (i < ccs.numAlienCategories) {
		Com_Printf("CP_ParseAlienTeam: alien category def \"%s\" with same name found, second ignored\n", name);
		return;
	}

	alienCategory = &ccs.alienCategories[ccs.numAlienCategories++];
	Q_strncpyz(alienCategory->id, name, sizeof(alienCategory->id));

	do {
		token = Com_EParse(text, errhead, name);
		if (!*text)
			break;
		if (*token == '}')
			break;

		if (Q_streq(token, "equipment")) {
			linkedList_t **list = &alienCategory->equipment;
			token = Com_EParse(text, errhead, name);
			if (!*text || *token != '{') {
				Com_Printf("CP_ParseAlienTeam: alien team category \"%s\" has equipment with no opening brace\n", name);
				break;
			}
			do {
				token = Com_EParse(text, errhead, name);
				if (!*text || *token == '}')
					break;
				LIST_AddString(list, token);
			} while (*text);
		} else if (Q_streq(token, "category")) {
			token = Com_EParse(text, errhead, name);
			if (!*text || *token != '{') {
				Com_Printf("CP_ParseAlienTeam: alien team category \"%s\" has category with no opening brace\n", name);
				break;
			}
			do {
				token = Com_EParse(text, errhead, name);
				if (!*text || *token == '}')
					break;
				alienCategory->missionCategories[alienCategory->numMissionCategories] = CP_GetAlienMissionTypeByID(token);
				if (alienCategory->missionCategories[alienCategory->numMissionCategories] == INTERESTCATEGORY_NONE)
					Com_Printf("CP_ParseAlienTeam: alien team category \"%s\" is used with no mission category. It won't be used in game.\n", name);
				alienCategory->numMissionCategories++;
			} while (*text);
		} else if (Q_streq(token, "team")) {
			alienTeamGroup_t *group;

			token = Com_EParse(text, errhead, name);
			if (!*text || *token != '{') {
				Com_Printf("CP_ParseAlienTeam: alien team \"%s\" has team with no opening brace\n", name);
				break;
			}

			if (alienCategory->numAlienTeamGroups >= MAX_ALIEN_GROUP_PER_CATEGORY) {
				Com_Printf("CP_ParseAlienTeam: maximum number of alien team reached (%i) in category \"%s\"\n", MAX_ALIEN_GROUP_PER_CATEGORY, name);
				break;
			}

			group = &alienCategory->alienTeamGroups[alienCategory->numAlienTeamGroups];
			group->idx = alienCategory->numAlienTeamGroups;
			group->categoryIdx = alienCategory - ccs.alienCategories;
			alienCategory->numAlienTeamGroups++;

			do {
				token = Com_EParse(text, errhead, name);

				if (!Com_ParseBlockToken(name, text, group, alien_group_vals, cp_campaignPool, token)) {
					const teamDef_t *teamDef;
					if (!*text || *token == '}')
						break;

					/* This is an alien team */
					if (group->numAlienTeams >= MAX_TEAMS_PER_MISSION)
						Com_Error(ERR_DROP, "CL_ParseAlienTeam: MAX_TEAMS_PER_MISSION hit");
					teamDef = Com_GetTeamDefinitionByID(token);
					if (teamDef)
						group->alienTeams[group->numAlienTeams++] = teamDef;
				}
			} while (*text);
		} else {
			Com_Printf("CP_ParseAlienTeam: unknown token \"%s\" ignored (category %s)\n", token, name);
			continue;
		}
	} while (*text);

	if (LIST_IsEmpty(alienCategory->equipment))
		Sys_Error("alien category equipment list is empty");
}
Beispiel #14
0
void LIST_Sort (linkedList_t **list, linkedListSort_t sorter, const void *userData)
{
	if (LIST_IsEmpty(*list))
		return;
	*list = _LIST_Sort(*list, sorter, userData);
}