UFO: Alien Invasion
Loading...
Searching...
No Matches
cp_produce.cpp
Go to the documentation of this file.
1
6
7/*
8Copyright (C) 2002-2025 UFO: Alien Invasion.
9
10This program is free software; you can redistribute it and/or
11modify it under the terms of the GNU General Public License
12as published by the Free Software Foundation; either version 2
13of the License, or (at your option) any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18
19See the GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License
22along with this program; if not, write to the Free Software
23Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24*/
25
26#include "../../DateTime.h"
27#include "../../cl_shared.h"
28#include "cp_campaign.h"
29#include "cp_capacity.h"
30#include "cp_ufo.h"
31#include "cp_produce.h"
33#include "save/save_produce.h"
34
40static int PR_CalculateTotalFrames (const base_t* base, const productionData_t* prodData)
41{
42 double time;
43 if (PR_IsProductionData(prodData)) {
44 const technology_t* tech = PR_GetTech(prodData);
45 time = tech->produceTime;
46 } else {
47 const storedUFO_t* storedUFO = prodData->data.ufo;
48 time = storedUFO->comp->time;
49 /* Production is 4 times longer when installation is on Antipodes
50 * Penalty starts when distance is greater than 45 degrees */
51 time *= std::max(1.0, GetDistanceOnGlobe(storedUFO->installation->pos, base->pos) / 45.0);
52 }
53 /* Calculate the time needed for production of the item for our amount of workers. */
54 time *= DateTime::MINUTES_PER_HOUR * ccs.curCampaign->produceRate;
55
56 /* Don't allow to return a time of less than 1 (you still need at least 1 minute to produce an item). */
57 return std::max(1.0, time) + 1;
58}
59
64int PR_WorkersAvailable (const base_t* base)
65{
66 assert(base);
67 /* Check how many workers hired in this base. */
68 const signed int allWorkers = E_CountHired(base, EMPL_WORKER);
69 /* We will not use more workers than workspace capacity in this base. */
70 const signed int maxWorkers = std::min(allWorkers, CAP_GetMax(base, CAP_WORKSPACE));
71
72 return maxWorkers;
73}
74
80{
81 assert(prod);
82 const base_t *base = PR_ProductionBase(prod);
83 return (prod->totalFrames - prod->frame) / std::max(1, PR_WorkersAvailable(base));
84}
85
91{
92 return round(PR_GetRemainingMinutes(prod) / (double)DateTime::MINUTES_PER_HOUR);
93}
94
100int PR_GetProductionHours (const base_t* base, const productionData_t* prodData)
101{
102 return round(PR_CalculateTotalFrames(base, prodData) / std::max(1, PR_WorkersAvailable(base)) / (double)DateTime::MINUTES_PER_HOUR);
103}
104
111void PR_UpdateRequiredItemsInBasestorage (base_t* base, int amount, const requirements_t* reqs)
112{
113 if (!base)
114 return;
115
116 if (amount == 0)
117 return;
118
119 for (int i = 0; i < reqs->numLinks; i++) {
120 const requirement_t* req = &reqs->links[i];
121 switch (req->type) {
122 case RS_LINK_ITEM: {
123 const objDef_t* item = req->link.od;
124 assert(item);
125 B_AddToStorage(base, item, req->amount * amount);
126 break;
127 }
129 B_AddAntimatter(base, req->amount * amount);
130 break;
131 case RS_LINK_TECH:
132 case RS_LINK_TECH_NOT:
133 break;
134 default:
135 cgi->Com_Error(ERR_DROP, "Invalid requirement for production!\n");
136 }
137 }
138}
139
147int PR_RequirementsMet (int amount, const requirements_t* reqs, base_t* base)
148{
149 int producibleAmount = amount;
150
151 for (int i = 0; i < reqs->numLinks; i++) {
152 const requirement_t* req = &reqs->links[i];
153
154 switch (req->type) {
155 case RS_LINK_ITEM: {
156 const int items = std::min(amount, B_ItemInBase(req->link.od, base) / ((req->amount) ? req->amount : 1));
157 producibleAmount = std::min(producibleAmount, items);
158 break;
159 }
160 case RS_LINK_ANTIMATTER: {
161 const int am = std::min(amount, B_AntimatterInBase(base) / ((req->amount) ? req->amount : 1));
162 producibleAmount = std::min(producibleAmount, am);
163 break;
164 }
165 case RS_LINK_TECH:
166 producibleAmount = (RS_IsResearched_ptr(req->link.tech)) ? producibleAmount : 0;
167 break;
168 case RS_LINK_TECH_NOT:
169 producibleAmount = (RS_IsResearched_ptr(req->link.tech)) ? 0 : producibleAmount;
170 break;
171 default:
172 break;
173 }
174 }
175
176 return producibleAmount;
177}
178
182const char* PR_GetName (const productionData_t* data)
183{
184 switch (data->type) {
186 return _(data->data.item->name);
188 return _(data->data.aircraft->tpl->name);
190 return UFO_TypeToName(data->data.ufo->ufoTemplate->getUfoType());
191 default:
192 cgi->Com_Error(ERR_DROP, "Invalid production type given: %i", data->type);
193 }
194}
195
200{
201 switch (data->type) {
203 return RS_GetTechForItem(data->data.item);
205 return data->data.aircraft->tech;
207 return data->data.ufo->ufoTemplate->tech;
208 default:
209 return nullptr;
210 }
211}
212
214{
216 if (PR_IsDisassembly(prod))
217 prod->data.data.ufo->disassembly = nullptr;
218}
219
221{
223 if (PR_IsDisassembly(prod))
224 prod->data.data.ufo->disassembly = prod;
225}
226
234production_t* PR_QueueNew (base_t* base, const productionData_t* data, signed int amount)
235{
237
238 if (queue->numItems >= MAX_PRODUCTIONS)
239 return nullptr;
240
241 /* Initialize */
242 production_t* prod = &queue->items[queue->numItems];
243 OBJZERO(*prod);
244 /* self-reference. */
245 prod->idx = queue->numItems;
246 prod->data = *data;
247 prod->amount = amount;
248
249 const technology_t* tech = PR_GetTech(&prod->data);
250 if (tech == nullptr)
251 return nullptr;
252
253
254 /* only one item for disassemblies */
256 amount = 1;
257 else if (tech->produceTime < 0)
258 /* Don't try to add an item to the queue which is not producible. */
259 return nullptr;
260
261 amount = PR_RequirementsMet(amount, &tech->requireForProduction, base);
262 if (amount == 0)
263 return nullptr;
264
266
268
270
271 queue->numItems++;
272 return prod;
273}
274
282{
283 production_t* prod = &queue->items[index];
284 const technology_t* tech = PR_GetTech(&prod->data);
285 if (tech == nullptr)
286 cgi->Com_Error(ERR_DROP, "No tech pointer for production");
287
289
290 assert(base);
292
294
295 /* Adjust ufos' disassembly pointer */
296 for (int i = index; i < queue->numItems; i++) {
297 production_t* disassembly = &queue->items[i];
298 PR_SetUFODisassembly(disassembly);
299 }
300}
301
309{
310 const int newIndex = std::max(0, std::min(index + offset, queue->numItems - 1));
311
312 if (newIndex == index)
313 return;
314
315 production_t saved = queue->items[index];
316
317 /* copy up */
318 for (int i = index; i < newIndex; i++) {
319 production_t* prod;
320 queue->items[i] = queue->items[i + 1];
321 prod = &queue->items[i];
322 prod->idx = i;
324 }
325
326 /* copy down */
327 for (int i = index; i > newIndex; i--) {
328 production_t* prod;
329 queue->items[i] = queue->items[i - 1];
330 prod = &queue->items[i];
331 prod->idx = i;
333 }
334
335 /* insert item */
336 queue->items[newIndex] = saved;
337 queue->items[newIndex].idx = newIndex;
338 PR_SetUFODisassembly(&queue->items[newIndex]);
339}
340
346{
348
349 PR_QueueDelete(base, queue, 0);
350
351 if (queue->numItems == 0) {
352 Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("Production queue for %s is empty"), base->name);
354 }
355}
356
360static void PR_EmptyQueue (base_t* base)
361{
362 if (!base)
363 return;
364
366 while (queue->numItems)
367 PR_QueueDelete(base, queue, 0);
368}
369
374{
376 if (queue->numItems < 2)
377 return;
378
379 PR_QueueMove(queue, 0, queue->numItems - 1);
380}
381
388static bool PR_CheckFrame (base_t* base, production_t* prod)
389{
390 int price = 0;
391
392 if (PR_IsItem(prod)) {
393 const objDef_t* od = prod->data.data.item;
394 price = PR_GetPrice(od->productionCost);
395 } else if (PR_IsAircraft(prod)) {
396 const aircraft_t* aircraft = prod->data.data.aircraft;
397 price = PR_GetPrice(aircraft->productionCost);
398 }
399
400 /* Not enough money */
401 if (price > 0 && price > ccs.credits) {
402 if (!prod->creditMessage) {
403 Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("Not enough credits to finish production in %s."), base->name);
405 prod->creditMessage = true;
406 }
407
409 return false;
410 }
411
412 return true;
413}
414
420static void PR_FinishProduction (base_t* base, production_t* prod)
421{
422 const char* name = PR_GetName(&prod->data);
423 technology_t* tech = PR_GetTech(&prod->data);
424
425 prod->frame = 0;
426 prod->amount--;
427
428 if (PR_IsItem(prod)) {
430 /* Now add it to equipment and update capacity. */
431 B_AddToStorage(base, prod->data.data.item, 1);
432 } else if (PR_IsAircraft(prod)) {
433 CP_UpdateCredits(ccs.credits - PR_GetPrice(prod->data.data.aircraft->productionCost));
434 /* Now add new aircraft. */
435 AIR_NewAircraft(base, prod->data.data.aircraft);
436 }
437
438 if (prod->amount > 0)
439 return;
440
441 Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("Work on %s at %s has finished."), name, base->name);
443 /* queue the next production */
444 PR_QueueNext(base);
445}
446
452static void PR_FinishDisassembly (base_t* base, production_t* prod)
453{
454 storedUFO_t* ufo = prod->data.data.ufo;
455
456 assert(ufo);
457 for (int i = 0; i < ufo->comp->numItemtypes; i++) {
458 const objDef_t* compOd = ufo->comp->items[i];
459 const int amount = (ufo->condition < 1 && ufo->comp->itemAmount2[i] != COMP_ITEMCOUNT_SCALED) ?
460 ufo->comp->itemAmount2[i] : round(ufo->comp->itemAmount[i] * ufo->condition);
461
462 assert(compOd);
463
464 if (amount <= 0)
465 continue;
466
467 if (Q_streq(compOd->id, ANTIMATTER_ITEM_ID)) {
468 B_AddAntimatter(base, amount);
469 } else {
470 technology_t* tech = RS_GetTechForItem(compOd);
471 B_AddToStorage(base, compOd, amount);
472 RS_MarkCollected(tech);
473 }
474 }
475
476 Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("The disassembling of %s at %s has finished."),
477 UFO_TypeToName(ufo->ufoTemplate->getUfoType()), base->name);
479
480 /* Removing UFO will remove the production too */
482}
483
490int PR_IncreaseProduction (production_t* prod, int amount)
491{
492 if (PR_IsDisassembly(prod))
493 return 0;
494
495 base_t* base = PR_ProductionBase(prod);
496 assert(base);
497
498 /* amount limit per one production */
499 if (prod->amount + amount > MAX_PRODUCTION_AMOUNT) {
500 amount = std::max(0, MAX_PRODUCTION_AMOUNT - prod->amount);
501 }
502
503 const technology_t* tech = PR_GetTech(&prod->data);
504 assert(tech);
505
506 amount = PR_RequirementsMet(amount, &tech->requireForProduction, base);
507 if (amount == 0)
508 return 0;
509
510 prod->amount += amount;
512
513 return amount;
514}
515
523int PR_DecreaseProduction (production_t* prod, int amount)
524{
525 assert(prod);
526 base_t* base = PR_ProductionBase(prod);
527 assert(base);
528
529 if (PR_IsDisassembly(prod))
530 return 0;
531
532 if (prod->amount <= amount) {
534 amount = prod->amount;
535 PR_QueueDelete(base, queue, prod->idx);
536 return amount;
537 }
538
539 const technology_t* tech = PR_GetTech(&prod->data);
540 if (tech == nullptr)
541 cgi->Com_Error(ERR_DROP, "No tech pointer for production");
542
543 prod->amount += -amount;
545
546 return amount;
547}
548
557{
558 /* Loop through all founded bases. Then check productions
559 * in global data array. Then increase prod->percentDone and check
560 * whether an item is produced. Then add to base storage. */
561 base_t* base = nullptr;
562 while ((base = B_GetNext(base)) != nullptr) {
564
565 /* not actually any active productions */
566 if (q->numItems <= 0)
567 continue;
568
569 /* Workshop is disabled because their dependences are disabled */
570 if (!PR_ProductionAllowed(base))
571 continue;
572
573 production_t* prod = &q->items[0];
574
575 if (!PR_CheckFrame(base, prod))
576 return;
577
578 prod->frame += PR_WorkersAvailable(base);
579
580 /* If Production/Disassembly is not finished yet, we're done, check next base */
581 if (!PR_IsReady(prod))
582 continue;
583
584 if (PR_IsProduction(prod))
585 PR_FinishProduction(base, prod);
586 else if (PR_IsDisassembly(prod))
587 PR_FinishDisassembly(base, prod);
588 }
589}
590
596bool PR_ProductionAllowed (const base_t* base)
597{
598 assert(base);
599 return !B_IsUnderAttack(base) && B_GetBuildingStatus(base, B_WORKSHOP) && E_CountHired(base, EMPL_WORKER) > 0;
600}
601
607void PR_UpdateProductionCap (base_t* base, int workerChange)
608{
609 assert(base);
610 capacities_t* workspaceCapacity = CAP_Get(base, CAP_WORKSPACE);
611
612 if (workspaceCapacity->max <= 0)
613 PR_EmptyQueue(base);
614
615 const int workers = E_CountHired(base, EMPL_WORKER) + workerChange;
616 if (workspaceCapacity->max >= workers)
617 workspaceCapacity->cur = workers;
618 else
619 workspaceCapacity->cur = workspaceCapacity->max;
620
621 /* recalculate time to finish */
623 /* not actually any active productions */
624 if (q->numItems <= 0)
625 return;
626 /* Workshop is disabled because their dependences are disabled */
627 if (!PR_ProductionAllowed(base))
628 return;
629
630 for (int i = 0; i < q->numItems; i++) {
631 production_t* prod = &q->items[i];
632 prod->totalFrames = std::max(prod->frame, PR_CalculateTotalFrames(base, &prod->data));
633 }
634}
635
641{
642 const technology_t* tech = RS_GetTechForItem(item);
643 return tech->produceTime != -1;
644}
645
652{
653 base_t* base = nullptr;
654 while ((base = B_GetNext(base)) != nullptr) {
655 const ptrdiff_t diff = ((ptrdiff_t)((production) - PR_GetProductionForBase(base)->items));
656
657 if (diff >= 0 && diff < MAX_PRODUCTIONS)
658 return base;
659 }
660 return nullptr;
661}
662
667int PR_GetPrice (const int productionCost)
668{
669 int price;
670 price = productionCost * ccs.curCampaign->componentRate;
671 return price;
672}
673
680{
681 xmlNode_t* node = cgi->XML_AddNode(p, SAVE_PRODUCE_PRODUCTION);
682
683 base_t* base = nullptr;
684 while ((base = B_GetNext(base)) != nullptr) {
686
687 xmlNode_t* snode = cgi->XML_AddNode(node, SAVE_PRODUCE_QUEUE);
689 cgi->XML_AddInt(snode, SAVE_PRODUCE_QUEUEIDX, base->idx);
690
691 for (int j = 0; j < pq->numItems; j++) {
692 const production_t* prod = &pq->items[j];
693 xmlNode_t* ssnode = cgi->XML_AddNode(snode, SAVE_PRODUCE_ITEM);
694 if (PR_IsItem(prod))
695 cgi->XML_AddString(ssnode, SAVE_PRODUCE_ITEMID, prod->data.data.item->id);
696 else if (PR_IsAircraft(prod))
697 cgi->XML_AddString(ssnode, SAVE_PRODUCE_AIRCRAFTID, prod->data.data.aircraft->id);
698 else if (PR_IsDisassembly(prod))
699 cgi->XML_AddInt(ssnode, SAVE_PRODUCE_UFOIDX, prod->data.data.ufo->idx);
700 cgi->XML_AddInt(ssnode, SAVE_PRODUCE_AMOUNT, prod->amount);
701 cgi->XML_AddInt(ssnode, SAVE_PRODUCE_PROGRESS, prod->frame);
702 }
703 }
704 return true;
705}
706
714{
715 xmlNode_t* node = cgi->XML_GetNode(p, SAVE_PRODUCE_PRODUCTION);
716
717 for (xmlNode_t* snode = cgi->XML_GetNode(node, SAVE_PRODUCE_QUEUE); snode;
718 snode = cgi->XML_GetNextNode(snode, node, SAVE_PRODUCE_QUEUE)) {
719 xmlNode_t* ssnode;
720 const int baseIDX = cgi->XML_GetInt(snode, SAVE_PRODUCE_QUEUEIDX, MAX_BASES);
721 base_t* base = B_GetBaseByIDX(baseIDX);
723
724 if (base == nullptr) {
725 cgi->Com_Printf("Invalid production queue index %i\n", baseIDX);
726 continue;
727 }
728
729 pq = PR_GetProductionForBase(base);
730
731 for (ssnode = cgi->XML_GetNode(snode, SAVE_PRODUCE_ITEM); pq->numItems < MAX_PRODUCTIONS && ssnode;
732 ssnode = cgi->XML_GetNextNode(ssnode, snode, SAVE_PRODUCE_ITEM)) {
733 const char* s1 = cgi->XML_GetString(ssnode, SAVE_PRODUCE_ITEMID);
734 production_t* prod = &pq->items[pq->numItems];
735
736 prod->idx = pq->numItems;
737 prod->amount = cgi->XML_GetInt(ssnode, SAVE_PRODUCE_AMOUNT, 0);
738 prod->frame = cgi->XML_GetInt(ssnode, SAVE_PRODUCE_PROGRESS, 0);
739
740 /* amount */
741 if (prod->amount <= 0) {
742 cgi->Com_Printf("PR_LoadXML: Production with amount <= 0 dropped (baseidx=%i, production idx=%i).\n",
743 baseIDX, pq->numItems);
744 continue;
745 }
746 /* item */
747 if (s1[0] != '\0')
749 /* UFO */
750 const int ufoIDX = cgi->XML_GetInt(ssnode, SAVE_PRODUCE_UFOIDX, -1);
751 if (ufoIDX != -1) {
752 storedUFO_t* ufo = US_GetStoredUFOByIDX(ufoIDX);
753
754 if (!ufo) {
755 cgi->Com_Printf("PR_LoadXML: Could not find ufo idx: %i\n", ufoIDX);
756 continue;
757 }
758
761 }
762 /* aircraft */
763 const char* s2 = cgi->XML_GetString(ssnode, SAVE_PRODUCE_AIRCRAFTID);
764 if (s2[0] != '\0')
766
767 if (!PR_IsDataValid(&prod->data)) {
768 cgi->Com_Printf("PR_LoadXML: Production is not an item an aircraft nor a disassembly\n");
769 continue;
770 }
771
772 prod->totalFrames = PR_CalculateTotalFrames(base, &prod->data);
773
774 pq->numItems++;
775 }
776 }
777 return true;
778}
779
785static bool PR_PostLoadInitProgress (void)
786{
787 base_t* base = nullptr;
788 while ((base = B_GetNext(base)) != nullptr) {
790 for (int j = 0; j < pq->numItems; j++) {
791 production_t* prod = &pq->items[j];
792 prod->totalFrames = PR_CalculateTotalFrames(base, &prod->data);
793 }
794 }
795
796 return true;
797}
798
804{
806}
DateTime class definition.
Share stuff between the different cgame implementations.
#define _(String)
Definition cl_shared.h:44
static const short MINUTES_PER_HOUR
Definition DateTime.h:35
#define REMOVE_ELEM_ADJUST_IDX(array, index, n)
Definition common.h:396
#define ERR_DROP
Definition common.h:211
aircraft_t * AIR_NewAircraft(base_t *base, const aircraft_t *aircraftTemplate)
Places a new aircraft in the given base.
const aircraft_t * AIR_GetAircraft(const char *name)
Searches the global array of aircraft types for a given aircraft.
base_t * B_GetNext(base_t *lastBase)
Iterates through founded bases.
Definition cp_base.cpp:286
int B_AddAntimatter(base_t *base, int amount)
Manages antimatter (adding, removing) through Antimatter Storage Facility.
Definition cp_base.cpp:2635
base_t * B_GetBaseByIDX(int baseIdx)
Array bound check for the base index. Will also return unfounded bases as long as the index is in the...
Definition cp_base.cpp:313
int B_AntimatterInBase(const base_t *base)
returns the amount of antimatter stored in a base
Definition cp_base.cpp:2613
int B_ItemInBase(const objDef_t *item, const base_t *base)
Check if the item has been collected (i.e it is in the storage) in the given base.
Definition cp_base.cpp:2133
int B_AddToStorage(base_t *base, const objDef_t *obj, int amount)
Add/remove items to/from the storage.
Definition cp_base.cpp:2576
bool B_GetBuildingStatus(const base_t *const base, const buildingType_t buildingType)
Get the status associated to a building.
Definition cp_base.cpp:478
#define B_IsUnderAttack(base)
Definition cp_base.h:53
#define MAX_BASES
Definition cp_base.h:32
@ B_WORKSHOP
Definition cp_building.h:56
void CP_UpdateCredits(int credits)
Sets credits and update mn_credits cvar.
ccs_t ccs
Header file for single player campaign control.
const cgame_import_t * cgi
@ CAP_WORKSPACE
Definition cp_capacity.h:34
#define CAP_GetMax(base, capacity)
Definition cp_capacity.h:51
#define CAP_Get(base, capacity)
Capacity macros.
Definition cp_capacity.h:50
#define COMP_ITEMCOUNT_SCALED
int E_CountHired(const base_t *const base, employeeType_t type)
Counts hired employees of a given type in a given base.
@ EMPL_WORKER
Definition cp_employee.h:33
uiMessageListNodeMessage_t * MSO_CheckAddNewMessage(const notify_t messagecategory, const char *title, const char *text, messageType_t type, technology_t *pedia, bool popup)
Adds a new message to message stack. It uses message settings to verify whether sound should be playe...
@ NT_PRODUCTION_QUEUE_EMPTY
@ NT_PRODUCTION_FAILED
@ NT_PRODUCTION_FINISHED
char cp_messageBuffer[MAX_MESSAGE_TEXT]
@ MSG_PRODUCTION
Definition cp_messages.h:46
void PR_UpdateRequiredItemsInBasestorage(base_t *base, int amount, const requirements_t *reqs)
Remove or add the required items from/to the a base.
void PR_ProductionRun(void)
Checks whether an item is finished.
static int PR_CalculateTotalFrames(const base_t *base, const productionData_t *prodData)
Calculates the total frame count (minutes) needed for producing an item for a single worker.
int PR_WorkersAvailable(const base_t *base)
Returns the numer of workers available to produce an item.
void PR_QueueDelete(base_t *base, production_queue_t *queue, int index)
Delete the selected entry from the queue.
const char * PR_GetName(const productionData_t *data)
int PR_GetPrice(const int productionCost)
Used in production costs (to allow reducing prices below 1x).
production_t * PR_QueueNew(base_t *base, const productionData_t *data, signed int amount)
Add a new item to the bottom of the production queue.
int PR_DecreaseProduction(production_t *prod, int amount)
decreases production amount
bool PR_LoadXML(xmlNode_t *p)
Load callback for xml savegames.
bool PR_ProductionAllowed(const base_t *base)
Returns true if the current base is able to produce items.
int PR_GetRemainingMinutes(const production_t *prod)
Calculates the remaining time for a technology in minutes.
static void PR_ResetUFODisassembly(production_t *prod)
int PR_IncreaseProduction(production_t *prod, int amount)
increases production amount if possible
static bool PR_PostLoadInitProgress(void)
Set percentDone values after loading the campaign.
static void PR_FinishProduction(base_t *base, production_t *prod)
Run actions on finishing production of one item/aircraft/UGV..
bool PR_SaveXML(xmlNode_t *p)
Save callback for savegames in XML Format.
int PR_RequirementsMet(int amount, const requirements_t *reqs, base_t *base)
Checks if the production requirements are met for a defined amount.
static void PR_FinishDisassembly(base_t *base, production_t *prod)
Run actions on finishing disassembling of a ufo.
int PR_GetRemainingHours(const production_t *prod)
Calculates the remaining hours for a technology.
static void PR_SetUFODisassembly(production_t *prod)
void PR_UpdateProductionCap(base_t *base, int workerChange)
Update the current capacity of Workshop.
int PR_GetProductionHours(const base_t *base, const productionData_t *prodData)
Calculates the production time (in hours) for a technology.
static void PR_ProductionRollBottom(base_t *base)
moves the first production to the bottom of the list
base_t * PR_ProductionBase(const production_t *production)
Returns the base pointer the production belongs to.
void PR_QueueMove(production_queue_t *queue, int index, int offset)
Moves the given queue item in the given direction.
static bool PR_CheckFrame(base_t *base, production_t *prod)
Checks whether production can continue.
technology_t * PR_GetTech(const productionData_t *data)
static void PR_EmptyQueue(base_t *base)
clears the production queue on a base
bool PR_ItemIsProduceable(const objDef_t *item)
check if an item is producable.
void PR_QueueNext(base_t *base)
Queues the next production in the queue.
bool PR_PostLoadInit(void)
actions to do with productions after loading a savegame
Header for production related stuff.
#define PR_IsProduction(prod)
Definition cp_produce.h:78
#define PR_IsDataValid(dataPtr)
Definition cp_produce.h:81
@ PRODUCTION_TYPE_DISASSEMBLY
Definition cp_produce.h:38
@ PRODUCTION_TYPE_ITEM
Definition cp_produce.h:36
@ PRODUCTION_TYPE_AIRCRAFT
Definition cp_produce.h:37
#define PR_IsProductionData(data)
Definition cp_produce.h:73
#define PR_IsAircraft(prod)
Definition cp_produce.h:76
#define MAX_PRODUCTION_AMOUNT
Definition cp_produce.h:30
#define PR_IsDisassemblyData(data)
Definition cp_produce.h:70
#define PR_SetData(dataPtr, typeVal, ptr)
Definition cp_produce.h:80
#define PR_GetProductionForBase(base)
Definition cp_produce.h:96
#define MAX_PRODUCTIONS
Maximum number of productions queued in any one base.
Definition cp_produce.h:28
#define PR_IsReady(prod)
Definition cp_produce.h:84
#define PR_IsDisassembly(prod)
Definition cp_produce.h:75
#define PR_IsItem(prod)
Definition cp_produce.h:77
Header file for menu related console command callbacks for production menu.
void RS_MarkCollected(technology_t *tech)
Marks a give technology as collected.
technology_t * RS_GetTechForItem(const objDef_t *item)
Returns technology entry for an item.
bool RS_IsResearched_ptr(const technology_t *tech)
Checks whether an item is already researched.
@ RS_LINK_TECH
Definition cp_research.h:62
@ RS_LINK_ITEM
Definition cp_research.h:64
@ RS_LINK_TECH_NOT
Definition cp_research.h:63
@ RS_LINK_ANTIMATTER
Definition cp_research.h:69
#define ANTIMATTER_ITEM_ID
Definition cp_research.h:37
const char * UFO_TypeToName(const ufoType_t type)
Translate UFO type to name.
Definition cp_ufo.cpp:231
storedUFO_t * US_GetStoredUFOByIDX(const int idx)
Returns a stored ufo.
void US_RemoveStoredUFO(storedUFO_t *ufo)
Removes an UFO from the storage.
const objDef_t * INVSH_GetItemByID(const char *id)
Returns the item that belongs to the given id or nullptr if it wasn't found.
voidpf uLong offset
Definition ioapi.h:45
double GetDistanceOnGlobe(const vec2_t pos1, const vec2_t pos2)
Calculate distance on the geoscape.
Definition mathlib.cpp:171
QGL_EXTERN GLsizei const GLvoid * data
Definition r_gl.h:89
QGL_EXTERN GLuint index
Definition r_gl.h:110
QGL_EXTERN GLint i
Definition r_gl.h:113
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition r_gl.h:110
XML tag constants for savegame.
#define SAVE_PRODUCE_QUEUEIDX
#define SAVE_PRODUCE_AIRCRAFTID
#define SAVE_PRODUCE_ITEM
#define SAVE_PRODUCE_ITEMID
#define SAVE_PRODUCE_QUEUE
#define SAVE_PRODUCE_AMOUNT
#define SAVE_PRODUCE_PROGRESS
#define SAVE_PRODUCE_UFOIDX
#define SAVE_PRODUCE_PRODUCTION
#define Q_streq(a, b)
Definition shared.h:136
#define OBJZERO(obj)
Definition shared.h:178
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition shared.cpp:494
An aircraft with all it's data.
int productionCost
ufoType_t getUfoType() const
struct technology_s * tech
A base with all it's data.
Definition cp_base.h:84
int idx
Definition cp_base.h:85
char name[MAX_VAR]
Definition cp_base.h:86
vec3_t pos
Definition cp_base.h:91
Store capacities in base.
Definition cp_capacity.h:41
Defines all attributes of objects used in the inventory.
Definition inv_shared.h:264
int productionCost
Definition inv_shared.h:333
const char * id
Definition inv_shared.h:268
A production queue. Lists all items to be produced.
Definition cp_produce.h:91
struct production_s items[MAX_PRODUCTIONS]
Definition cp_produce.h:93
Holds all information for the production of one item-type.
Definition cp_produce.h:60
signed int amount
Definition cp_produce.h:66
productionData_t data
Definition cp_produce.h:62
bool creditMessage
Definition cp_produce.h:67
union productionData_t::productionItem_t data
union requirement_t::typelink_t link
requirementType_t type
Definition cp_research.h:74
requirement_t links[MAX_TECHLINKS]
Definition cp_research.h:88
Structure for stored UFOs.
struct components_s * comp
const aircraft_t * ufoTemplate
installation_t * installation
This is the technology parsed from research.ufo.
requirements_t requireForProduction
const struct aircraft_s * aircraft
Definition cp_produce.h:49
#define xmlNode_t
Definition xml.h:24