Ejemplo n.º 1
0
/**
 * @brief Show item description in bdef menu
 * @note it handles items in both slots and storage
 */
static void BDEF_SelectItem_f (void)
{
	aircraftSlot_t* slot;
	installation_t* installation = INS_GetCurrentSelectedInstallation();
	base_t* base = B_GetCurrentSelectedBase();
	aircraftItemType_t bdefType;
	int slotIDX;
	int itemIDX;

	if (cgi->Cmd_Argc() < 4) {
		Com_Printf("Usage: %s <type> <slotIDX> <itemIDX>\n", cgi->Cmd_Argv(0));
		return;
	}

	bdefType = BDEF_GetItemTypeFromID(cgi->Cmd_Argv(1));
	slotIDX = atoi(cgi->Cmd_Argv(2));
	itemIDX = atoi(cgi->Cmd_Argv(3));

	if (bdefType == MAX_ACITEMS) {
		Com_Printf("BDEF_AddItem_f: Invalid defence type.\n");
		return;
	}

	if (slotIDX >= 0) {
		const objDef_t* item;
		slot = (installation) ? BDEF_GetInstallationSlotByIDX(installation, bdefType, slotIDX) : BDEF_GetBaseSlotByIDX(base, bdefType, slotIDX);
		item = (slot) ? ( (slot->nextItem) ? slot->nextItem : slot->item ) : nullptr;
		UP_AircraftItemDescription(item);
	} else if (itemIDX >= 0) {
		technology_t** list;
		technology_t* itemTech = nullptr;
		int i = 0;

		slot = (installation) ? BDEF_GetInstallationSlotByIDX(installation, bdefType, 0) : BDEF_GetBaseSlotByIDX(base, bdefType, 0);
		list = AII_GetCraftitemTechsByType(bdefType);
		while (*list && i <= itemIDX) {
			if (AIM_SelectableCraftItem(slot, *list)) {
				itemTech = *list;
				i++;
				break;
			}
			list++;
		}
		UP_AircraftItemDescription((itemTech) ? INVSH_GetItemByIDSilent(itemTech->provides) : nullptr);
	} else {
		Com_Printf("BDEF_AddItem_f: Invalid item-space.\n");
	}
}
/**
 * @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 Update the item description according to the tech and the slot selected
 */
static void AIM_UpdateItemDescription (bool fromList, bool fromSlot)
{
	int status;
	aircraft_t *aircraft;
	aircraftSlot_t *slot;
	base_t *base = B_GetCurrentSelectedBase();
	assert(base);

	aircraft = base->aircraftCurrent;
	assert(aircraft);
	slot = AII_SelectAircraftSlot(aircraft, airequipID);

	/* update mini ufopedia */
	/** @todo we should clone the text, and not using the ufopedia text */
	if (fromList)
		UP_AircraftItemDescription(INVSH_GetItemByIDSilent(aimSelectedTechnology ? aimSelectedTechnology->provides : NULL));
	else if (fromSlot) {
		if (airequipID == AC_ITEM_AMMO)
			UP_AircraftItemDescription(slot->ammo);
		else
			UP_AircraftItemDescription(slot->item);
	}

	/* update status */
	status = AIM_CheckTechnologyIntoSlot(slot, aimSelectedTechnology);
	switch (status) {
	case AIM_LOADING_NOSLOTSELECTED:
		Cvar_Set("mn_aircraft_item_warning", _("No slot selected."));
		break;
	case AIM_LOADING_NOTECHNOLOGYSELECTED:
		Cvar_Set("mn_aircraft_item_warning", _("No item selected."));
		break;
	case AIM_LOADING_ALIENTECH:
		Cvar_Set("mn_aircraft_item_warning", _("You can't equip an alien technology."));
		break;
	case AIM_LOADING_TECHNOLOGYNOTRESEARCHED:
		Cvar_Set("mn_aircraft_item_warning", _("Technology requested is not yet completed."));
		break;
	case AIM_LOADING_TOOHEAVY:
		Cvar_Set("mn_aircraft_item_warning", _("This item is too heavy for the selected slot."));
		break;
	case AIM_LOADING_NOWEAPON:
		Cvar_Set("mn_aircraft_item_warning", _("Equip a weapon first."));
		break;
	case AIM_LOADING_NOTUSABLEWITHWEAPON:
		Cvar_Set("mn_aircraft_item_warning", _("Ammo not usable with current weapon."));
		break;
	case AIM_LOADING_UNKNOWNPROBLEM:
		Cvar_Set("mn_aircraft_item_warning", _("Unknown problem."));
		break;
	case AIM_LOADING_OK:
		Cvar_Set("mn_aircraft_item_warning", _("Ok"));
		break;
	}

	if (*Cvar_GetString("mn_item") == '\0') {
		cgi->UI_ExecuteConfunc("airequip_no_item");
	} else {
		if (fromSlot) {
			cgi->UI_ExecuteConfunc("airequip_installed_item");
		} else {
			if (status == AIM_LOADING_OK)
				cgi->UI_ExecuteConfunc("airequip_installable_item");
			else
				cgi->UI_ExecuteConfunc("airequip_noinstallable_item");
		}
	}
}
Ejemplo n.º 4
0
/**
 * @brief Show information 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) {
		cgi->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) {
			cgi->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* robot = E_GetEmployeeByTypeFromChrUCN(EMPL_ROBOT, ucn);

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

		/** @todo show specialized info about PHLANX UGVs */
		UP_UGVDescription(robot->getUGV());
		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
			cgi->INV_ItemDescription(od);
		return;
	}
	cgi->Com_Printf("Invalid item ID\n");
}
Ejemplo n.º 5
0
/**
 * @brief Display only the TEXT_UFOPEDIA part for a given technology
 * @param[in] tech The technology_t pointer to print the UFOpaedia article for
 * @param[in] mail The mail parameters in case we produce a mail
 * @sa UP_Article
 */
