Exemplo n.º 1
0
/**
 * @brief Removes employee until all employees fit in quarters capacity.
 * @param[in] base Pointer to the base where the number of employees should be updated.
 * @note employees are killed, and not just unhired (if base is destroyed, you can't recruit the same employees elsewhere)
 *	if you want to unhire employees, you should do it before calling this function.
 * @note employees are not randomly chosen. Reason is that all Quarter will be destroyed at the same time,
 *	so all employees are going to be killed anyway.
 */
void E_DeleteEmployeesExceedingCapacity (base_t *base)
{
	int type;

	/* Check if there are too many employees */
	if (base->capacities[CAP_EMPLOYEES].cur <= base->capacities[CAP_EMPLOYEES].max)
		return;

	/* do a reverse loop in order to finish by soldiers (the most important employees) */
	for (type = MAX_EMPL - 1; type >= 0; type--) {
		employee_t *employee;

		/* UGV are not stored in Quarters */
		if (type == EMPL_ROBOT)
			continue;

		E_Foreach(type, employee) {
			if (E_IsInBase(employee, base))
				E_DeleteEmployee(employee);

			if (base->capacities[CAP_EMPLOYEES].cur <= base->capacities[CAP_EMPLOYEES].max)
				return;
		}
	}

	Com_Printf("E_DeleteEmployeesExceedingCapacity: Warning, removed all employees from base '%s', but capacity is still > 0\n", base->name);
}
Exemplo n.º 2
0
/**
 * @brief Gets an assigned employee of a given type from the given base.
 * @param[in] base Which base the employee should be hired in.
 * @param[in] type The type of employee to search.
 * @return employee_t
 * @sa E_EmployeeIsUnassigned
 * @note unassigned is not unhired - they are already hired in a base but are at quarters
 */
employee_t* E_GetUnassignedEmployee (const base_t* const base, const employeeType_t type)
{
	employee_t *employee;

	E_Foreach(type, employee) {
		if (!E_IsInBase(employee, base))
			continue;
		if (E_EmployeeIsUnassigned(employee))
			return employee;
	}
	return NULL;
}
Exemplo n.º 3
0
/**
 * @brief Counts 'hired' (i.e. bought or produced UGVs and other robots of a given ugv-type in a given base.
 * @param[in] base The base where we count (@c NULL to count all).
 * @param[in] ugvType What type of robot/ugv we are looking for.
 * @return Count of Robots/UGVs.
 */
int E_CountHiredRobotByType (const base_t* const base, const ugv_t *ugvType)
{
	int count = 0;
	employee_t *employee;

	E_Foreach(EMPL_ROBOT, employee) {
		if (!E_IsHired(employee))
			continue;
		if (employee->ugv == ugvType && (!base || E_IsInBase(employee, base)))
			count++;
	}
	return count;
}
Exemplo n.º 4
0
/**
 * @brief Counts hired employees of a given type in a given base
 * @param[in] base The base where we count (@c NULL to count all).
 * @param[in] type The type of employee to search.
 * @return count of hired employees of a given type in a given base
 */
int E_CountHired (const base_t* const base, employeeType_t type)
{
	int count = 0;
	employee_t *employee;

	E_Foreach(type, employee) {
		if (!E_IsHired(employee))
			continue;
		if (!base || E_IsInBase(employee, base))
			count++;
	}
	return count;
}
Exemplo n.º 5
0
/**
 * @brief Reset the hired flag for all employees of a given type in a given base
 * @param[in] base Which base the employee should be fired from.
 * @param[in] type Which employee type do we search.
 */
void E_UnhireAllEmployees (base_t* base, employeeType_t type)
{
	employee_t *employee;

	if (!base)
		return;

	assert(type < MAX_EMPL);

	E_Foreach(type, employee) {
		if (!E_IsInBase(employee, base))
			continue;
		E_UnhireEmployee(employee);
	}
}
Exemplo n.º 6
0
/**
 * @brief Removes all employees completely from the game (buildings + global list) from a given base.
 * @note Used if the base e.g is destroyed by the aliens.
 * @param[in] base Which base the employee should be fired from.
 */
void E_DeleteAllEmployees (base_t* base)
{
	employeeType_t type;

	for (type = EMPL_SOLDIER; type < MAX_EMPL; type++) {
		employee_t *lastEmployee = NULL;
		employee_t *employee = NULL;

		E_Foreach(type, employee) {
			if ((base == NULL || E_IsInBase(employee, base)) && E_DeleteEmployee(employee))
				employee = lastEmployee;
			else
				lastEmployee = employee;
		}
	}
}
Exemplo n.º 7
0
/**
 * @brief Counts unassigned employees of a given type in a given base
 * @param[in] type The type of employee to search.
 * @param[in] base The base where we count
 */
