예제 #1
0
/**
 * @brief Make sure values of items after parsing are proper.
 */
static qboolean CP_ItemsSanityCheck (void)
{
	int i;
	qboolean result = qtrue;

	for (i = 0; i < csi.numODs; i++) {
		const objDef_t *item = INVSH_GetItemByIDX(i);

		/* Warn if item has no size set. */
		if (item->size <= 0 && B_ItemIsStoredInBaseStorage(item)) {
			result = qfalse;
			Com_Printf("CP_ItemsSanityCheck: Item %s has zero size set.\n", item->id);
		}

		/* Warn if no price is set. */
		if (item->price <= 0 && BS_IsOnMarket(item)) {
			result = qfalse;
			Com_Printf("CP_ItemsSanityCheck: Item %s has zero price set.\n", item->id);
		}

		if (item->price > 0 && !BS_IsOnMarket(item) && !PR_ItemIsProduceable(item)) {
			result = qfalse;
			Com_Printf("CP_ItemsSanityCheck: Item %s has a price set though it is neither available on the market and production.\n", item->id);
		}

		/* extension and headgear are mutual exclusive */
		if (item->extension && item->headgear) {
			result = qfalse;
			Com_Printf("CP_ItemsSanityCheck: Item %s has both extension and headgear set.\n",  item->id);
		}
	}

	return result;
}
예제 #2
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;
				}
			}
		}
	}
예제 #3
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));
}
예제 #4
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 NULL 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, qboolean success)
{
	assert(transfer);

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

		/* antimatter */
		if (transfer->itemAmount[od->idx] > 0) {
			if (B_GetBuildingStatus(destination, B_ANTIMATTER)) {
				B_ManageAntimatter(destination, transfer->itemAmount[od->idx], qtrue);
			} 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, qfalse, MSG_TRANSFERFINISHED, NULL);
			}
		}
		/* items */
		for (i = 0; i < csi.numODs; i++) {
			od = INVSH_GetItemByIDX(i);

			if (transfer->itemAmount[od->idx] <= 0)
				continue;
			if (!B_ItemIsStoredInBaseStorage(od))
				continue;
			if (!B_GetBuildingStatus(destination, B_STORAGE)) {
				Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("%s does not have Storage, items are removed!"), destination->name);
				MSO_CheckAddNewMessage(NT_TRANSFER_LOST, _("Transport mission"), cp_messageBuffer, qfalse, MSG_TRANSFERFINISHED, NULL);
				break;
			}
			B_UpdateStorageAndCapacity(destination, od, transfer->itemAmount[od->idx], qfalse, qtrue);
		}
	}

	if (transfer->hasEmployees && transfer->srcBase) {	/* Employees. (cannot come from a mission) */
		if (!success || !B_GetBuildingStatus(destination, B_QUARTERS)) {	/* Employees will be unhired. */
			employeeType_t i;
			if (success) {
				Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("%s does not have Living Quarters, employees got unhired!"), destination->name);
				MSO_CheckAddNewMessage(NT_TRANSFER_LOST, _("Transport mission"), cp_messageBuffer, qfalse, MSG_TRANSFERFINISHED, NULL);
			}
			for (i = EMPL_SOLDIER; i < MAX_EMPL; i++) {
				employee_t *employee;
				TR_ForeachEmployee(employee, transfer, i) {
					employee->baseHired = transfer->srcBase;	/* Restore back the original baseid. */
					employee->transfer = qfalse;
					E_UnhireEmployee(employee);
				}
			}
		} else {
예제 #5
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));
}
예제 #6
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++) {