static inline qboolean BS_GetMinMaxValueByItemID (const base_t *base, int itemNum, int *min, int *max, int *value)
{
	assert(base);

	if (itemNum < 0 || itemNum + buyList.scroll >= buyList.length)
		return qfalse;

	if (buyCat == FILTER_AIRCRAFT && buyList.l[itemNum + buyList.scroll].aircraft) {
		const aircraft_t *aircraft = buyList.l[itemNum + buyList.scroll].aircraft;
		if (!aircraft)
			return qfalse;
		*value = BS_GetStorageAmountInBase(base, aircraft->id);
		*max = BS_GetStorageAmountInBase(base, aircraft->id) + BS_GetAircraftOnMarket(aircraft);
		*min = 0;
	} else {
		const objDef_t *item = BS_GetObjectDefition(&buyList.l[itemNum + buyList.scroll]);
		if (!item)
			return qfalse;
		*value = B_ItemInBase(item, base);
		*max = B_ItemInBase(item, base) + ccs.eMarket.numItems[item->idx];
		*min = 0;
	}

	return qtrue;
}
Пример #2
0
/**
 * @brief Remove items until everything fits in storage.
 * @note items will be randomly selected for removal.
 * @param[in] base Pointer to the base
 */
void CAP_RemoveItemsExceedingCapacity (base_t *base)
{
	int i;
	int objIdx[MAX_OBJDEFS];	/**< Will contain idx of items that can be removed */
	int num, cnt;

	if (CAP_GetFreeCapacity(base, CAP_ITEMS) >= 0)
		return;

	for (i = 0, num = 0; i < cgi->csi->numODs; i++) {
		const objDef_t *obj = INVSH_GetItemByIDX(i);

		if (!B_ItemIsStoredInBaseStorage(obj))
			continue;

		/* Don't count item that we don't have in base */
		if (B_ItemInBase(obj, base) <= 0)
			continue;

		objIdx[num++] = i;
	}

	cnt = E_CountHired(base, EMPL_ROBOT);
	/* UGV takes room in storage capacity: we store them with a value MAX_OBJDEFS that can't be used by objIdx */
	for (i = 0; i < cnt; i++) {
		objIdx[num++] = MAX_OBJDEFS;
	}

	while (num && CAP_GetFreeCapacity(base, CAP_ITEMS) < 0) {
		/* Select the item to remove */
		const int randNumber = rand() % num;
		if (objIdx[randNumber] >= MAX_OBJDEFS) {
			/* A UGV is destroyed: get first one */
			Employee* employee = E_GetHiredRobot(base, 0);
			/* There should be at least a UGV */
			assert(employee);
			E_DeleteEmployee(employee);
		} else {
			/* items are destroyed. We guess that all items of a given type are stored in the same location
			 *	=> destroy all items of this type */
			const int idx = objIdx[randNumber];
			const objDef_t *od = INVSH_GetItemByIDX(idx);
			B_UpdateStorageAndCapacity(base, od, -B_ItemInBase(od, base), false);
		}
		REMOVE_ELEM(objIdx, randNumber, num);

		/* Make sure that we don't have an infinite loop */
		if (num <= 0)
			break;
	}
	Com_DPrintf(DEBUG_CLIENT, "B_RemoveItemsExceedingCapacity: Remains %i in storage for a maximum of %i\n",
		CAP_GetCurrent(base, CAP_ITEMS), CAP_GetMax(base, CAP_ITEMS));
}
Пример #3
0
/**
 * @brief Checks if the production requirements are met for a defined amount.
 * @param[in] amount How many items are planned to be produced.
 * @param[in] reqs The production requirements of the item that is to be produced.
 * @param[in] base Pointer to base.
 * @return how much item/aircraft/etc can be produced
 */