int E_CountUnassigned (const base_t* const base, employeeType_t type)
{
	int count;
	employee_t *employee;

	if (!base)
		return 0;

	count = 0;

	E_Foreach(type, employee) {
		if (!E_IsInBase(employee, base))
			continue;
		if (E_EmployeeIsUnassigned(employee))
			count++;
	}
	return count;
}
Exemplo n.º 8
0
/**
 * @brief Return a "hired" ugv-employee pointer of a given ugv-type in a given base.
 * @param[in] base Which base the ugv should be searched in.c
 * @param[in] ugvType What type of robot we want.
 * @return employee_t pointer on success or NULL on error.
 * @sa E_GetUnhiredRobot
 */
employee_t* E_GetHiredRobot (const base_t* const base, const ugv_t *ugvType)
{
	linkedList_t *hiredEmployees = NULL;
	employee_t *employee;

	E_GetHiredEmployees(base, EMPL_ROBOT, &hiredEmployees);

	LIST_Foreach(hiredEmployees, employee_t, employee) {
		if ((employee->ugv == ugvType || !ugvType)	/* If no type was given we return the first ugv we find. */
		 && E_IsInBase(employee, base)) {		/* It has to be in the defined base. */
			assert(E_IsHired(employee));
			break;
		}
	}

	LIST_Delete(&hiredEmployees);

	if (!employee)
		Com_DPrintf(DEBUG_CLIENT, "Could not get unhired ugv/robot.\n");

	return employee;
}
Exemplo n.º 9
0
/**
 * @brief Return a list of hired employees in the given base of a given type
 * @param[in] base Which base the employee should be searched in. If NULL is given employees in all bases will be listed.
 * @param[in] type Which employee type to search for.
 * @param[out] hiredEmployees Linked list of hired employees in the base.
 * @return Number of hired employees in the base that are currently not on a transfer. Or @c -1 in case of an error.
 */
int E_GetHiredEmployees (const base_t* const base, employeeType_t type, linkedList_t **hiredEmployees)
{
	employee_t *employee;

	if (type >= MAX_EMPL) {
		Com_Printf("E_GetHiredEmployees: Unknown EmployeeType: %i\n", type);
		*hiredEmployees = NULL;
		return -1;
	}

	LIST_Delete(hiredEmployees);

	E_Foreach(type, employee) {
		if (!E_IsHired(employee))
			continue;
		if (!employee->transfer && (!base || E_IsInBase(employee, base))) {
			LIST_AddPointer(hiredEmployees, employee);
		}
	}

	if (hiredEmployees == NULL)
		return 0;
	return LIST_Count(*hiredEmployees);
}
Exemplo n.º 10
0
/**
 * @brief Updates the hospital menu.
 * @sa HOS_Init_f
 */
