/**
 * @brief Update the GUI with the selected item
 */
static void INV_UpdateObject_f (void)
{
    /* check syntax */
    if (Cmd_Argc() < 3) {
        Com_Printf("Usage: %s <objectid> <confunc> [mustwechangetab]\n", Cmd_Argv(0));
        return;
    }

    bool changeTab = true;
    if (Cmd_Argc() == 4)
        changeTab = atoi(Cmd_Argv(3)) >= 1;

    const int num = atoi(Cmd_Argv(1));
    if (num < 0 || num >= csi.numODs) {
        Com_Printf("Id %i out of range 0..%i\n", num, csi.numODs);
        return;
    }
    const objDef_t* obj = INVSH_GetItemByIDX(num);

    /* update tab */
    if (changeTab) {
        const cvar_t* var = Cvar_FindVar("mn_equiptype");
        const int filter = INV_GetFilterFromItem(obj);
        if (var && var->integer != filter) {
            Cvar_SetValue("mn_equiptype", filter);
            UI_ExecuteConfunc("%s", Cmd_Argv(2));
        }
    }

    /* update item description */
    INV_ItemDescription(obj);
}
/**
 * @brief Decreases the number of the firemode to display (for ammo) or the ammo to display (for weapon)
 * @sa UP_ItemDescription
 */
static void INV_DecreaseItem_f (void)
{
    const objDef_t* od = currentDisplayedObject;

    if (!od)
        return;

    if (od->numWeapons) {
        const int current = itemIndex;
        do {
            itemIndex--;
            if (itemIndex < 0) {
                itemIndex = od->numWeapons - 1;
            }
        } while (itemIndex != current && !GAME_ItemIsUseable(od->weapons[itemIndex]));
    } else if (od->numAmmos) {
        const int current = itemIndex;
        do {
            itemIndex--;
            if (itemIndex < 0) {
                itemIndex = od->numAmmos - 1;
            }
        } while (itemIndex != current && !GAME_ItemIsUseable(od->ammos[itemIndex]));
    }
    INV_ItemDescription(od);
}
/**
 * @brief Decreases the number of the firemode to display
 * @sa UP_ItemDescription
 */
static void INV_DecreaseFiremode_f (void)
{
    if (!currentDisplayedObject)
        return;

    fireModeIndex--;

    INV_ItemDescription(currentDisplayedObject);
}
/**
 * @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);
		}
	}
}
/**
 * @brief Buy one item of a given type.
 * @sa BS_SellItem_f
 * @sa BS_SellAircraft_f
 * @sa BS_BuyAircraft_f
 */
static void BS_BuyItem_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_BuyItem_f: Redirects to BS_BuyAircraft_f\n");
		BS_BuyAircraft_f();
		return;
	}

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

	UI_ExecuteConfunc("buy_selectitem %i", num + buyList.scroll);

	{
		/* Normal item (or equipment for UGVs/Robots if buyCategory==BUY_HEAVY) */
		const objDef_t *item = BS_GetObjectDefition(&buyList.l[num + buyList.scroll]);
		assert(item);
		currentSelectedMenuEntry = item;
		INV_ItemDescription(item);
		Com_DPrintf(DEBUG_CLIENT, "BS_BuyItem_f: item %s\n", item->id);
		BS_CheckAndDoBuyItem(base, item, BS_GetBuySellFactor());
		/* reinit the menu */
		BS_BuyType(base);
		BS_UpdateItem(base, num);
	}
}
/**
 * @brief Select one entry on the list.
 * @sa BS_MarketScroll_f
 * @sa BS_AddToList
 */
static void BS_MarketClick_f (void)
{
	int num;

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

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

	Cvar_Set("mn_item", "");

	switch (buyCat) {
	case FILTER_AIRCRAFT:
		assert(buyList.l[num].aircraft);
		BS_MarketAircraftDescription(buyList.l[num].aircraft->tpl);
		break;
	case FILTER_CRAFTITEM:
		UP_AircraftItemDescription(buyList.l[num].item);
		Cvar_Set("mn_aircraftname", "");
		break;
	case MAX_FILTERTYPES:
		break;
	default:
		if (buyList.l[num].item->craftitem.type != MAX_ACITEMS)
			UP_AircraftItemDescription(buyList.l[num].item);
		else
			INV_ItemDescription(buyList.l[num].item);
		currentSelectedMenuEntry = buyList.l[num].item;
		break;
	}

	/* update selected element */
	UI_ExecuteConfunc("buy_selectitem %i", num);
}
/**
 * @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);
}
Пример #8
0
/**
 * @brief Show informations about item/aircaft/ugv in the market
 */
static void BS_ShowInfo_f (void)
{
	const char *itemid;
	const aircraft_t *aircraft;
	const ugv_t *ugv;
	const objDef_t *od;

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

	itemid = cgi->Cmd_Argv(1);

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

		if (!aircraft) {
			Com_Printf("Invalid aircraft index!\n");
			return;
		}
		/** @todo show specialized info about PHALANX aircraft */
		BS_MarketAircraftDescription(aircraft->tpl);
		return;
	}

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

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

		/** @todo show specialized info about PHLANX UGVs */
		UP_UGVDescription(robot->ugv);
		return;
	}

	aircraft = AIR_GetAircraftSilent(itemid);
	if (aircraft) {
		BS_MarketAircraftDescription(aircraft->tpl);
		return;
	}

	ugv = cgi->Com_GetUGVByIDSilent(itemid);
	if (ugv) {
		UP_UGVDescription(ugv);
		return;
	}

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

		if (od->craftitem.type != MAX_ACITEMS)
			UP_AircraftItemDescription(od);
		else
			INV_ItemDescription(od);
		return;
	}
	Com_Printf("Invalid item ID\n");
}