예제 #1
0
/**
 * @brief Buys the given UGV
 * @param[in] ugv The ugv template of the UGV to buy
 * @param[out] base Base to buy at
 * @return @c true if the ugv could get bought, @c false otherwise
 * @todo Implement this correctly once we have UGV
 */
bool BS_BuyUGV (const ugv_t* ugv, base_t* base)
{
	const objDef_t* ugvWeapon;

	if (!ugv)
		cgi->Com_Error(ERR_DROP, "BS_BuyUGV: Called on nullptr UGV!");
	if (!base)
		cgi->Com_Error(ERR_DROP, "BS_BuyUGV: Called on nullptr base!");
	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 (ccs.credits < ugv->price)
		return false;
	if (E_CountUnhiredRobotsByType(ugv) <= 0)
		return false;
	if (BS_GetItemOnMarket(ugvWeapon) <= 0)
		return false;
	if (CAP_GetFreeCapacity(base, CAP_ITEMS) < UGV_SIZE + ugvWeapon->size)
		return false;
	if (!E_HireRobot(base, ugv))
		return false;

	BS_RemoveItemFromMarket(ugvWeapon, 1);
	CP_UpdateCredits(ccs.credits - ugv->price);
	B_AddToStorage(base, ugvWeapon, 1);

	return true;
}
예제 #2
0
/**
 * @brief Sells the given UGV with all the equipment.
 * @param robot The employee record of the UGV to sell
 * @return @c true if the ugv could get sold, @c false otherwise
 * @todo Implement this correctly once we have UGV
 */
bool BS_SellUGV (Employee* robot)
{
	const objDef_t* ugvWeapon;
	const ugv_t* ugv;
	base_t* base;

	if (!robot)
		cgi->Com_Error(ERR_DROP, "Selling nullptr UGV!");
	if (!robot->getUGV())
		cgi->Com_Error(ERR_DROP, "Selling invalid UGV with UCN: %i", robot->chr.ucn);
	ugv = robot->getUGV();
	base = robot->baseHired;

	/* Check if we have a weapon for this ugv in the market to sell it. */
	ugvWeapon = INVSH_GetItemByID(ugv->weapon);
	if (!ugvWeapon)
		cgi->Com_Error(ERR_DROP, "BS_BuyItem_f: Could not get wepaon '%s' for ugv/tank '%s'.", ugv->weapon, ugv->id);

	if (!robot->unhire()) {
		/** @todo message - Couldn't fire employee. */
		Com_DPrintf(DEBUG_CLIENT, "Couldn't sell/fire robot/ugv.\n");
		return false;
	}

	BS_AddItemToMarket(ugvWeapon, 1);
	CP_UpdateCredits(ccs.credits + ugv->price);
	B_AddToStorage(base, ugvWeapon, -1);

	return true;
}
예제 #3
0
/**
 * @brief Run actions on finishing disassembling of a ufo
 * @param base The base to produce in
 * @param prod The production that is running
 */
static void PR_FinishDisassembly (base_t* base, production_t* prod)
{
	storedUFO_t* ufo = prod->data.data.ufo;

	assert(ufo);
	for (int i = 0; i < ufo->comp->numItemtypes; i++) {
		const objDef_t* compOd = ufo->comp->items[i];
		const int amount = (ufo->condition < 1 && ufo->comp->itemAmount2[i] != COMP_ITEMCOUNT_SCALED) ?
			ufo->comp->itemAmount2[i] : round(ufo->comp->itemAmount[i] * ufo->condition);

		assert(compOd);

		if (amount <= 0)
			continue;

		if (Q_streq(compOd->id, ANTIMATTER_ITEM_ID)) {
			B_AddAntimatter(base, amount);
		} else {
			technology_t* tech = RS_GetTechForItem(compOd);
			B_AddToStorage(base, compOd, amount);
			RS_MarkCollected(tech);
		}
	}

	Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("The disassembling of %s at %s has finished."),
			UFO_TypeToName(ufo->ufoTemplate->getUfoType()), base->name);
	MSO_CheckAddNewMessage(NT_PRODUCTION_FINISHED, _("Production finished"), cp_messageBuffer, MSG_PRODUCTION, ufo->ufoTemplate->tech);

	/* Removing UFO will remove the production too */
	US_RemoveStoredUFO(ufo);
}
예제 #4
0
/**
 * @brief Run actions on finishing production of one item/aircraft/UGV..
 * @param base The base to produce in
 * @param prod The production that is running
 */