static void HOS_UpdateMenu (void)
{
	char name[128];
	char rank[128];
	int j, type;
	int entry;
	base_t *base = B_GetCurrentSelectedBase();

	if (!base)
		return;

	/* Reset list. */
	cgi->UI_ExecuteConfunc("hospital_clear");

	for (type = 0, j = 0, entry = 0; type < MAX_EMPL; type++) {
		E_Foreach(type, employee) {
			float injuryLevel = HOS_InjuryLevel(&employee->chr);
			if (!E_IsInBase(employee, base))
				continue;
			/* Don't show soldiers who are gone in mission */
			if (E_IsAwayFromBase(employee))
				continue;
			/* Don't show healthy employees */
			if (employee->chr.HP >= employee->chr.maxHP && injuryLevel <= 0)
				continue;

			if (j >= hospitalFirstEntry && entry < HOS_MENU_MAX_ENTRIES) {
				/* Print name. */
				Q_strncpyz(name, employee->chr.name, sizeof(name));
				/* Print rank for soldiers or type for other personel. */
				if (type == EMPL_SOLDIER) {
					const rank_t *rankPtr = CL_GetRankByIdx(employee->chr.score.rank);
					Q_strncpyz(rank, _(rankPtr->name), sizeof(rank));
				} else
					Q_strncpyz(rank, E_GetEmployeeString(employee->type, 1), sizeof(rank));
				Com_DPrintf(DEBUG_CLIENT, "%s ucn: %i entry: %i\n", name, employee->chr.ucn, entry);
				/* If the employee is seriously wounded (HP <= 50% maxHP), make him red. */
				if (employee->chr.HP <= (int) (employee->chr.maxHP * 0.5) || injuryLevel >= 0.5)
					cgi->UI_ExecuteConfunc("hospitalserious %i", entry);
				/* If the employee is semi-seriously wounded (HP <= 85% maxHP), make him yellow. */
				else if (employee->chr.HP <= (int) (employee->chr.maxHP * 0.85) || injuryLevel >= 0.15)
					cgi->UI_ExecuteConfunc("hospitalmedium %i", entry);
				else
					cgi->UI_ExecuteConfunc("hospitallight %i", entry);

				/* Display name in the correct list-entry. */
				cgi->Cvar_Set(va("mn_hos_item%i", entry), name);
				/* Display rank in the correct list-entry. */
				cgi->Cvar_Set(va("mn_hos_rank%i", entry), rank);
				/* Prepare the health bar */
				cgi->Cvar_Set(va("mn_hos_hp%i", entry), va("%i", employee->chr.HP));
				cgi->Cvar_Set(va("mn_hos_hpmax%i", entry), va("%i", employee->chr.maxHP));

				/* Send wound info */
				HOS_EntryWoundData(&employee->chr, entry);

				/* Increase the counter of list entries. */
				entry++;
			}
			j++;
		}
	}
Exemplo n.º 11
0
/**
 * @brief Fill market item list
 */
static void BS_FillMarket_f (void)
{
	const base_t *base = B_GetCurrentSelectedBase();
	itemFilterTypes_t type;

	if (cgi->Cmd_Argc() < 2) {
		Com_Printf("Usage: %s <category>\n", cgi->Cmd_Argv(0));
		return;
	}
	if (cgi->Cmd_Argc() >= 3)
		base = B_GetFoundedBaseByIDX(atoi(cgi->Cmd_Argv(2)));
	if (!base) {
		Com_Printf("No/invalid base selected.\n");
		return;
	}

	type = INV_GetFilterTypeID(cgi->Cmd_Argv(1));
	cgi->UI_ExecuteConfunc("ui_market_clear");
	switch (type) {
	case FILTER_UGVITEM:
		/* show own UGV */
		E_Foreach(EMPL_ROBOT, robot) {
			const ugv_t *ugv = robot->ugv;
			const technology_t* tech = RS_GetTechByProvided(ugv->id);

			if (!E_IsInBase(robot, base))
				continue;

			cgi->UI_ExecuteConfunc("ui_market_add \"ugv-%d\" \"%s\" 1 0 0 %d - \"%s\"", robot->chr.ucn, _(tech->name), ugv->price, E_IsAwayFromBase(robot) ? _("UGV is away from home") : "-");
		}
		/* show buyable UGV */
		for (int i = 0; i < cgi->csi->numUGV; i++) {
			const ugv_t *ugv = &cgi->csi->ugvs[i];
			const technology_t* tech = RS_GetTechByProvided(ugv->id);
			const objDef_t *ugvWeapon = INVSH_GetItemByID(ugv->weapon);
			const int buyable = std::min(E_CountUnhiredRobotsByType(ugv), BS_GetItemOnMarket(ugvWeapon));

			assert(tech);
			if (!RS_IsResearched_ptr(tech))
				continue;
			if (buyable <= 0)
				continue;

			cgi->UI_ExecuteConfunc("ui_market_add %s \"%s\" 0 %d %d %d - -", ugv->id, _(tech->name), buyable, ugv->price, ugv->price);
		}
		/* show (UGV) items */
	case FILTER_S_PRIMARY:
	case FILTER_S_SECONDARY:
	case FILTER_S_HEAVY:
	case FILTER_S_MISC:
	case FILTER_S_ARMOUR:
	case FILTER_DUMMY:
	case FILTER_CRAFTITEM:
	case MAX_FILTERTYPES: {
		for (int i = 0; i < cgi->csi->numODs; i++) {
			const objDef_t *od = &cgi->csi->ods[i];
			const technology_t *tech = RS_GetTechForItem(od);

			if (!BS_IsOnMarket(od))
				continue;
			if (B_ItemInBase(od, base) + BS_GetItemOnMarket(od) <= 0)
				continue;
			if (type != MAX_FILTERTYPES && !INV_ItemMatchesFilter(od, type))
				continue;
			cgi->UI_ExecuteConfunc("ui_market_add %s \"%s\" %d %d %d %d %s -", od->id, _(od->name), B_ItemInBase(od, base), BS_GetItemOnMarket(od), BS_GetItemBuyingPrice(od), BS_GetItemSellingPrice(od), RS_IsResearched_ptr(tech) ? va("%d", ccs.eMarket.autosell[i]) : "-");
		}
		break;
	}
	case FILTER_AIRCRAFT: {
		AIR_ForeachFromBase(aircraft, base) {
			cgi->UI_ExecuteConfunc("ui_market_add \"aircraft-%d\" \"%s\" 1 0 0 %d - \"%s\"", aircraft->idx, aircraft->name, BS_GetAircraftSellingPrice(aircraft), AIR_IsAircraftInBase(aircraft) ? "-" : _("Aircraft is away from home"));
		}
		for (int i = 0; i < ccs.numAircraftTemplates; i++) {
			const aircraft_t *aircraft = &ccs.aircraftTemplates[i];
			if (!BS_AircraftIsOnMarket(aircraft))
				continue;
			if (!RS_IsResearched_ptr(aircraft->tech))
				continue;
			cgi->UI_ExecuteConfunc("ui_market_add \"%s\" \"%s\" 0 %d %d %d - -", aircraft->id, _(aircraft->tech->name), BS_GetAircraftOnMarket(aircraft), BS_GetAircraftBuyingPrice(aircraft), BS_GetAircraftSellingPrice(aircraft));
		}
		break;
	}
	default:
		break;
	}