UFO: Alien Invasion
cp_produce.cpp
Go to the documentation of this file.
1 
7 /*
8 Copyright (C) 2002-2022 UFO: Alien Invasion.
9 
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation; either version 2
13 of the License, or (at your option) any later version.
14 
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 
19 See the GNU General Public License for more details.
20 
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, 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"
32 #include "cp_produce_callbacks.h"
33 #include "save/save_produce.h"
34 
40 static 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. */
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 
64 int 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 
100 int 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 
111 void 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  }
128  case RS_LINK_ANTIMATTER:
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 
147 int 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 
182 const 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 
234 production_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 
269  PR_SetUFODisassembly(prod);
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 
293  REMOVE_ELEM_ADJUST_IDX(queue->items, index, queue->numItems);
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;
323  PR_SetUFODisassembly(prod);
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;
332  PR_SetUFODisassembly(prod);
333  }
334 
335  /* insert item */
336  queue->items[newIndex] = saved;
337  queue->items[newIndex].idx = newIndex;
338  PR_SetUFODisassembly(&queue->items[newIndex]);
339 }
340 
345 void PR_QueueNext (base_t* base)
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 
360 static 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 
373 static void PR_ProductionRollBottom (base_t* base)
374 {
376  if (queue->numItems < 2)
377  return;
378 
379  PR_QueueMove(queue, 0, queue->numItems - 1);
380 }
381 
388 static 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 
420 static 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 
452 static 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 */
481  US_RemoveStoredUFO(ufo);
482 }
483 
490 int 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 
523 int 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 
556 void PR_ProductionRun (void)
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 
596 bool 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 
607 void 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 
640 bool PR_ItemIsProduceable (const objDef_t* item)
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 }
667 int PR_GetPrice (const int productionCost)
668 {
669  int price;
670  price = productionCost * ccs.curCampaign->componentRate;
671  return price;
672 }
680 {
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 {
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);
722  production_queue_t* pq;
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 
760  PR_SetUFODisassembly(prod);
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 
785 static 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 
803 bool PR_PostLoadInit (void)
804 {
805  return PR_PostLoadInitProgress();
806 }
xmlNode_t *IMPORT * XML_GetNode(xmlNode_t *parent, const char *name)
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.
Definition: cp_produce.cpp:234
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
#define SAVE_PRODUCE_AMOUNT
Definition: save_produce.h:36
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...
requirement_t links[MAX_TECHLINKS]
Definition: cp_research.h:88
Store capacities in base.
Definition: cp_capacity.h:41
bool RS_IsResearched_ptr(const technology_t *tech)
Checks whether an item is already researched.
const objDef_t * INVSH_GetItemByID(const char *id)
Returns the item that belongs to the given id or nullptr if it wasn&#39;t found.
Definition: inv_shared.cpp:282
Defines all attributes of objects used in the inventory.
Definition: inv_shared.h:264
bool B_GetBuildingStatus(const base_t *const base, const buildingType_t buildingType)
Get the status associated to a building.
Definition: cp_base.cpp:478
static bool PR_CheckFrame(base_t *base, production_t *prod)
Checks whether production can continue.
Definition: cp_produce.cpp:388
aircraft_t * AIR_NewAircraft(base_t *base, const aircraft_t *aircraftTemplate)
Places a new aircraft in the given base.
A base with all it&#39;s data.
Definition: cp_base.h:84
const char * PR_GetName(const productionData_t *data)
Definition: cp_produce.cpp:182
XML tag constants for savegame.
Holds all information for the production of one item-type.
Definition: cp_produce.h:59
void PR_UpdateRequiredItemsInBasestorage(base_t *base, int amount, const requirements_t *reqs)
Remove or add the required items from/to the a base.
Definition: cp_produce.cpp:111
#define _(String)
Definition: cl_shared.h:44
float componentRate
Definition: cp_campaign.h:201
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition: shared.cpp:494
int B_AddToStorage(base_t *base, const objDef_t *obj, int amount)
Add/remove items to/from the storage.
Definition: cp_base.cpp:2576
#define B_IsUnderAttack(base)
Definition: cp_base.h:53
#define CAP_Get(base, capacity)
Capacity macros.
Definition: cp_capacity.h:50
#define PR_GetProductionForBase(base)
Definition: cp_produce.h:96
#define REMOVE_ELEM_ADJUST_IDX(array, index, n)
Definition: common.h:395
static void PR_FinishProduction(base_t *base, production_t *prod)
Run actions on finishing production of one item/aircraft/UGV..
Definition: cp_produce.cpp:420
#define PR_IsDisassembly(prod)
Definition: cp_produce.h:75
int PR_IncreaseProduction(production_t *prod, int amount)
increases production amount if possible
Definition: cp_produce.cpp:490
#define SAVE_PRODUCE_QUEUEIDX
Definition: save_produce.h:30
char name[MAX_VAR]
Definition: cp_base.h:86
QGL_EXTERN GLsizei const GLvoid * data
Definition: r_gl.h:89
const aircraft_t * AIR_GetAircraft(const char *name)
Searches the global array of aircraft types for a given aircraft.
requirements_t requireForProduction
Definition: cp_research.h:181
union productionData_t::productionItem_t data
#define PR_SetData(dataPtr, typeVal, ptr)
Definition: cp_produce.h:80
#define MAX_PRODUCTION_AMOUNT
Definition: cp_produce.h:30
#define PR_IsItem(prod)
Definition: cp_produce.h:77
Structure for stored UFOs.
void PR_QueueNext(base_t *base)
Queues the next production in the queue.
Definition: cp_produce.cpp:345
#define SAVE_PRODUCE_ITEM
Definition: save_produce.h:32
const char * id
Definition: inv_shared.h:268
int E_CountHired(const base_t *const base, employeeType_t type)
Counts hired employees of a given type in a given base.
int idx
Definition: cp_base.h:85
#define xmlNode_t
Definition: xml.h:24
#define PR_IsReady(prod)
Definition: cp_produce.h:84
int PR_WorkersAvailable(const base_t *base)
Returns the numer of workers available to produce an item.
Definition: cp_produce.cpp:64
void US_RemoveStoredUFO(storedUFO_t *ufo)
Removes an UFO from the storage.
#define ERR_DROP
Definition: common.h:211
signed int amount
Definition: cp_produce.h:66
#define OBJZERO(obj)
Definition: shared.h:178
int PR_GetRemainingHours(const production_t *prod)
Calculates the remaining hours for a technology.
Definition: cp_produce.cpp:90
float produceRate
Definition: cp_campaign.h:197
base_t * B_GetNext(base_t *lastBase)
Iterates through founded bases.
Definition: cp_base.cpp:286
#define PR_IsProduction(prod)
Definition: cp_produce.h:78
void RS_MarkCollected(technology_t *tech)
Marks a give technology as collected.
const char *IMPORT * XML_GetString(xmlNode_t *parent, const char *name)
base_t * PR_ProductionBase(const production_t *production)
Returns the base pointer the production belongs to.
Definition: cp_produce.cpp:651
const cgame_import_t * cgi
int PR_GetPrice(const int productionCost)
Used in production costs (to allow reducing prices below 1x).
Definition: cp_produce.cpp:667
void CP_UpdateCredits(int credits)
Sets credits and update mn_credits cvar.
Header for production related stuff.
const char * UFO_TypeToName(const ufoType_t type)
Translate UFO type to name.
Definition: cp_ufo.cpp:231
ccs_t ccs
Definition: cp_campaign.cpp:63
int PR_GetProductionHours(const base_t *base, const productionData_t *prodData)
Calculates the production time (in hours) for a technology.
Definition: cp_produce.cpp:100
#define SAVE_PRODUCE_ITEMID
Definition: save_produce.h:33
Header file for menu related console command callbacks for production menu.
#define SAVE_PRODUCE_PROGRESS
Definition: save_produce.h:37
A production queue. Lists all items to be produced.
Definition: cp_produce.h:90
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
#define SAVE_PRODUCE_AIRCRAFTID
Definition: save_produce.h:34
xmlNode_t *IMPORT * XML_GetNextNode(xmlNode_t *current, xmlNode_t *parent, const char *name)
void PR_QueueDelete(base_t *base, production_queue_t *queue, int index)
Delete the selected entry from the queue.
Definition: cp_produce.cpp:281
int productionCost
Definition: inv_shared.h:333
ufoType_t getUfoType() const
Definition: cp_aircraft.h:180
const aircraft_t * ufoTemplate
static void PR_ProductionRollBottom(base_t *base)
moves the first production to the bottom of the list
Definition: cp_produce.cpp:373
char cp_messageBuffer[MAX_MESSAGE_TEXT]
Definition: cp_messages.cpp:33
QGL_EXTERN GLuint index
Definition: r_gl.h:110
static void PR_FinishDisassembly(base_t *base, production_t *prod)
Run actions on finishing disassembling of a ufo.
Definition: cp_produce.cpp:452
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...
Definition: cp_produce.cpp:40
productionData_t data
Definition: cp_produce.h:62
#define CAP_GetMax(base, capacity)
Definition: cp_capacity.h:51
storedUFO_t * US_GetStoredUFOByIDX(const int idx)
Returns a stored ufo.
An aircraft with all it&#39;s data.
Definition: cp_aircraft.h:115
struct technology_s * tech
Definition: cp_aircraft.h:163
technology_t * PR_GetTech(const productionData_t *data)
Definition: cp_produce.cpp:199
#define SAVE_PRODUCE_QUEUE
Definition: save_produce.h:29
#define MAX_PRODUCTIONS
Maximum number of productions queued in any one base.
Definition: cp_produce.h:28
static void PR_SetUFODisassembly(production_t *prod)
Definition: cp_produce.cpp:220
requirementType_t type
Definition: cp_research.h:74
int B_AntimatterInBase(const base_t *base)
returns the amount of antimatter stored in a base
Definition: cp_base.cpp:2613
bool PR_ProductionAllowed(const base_t *base)
Returns true if the current base is able to produce items.
Definition: cp_produce.cpp:596
int PR_GetRemainingMinutes(const production_t *prod)
Calculates the remaining time for a technology in minutes.
Definition: cp_produce.cpp:79
campaign_t * curCampaign
Definition: cp_campaign.h:378
static bool PR_PostLoadInitProgress(void)
Set percentDone values after loading the campaign.
Definition: cp_produce.cpp:785
QGL_EXTERN GLint i
Definition: r_gl.h:113
installation_t * installation
const struct aircraft_s * aircraft
Definition: cp_produce.h:49
bool creditMessage
Definition: cp_produce.h:67
This is the technology parsed from research.ufo.
Definition: cp_research.h:139
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition: r_gl.h:110
bool PR_LoadXML(xmlNode_t *p)
Load callback for xml savegames.
Definition: cp_produce.cpp:713
int PR_DecreaseProduction(production_t *prod, int amount)
decreases production amount
Definition: cp_produce.cpp:523
union requirement_t::typelink_t link
int B_AddAntimatter(base_t *base, int amount)
Manages antimatter (adding, removing) through Antimatter Storage Facility.
Definition: cp_base.cpp:2635
#define SAVE_PRODUCE_PRODUCTION
Definition: save_produce.h:27
Header file for single player campaign control.
#define PR_IsDataValid(dataPtr)
Definition: cp_produce.h:81
xmlNode_t *IMPORT * XML_AddNode(xmlNode_t *parent, const char *name)
#define PR_IsAircraft(prod)
Definition: cp_produce.h:76
int totalFrames
Definition: cp_produce.h:64
bool PR_ItemIsProduceable(const objDef_t *item)
check if an item is producable.
Definition: cp_produce.cpp:640
#define Q_streq(a, b)
Definition: shared.h:136
bool PR_SaveXML(xmlNode_t *p)
Save callback for savegames in XML Format.
Definition: cp_produce.cpp:679
int PR_RequirementsMet(int amount, const requirements_t *reqs, base_t *base)
Checks if the production requirements are met for a defined amount.
Definition: cp_produce.cpp:147
static const short MINUTES_PER_HOUR
Definition: DateTime.h:35
voidpf uLong offset
Definition: ioapi.h:45
#define MAX_BASES
Definition: cp_base.h:32
void PR_UpdateProductionCap(base_t *base, int workerChange)
Update the current capacity of Workshop.
Definition: cp_produce.cpp:607
#define PR_IsDisassemblyData(data)
Definition: cp_produce.h:70
technology_t * RS_GetTechForItem(const objDef_t *item)
Returns technology entry for an item.
vec3_t pos
Definition: cp_base.h:91
int credits
Definition: cp_campaign.h:243
#define PR_IsProductionData(data)
Definition: cp_produce.h:73
#define ANTIMATTER_ITEM_ID
Definition: cp_research.h:37
#define SAVE_PRODUCE_UFOIDX
Definition: save_produce.h:35
void PR_QueueMove(production_queue_t *queue, int index, int offset)
Moves the given queue item in the given direction.
Definition: cp_produce.cpp:308
#define COMP_ITEMCOUNT_SCALED
Definition: cp_component.h:30
struct storedUFO_s * ufo
Definition: cp_produce.h:50
bool PR_PostLoadInit(void)
actions to do with productions after loading a savegame
Definition: cp_produce.cpp:803
void PR_ProductionRun(void)
Checks whether an item is finished.
Definition: cp_produce.cpp:556
int productionCost
Definition: cp_aircraft.h:129
static void PR_EmptyQueue(base_t *base)
clears the production queue on a base
Definition: cp_produce.cpp:360
struct production_s items[MAX_PRODUCTIONS]
Definition: cp_produce.h:93
struct components_s * comp
static void PR_ResetUFODisassembly(production_t *prod)
Definition: cp_produce.cpp:213
double GetDistanceOnGlobe(const vec2_t pos1, const vec2_t pos2)
Calculate distance on the geoscape.
Definition: mathlib.cpp:171