Esempio n. 1
0
/**
 * @brief Display the popup_homebase
 * @param[in] aircraft Pointer to aircraft we want to change homebase.
 * @param[in] alwaysDisplay False if popup should be displayed only if at least one base is available.
 * @return true if popup is displayed.
 */
qboolean CL_DisplayHomebasePopup (aircraft_t *aircraft, qboolean alwaysDisplay)
{
	int homebase;
	int numAvailableBases = 0;
	baseCapacities_t capacity;
	linkedList_t* popupListText = NULL;
	base_t *base;

	assert(aircraft);

	capacity = AIR_GetCapacityByAircraftWeight(aircraft);

	LIST_Delete(&popupListData);

	popupNum = 0;
	homebase = -1;

	base = NULL;
	while ((base = B_GetNext(base)) != NULL) {
		char text[MAX_VAR];
		char const* msg;

		if (base == aircraft->homebase) {
			msg = _("current homebase of aircraft");
			LIST_Add(&popupListData, (byte *)&INVALID_BASE, sizeof(int));
			homebase = popupNum;
		} else {
			msg = AIR_CheckMoveIntoNewHomebase(aircraft, base, capacity);
			if (!msg) {
				msg = _("base can hold aircraft");
				LIST_Add(&popupListData, (byte *)&base->idx, sizeof(int));
				numAvailableBases++;
			} else {
				LIST_Add(&popupListData, (byte *)&INVALID_BASE, sizeof(int));
			}
		}

		Com_sprintf(text, sizeof(text), "%s\t%s", base->name, msg);
		LIST_AddString(&popupListText, text);
		popupNum++;
	}

	if (alwaysDisplay || numAvailableBases > 0) {
		CL_GameTimeStop();
		popupListNode = UI_PopupList(_("Change homebase of aircraft"), _("Base\tStatus"), popupListText, "change_homebase <lineselected>;");
		VectorSet(popupListNode->selectedColor, 0.0, 0.78, 0.0);	/**< Set color for selected entry. */
		popupListNode->selectedColor[3] = 1.0;
		UI_TextNodeSelectLine(popupListNode, homebase);
		MAP_SelectAircraft(aircraft);
		return qtrue;
	}

	return qfalse;
}
Esempio n. 2
0
/**
 * @brief Prints the UFOpaedia description for aircraft
 * @note Also checks whether the aircraft tech is already researched or collected
 * @sa BS_MarketAircraftDescription
 * @sa UP_Article
 */
void UP_AircraftDescription (const technology_t* tech)
{
	cgi->INV_ItemDescription(nullptr);

	/* ensure that the buffer is emptied in every case */
	upBuffer[0] = '\0';

	if (RS_IsResearched_ptr(tech)) {
		const aircraft_t* aircraft = AIR_GetAircraft(tech->provides);
		for (int i = 0; i < AIR_STATS_MAX; i++) {
			switch (i) {
			case AIR_STATS_SPEED:
				/* speed may be converted to km/h : multiply by pi / 180 * earth_radius */
				Q_strcat(upBuffer, sizeof(upBuffer), _("%s:\t%i km/h\n"), UP_AircraftStatToName(i),
					AIR_AircraftMenuStatsValues(aircraft->stats[i], i));
				break;
			case AIR_STATS_MAXSPEED:
				/* speed may be converted to km/h : multiply by pi / 180 * earth_radius */
				Q_strcat(upBuffer, sizeof(upBuffer), _("%s:\t%i km/h\n"), UP_AircraftStatToName(i),
					AIR_AircraftMenuStatsValues(aircraft->stats[i], i));
				break;
			case AIR_STATS_FUELSIZE:
				Q_strcat(upBuffer, sizeof(upBuffer), _("Operational range:\t%i km\n"),
					AIR_GetOperationRange(aircraft));
				break;
			case AIR_STATS_ACCURACY:
				Q_strcat(upBuffer, sizeof(upBuffer), _("%s:\t%i\n"), UP_AircraftStatToName(i),
					AIR_AircraftMenuStatsValues(aircraft->stats[i], i));
				break;
			default:
				break;
			}
		}

		const baseCapacities_t cap = AIR_GetCapacityByAircraftWeight(aircraft);
		const buildingType_t buildingType = B_GetBuildingTypeByCapacity(cap);
		const building_t* building = B_GetBuildingTemplateByType(buildingType);

		Q_strcat(upBuffer, sizeof(upBuffer), _("Required Hangar:\t%s\n"), _(building->name));
		/* @note: while MAX_ACTIVETEAM limits the number of soldiers on a craft
		 * there is no use to show this in case of an UFO (would be misleading): */
		if (!AIR_IsUFO(aircraft))
			Q_strcat(upBuffer, sizeof(upBuffer), _("Max. soldiers:\t%i\n"), aircraft->maxTeamSize);
	} else if (RS_Collected_(tech)) {
		/** @todo Display crippled info and pre-research text here */
		Com_sprintf(upBuffer, sizeof(upBuffer), _("Unknown - need to research this"));
	} else {
		Com_sprintf(upBuffer, sizeof(upBuffer), _("Unknown - need to research this"));
	}

	cgi->Cvar_Set("mn_upmetadata", "1");
	cgi->UI_RegisterText(TEXT_ITEMDESCRIPTION, upBuffer);
	UP_DisplayTechTree(tech);
}
Esempio n. 3
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) {
		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) {
			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) {
			Com_Printf("Invalid UCN for UGV!\n");
			return;
		}

		BS_SellUGV(robot);
		return;
	}

	if (!base) {
		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_GetCapacityByAircraftWeight(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) {
		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) {
				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) {
				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;
	}
	Com_Printf("Invalid item ID\n");
}