static void PR_FinishProduction (base_t* base, production_t* prod)
{
	const char* name = PR_GetName(&prod->data);
	technology_t* tech = PR_GetTech(&prod->data);

	prod->frame = 0;
	prod->amount--;

	if (PR_IsItem(prod)) {
		CP_UpdateCredits(ccs.credits - PR_GetPrice(prod->data.data.item));
		/* Now add it to equipment and update capacity. */
		B_AddToStorage(base, prod->data.data.item, 1);
	} else if (PR_IsAircraft(prod)) {
		CP_UpdateCredits(ccs.credits - PR_GetPrice(prod->data.data.aircraft));
		/* Now add new aircraft. */
		AIR_NewAircraft(base, prod->data.data.aircraft);
	}

	if (prod->amount > 0)
		return;

	Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("Work on %s at %s has finished."), name, base->name);
	MSO_CheckAddNewMessage(NT_PRODUCTION_FINISHED, _("Production finished"), cp_messageBuffer, MSG_PRODUCTION, tech);
	/* queue the next production */
	PR_QueueNext(base);
}
예제 #5
0
/**
 * @brief Remove or add the required items from/to the a base.
 * @param[in] base Pointer to base.
 * @param[in] amount How many items are planned to be added (positive number) or removed (negative number).
 * @param[in] reqs The production requirements of the item that is to be produced. These included numbers are multiplied with 'amount')
 */
void PR_UpdateRequiredItemsInBasestorage (base_t* base, int amount, const requirements_t* reqs)
{
	if (!base)
		return;

	if (amount == 0)
		return;

	for (int i = 0; i < reqs->numLinks; i++) {
		const requirement_t* req = &reqs->links[i];
		switch (req->type) {
		case RS_LINK_ITEM: {
			const objDef_t* item = req->link.od;
			assert(item);
			B_AddToStorage(base, item, req->amount * amount);
			break;
		}
		case RS_LINK_ANTIMATTER:
			B_AddAntimatter(base, req->amount * amount);
			break;
		case RS_LINK_TECH:
		case RS_LINK_TECH_NOT:
			break;
		default:
			cgi->Com_Error(ERR_DROP, "Invalid requirement for production!\n");
		}
	}
}
예제 #6
0
파일: cp_transfer.cpp 프로젝트: ufoai/ufoai
/**
 * @brief Unloads transfer cargo when finishing the transfer or destroys it when no buildings/base.
 * @param[in,out] destination The destination base - might be nullptr in case the base
 * is already destroyed
 * @param[in] transfer Pointer to transfer in ccs.transfers.
 * @param[in] success True if the transfer reaches dest base, false if the base got destroyed.
 * @sa TR_TransferEnd
 */
static void TR_EmptyTransferCargo (base_t* destination, transfer_t* transfer, bool success)
{
	assert(transfer);

	/* antimatter */
	if (transfer->antimatter > 0 && success) {
		if (B_GetBuildingStatus(destination, B_ANTIMATTER)) {
			B_AddAntimatter(destination, transfer->antimatter);
		} else {
			Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("%s does not have Antimatter Storage, antimatter are removed!"), destination->name);
			MSO_CheckAddNewMessage(NT_TRANSFER_LOST, _("Transport mission"), cp_messageBuffer, MSG_TRANSFERFINISHED);
		}
	}

	/* items */
	if (transfer->itemCargo != nullptr) {
		if (success) {
			linkedList_t* cargo = transfer->itemCargo->list();
			LIST_Foreach(cargo, itemCargo_t, item) {
				if (item->amount <= 0)
					continue;
				if (!B_ItemIsStoredInBaseStorage(item->objDef))
					continue;
				B_AddToStorage(destination, item->objDef, item->amount);
			}
			cgi->LIST_Delete(&cargo);
		}
		delete transfer->alienCargo;
		transfer->alienCargo = nullptr;
	}

	/* Employee */
	if (transfer->hasEmployees && transfer->srcBase) {	/* Employees. (cannot come from a mission) */
		for (int i = EMPL_SOLDIER; i < MAX_EMPL; i++) {
			const employeeType_t type = (employeeType_t)i;
			TR_ForeachEmployee(employee, transfer, type) {
				employee->transfer = false;
				if (!success) {
					E_DeleteEmployee(employee);
					continue;
				}
				switch (type) {
				case EMPL_WORKER:
					PR_UpdateProductionCap(destination, 0);
					break;
				case EMPL_PILOT:
					AIR_AutoAddPilotToAircraft(destination, employee);
					break;
				default:
					break;
				}
			}
		}
	}