int PR_RequirementsMet (int amount, const requirements_t* reqs, base_t* base)
{
	int producibleAmount = amount;

	for (int i = 0; i < reqs->numLinks; i++) {
		const requirement_t* req = &reqs->links[i];

		switch (req->type) {
		case RS_LINK_ITEM: {
				const int items = std::min(amount, B_ItemInBase(req->link.od, base) / ((req->amount) ? req->amount : 1));
				producibleAmount = std::min(producibleAmount, items);
				break;
			}
		case RS_LINK_ANTIMATTER: {
				const int am = std::min(amount, B_AntimatterInBase(base) / ((req->amount) ? req->amount : 1));
				producibleAmount = std::min(producibleAmount, am);
				break;
			}
		case RS_LINK_TECH:
			producibleAmount = (RS_IsResearched_ptr(req->link.tech)) ? producibleAmount : 0;
			break;
		case RS_LINK_TECH_NOT:
			producibleAmount = (RS_IsResearched_ptr(req->link.tech)) ? 0 : producibleAmount;
			break;
		default:
			break;
		}
	}

	return producibleAmount;
}
Пример #4
0
/**
 * @brief Update Storage Capacity.
 * @param[in] base Pointer to the base
 * @sa B_ResetAllStatusAndCapacities_f
 */
void CAP_UpdateStorageCap (base_t* base)
{
	CAP_SetCurrent(base, CAP_ITEMS, 0);

	for (int i = 0; i < cgi->csi->numODs; i++) {
		const objDef_t* obj = INVSH_GetItemByIDX(i);

		if (!B_ItemIsStoredInBaseStorage(obj))
			continue;

		CAP_AddCurrent(base, CAP_ITEMS, B_ItemInBase(obj, base) * obj->size);
	}

	/* UGV takes room in storage capacity */
	CAP_AddCurrent(base, CAP_ITEMS, UGV_SIZE * E_CountHired(base, EMPL_ROBOT));
}
/**
 * @brief
 * @sa BS_MarketClick_f
 * @sa BS_AddToList
 */
static void BS_MarketScroll_f (void)
{
	int i;
	base_t *base = B_GetCurrentSelectedBase();

	if (!base || buyCat >= MAX_FILTERTYPES || buyCat < 0)
		return;

	if (Cmd_Argc() < 2) {
		Com_Printf("Usage: %s <scrollpos>\n", Cmd_Argv(0));
		return;
	}

	buyList.scroll = atoi(Cmd_Argv(1));
	assert(buyList.scroll >= 0);
	assert(!((buyList.length > MAX_MARKET_MENU_ENTRIES && buyList.scroll >= buyList.length - MAX_MARKET_MENU_ENTRIES)));

	/* now update the menu pics */
	for (i = 0; i < MAX_MARKET_MENU_ENTRIES; i++) {
		UI_ExecuteConfunc("buy_autoselli %i", i);
	}

	/* get item list */
	for (i = buyList.scroll; i < buyList.length - buyList.scroll; i++) {
		const objDef_t *od = BS_GetObjectDefition(&buyList.l[i]);

		if (i >= MAX_MARKET_MENU_ENTRIES)
			break;

		/* Check whether the item matches the proper filter, storage in current base and market. */
		if (od && (B_ItemInBase(od, base) > 0 || ccs.eMarket.numItems[od->idx]) && INV_ItemMatchesFilter(od, buyCat)) {
			const technology_t *tech = RS_GetTechForItem(od);

			UI_ExecuteConfunc("buy_show %i", i - buyList.scroll);
			BS_UpdateItem(base, i - buyList.scroll);

			/* autosell setting */
			if (!RS_IsResearched_ptr(tech))
				continue;
			if (ccs.eMarket.autosell[od->idx])
				UI_ExecuteConfunc("buy_autoselle %i", i - buyList.scroll);
			else
				UI_ExecuteConfunc("buy_autoselld %i", i - buyList.scroll);
		}
	}
}
/**
 * @brief Sell one item of a given type.
 * @sa BS_BuyItem_f
 * @sa BS_SellAircraft_f
 * @sa BS_BuyAircraft_f
 */
