Пример #1
0
/**
 * @brief Update the current capacity of Workshop
 * @param[in] base Pointer to the base containing workshop.
 * @param[in] workerChange Number of workers going to be hired/fired
 */
void PR_UpdateProductionCap (base_t* base, int workerChange)
{
	assert(base);
	capacities_t* workspaceCapacity = CAP_Get(base, CAP_WORKSPACE);

	if (workspaceCapacity->max <= 0)
		PR_EmptyQueue(base);

	const int workers = E_CountHired(base, EMPL_WORKER) + workerChange;
	if (workspaceCapacity->max >= workers)
		workspaceCapacity->cur = workers;
	else
		workspaceCapacity->cur = workspaceCapacity->max;

	/* recalculate time to finish */
	production_queue_t* q = PR_GetProductionForBase(base);
	/* not actually any active productions */
	if (q->numItems <= 0)
		return;
	/* Workshop is disabled because their dependences are disabled */
	if (!PR_ProductionAllowed(base))
		return;

	for (int i = 0; i < q->numItems; i++) {
		production_t* prod = &q->items[i];
		prod->totalFrames = std::max(prod->frame, PR_CalculateTotalFrames(base, &prod->data));
	}
}
Пример #2
0
/**
 * @brief Checks whether an item is finished.
 * @note One call each game time minute
 * @sa CP_CampaignRun
 * @sa PR_DisassemblingFrame
 * @sa PR_ProductionFrame
 */
void PR_ProductionRun (void)
{
	/* Loop through all founded bases. Then check productions
	 * in global data array. Then increase prod->percentDone and check
	 * whether an item is produced. Then add to base storage. */
	base_t* base = nullptr;
	while ((base = B_GetNext(base)) != nullptr) {
		production_queue_t* q = PR_GetProductionForBase(base);

		/* not actually any active productions */
		if (q->numItems <= 0)
			continue;

		/* Workshop is disabled because their dependences are disabled */
		if (!PR_ProductionAllowed(base))
			continue;

		production_t* prod = &q->items[0];
		prod->totalFrames = PR_CalculateTotalFrames(base, &prod->data);

		if (!PR_CheckFrame(base, prod))
			return;

		prod->frame++;

		/* If Production/Disassembly is not finished yet, we're done, check next base */
		if (!PR_IsReady(prod))
			continue;

		if (PR_IsProduction(prod))
			PR_FinishProduction(base, prod);
		else if (PR_IsDisassembly(prod))
			PR_FinishDisassembly(base, prod);
	}
}
Пример #3
0
/**
 * @brief Set percentDone values after loading the campaign
 * @note it need to be done after B_PostLoadInitCapacity
 * @sa PR_PostLoadInit
 */
static bool PR_PostLoadInitProgress (void)
{
	base_t* base = nullptr;
	while ((base = B_GetNext(base)) != nullptr) {
		production_queue_t* pq = PR_GetProductionForBase(base);
		for (int j = 0; j < pq->numItems; j++) {
			production_t* prod = &pq->items[j];
			prod->totalFrames = PR_CalculateTotalFrames(base, &prod->data);
		}
	}

	return true;
}
Пример #4
0
/**
 * @brief Add a new item to the bottom of the production queue.
 * @param[in] base Pointer to base, where the queue is.
 * @param[in] data The production data
 * @param[in] amount Desired amount to produce.
 * @return @c NULL in case the production wasn't enqueued, otherwise the production pointer
 */
production_t* PR_QueueNew (base_t* base, const productionData_t* data, signed int amount)
{
	production_queue_t* queue = PR_GetProductionForBase(base);

	if (queue->numItems >= MAX_PRODUCTIONS)
		return nullptr;

	/* Initialize */
	production_t* prod = &queue->items[queue->numItems];
	OBJZERO(*prod);
	/* self-reference. */
	prod->idx = queue->numItems;
	prod->data = *data;
	prod->amount = amount;

	const technology_t* tech = PR_GetTech(&prod->data);
	if (tech == nullptr)
		return nullptr;


	/* only one item for disassemblies */
	if (PR_IsDisassemblyData(data))
		amount = 1;
	else if (tech->produceTime < 0)
		/* Don't try to add an item to the queue which is not producible. */
		return nullptr;

	amount = PR_RequirementsMet(amount, &tech->requireForProduction, base);
	if (amount == 0)
		return nullptr;

	prod->totalFrames = PR_CalculateTotalFrames(base, data);

	PR_UpdateRequiredItemsInBasestorage(base, -amount, &tech->requireForProduction);

	PR_SetUFODisassembly(prod);

	queue->numItems++;
	return prod;
}
Пример #5
0
/**
 * @brief Calculates the production time (in hours) for a technology
 * @param[in] base Pointer to the base to calculate production time at
 * @param[in] prodData Pointer to the production data structure
 */