예제 #7
0
/**
 * @brief Unloads transfer cargo when finishing the transfer or destroys it when no buildings/base.
 * @param[in,out] destination The destination base - might be nullptr in case the base
 * is already destroyed
 * @param[in] transfer Pointer to transfer in ccs.transfers.
 * @param[in] success True if the transfer reaches dest base, false if the base got destroyed.
 * @sa TR_TransferEnd
 */
static void TR_EmptyTransferCargo (base_t* destination, transfer_t* transfer, bool success)
{
	assert(transfer);

	if (transfer->hasItems && success) {	/* Items. */
		const objDef_t* od = INVSH_GetItemByID(ANTIMATTER_ITEM_ID);
		int i;

		/* antimatter */
		if (transfer->itemAmount[od->idx] > 0) {
			if (B_GetBuildingStatus(destination, B_ANTIMATTER)) {
				B_ManageAntimatter(destination, transfer->itemAmount[od->idx], true);
			} else {
				Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("%s does not have Antimatter Storage, antimatter are removed!"), destination->name);
				MSO_CheckAddNewMessage(NT_TRANSFER_LOST, _("Transport mission"), cp_messageBuffer, MSG_TRANSFERFINISHED);
			}
		}
		/* items */
		for (i = 0; i < cgi->csi->numODs; i++) {
			od = INVSH_GetItemByIDX(i);

			if (transfer->itemAmount[od->idx] <= 0)
				continue;
			if (!B_ItemIsStoredInBaseStorage(od))
				continue;
			B_AddToStorage(destination, od, transfer->itemAmount[od->idx]);
		}
	}

	if (transfer->hasEmployees && transfer->srcBase) {	/* Employees. (cannot come from a mission) */
		if (!success) {	/* Employees will be unhired. */
			for (int i = EMPL_SOLDIER; i < MAX_EMPL; i++) {
				const employeeType_t type = (employeeType_t)i;
				TR_ForeachEmployee(employee, transfer, type) {
					employee->baseHired = transfer->srcBase;	/* Restore back the original baseid. */
					employee->transfer = false;
					employee->unhire();
				}
			}
		} else {
			for (int i = EMPL_SOLDIER; i < MAX_EMPL; i++) {
예제 #8
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;
}
예제 #9
0
/**
 * @brief Buys items from the market
 * @param[in] od pointer to the item (Object Definition record)
 * @param[out] base Base to buy at
 * @param[in ] count Number of items to buy
 * @return @c true if the ugv could get bought, @c false otherwise
 */
bool BS_BuyItem (const objDef_t* od, base_t* base, int count)
{
	if (!od)
		cgi->Com_Error(ERR_DROP, "BS_BuyItem: Called on nullptr objDef!");
	if (!base)
		cgi->Com_Error(ERR_DROP, "BS_BuyItem: Called on nullptr base!");

	if (count <= 0)
		return false;
	if (!BS_IsOnMarket(od))
		return false;
	if (ccs.credits < BS_GetItemBuyingPrice(od) * count)
		return false;
	if (BS_GetItemOnMarket(od) < count)
		return false;
	if (CAP_GetFreeCapacity(base, CAP_ITEMS) < od->size * count)
		return false;

	B_AddToStorage(base, od, count);
	BS_RemoveItemFromMarket(od, count);
	CP_UpdateCredits(ccs.credits - BS_GetItemBuyingPrice(od) * count);

	return true;
}