static void BS_SellItem_f (void)
{
	int num;
	base_t *base = B_GetCurrentSelectedBase();

	if (Cmd_Argc() < 2) {
		Com_Printf("Usage: %s <num>\n", Cmd_Argv(0));
		return;
	}

	if (!base)
		return;

	if (buyCat == FILTER_AIRCRAFT) {
		Com_DPrintf(DEBUG_CLIENT, "BS_SellItem_f: Redirects to BS_SellAircraft_f\n");
		BS_SellAircraft_f();
		return;
	}

	num = atoi(Cmd_Argv(1));
	if (num < 0 || num >= buyList.length)
		return;

	UI_ExecuteConfunc("buy_selectitem %i", num + buyList.scroll);
	{
		const objDef_t *item = BS_GetObjectDefition(&buyList.l[num + buyList.scroll]);
		/* don't sell more items than we have */
		const int numItems = min(B_ItemInBase(item, base), BS_GetBuySellFactor());
		/* Normal item (or equipment for UGVs/Robots if buyCategory==BUY_HEAVY) */
		assert(item);
		currentSelectedMenuEntry = item;
		INV_ItemDescription(item);

		/* don't sell more items than we have */
		if (numItems) {
			/* reinit the menu */
			B_UpdateStorageAndCapacity(base, item, -numItems, qfalse);
			BS_AddItemToMarket(item, numItems);
			BS_BuyType(base);
			CP_UpdateCredits(ccs.credits + BS_GetItemSellingPrice(item) * numItems);
			BS_UpdateItem(base, num);
		}
	}
}
Пример #7
0
/**
 * @brief Sells items from the market
 * @param[in] od pointer to the item (Object Definition record)
 * @param[out] base Base to sell at
 * @param[in ] count Number of items to sell
 * @return @c true if the ugv could get sold, @c false otherwise
 */
bool BS_SellItem (const objDef_t* od, base_t* base, int count)
{
	if (!od)
		cgi->Com_Error(ERR_DROP, "BS_SellItem: Called on nullptr objDef!");

	if (count <= 0)
		return false;
	if (!BS_IsOnMarket(od))
		return false;

	if (base) {
		if (B_ItemInBase(od, base) < count)
			return false;
		B_AddToStorage(base, od, -count);
	}

	BS_AddItemToMarket(od, count);
	CP_UpdateCredits(ccs.credits + BS_GetItemSellingPrice(od) * count);

	return true;
}
/**
 * @brief Update the list of item you can choose
 * @param[in] slot Pointer to aircraftSlot where items can be equiped
 */