int PR_GetProductionHours (const base_t* base, const productionData_t* prodData)
{
	return round(PR_CalculateTotalFrames(base, prodData) / (double)MINUTES_PER_HOUR);
}
Пример #6
0
/**
 * @brief Calculates the production time (in hours) for a technology
 * @param[in] base Pointer to the base to calculate production time at
 * @param[in] prodData Pointer to the production data structure
 */
int PR_GetProductionHours (const base_t* base, const productionData_t* prodData)
{
	return round(PR_CalculateTotalFrames(base, prodData) / std::max(1, PR_WorkersAvailable(base)) / (double)MINUTES_PER_HOUR);
}
Пример #7
0
/**
 * @brief Load callback for xml savegames
 * @param[in] p XML Node structure, where we get the information from
 * @sa PR_SaveXML
 * @sa SAV_GameLoadXML
 */
bool PR_LoadXML (xmlNode_t* p)
{
	xmlNode_t* node = cgi->XML_GetNode(p, SAVE_PRODUCE_PRODUCTION);

	for (xmlNode_t* snode = cgi->XML_GetNode(node, SAVE_PRODUCE_QUEUE); snode;
			snode = cgi->XML_GetNextNode(snode, node, SAVE_PRODUCE_QUEUE)) {
		xmlNode_t* ssnode;
		const int baseIDX = cgi->XML_GetInt(snode, SAVE_PRODUCE_QUEUEIDX, MAX_BASES);
		base_t* base = B_GetBaseByIDX(baseIDX);
		production_queue_t* pq;

		if (base == nullptr) {
			Com_Printf("Invalid production queue index %i\n", baseIDX);
			continue;
		}

		pq = PR_GetProductionForBase(base);

		for (ssnode = cgi->XML_GetNode(snode, SAVE_PRODUCE_ITEM); pq->numItems < MAX_PRODUCTIONS && ssnode;
				ssnode = cgi->XML_GetNextNode(ssnode, snode, SAVE_PRODUCE_ITEM)) {
			const char* s1 = cgi->XML_GetString(ssnode, SAVE_PRODUCE_ITEMID);
			production_t* prod = &pq->items[pq->numItems];

			prod->idx = pq->numItems;
			prod->amount = cgi->XML_GetInt(ssnode, SAVE_PRODUCE_AMOUNT, 0);
			prod->frame = cgi->XML_GetInt(ssnode, SAVE_PRODUCE_PROGRESS, 0);

			/* amount */
			if (prod->amount <= 0) {
				Com_Printf("PR_LoadXML: Production with amount <= 0 dropped (baseidx=%i, production idx=%i).\n",
						baseIDX, pq->numItems);
				continue;
			}
			/* item */
			if (s1[0] != '\0')
				PR_SetData(&prod->data, PRODUCTION_TYPE_ITEM, INVSH_GetItemByID(s1));
			/* UFO */
			const int ufoIDX = cgi->XML_GetInt(ssnode, SAVE_PRODUCE_UFOIDX, -1);
			if (ufoIDX != -1) {
				storedUFO_t* ufo = US_GetStoredUFOByIDX(ufoIDX);

				if (!ufo) {
					Com_Printf("PR_LoadXML: Could not find ufo idx: %i\n", ufoIDX);
					continue;
				}

				PR_SetData(&prod->data, PRODUCTION_TYPE_DISASSEMBLY, ufo);
				PR_SetUFODisassembly(prod);
			}
			/* aircraft */
			const char* s2 = cgi->XML_GetString(ssnode, SAVE_PRODUCE_AIRCRAFTID);
			if (s2[0] != '\0')
				PR_SetData(&prod->data, PRODUCTION_TYPE_AIRCRAFT, AIR_GetAircraft(s2));

			if (!PR_IsDataValid(&prod->data)) {
				Com_Printf("PR_LoadXML: Production is not an item an aircraft nor a disassembly\n");
				continue;
			}

			prod->totalFrames = PR_CalculateTotalFrames(base, &prod->data);

			pq->numItems++;
		}
	}
	return true;
}