00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "../cl_shared.h"
00027 #include "../cl_inventory.h"
00028 #include "../ui/ui_main.h"
00029 #include "../ui/ui_popup.h"
00030 #include "cp_campaign.h"
00031 #include "cp_market.h"
00032 #include "cp_ufo.h"
00033 #include "cp_produce.h"
00034 #include "cp_produce_callbacks.h"
00035
00040 static int produceCategory = FILTER_S_PRIMARY;
00041
00043 static production_t *selectedProduction = NULL;
00044
00046 static linkedList_t *productionItemList;
00047
00049 static objDef_t *selectedItem = NULL;
00050 static storedUFO_t *selectedDisassembly = NULL;
00051 static aircraft_t *selectedAircraft = NULL;
00052
00054 static const int QUEUE_SPACERS = 2;
00055
00059 static void PR_ClearSelected (void)
00060 {
00061 selectedProduction = NULL;
00062 selectedAircraft = NULL;
00063 selectedItem = NULL;
00064 selectedDisassembly = NULL;
00065 }
00066
00071 static void PR_UpdateProductionList (const base_t* base)
00072 {
00073 int i, j, counter;
00074 linkedList_t *productionList = NULL;
00075 linkedList_t *productionQueued = NULL;
00076 linkedList_t *productionAmount = NULL;
00077 const production_queue_t *queue;
00078
00079 assert(base);
00080
00081 queue = &ccs.productions[base->idx];
00082
00083
00084 for (i = 0; i < queue->numItems; i++) {
00085 const production_t *prod = &queue->items[i];
00086 if (prod->item) {
00087 const objDef_t *od = prod->item;
00088 LIST_AddString(&productionList, va("%s", _(od->name)));
00089 LIST_AddString(&productionAmount, va("%i", base->storage.numItems[prod->item->idx]));
00090 LIST_AddString(&productionQueued, va("%i", prod->amount));
00091 } else if (prod->aircraft) {
00092 const aircraft_t *aircraftTemplate = prod->aircraft;
00093 LIST_AddString(&productionList, va("%s", _(aircraftTemplate->name)));
00094 for (j = 0, counter = 0; j < ccs.numAircraft; j++) {
00095 const aircraft_t *aircraftBase = AIR_AircraftGetFromIDX(j);
00096 assert(aircraftBase);
00097 if (aircraftBase->homebase == base && aircraftBase->tpl == aircraftTemplate)
00098 counter++;
00099 }
00100 LIST_AddString(&productionAmount, va("%i", counter));
00101 LIST_AddString(&productionQueued, va("%i", prod->amount));
00102 } else if (prod->ufo) {
00103 const storedUFO_t *ufo = prod->ufo;
00104
00105 LIST_AddString(&productionList, va("%s (%.0f%%)", UFO_TypeToName(ufo->ufoTemplate->ufotype), ufo->condition * 100));
00106 LIST_AddString(&productionAmount, va("%i", US_UFOsInStorage(ufo->ufoTemplate, ufo->installation)));
00107 LIST_AddString(&productionQueued, "1");
00108 }
00109 }
00110
00111
00112 for (i = 0; i < QUEUE_SPACERS; i++) {
00113 LIST_AddString(&productionList, "");
00114 LIST_AddString(&productionAmount, "");
00115 LIST_AddString(&productionQueued, "");
00116 }
00117
00118 LIST_Delete(&productionItemList);
00119
00120
00121 if (produceCategory == FILTER_DISASSEMBLY) {
00122 storedUFO_t *ufo = NULL;
00124 while ((ufo = US_GetNext(ufo)) != NULL) {
00125
00126 if (ufo->status != SUFO_STORED)
00127 continue;
00128
00129 if (!RS_IsResearched_ptr(ufo->ufoTemplate->tech))
00130 continue;
00131
00132 if (ufo->disassembly)
00133 continue;
00134
00135 LIST_AddPointer(&productionItemList, ufo);
00136 LIST_AddString(&productionList, va("%s (%.0f%%)", UFO_TypeToName(ufo->ufoTemplate->ufotype), ufo->condition * 100));
00137 LIST_AddString(&productionAmount, va("%i", US_UFOsInStorage(ufo->ufoTemplate, ufo->installation)));
00138 LIST_AddString(&productionQueued, "");
00139 }
00140 } else if (produceCategory == FILTER_AIRCRAFT) {
00141 for (i = 0; i < ccs.numAircraftTemplates; i++) {
00142 aircraft_t *aircraftTemplate = &ccs.aircraftTemplates[i];
00143
00144 if (AIR_IsUFO(aircraftTemplate))
00145 continue;
00146 if (!aircraftTemplate->tech) {
00147 Com_Printf("PR_UpdateProductionList: no technology for craft %s!\n", aircraftTemplate->id);
00148 continue;
00149 }
00150
00151 Com_DPrintf(DEBUG_CLIENT, "air: %s ufotype: %i tech: %s time: %i\n", aircraftTemplate->id,
00152 aircraftTemplate->ufotype, aircraftTemplate->tech->id, aircraftTemplate->tech->produceTime);
00153
00154 if (aircraftTemplate->tech->produceTime > 0 && RS_IsResearched_ptr(aircraftTemplate->tech)) {
00155 LIST_AddPointer(&productionItemList, aircraftTemplate);
00156
00157 LIST_AddString(&productionList, va("%s", _(aircraftTemplate->name)));
00158 for (j = 0, counter = 0; j < ccs.numAircraft; j++) {
00159 const aircraft_t *aircraftBase = AIR_AircraftGetFromIDX(j);
00160 assert(aircraftBase);
00161 if (aircraftBase->homebase == base && aircraftBase->tpl == aircraftTemplate)
00162 counter++;
00163 }
00164 LIST_AddString(&productionAmount, va("%i", counter));
00165 LIST_AddString(&productionQueued, "");
00166 }
00167 }
00168 } else {
00169 objDef_t *od;
00170 for (i = 0, od = csi.ods; i < csi.numODs; i++, od++) {
00171 const technology_t *tech;
00172 if (od->isVirtual)
00173 continue;
00174 tech = RS_GetTechForItem(od);
00175
00176
00177 if (RS_IsResearched_ptr(tech) && PR_ItemIsProduceable(od) && INV_ItemMatchesFilter(od, produceCategory)) {
00178 LIST_AddPointer(&productionItemList, od);
00179
00180 LIST_AddString(&productionList, va("%s", _(od->name)));
00181 LIST_AddString(&productionAmount, va("%i", base->storage.numItems[i]));
00182 LIST_AddString(&productionQueued, "");
00183 }
00184 }
00185 }
00186
00187
00188 UI_RegisterLinkedListText(TEXT_PRODUCTION_LIST, productionList);
00189
00190 UI_RegisterLinkedListText(TEXT_PRODUCTION_AMOUNT, productionAmount);
00191
00192 UI_RegisterLinkedListText(TEXT_PRODUCTION_QUEUED, productionQueued);
00193 }
00194
00202 static void PR_ItemProductionInfo (const base_t *base, const objDef_t *od, const float percentDone)
00203 {
00204 static char productionInfo[512];
00205
00206 assert(base);
00207 assert(od);
00208
00209
00210 if (!PR_ItemIsProduceable(od)) {
00211 Com_sprintf(productionInfo, sizeof(productionInfo), _("No item selected"));
00212 Cvar_Set("mn_item", "");
00213 } else {
00214 const technology_t *tech = RS_GetTechForItem(od);
00215 const float prodPerHour = PR_CalculateProductionPercentDone(base, tech, NULL);
00216
00217 const int time = ceil((1.0f - percentDone) / prodPerHour);
00218
00219 Com_sprintf(productionInfo, sizeof(productionInfo), "%s\n", _(od->name));
00220 Q_strcat(productionInfo, va(_("Costs per item\t%i c\n"), (od->price * PRODUCE_FACTOR / PRODUCE_DIVISOR)),
00221 sizeof(productionInfo));
00222 Q_strcat(productionInfo, va(_("Production time\t%ih\n"), time), sizeof(productionInfo));
00223 Q_strcat(productionInfo, va(_("Item size\t%i\n"), od->size), sizeof(productionInfo));
00224 Cvar_Set("mn_item", od->id);
00225 }
00226 UI_RegisterText(TEXT_PRODUCTION_INFO, productionInfo);
00227 }
00228
00236 static void PR_DisassemblyInfo (const base_t *base, const storedUFO_t *ufo, float percentDone)
00237 {
00238 static char productionInfo[512];
00239 int time, i;
00240 float prodPerHour;
00241
00242 assert(base);
00243 assert(ufo);
00244 assert(ufo->ufoTemplate);
00245 assert(ufo->ufoTemplate->tech);
00246
00247 prodPerHour = PR_CalculateProductionPercentDone(base, ufo->ufoTemplate->tech, ufo);
00248
00249 assert(prodPerHour > 0);
00250 time = ceil((1.0f - percentDone) / prodPerHour);
00251
00252 Com_sprintf(productionInfo, sizeof(productionInfo), "%s (%.0f%%) - %s\n", _(UFO_TypeToName(ufo->ufoTemplate->ufotype)), ufo->condition * 100, _("Disassembly"));
00253 Q_strcat(productionInfo, va(_("Stored at: %s\n"), ufo->installation->name), sizeof(productionInfo));
00254 Q_strcat(productionInfo, va(_("Disassembly time: %ih\n"), time), sizeof(productionInfo));
00255 Q_strcat(productionInfo, _("Components:\n"), sizeof(productionInfo));
00256
00257 for (i = 0; i < ufo->comp->numItemtypes; i++) {
00258 const objDef_t *compOd = ufo->comp->items[i];
00259 const int amount = (ufo->condition < 1 && ufo->comp->itemAmount2[i] != COMP_ITEMCOUNT_SCALED) ? ufo->comp->itemAmount2[i] : round(ufo->comp->itemAmount[i] * ufo->condition);
00260
00261 assert(compOd);
00262 if (amount == 0)
00263 continue;
00264
00265 Q_strcat(productionInfo, va(" %s (%i)\n", _(compOd->name), amount), sizeof(productionInfo));
00266 }
00267 UI_RegisterText(TEXT_PRODUCTION_INFO, productionInfo);
00268 Cvar_Set("mn_item", ufo->id);
00269 }
00270
00276 static void PR_AircraftInfo (const base_t *base, const aircraft_t *aircraftTemplate, float percentDone)
00277 {
00278 static char productionInfo[512];
00279 int time;
00280 float prodPerHour;
00281 assert(aircraftTemplate);
00282
00283 prodPerHour = PR_CalculateProductionPercentDone(base, aircraftTemplate->tech, NULL);
00284
00285 assert(prodPerHour > 0);
00286 time = ceil((1.0f - percentDone) / prodPerHour);
00287
00288 Com_sprintf(productionInfo, sizeof(productionInfo), "%s\n", _(aircraftTemplate->name));
00289 Q_strcat(productionInfo, va(_("Production costs\t%i c\n"), (aircraftTemplate->price * PRODUCE_FACTOR / PRODUCE_DIVISOR)),
00290 sizeof(productionInfo));
00291 assert(aircraftTemplate->tech);
00292 Q_strcat(productionInfo, va(_("Production time\t%ih\n"), time), sizeof(productionInfo));
00293 UI_RegisterText(TEXT_PRODUCTION_INFO, productionInfo);
00294 Cvar_Set("mn_item", aircraftTemplate->id);
00295 }
00296
00304 static void PR_ProductionInfo (const base_t *base)
00305 {
00306 if (selectedProduction) {
00307 production_t *prod = selectedProduction;
00308 UI_ExecuteConfunc("prod_taskselected");
00309 if (prod->aircraft) {
00310 PR_AircraftInfo(base, prod->aircraft, prod->percentDone);
00311 UI_ExecuteConfunc("amountsetter enable");
00312 } else if (prod->item) {
00313 PR_ItemProductionInfo(base, prod->item, prod->percentDone);
00314 UI_ExecuteConfunc("amountsetter enable");
00315 } else if (prod->ufo) {
00316 PR_DisassemblyInfo(base, prod->ufo, prod->percentDone);
00317 UI_ExecuteConfunc("amountsetter disable");
00318 } else {
00319 Com_Error(ERR_DROP, "PR_ProductionInfo: Selected production is not item nor aircraft nor ufo.\n");
00320 }
00321 Cvar_SetValue("mn_production_amount", selectedProduction->amount);
00322 } else {
00323 if (!(selectedAircraft || selectedItem || selectedDisassembly)) {
00324 UI_ExecuteConfunc("prod_nothingselected");
00325 if (produceCategory == FILTER_AIRCRAFT)
00326 UI_RegisterText(TEXT_PRODUCTION_INFO, _("No aircraft selected."));
00327 else
00328 UI_RegisterText(TEXT_PRODUCTION_INFO, _("No item selected"));
00329 Cvar_Set("mn_item", "");
00330 } else {
00331 UI_ExecuteConfunc("prod_availableselected");
00332 if (selectedAircraft) {
00333 PR_AircraftInfo(base, selectedAircraft, 0.0);
00334 } else if (selectedItem) {
00335 PR_ItemProductionInfo(base, selectedItem, 0.0);
00336 } else if (selectedDisassembly) {
00337 PR_DisassemblyInfo(base, selectedDisassembly, 0.0);
00338 }
00339 }
00340 }
00341 }
00342
00347 static void PR_ProductionListRightClick_f (void)
00348 {
00349 int num;
00350 production_queue_t *queue;
00351 base_t *base = B_GetCurrentSelectedBase();
00352
00353
00354 if (!base)
00355 return;
00356
00357 queue = &ccs.productions[base->idx];
00358
00359
00360 if (Cmd_Argc() < 2) {
00361 Com_Printf("Usage: %s <arg>\n", Cmd_Argv(0));
00362 return;
00363 }
00364
00365
00366 num = atoi(Cmd_Argv(1));
00367
00368
00369 if (num < queue->numItems && num >= 0) {
00370 selectedProduction = &queue->items[num];
00371 if (selectedProduction->aircraft) {
00372 assert(selectedProduction->aircraft->tech);
00373 UP_OpenWith(selectedProduction->aircraft->tech->id);
00374 } else if (selectedProduction->item) {
00375 const objDef_t *od = selectedProduction->item;
00376 const technology_t *tech = RS_GetTechForItem(od);
00377 UP_OpenWith(tech->id);
00378 } else if (selectedProduction->ufo) {
00379 const aircraft_t *ufoTemplate = selectedProduction->ufo->ufoTemplate;
00380 const technology_t *tech = ufoTemplate->tech;
00381 UP_OpenWith(tech->id);
00382 }
00383 } else if (num >= queue->numItems + QUEUE_SPACERS) {
00384
00385 const int idx = num - queue->numItems - QUEUE_SPACERS;
00386
00387 if (produceCategory == FILTER_AIRCRAFT) {
00388 const aircraft_t *aircraftTemplate = (aircraft_t*)LIST_GetByIdx(productionItemList, idx);
00389
00390
00391
00392 if (aircraftTemplate && aircraftTemplate->tech)
00393 UP_OpenWith(aircraftTemplate->tech->id);
00394 } else if (produceCategory == FILTER_DISASSEMBLY) {
00395 storedUFO_t *ufo = (storedUFO_t*)LIST_GetByIdx(productionItemList, idx);
00396 if (ufo && ufo->ufoTemplate && ufo->ufoTemplate->tech) {
00397 UP_OpenWith(ufo->ufoTemplate->tech->id);
00398 }
00399 } else {
00400 objDef_t *od = (objDef_t*)LIST_GetByIdx(productionItemList, idx);
00401 const technology_t *tech = RS_GetTechForItem(od);
00402
00403
00404 if (RS_IsResearched_ptr(tech) && INV_ItemMatchesFilter(od, produceCategory)) {
00405 PR_ClearSelected();
00406 selectedItem = od;
00407 UP_OpenWith(tech->id);
00408 return;
00409 }
00410 }
00411 }
00412 #ifdef DEBUG
00413 else
00414 Com_DPrintf(DEBUG_CLIENT, "PR_ProductionListRightClick_f: Click on spacer %i\n", num);
00415 #endif
00416 }
00417
00423 static void PR_ProductionListClick_f (void)
00424 {
00425 int num;
00426 production_queue_t *queue;
00427 base_t *base = B_GetCurrentSelectedBase();
00428
00429
00430 if (!base)
00431 return;
00432
00433 queue = &ccs.productions[base->idx];
00434
00435
00436 if (Cmd_Argc() < 2) {
00437 Com_Printf("Usage: %s <arg>\n", Cmd_Argv(0));
00438 return;
00439 }
00440
00441
00442 num = atoi(Cmd_Argv(1));
00443
00444
00445 if (num < queue->numItems && num >= 0) {
00446 selectedProduction = &queue->items[num];
00447 PR_ProductionInfo(base);
00448 } else if (num >= queue->numItems + QUEUE_SPACERS) {
00449
00450 const int idx = num - queue->numItems - QUEUE_SPACERS;
00451
00452 if (produceCategory == FILTER_DISASSEMBLY) {
00453 storedUFO_t *ufo = (storedUFO_t*)LIST_GetByIdx(productionItemList, idx);
00454
00455 PR_ClearSelected();
00456 selectedDisassembly = ufo;
00457
00458 PR_ProductionInfo(base);
00459 } else if (produceCategory == FILTER_AIRCRAFT) {
00460 aircraft_t *aircraftTemplate = (aircraft_t*)LIST_GetByIdx(productionItemList, idx);
00461 if (!aircraftTemplate) {
00462 Com_DPrintf(DEBUG_CLIENT, "PR_ProductionListClick_f: No item found at the list-position %i!\n", idx);
00463 return;
00464 }
00465
00466
00467
00468 if (aircraftTemplate->tech && aircraftTemplate->tech->produceTime >= 0
00469 && RS_IsResearched_ptr(aircraftTemplate->tech)) {
00470 PR_ClearSelected();
00471 selectedAircraft = aircraftTemplate;
00472 PR_ProductionInfo(base);
00473 }
00474 } else {
00475 objDef_t *od = (objDef_t*)LIST_GetByIdx(productionItemList, idx);
00476 const technology_t *tech = RS_GetTechForItem(od);
00477
00478
00479 if (RS_IsResearched_ptr(tech) && PR_ItemIsProduceable(od) && INV_ItemMatchesFilter(od, produceCategory)) {
00480 PR_ClearSelected();
00481 selectedItem = od;
00482 PR_ProductionInfo(base);
00483 }
00484 }
00485 }
00486 }
00487
00491 static void PR_ProductionType_f (void)
00492 {
00493 int cat;
00494 base_t *base = B_GetCurrentSelectedBase();
00495
00496 if (Cmd_Argc() < 2) {
00497 Com_Printf("Usage: %s <category>\n", Cmd_Argv(0));
00498 return;
00499 }
00500
00501 cat = INV_GetFilterTypeID(Cmd_Argv(1));
00502
00503
00504 if (cat < 0 || cat >= MAX_FILTERTYPES)
00505 cat = FILTER_S_PRIMARY;
00506
00507
00508 if (!base)
00509 return;
00510
00511 produceCategory = cat;
00512 Cvar_Set("mn_itemtype", INV_GetFilterType(produceCategory));
00513
00514
00515 PR_UpdateProductionList(base);
00516
00517
00518 selectedItem = NULL;
00519 selectedDisassembly = NULL;
00520 selectedAircraft = NULL;
00521
00522
00523 if (LIST_Count(productionItemList) > 0) {
00524 if (produceCategory == FILTER_AIRCRAFT)
00525 selectedAircraft = (aircraft_t*)LIST_GetByIdx(productionItemList, 0);
00526 else if (produceCategory == FILTER_DISASSEMBLY)
00527 selectedDisassembly = (storedUFO_t*)LIST_GetByIdx(productionItemList, 0);
00528 else
00529 selectedItem = (objDef_t*)LIST_GetByIdx(productionItemList, 0);
00530 }
00531
00532 if (!selectedProduction)
00533 UI_ExecuteConfunc("prod_selectline %i", ccs.productions[base->idx].numItems + QUEUE_SPACERS);
00534
00535
00536 PR_ProductionInfo(base);
00537 }
00538
00543 static void PR_ProductionList_f (void)
00544 {
00545 char tmpbuf[MAX_VAR];
00546 int numWorkshops;
00547 base_t *base = B_GetCurrentSelectedBase();
00548
00549
00550 if (!base)
00551 return;
00552
00553 numWorkshops = max(0, B_GetNumberOfBuildingsInBaseByBuildingType(base, B_WORKSHOP));
00554
00555 Cvar_SetValue("mn_production_limit", MAX_PRODUCTIONS_PER_WORKSHOP * numWorkshops);
00556 Cvar_SetValue("mn_production_basecap", base->capacities[CAP_WORKSPACE].max);
00557
00558
00559 PR_UpdateProductionCap(base);
00560
00561 Com_sprintf(tmpbuf, sizeof(tmpbuf), "%i/%i",
00562 base->capacities[CAP_WORKSPACE].cur,
00563 E_CountHired(base, EMPL_WORKER));
00564 Cvar_Set("mn_production_workers", tmpbuf);
00565
00566 Com_sprintf(tmpbuf, sizeof(tmpbuf), "%i/%i",
00567 base->capacities[CAP_ITEMS].cur,
00568 base->capacities[CAP_ITEMS].max);
00569 Cvar_Set("mn_production_storage", tmpbuf);
00570
00571 PR_ClearSelected();
00572 }
00573
00577 static void PR_ProductionIncrease_f (void)
00578 {
00579 production_queue_t *queue;
00580 production_t *prod;
00581 base_t *base = B_GetCurrentSelectedBase();
00582 technology_t *tech = NULL;
00583 int amount = 1;
00584 int producibleAmount;
00585 static char productionPopup[UI_MAX_SMALLTEXTLEN];
00586
00587 if (!base)
00588 return;
00589
00590 if (!(selectedProduction || selectedAircraft || selectedItem || selectedDisassembly))
00591 return;
00592
00593 if (Cmd_Argc() == 2)
00594 amount = atoi(Cmd_Argv(1));
00595
00596 queue = &ccs.productions[base->idx];
00597
00598 if (selectedProduction) {
00599 prod = selectedProduction;
00600
00601
00602 if (prod->ufo)
00603 return;
00604
00605 if (prod->aircraft) {
00606
00607 if (AIR_CalculateHangarStorage(prod->aircraft, base, 0) <= 0) {
00608 UI_Popup(_("Hangars not ready"), _("You cannot queue aircraft.\nNo free space in hangars.\n"));
00609 Cvar_SetValue("mn_production_amount", prod->amount);
00610 return;
00611 }
00612 }
00613
00614
00615 if (prod->amount + amount > MAX_PRODUCTION_AMOUNT) {
00616 amount = max(0, MAX_PRODUCTION_AMOUNT - prod->amount);
00617 }
00618 if (amount == 0) {
00619 Cvar_SetValue("mn_production_amount", prod->amount);
00620 return;
00621 }
00622
00623 if (prod->item) {
00624 tech = RS_GetTechForItem(prod->item);
00625 } else if (prod->aircraft) {
00626 tech = prod->aircraft->tech;
00627 }
00628 assert(tech);
00629
00630 producibleAmount = PR_RequirementsMet(amount, &tech->requireForProduction, base);
00631 if (producibleAmount == 0) {
00632 UI_Popup(_("Not enough materials"), _("You don't have the materials needed for producing more of this item.\n"));
00633 Cvar_SetValue("mn_production_amount", prod->amount);
00634 return;
00635 } else if (amount != producibleAmount) {
00636 Com_sprintf(productionPopup, lengthof(productionPopup), _("You don't have enough material to produce all (%i) additional items. Only %i could be added."), amount, producibleAmount);
00637 UI_Popup(_("Not enough material!"), productionPopup);
00638 }
00639
00640 PR_IncreaseProduction(prod, producibleAmount);
00641 Cvar_SetValue("mn_production_amount", prod->amount);
00642 } else {
00643 const char *name = NULL;
00644
00645
00646 if (PR_QueueFreeSpace(queue) <= 0) {
00647 UI_Popup(_("Not enough workshops"), _("You cannot queue more items.\nBuild more workshops.\n"));
00648 return;
00649 }
00650
00651 if (selectedItem) {
00652 tech = RS_GetTechForItem(selectedItem);
00653 name = selectedItem->name;
00654 } else if (selectedAircraft) {
00655 tech = selectedAircraft->tech;
00656 name = selectedAircraft->name;
00657 } else if (selectedDisassembly) {
00658 assert(selectedDisassembly->ufoTemplate);
00659 tech = selectedDisassembly->ufoTemplate->tech;
00660 name = selectedDisassembly->ufoTemplate->name;
00661 amount = 1;
00662 }
00663 assert(tech);
00664 assert(name);
00665
00666 producibleAmount = PR_RequirementsMet(amount, &tech->requireForProduction, base);
00667 if (producibleAmount == 0) {
00668 UI_Popup(_("Not enough materials"), _("You don't have the materials needed for producing this item.\n"));
00669 return;
00670 } else if (amount != producibleAmount) {
00671 Com_sprintf(productionPopup, lengthof(productionPopup), _("You don't have enough material to produce all (%i) items. Production will continue with a reduced (%i) number."), amount, producibleAmount);
00672 UI_Popup(_("Not enough material!"), productionPopup);
00673 }
00679 if (selectedAircraft && AIR_CalculateHangarStorage(selectedAircraft, base, 0) <= 0) {
00680 UI_Popup(_("Hangars not ready"), _("You cannot queue aircraft.\nNo free space in hangars.\n"));
00681 return;
00682 }
00683
00684
00685 prod = PR_QueueNew(base, queue, selectedItem, selectedAircraft, selectedDisassembly, producibleAmount);
00686
00688 if (!prod)
00689 return;
00690
00691
00692 UI_ExecuteConfunc("prod_selectline %i", prod->idx);
00693 PR_ClearSelected();
00694 selectedProduction = &queue->items[queue->numItems - 1];
00695
00696
00697 Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("Production of %s started"), _(name));
00698 MSO_CheckAddNewMessage(NT_PRODUCTION_STARTED, _("Production started"), cp_messageBuffer, qfalse, MSG_PRODUCTION, tech);
00699 }
00700
00701 PR_ProductionInfo(base);
00702 PR_UpdateProductionList(base);
00703 }
00704
00708 static void PR_ProductionStop_f (void)
00709 {
00710 production_queue_t *queue;
00711 base_t *base = B_GetCurrentSelectedBase();
00712 int prodIDX;
00713
00714 if (!base || !selectedProduction)
00715 return;
00716
00717 prodIDX = selectedProduction->idx;
00718 queue = &ccs.productions[base->idx];
00719
00720 PR_QueueDelete(base, queue, prodIDX);
00721
00722 if (queue->numItems == 0) {
00723 selectedProduction = NULL;
00724 UI_ExecuteConfunc("prod_selectline -1");
00725 } else if (prodIDX >= queue->numItems) {
00726 selectedProduction = &queue->items[queue->numItems - 1];
00727 UI_ExecuteConfunc("prod_selectline %i", prodIDX);
00728 }
00729
00730 PR_ProductionInfo(base);
00731 PR_UpdateProductionList(base);
00732 }
00733
00737 static void PR_ProductionDecrease_f (void)
00738 {
00739 int amount = 1;
00740 base_t *base = B_GetCurrentSelectedBase();
00741 production_t *prod = selectedProduction;
00742
00743 if (Cmd_Argc() == 2)
00744 amount = atoi(Cmd_Argv(1));
00745
00746 if (!prod)
00747 return;
00748
00749 if (prod->amount <= amount) {
00750 PR_ProductionStop_f();
00751 return;
00752 }
00753
00755 PR_DecreaseProduction(prod, amount);
00756
00757 if (base) {
00758 PR_ProductionInfo(base);
00759 PR_UpdateProductionList(base);
00760 }
00761 }
00762
00766 static void PR_ProductionChange_f (void)
00767 {
00768 int amount;
00769
00770 if (!(selectedProduction || selectedAircraft || selectedItem || selectedDisassembly))
00771 return;
00772
00773 if (Cmd_Argc() != 2) {
00774 Com_Printf("Usage: %s <diff> : change the production amount\n", Cmd_Argv(0));
00775 return;
00776 }
00777
00778 amount = atoi(Cmd_Argv(1));
00779 if (amount > 0) {
00780 Cbuf_AddText(va("prod_inc %i\n", amount));
00781 } else {
00782 Cbuf_AddText(va("prod_dec %i\n", -amount));
00783 }
00784 }
00785
00789 static void PR_ProductionUp_f (void)
00790 {
00791 production_queue_t *queue;
00792 base_t *base = B_GetCurrentSelectedBase();
00793
00794 if (!base || !selectedProduction)
00795 return;
00796
00797
00798 if (selectedProduction->idx == 0)
00799 return;
00800
00801 queue = &ccs.productions[base->idx];
00802 PR_QueueMove(queue, selectedProduction->idx, -1);
00803
00804 selectedProduction = &queue->items[selectedProduction->idx - 1];
00805 UI_ExecuteConfunc("prod_selectline %i", selectedProduction->idx);
00806 PR_UpdateProductionList(base);
00807 }
00808
00812 static void PR_ProductionDown_f (void)
00813 {
00814 production_queue_t *queue;
00815 base_t *base = B_GetCurrentSelectedBase();
00816
00817 if (!base || !selectedProduction)
00818 return;
00819
00820 queue = &ccs.productions[base->idx];
00821
00822 if (selectedProduction->idx >= queue->numItems - 1)
00823 return;
00824
00825 PR_QueueMove(queue, selectedProduction->idx, 1);
00826
00827 selectedProduction = &queue->items[selectedProduction->idx + 1];
00828 UI_ExecuteConfunc("prod_selectline %i", selectedProduction->idx);
00829 PR_UpdateProductionList(base);
00830 }
00831
00832 void PR_InitCallbacks (void)
00833 {
00834 Cmd_AddCommand("prod_init", PR_ProductionList_f, NULL);
00835 Cmd_AddCommand("prod_type", PR_ProductionType_f, NULL);
00836 Cmd_AddCommand("prod_up", PR_ProductionUp_f, "Move production item up in the queue");
00837 Cmd_AddCommand("prod_down", PR_ProductionDown_f, "Move production item down in the queue");
00838 Cmd_AddCommand("prod_change", PR_ProductionChange_f, "Change production amount");
00839 Cmd_AddCommand("prod_inc", PR_ProductionIncrease_f, "Increase production amount");
00840 Cmd_AddCommand("prod_dec", PR_ProductionDecrease_f, "Decrease production amount");
00841 Cmd_AddCommand("prod_stop", PR_ProductionStop_f, "Stop production");
00842 Cmd_AddCommand("prodlist_rclick", PR_ProductionListRightClick_f, NULL);
00843 Cmd_AddCommand("prodlist_click", PR_ProductionListClick_f, NULL);
00844 }
00845
00846 void PR_ShutdownCallbacks (void)
00847 {
00848 Cmd_RemoveCommand("prod_init");
00849 Cmd_RemoveCommand("prod_type");
00850 Cmd_RemoveCommand("prod_up");
00851 Cmd_RemoveCommand("prod_down");
00852 Cmd_RemoveCommand("prod_change");
00853 Cmd_RemoveCommand("prod_inc");
00854 Cmd_RemoveCommand("prod_dec");
00855 Cmd_RemoveCommand("prod_stop");
00856 Cmd_RemoveCommand("prodlist_rclick");
00857 Cmd_RemoveCommand("prodlist_click");
00858 }