static void AIM_UpdateAircraftItemList (const aircraftSlot_t *slot)
{
	linkedList_t *amountList = NULL;
	technology_t **techList;
	technology_t **currentTech;
	const base_t *base = slot->aircraft->homebase;
	int count = 0;
	uiNode_t *AIM_items = NULL;

	/* Add all items corresponding to airequipID to list */
	techList = AII_GetCraftitemTechsByType(airequipID);

	/* Count only those which are researched to buffer */
	currentTech = techList;
	while (*currentTech) {
		if (AIM_CrafttypeFilter(base, airequipID, *currentTech))
			count++;
		currentTech++;
	}

	/* List only those which are researched to buffer */
	currentTech = techList;
	while (*currentTech) {
		if (AIM_CrafttypeFilter(base, airequipID, *currentTech)) {
			uiNode_t *option;
			const objDef_t *item = INVSH_GetItemByID((*currentTech)->provides);
			const int amount = B_ItemInBase(item, base);

			LIST_AddString(&amountList, va("%d", amount));
			option = cgi->UI_AddOption(&AIM_items, (*currentTech)->name, _((*currentTech)->name), va("%d", (*currentTech)->idx));
			if (!AIM_SelectableCraftItem(slot, *currentTech))
				option->disabled = true;
		}
		currentTech++;
	}

	cgi->UI_RegisterOption(TEXT_LIST, AIM_items);
	cgi->UI_RegisterLinkedListText(TEXT_LIST2, amountList);
}
Пример #9
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) {
		cgi->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) {
		cgi->Com_Printf("No/invalid base selected.\n");
		return;
	}

	type = cgi->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->getUGV();
			const technology_t* tech = RS_GetTechByProvided(ugv->id);

			if (!robot->isHiredInBase(base))
				continue;

			cgi->UI_ExecuteConfunc("ui_market_add \"ugv-%d\" \"%s\" 1 0 0 %d - \"%s\"", robot->chr.ucn, _(tech->name), ugv->price, robot->isAwayFromBase() ? _("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, fall through */
	case FILTER_S_PRIMARY:
	case FILTER_S_SECONDARY:
	case FILTER_S_HEAVY:
	case FILTER_S_IMPLANT:
	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 && !cgi->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;
			if (BS_GetAircraftOnMarket(aircraft) <= 0)
				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;
	}
Пример #10
0
/**
 * @brief Buy/Sell item/aircraft/ugv on the market
 */
static void BS_Buy_f (void)
{
	const char* itemid;
	int count;
	base_t* base = B_GetCurrentSelectedBase();
	const aircraft_t* aircraft;
	const ugv_t* ugv;
	const objDef_t* od;

	if (cgi->Cmd_Argc() < 2) {
		cgi->Com_Printf("Usage: %s <item-id> <count> [base-idx] \nNegative count means selling. If base index is omitted buys on the currently selected base.\n",
				cgi->Cmd_Argv(0));
		return;
	}

	itemid = cgi->Cmd_Argv(1);
	count = atoi(cgi->Cmd_Argv(2));

	if (cgi->Cmd_Argc() >= 4)
		base = B_GetFoundedBaseByIDX(atoi(cgi->Cmd_Argv(3)));

	if (char const* const rest = Q_strstart(itemid, "aircraft_")) {
		/* aircraft sell - with aircraft golbal idx */
		int idx = atoi(rest);
		aircraft_t* aircraft = AIR_AircraftGetFromIDX(idx);

		if (!aircraft) {
			cgi->Com_Printf("Invalid aircraft index!\n");
			return;
		}
		AIR_RemoveEmployees(*aircraft);
		BS_SellAircraft(aircraft);
		return;
	}

	if (char const* const rest = Q_strstart(itemid, "ugv-")) {
		/* ugv sell - with unique character number index */
		int ucn = atoi(rest);
		Employee* robot = E_GetEmployeeByTypeFromChrUCN(EMPL_ROBOT, ucn);

		if (!robot) {
			cgi->Com_Printf("Invalid UCN for UGV!\n");
			return;
		}

		BS_SellUGV(robot);
		return;
	}

	if (!base) {
		cgi->Com_Printf("No/invalid base selected.\n");
		return;
	}

	aircraft = AIR_GetAircraftSilent(itemid);
	if (aircraft) {
		if (!B_GetBuildingStatus(base, B_COMMAND)) {
			CP_Popup(_("Note"), _("No Command Centre in this base.\nHangars are not functional.\n"));
			return;
		}
		/* We cannot buy aircraft if there is no power in our base. */
		if (!B_GetBuildingStatus(base, B_POWER)) {
			CP_Popup(_("Note"), _("No power supplies in this base.\nHangars are not functional."));
			return;
		}
		/* We cannot buy aircraft without any hangar. */
		if (!AIR_AircraftAllowed(base)) {
			CP_Popup(_("Note"), _("Build a hangar first."));
			return;
		}
		/* Check free space in hangars. */
		if (CAP_GetFreeCapacity(base, AIR_GetHangarCapacityType(aircraft)) <= 0) {
			CP_Popup(_("Notice"), _("You cannot buy this aircraft.\nNot enough space in hangars.\n"));
			return;
		}

		if (ccs.credits < BS_GetAircraftBuyingPrice(aircraft)) {
			CP_Popup(_("Notice"), _("You cannot buy this aircraft.\nNot enough credits.\n"));
			return;
		}

		BS_BuyAircraft(aircraft, base);
		return;
	}

	ugv = cgi->Com_GetUGVByIDSilent(itemid);
	if (ugv) {
		const objDef_t* ugvWeapon = INVSH_GetItemByID(ugv->weapon);
		if (!ugvWeapon)
			cgi->Com_Error(ERR_DROP, "BS_BuyItem_f: Could not get weapon '%s' for ugv/tank '%s'.", ugv->weapon, ugv->id);

		if (E_CountUnhiredRobotsByType(ugv) < 1)
			return;
		if (ccs.eMarket.numItems[ugvWeapon->idx] < 1)
			return;

		if (ccs.credits < ugv->price) {
			CP_Popup(_("Not enough money"), _("You cannot buy this item as you don't have enough credits."));
			return;
		}

		if (CAP_GetFreeCapacity(base, CAP_ITEMS) < UGV_SIZE + ugvWeapon->size) {
			CP_Popup(_("Not enough storage space"), _("You cannot buy this item.\nNot enough space in storage.\nBuild more storage facilities."));
			return;
		}

		BS_BuyUGV(ugv, base);
		return;
	}

	if (count == 0) {
		cgi->Com_Printf("Invalid number of items to buy/sell: %s\n", cgi->Cmd_Argv(2));
		return;
	}

	/* item */
	od = INVSH_GetItemByID(cgi->Cmd_Argv(1));
	if (od) {
		if (!BS_IsOnMarket(od))
			return;

		if (count > 0) {
			/* buy */
			const int price = BS_GetItemBuyingPrice(od);
			count = std::min(count, BS_GetItemOnMarket(od));

			/* no items available on market */
			if (count <= 0)
				return;

			if (price <= 0) {
				cgi->Com_Printf("Item on market with invalid buying price: %s (%d)\n", od->id, BS_GetItemBuyingPrice(od));
				return;
			}
			/** @todo warn if player can buy less item due to available credits? */
			count = std::min(count, ccs.credits / price);
			/* not enough money for a single item */
			if (count <= 0) {
				CP_Popup(_("Not enough money"), _("You cannot buy this item as you don't have enough credits."));
				return;
			}

			if (od->size <= 0) {
				cgi->Com_Printf("Item on market with invalid size: %s (%d)\n", od->id, od->size);
				return;
			}
			count = std::min(count, CAP_GetFreeCapacity(base, CAP_ITEMS) / od->size);
			if (count <= 0) {
				CP_Popup(_("Not enough storage space"), _("You cannot buy this item.\nNot enough space in storage.\nBuild more storage facilities."));
				return;
			}

			BS_BuyItem(od, base, count);
		} else {
			/* sell */
			count = std::min(-1 * count, B_ItemInBase(od, base));
			/* no items in storage */
			if (count <= 0)
				return;
			BS_SellItem(od, base, count);
		}
		return;
	}
	cgi->Com_Printf("Invalid item ID\n");
}
/**
 * @brief Updates the Buy/Sell menu list.
 * @param[in] base Pointer to the base to buy/sell at
 * @sa BS_BuyType_f
 */
static void BS_BuyType (const base_t *base)
{
	const objDef_t *od;
	int i, j = 0;
	char tmpbuf[MAX_VAR];

	if (!base || buyCat >= MAX_FILTERTYPES || buyCat < 0)
		return;

	CP_UpdateCredits(ccs.credits);

	bsMarketNames = NULL;
	bsMarketStorage = NULL;
	bsMarketMarket = NULL;
	bsMarketPrices = NULL;
	UI_ResetData(TEXT_ITEMDESCRIPTION);

	/* hide autosell checkboxes by default */
	for (i = 0; i < MAX_MARKET_MENU_ENTRIES; i++) {
		UI_ExecuteConfunc("buy_autoselli %i", i);
	}

	switch (buyCat) {
	case FILTER_AIRCRAFT:	/* Aircraft */
		{
		const aircraft_t *aircraftTemplate;
		for (i = 0, j = 0, aircraftTemplate = ccs.aircraftTemplates; i < ccs.numAircraftTemplates; i++, aircraftTemplate++) {
			if (!BS_AircraftIsOnMarket(aircraftTemplate))
				continue;
			assert(aircraftTemplate->tech);
			if (BS_GetStorageAmountInBase(base, aircraftTemplate->id) + BS_GetAircraftOnMarket(aircraftTemplate) > 0) {
				if (j >= buyList.scroll && j < MAX_MARKET_MENU_ENTRIES) {
					UI_ExecuteConfunc("buy_show %i", j - buyList.scroll);
				}
				BS_AddToList(aircraftTemplate->name, BS_GetStorageAmountInBase(base, aircraftTemplate->id),
						BS_GetAircraftOnMarket(aircraftTemplate), BS_GetAircraftBuyingPrice(aircraftTemplate));
				if (j >= MAX_BUYLIST)
					Com_Error(ERR_DROP, "Increase the MAX_BUYLIST value to handle that much items\n");
				buyList.l[j].item = NULL;
				buyList.l[j].aircraft = aircraftTemplate;
				buyList.length = j + 1;
				BS_UpdateItem(base, j - buyList.scroll);
				j++;
			}
		}
		}
		break;
	case FILTER_CRAFTITEM:	/* Aircraft items */
		/* get item list */
		for (i = 0, j = 0, od = csi.ods; i < csi.numODs; i++, od++) {
			if (!BS_IsOnMarket(od))
				continue;
			/* Check whether the item matches the proper filter, storage in current base and market. */
			if ((B_ItemInBase(od, base) || ccs.eMarket.numItems[i])
			 && INV_ItemMatchesFilter(od, FILTER_CRAFTITEM)) {
				if (j >= buyList.scroll && j < MAX_MARKET_MENU_ENTRIES) {
					const technology_t *tech = RS_GetTechForItem(od);

					UI_ExecuteConfunc("buy_show %i", j - buyList.scroll);
					if (RS_IsResearched_ptr(tech)) {
						if (ccs.eMarket.autosell[i])
							UI_ExecuteConfunc("buy_autoselle %i", j - buyList.scroll);
						else
							UI_ExecuteConfunc("buy_autoselld %i", j - buyList.scroll);
					}
				}
				BS_AddToList(od->name, B_ItemInBase(od, base), ccs.eMarket.numItems[i], BS_GetItemBuyingPrice(od));
				if (j >= MAX_BUYLIST)
					Com_Error(ERR_DROP, "Increase the MAX_FILTERLIST value to handle that much items\n");
				buyList.l[j].item = od;
				buyList.l[j].aircraft = NULL;
				buyList.length = j + 1;
				BS_UpdateItem(base, j - buyList.scroll);
				j++;
			}
		}
		break;
	default:	/* Normal items */
		if (buyCat < MAX_SOLDIER_FILTERTYPES || buyCat == FILTER_DUMMY) {
			/* get item list */
			for (i = 0, j = 0, od = csi.ods; i < csi.numODs; i++, od++) {
				if (!BS_IsOnMarket(od))
					continue;
				/* Check whether the item matches the proper filter, storage in current base and market. */
				if ((B_ItemInBase(od, base) || ccs.eMarket.numItems[i]) && INV_ItemMatchesFilter(od, buyCat)) {
					BS_AddToList(od->name, B_ItemInBase(od, base), ccs.eMarket.numItems[i], BS_GetItemBuyingPrice(od));
					/* Set state of Autosell button. */
					if (j >= buyList.scroll && j < MAX_MARKET_MENU_ENTRIES) {
						const technology_t *tech = RS_GetTechForItem(od);

						UI_ExecuteConfunc("buy_show %i", j - buyList.scroll);
						if (RS_IsResearched_ptr(tech)) {
							if (ccs.eMarket.autosell[i])
								UI_ExecuteConfunc("buy_autoselle %i", j - buyList.scroll);
							else
								UI_ExecuteConfunc("buy_autoselld %i", j - buyList.scroll);
						}
					}

					if (j >= MAX_BUYLIST)
						Com_Error(ERR_DROP, "Increase the MAX_BUYLIST value to handle that much items\n");
					buyList.l[j].item = od;
					buyList.l[j].aircraft = NULL;
					buyList.length = j + 1;
					BS_UpdateItem(base, j - buyList.scroll);
					j++;
				}
			}
		}
		break;
	}

	for (; j < MAX_MARKET_MENU_ENTRIES; j++) {
		/* Hide the rest of the entries. */
		UI_ExecuteConfunc("buy_hide %i", j);
	}

	/* Update some menu cvars. */
	/* Set up base capacities. */
	Com_sprintf(tmpbuf, sizeof(tmpbuf), "%i/%i", CAP_GetCurrent(base, CAP_ITEMS),
		CAP_GetMax(base, CAP_ITEMS));
	Cvar_Set("mn_bs_storage", tmpbuf);

	/* select first item */
	if (buyList.length) {
		switch (buyCat) {	/** @sa BS_MarketClick_f */
		case FILTER_AIRCRAFT:
			BS_MarketAircraftDescription(buyList.l[0].aircraft);
			break;
		case FILTER_CRAFTITEM:
			Cvar_Set("mn_aircraftname", "");	/** @todo Use craftitem name here? See also BS_MarketClick_f */
			/* Select current item or first one. */
			if (currentSelectedMenuEntry)
				UP_AircraftItemDescription(currentSelectedMenuEntry);
			else
				UP_AircraftItemDescription(buyList.l[0].item);
			break;
		default:
			assert(buyCat != MAX_FILTERTYPES);
			/* Select current item or first one. */
			if (currentSelectedMenuEntry)
				INV_ItemDescription(currentSelectedMenuEntry);
			else
				INV_ItemDescription(buyList.l[0].item);
			break;
		}
	} else {
		/* reset description */
		INV_ItemDescription(NULL);
	}

	UI_RegisterLinkedListText(TEXT_MARKET_NAMES, bsMarketNames);
	UI_RegisterLinkedListText(TEXT_MARKET_STORAGE, bsMarketStorage);
	UI_RegisterLinkedListText(TEXT_MARKET_MARKET, bsMarketMarket);
	UI_RegisterLinkedListText(TEXT_MARKET_PRICES, bsMarketPrices);
}