static void UP_Article (technology_t* tech, eventMail_t* mail)
{
	UP_ChangeDisplay(UFOPEDIA_ARTICLE);

	if (tech) {
		if (tech->mdl)
			cgi->Cvar_Set("mn_upmodel_top", "%s", tech->mdl);
		else
			cgi->Cvar_Set("mn_upmodel_top", "");

		if (tech->image)
			cgi->Cvar_Set("mn_upimage_top", "%s", tech->image);
		else
			cgi->Cvar_Set("mn_upimage_top", "");

		cgi->Cvar_Set("mn_upmodel_bottom", "");

		if (tech->type == RS_WEAPON)
			UP_DrawAssociatedAmmo(tech);
		cgi->Cvar_Set("mn_uprequirement", "");
		cgi->Cvar_Set("mn_upmetadata", "");
	}

	cgi->UI_ResetData(TEXT_UFOPEDIA);
	cgi->UI_ResetData(TEXT_UFOPEDIA_REQUIREMENT);

	if (mail) {
		/* event mail */
		cgi->Cvar_SetValue("mn_uppreavailable", 0);
		cgi->Cvar_SetValue("mn_updisplay", UFOPEDIA_CHAPTERS);
		UP_SetMailHeader(nullptr, TECHMAIL_PRE, mail);
		cgi->UI_RegisterText(TEXT_UFOPEDIA, _(mail->body));
		/* This allows us to use the index button in the UFOpaedia,
		 * eventMails don't have any chapter to go back to. */
		upDisplay = UFOPEDIA_INDEX;
	} else if (tech) {
		currentChapter = tech->upChapter;
		upCurrentTech = tech;

		/* Reset itemdescription */
		cgi->UI_ExecuteConfunc("itemdesc_view 0 0;");
		if (RS_IsResearched_ptr(tech)) {
			cgi->Cvar_Set("mn_uptitle", _("UFOpaedia: %s (complete)"), _(tech->name));
			/* If researched -> display research text */
			cgi->UI_RegisterText(TEXT_UFOPEDIA, _(RS_GetDescription(&tech->description)));
			if (tech->preDescription.numDescriptions > 0) {
				/* Display pre-research text and the buttons if a pre-research text is available. */
				if (mn_uppretext->integer) {
					cgi->UI_RegisterText(TEXT_UFOPEDIA, _(RS_GetDescription(&tech->preDescription)));
					UP_SetMailHeader(tech, TECHMAIL_PRE, nullptr);
				} else {
					UP_SetMailHeader(tech, TECHMAIL_RESEARCHED, nullptr);
				}
				cgi->Cvar_SetValue("mn_uppreavailable", 1);
			} else {
				/* Do not display the pre-research-text button if none is available (no need to even bother clicking there). */
				cgi->Cvar_SetValue("mn_uppreavailable", 0);
				cgi->Cvar_SetValue("mn_updisplay", UFOPEDIA_CHAPTERS);
				UP_SetMailHeader(tech, TECHMAIL_RESEARCHED, nullptr);
			}

			switch (tech->type) {
			case RS_ARMOUR:
			case RS_WEAPON:
				for (int i = 0; i < cgi->csi->numODs; i++) {
					const objDef_t* od = INVSH_GetItemByIDX(i);
					if (Q_streq(tech->provides, od->id)) {
						cgi->INV_ItemDescription(od);
						UP_DisplayTechTree(tech);
						cgi->Cvar_Set("mn_upmetadata", "1");
						break;
					}
				}
				break;
			case RS_TECH:
				UP_DisplayTechTree(tech);
				break;
			case RS_CRAFT:
				UP_AircraftDescription(tech);
				break;
			case RS_CRAFTITEM:
				UP_AircraftItemDescription(INVSH_GetItemByID(tech->provides));
				break;
			case RS_BUILDING:
				UP_BuildingDescription(tech);
				break;
			case RS_UGV:
				UP_UGVDescription(cgi->Com_GetUGVByIDSilent(tech->provides));
				break;
			default:
				break;
			}
		/* see also UP_TechGetsDisplayed */
		} else if (RS_Collected_(tech) || (tech->statusResearchable && tech->preDescription.numDescriptions > 0)) {
			/* This tech has something collected or has a research proposal. (i.e. pre-research text) */
			cgi->Cvar_Set("mn_uptitle", _("UFOpaedia: %s"), _(tech->name));
			/* Not researched but some items collected -> display pre-research text if available. */
			if (tech->preDescription.numDescriptions > 0) {
				cgi->UI_RegisterText(TEXT_UFOPEDIA, _(RS_GetDescription(&tech->preDescription)));
				UP_SetMailHeader(tech, TECHMAIL_PRE, nullptr);
			} else {
				cgi->UI_RegisterText(TEXT_UFOPEDIA, _("No pre-research description available."));
			}
		} else {
			cgi->Cvar_Set("mn_uptitle", _("UFOpaedia: %s"), _(tech->name));
			cgi->UI_ResetData(TEXT_UFOPEDIA);
		}
	} else {
		cgi->Com_Error(ERR_DROP, "UP_Article: No mail or tech given");
	}
}
/**
 * @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);
}