00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "../cl_shared.h"
00026 #include "cp_campaign.h"
00027 #include "cp_transfer_callbacks.h"
00028 #include "cp_transfer.h"
00029 #include "../ui/ui_main.h"
00030 #include "../ui/ui_popup.h"
00031 #include "../ui/ui_data.h"
00032
00036 static const char* transferTypeIDs[] = {
00037 "item",
00038 "employee",
00039 "alien",
00040 "aircraft"
00041 };
00042 CASSERT(lengthof(transferTypeIDs) == TRANS_TYPE_MAX);
00043
00045 static transferData_t td;
00046
00048 static const int MAX_TR_FACTORS = 500;
00050 static const int MAX_TRANSLIST_MENU_ENTRIES = 21;
00051
00056 static int TR_CountStunnedAliensInCargo (const aircraft_t *transferAircraft)
00057 {
00058 int stunnedAliens = 0;
00059 const aliensTmp_t *cargo = AL_GetAircraftAlienCargo(transferAircraft);
00060
00061 if (cargo) {
00062 int i;
00063 for (i = 0; i < MAX_CARGO; i++)
00064 stunnedAliens += cargo[i].amountAlive;
00065 }
00066 return stunnedAliens;
00067 }
00068
00074 static void TR_TransferBaseListClick_f (void)
00075 {
00076 int num;
00077 base_t *base;
00078
00079 assert(td.transferStartAircraft);
00080
00081 if (Cmd_Argc() < 2) {
00082 Com_Printf("Usage: %s <base index>\n", Cmd_Argv(0));
00083 return;
00084 }
00085
00086 num = atoi(Cmd_Argv(1));
00087 base = B_GetFoundedBaseByIDX(num);
00088 if (!base) {
00089 Com_Printf("TR_TransferBaseListClick_f: baseIdx %i doesn't exist.\n", num);
00090 return;
00091 }
00092
00093 TR_TransferAlienAfterMissionStart(base, td.transferStartAircraft);
00094 }
00095
00100 static void TR_TransferAliensFromMission_f (void)
00101 {
00102 const vec4_t green = {0.0f, 1.0f, 0.0f, 0.8f};
00103 const vec4_t yellow = {1.0f, 0.874f, 0.294f, 1.0f};
00104 const vec4_t red = {1.0f, 0.0f, 0.0f, 0.8f};
00105 int i;
00106 aircraft_t *aircraft;
00107 int stunnedAliens;
00108 uiNode_t *baseList = NULL;
00109
00110 if (Cmd_Argc() < 2) {
00111 Com_Printf("Usage: %s <aircraft index>\n", Cmd_Argv(0));
00112 return;
00113 }
00114
00115 i = atoi(Cmd_Argv(1));
00116 aircraft = AIR_AircraftGetFromIDX(i);
00117 if (!aircraft) {
00118 Com_Printf("Usage: No aircraft with index %i\n", i);
00119 return;
00120 }
00121
00122 stunnedAliens = TR_CountStunnedAliensInCargo(aircraft);
00123
00124
00125 td.transferStartAircraft = aircraft;
00126
00127 for (i = 0; i < ccs.numBases; i++) {
00128 base_t *base = B_GetFoundedBaseByIDX(i);
00129 const char* string;
00130 uiNode_t *option;
00131 int freeSpace;
00132
00133 if (!base)
00134 continue;
00135 if (!AC_ContainmentAllowed(base))
00136 continue;
00137 freeSpace = B_FreeCapacity(base, CAP_ALIENS);
00138
00139 string = va(ngettext("(can host %i live alien)", "(can host %i live aliens)", freeSpace), freeSpace);
00140 string = va("%s %s", base->name, string);
00141 option = UI_AddOption(&baseList, va("base%i", base->idx), string, va("%i", base->idx));
00142
00144 if (freeSpace >= stunnedAliens) {
00145 Vector4Copy(green, option->color);
00146
00147 } else if (freeSpace > 0) {
00148 Vector4Copy(yellow, option->color);
00149
00150 } else {
00151 Vector4Copy(red, option->color);
00152
00153 }
00154 }
00155
00156 if (baseList != NULL){
00157 UI_RegisterOption(OPTION_BASELIST, baseList);
00158 UI_PushWindow("popup_transferbaselist", NULL);
00159 } else {
00161 Com_Printf("TR_TransferAliensFromMission_f: No base with alien containment available.\n");
00162 }
00163 }
00164
00170 static void TR_TransferStart_f (void)
00171 {
00172 char message[1024];
00173 base_t *base = B_GetCurrentSelectedBase();
00174
00175 if (td.currentTransferType == TRANS_TYPE_INVALID) {
00176 Com_Printf("TR_TransferStart_f: currentTransferType is wrong!\n");
00177 return;
00178 }
00179 TR_TransferStart(base, &td);
00180
00181
00182 memset(td.trItemsTmp, 0, sizeof(td.trItemsTmp));
00183 memset(td.trAliensTmp, 0, sizeof(td.trAliensTmp));
00184 memset(td.trEmployeesTmp, 0, sizeof(td.trEmployeesTmp));
00185 memset(td.trAircraftsTmp, TRANS_LIST_EMPTY_SLOT, sizeof(td.trAircraftsTmp));
00186
00187 Com_sprintf(message, sizeof(message), _("Transport mission started, cargo is being transported to %s"), td.transferBase->name);
00188 MSO_CheckAddNewMessage(NT_TRANSFER_STARTED, _("Transport mission"), message, qfalse, MSG_TRANSFERFINISHED, NULL);
00189 UI_PopWindow(qfalse);
00190 }
00191
00192
00198 static transferType_t TR_GetTransferType (const char *id)
00199 {
00200 int i;
00201 for (i = 0; i < TRANS_TYPE_MAX; i++) {
00202 if (!strcmp(transferTypeIDs[i], id))
00203 return i;
00204 }
00205 return TRANS_TYPE_INVALID;
00206 }
00207
00215 static int TR_CheckItem (const objDef_t *od, const base_t *destbase, int amount)
00216 {
00217 int i;
00218 int intransfer = 0;
00219 int amtransfer = 0;
00220
00221 assert(od);
00222 assert(destbase);
00223
00224
00225 for (i = 0; i < csi.numODs; i++) {
00226 const objDef_t *object = INVSH_GetItemByIDX(i);
00227 if (td.trItemsTmp[i] > 0) {
00228 if (!strcmp(object->id, ANTIMATTER_TECH_ID))
00229 amtransfer = td.trItemsTmp[i];
00230 else
00231 intransfer += object->size * td.trItemsTmp[i];
00232 }
00233 }
00234
00235
00236 if (!strcmp(od->id, ANTIMATTER_TECH_ID)) {
00237
00238 if (!B_GetBuildingStatus(destbase, B_ANTIMATTER)) {
00239 UI_Popup(_("Missing storage"), _("Destination base does not have an Antimatter Storage.\n"));
00240 return 0;
00241 }
00242 amount = min(amount, B_FreeCapacity(destbase, CAP_ANTIMATTER) - amtransfer);
00243 if (amount <= 0) {
00244 UI_Popup(_("Not enough space"), _("Destination base does not have enough\nAntimatter Storage space to store more antimatter.\n"));
00245 return 0;
00246 }
00247 } else {
00248 if (!B_GetBuildingStatus(destbase, B_STORAGE))
00249 return 0;
00250
00251
00252 amount = min(amount, destbase->capacities[CAP_ITEMS].max - destbase->capacities[CAP_ITEMS].cur - intransfer / od->size);
00253 if (amount <= 0) {
00254 UI_Popup(_("Not enough space"), _("Destination base does not have enough\nStorage space to store this item.\n"));
00255 return 0;
00256 }
00257 }
00258
00259 return amount;
00260 }
00261
00268 static qboolean TR_CheckEmployee (const employee_t *employee, const base_t *destbase)
00269 {
00270 int i, intransfer = 0;
00271 employeeType_t emplType;
00272
00273 assert(employee && destbase);
00274
00275
00276 for (emplType = 0; emplType < MAX_EMPL; emplType++) {
00277 for (i = 0; i < ccs.numEmployees[emplType]; i++) {
00278 if (td.trEmployeesTmp[emplType][i])
00279 intransfer++;
00280 }
00281 }
00282
00283
00284 if (destbase->capacities[CAP_EMPLOYEES].max - destbase->capacities[CAP_EMPLOYEES].cur - intransfer < 1) {
00285 UI_Popup(_("Not enough space"), _("Destination base does not have enough space\nin Living Quarters.\n"));
00286 return qfalse;
00287 }
00288
00289 switch (employee->type) {
00290 case EMPL_SOLDIER:
00291
00292 if (AIR_IsEmployeeInAircraft(employee, NULL)) {
00293 const rank_t *rank = CL_GetRankByIdx(employee->chr.score.rank);
00294 Com_sprintf(popupText, sizeof(popupText), _("%s %s is assigned to aircraft and cannot be\ntransfered to another base.\n"),
00295 _(rank->shortname), employee->chr.name);
00296 UI_Popup(_("Soldier in aircraft"), popupText);
00297 return qfalse;
00298 }
00299 break;
00300 case EMPL_PILOT:
00301
00302 if (AIR_IsEmployeeInAircraft(employee, NULL)) {
00303 Com_sprintf(popupText, sizeof(popupText), _("%s is assigned to aircraft and cannot be\ntransfered to another base.\n"),
00304 employee->chr.name);
00305 UI_Popup(_("Pilot in aircraft"), popupText);
00306 return qfalse;
00307 }
00308 break;
00309 default:
00310 break;
00311 }
00312
00313 return qtrue;
00314 }
00315
00322 static qboolean TR_CheckAlien (base_t *destbase)
00323 {
00324 int i, intransfer = 0;
00325
00326 assert(destbase);
00327
00328
00329 for (i = 0; i < ccs.numAliensTD; i++) {
00330 if (td.trAliensTmp[i][TRANS_ALIEN_ALIVE] > 0)
00331 intransfer += td.trAliensTmp[i][TRANS_ALIEN_ALIVE];
00332 }
00333
00334
00335 intransfer++;
00336
00337
00338 if (!AL_CheckAliveFreeSpace(destbase, NULL, intransfer)) {
00339 UI_Popup(_("Not enough space"), _("Destination base does not have enough space\nin Alien Containment.\n"));
00340 return qfalse;
00341 }
00342
00343 return qtrue;
00344 }
00345
00352 static qboolean TR_CheckAircraft (const aircraft_t *aircraft, const base_t *destbase)
00353 {
00354 int i, hangarStorage, numAircraftTransfer = 0;
00355 assert(aircraft);
00356 assert(destbase);
00357
00358
00359
00360 for (i = 0; i < ccs.numAircraft; i++)
00361 if (td.trAircraftsTmp[i] > TRANS_LIST_EMPTY_SLOT) {
00362 const aircraft_t *aircraftTemp = AIR_AircraftGetFromIDX(i);
00363 assert(aircraftTemp);
00364 if (aircraftTemp->size == aircraft->size)
00365 numAircraftTransfer++;
00366 }
00367
00368
00369 if (!B_GetBuildingStatus(destbase, B_POWER)) {
00370 UI_Popup(_("Hangars not ready"), _("Destination base does not have hangars ready.\nProvide power supplies.\n"));
00371 return qfalse;
00372 } else if (!B_GetBuildingStatus(destbase, B_COMMAND)) {
00373 UI_Popup(_("Hangars not ready"), _("Destination base does not have command centre.\nHangars not functional.\n"));
00374 return qfalse;
00375 } else if (!B_GetBuildingStatus(destbase, B_HANGAR) && !B_GetBuildingStatus(destbase, B_SMALL_HANGAR)) {
00376 UI_Popup(_("Hangars not ready"), _("Destination base does not have any hangar."));
00377 return qfalse;
00378 }
00379
00380 hangarStorage = AIR_CalculateHangarStorage(aircraft->tpl, destbase, numAircraftTransfer);
00381 if (hangarStorage == 0) {
00382 UI_Popup(_("Not enough space"), _("Destination base does not have enough space in hangars.\n"));
00383 return qfalse;
00384 } else if (hangarStorage > 0) {
00385 return qtrue;
00386 }
00387
00388 return qtrue;
00389 }
00390
00394 static void TR_CargoList (void)
00395 {
00396 int i = 0;
00397 employeeType_t emplType;
00398 int trempl[MAX_EMPL];
00399 linkedList_t *cargoList = NULL;
00400 linkedList_t *cargoListAmount = NULL;
00401 char str[128];
00402
00403 td.trCargoCountTmp = 0;
00404 memset(td.cargo, 0, sizeof(td.cargo));
00405 memset(trempl, 0, sizeof(trempl));
00406
00407
00408 for (i = 0; i < csi.numODs; i++) {
00409 const objDef_t *od = INVSH_GetItemByIDX(i);
00410 if (td.trItemsTmp[i] > 0) {
00411 LIST_AddString(&cargoList, _(od->name));
00412 LIST_AddString(&cargoListAmount, va("%i", td.trItemsTmp[i]));
00413 td.cargo[td.trCargoCountTmp].type = CARGO_TYPE_ITEM;
00414 td.cargo[td.trCargoCountTmp].itemidx = i;
00415 td.trCargoCountTmp++;
00416 if (td.trCargoCountTmp >= MAX_CARGO) {
00417 Com_DPrintf(DEBUG_CLIENT, "TR_CargoList: Cargo is full\n");
00418 break;
00419 }
00420 }
00421 }
00422
00423
00424 for (emplType = 0; emplType < MAX_EMPL; emplType++) {
00425 for (i = 0; i < ccs.numEmployees[emplType]; i++) {
00426 if (td.trEmployeesTmp[emplType][i]) {
00427 if (emplType == EMPL_SOLDIER || emplType == EMPL_PILOT) {
00428 const employee_t *employee = td.trEmployeesTmp[emplType][i];
00429 if (emplType == EMPL_SOLDIER) {
00430 const rank_t *rank = CL_GetRankByIdx(employee->chr.score.rank);
00431 Com_sprintf(str, lengthof(str), _("Soldier %s %s"), _(rank->shortname), employee->chr.name);
00432 } else
00433 Com_sprintf(str, lengthof(str), _("Pilot %s"), employee->chr.name);
00434 LIST_AddString(&cargoList, str);
00435 LIST_AddString(&cargoListAmount, "1");
00436 td.cargo[td.trCargoCountTmp].type = CARGO_TYPE_EMPLOYEE;
00437 td.cargo[td.trCargoCountTmp].itemidx = employee->idx;
00438 td.trCargoCountTmp++;
00439 if (td.trCargoCountTmp >= MAX_CARGO) {
00440 Com_DPrintf(DEBUG_CLIENT, "TR_CargoList: Cargo is full\n");
00441 break;
00442 }
00443 }
00444 trempl[emplType]++;
00445 }
00446 }
00447 }
00448 for (emplType = 0; emplType < MAX_EMPL; emplType++) {
00449 if (emplType == EMPL_SOLDIER || emplType == EMPL_PILOT)
00450 continue;
00451 if (trempl[emplType] > 0) {
00452 LIST_AddString(&cargoList, E_GetEmployeeString(emplType));
00453 LIST_AddString(&cargoListAmount, va("%i", trempl[emplType]));
00454 td.cargo[td.trCargoCountTmp].type = CARGO_TYPE_EMPLOYEE;
00455 td.trCargoCountTmp++;
00456 if (td.trCargoCountTmp >= MAX_CARGO) {
00457 Com_DPrintf(DEBUG_CLIENT, "TR_CargoList: Cargo is full\n");
00458 break;
00459 }
00460 }
00461 }
00462
00463
00464 for (i = 0; i < ccs.numAliensTD; i++) {
00465 if (td.trAliensTmp[i][TRANS_ALIEN_DEAD] > 0) {
00466 Com_sprintf(str, sizeof(str), _("Corpse of %s"),
00467 _(AL_AlienTypeToName(AL_GetAlienGlobalIDX(i))));
00468 LIST_AddString(&cargoList, str);
00469 LIST_AddString(&cargoListAmount, va("%i", td.trAliensTmp[i][TRANS_ALIEN_DEAD]));
00470 td.cargo[td.trCargoCountTmp].type = CARGO_TYPE_ALIEN_DEAD;
00471 td.cargo[td.trCargoCountTmp].itemidx = i;
00472 td.trCargoCountTmp++;
00473 if (td.trCargoCountTmp >= MAX_CARGO) {
00474 Com_DPrintf(DEBUG_CLIENT, "TR_CargoList: Cargo is full\n");
00475 break;
00476 }
00477 }
00478 }
00479 for (i = 0; i < ccs.numAliensTD; i++) {
00480 if (td.trAliensTmp[i][TRANS_ALIEN_ALIVE] > 0) {
00481 LIST_AddString(&cargoList, _(AL_AlienTypeToName(AL_GetAlienGlobalIDX(i))));
00482 LIST_AddString(&cargoListAmount, va("%i", td.trAliensTmp[i][TRANS_ALIEN_ALIVE]));
00483 td.cargo[td.trCargoCountTmp].type = CARGO_TYPE_ALIEN_ALIVE;
00484 td.cargo[td.trCargoCountTmp].itemidx = i;
00485 td.trCargoCountTmp++;
00486 if (td.trCargoCountTmp >= MAX_CARGO) {
00487 Com_DPrintf(DEBUG_CLIENT, "TR_CargoList: Cargo is full\n");
00488 break;
00489 }
00490 }
00491 }
00492
00493
00494 for (i = 0; i < ccs.numAircraft; i++) {
00495 if (td.trAircraftsTmp[i] > TRANS_LIST_EMPTY_SLOT) {
00496 aircraft_t *aircraft = AIR_AircraftGetFromIDX(td.trAircraftsTmp[i]);
00497 assert(aircraft);
00498 Com_sprintf(str, lengthof(str), _("Aircraft %s"), aircraft->name);
00499 LIST_AddString(&cargoList, str);
00500 LIST_AddString(&cargoListAmount, "1");
00501 td.cargo[td.trCargoCountTmp].type = CARGO_TYPE_AIRCRAFT;
00502 td.cargo[td.trCargoCountTmp].itemidx = i;
00503 td.trCargoCountTmp++;
00504 if (td.trCargoCountTmp >= MAX_CARGO) {
00505 Com_DPrintf(DEBUG_CLIENT, "TR_CargoList: Cargo is full\n");
00506 break;
00507 }
00508 }
00509 }
00510
00511 UI_RegisterLinkedListText(TEXT_CARGO_LIST, cargoList);
00512 UI_RegisterLinkedListText(TEXT_CARGO_LIST_AMOUNT, cargoListAmount);
00513 }
00514
00520 static qboolean TR_AircraftListSelect (int i)
00521 {
00522 aircraft_t *aircraft;
00523
00524 if (td.trAircraftsTmp[i] > TRANS_LIST_EMPTY_SLOT)
00525 return qfalse;
00526
00527 aircraft = AIR_AircraftGetFromIDX(i);
00528 if (!AIR_IsAircraftInBase(aircraft))
00529 return qfalse;
00530
00531 return qtrue;
00532 }
00533
00542 static void TR_TransferSelect (base_t *srcbase, base_t *destbase, transferType_t transferType)
00543 {
00544 linkedList_t *transferList = NULL;
00545 linkedList_t *transferListAmount = NULL;
00546 linkedList_t *transferListTransfered = NULL;
00547 int numempl[MAX_EMPL], trempl[MAX_EMPL];
00548 int i, j, cnt = 0;
00549 char str[128];
00550
00551
00552 UI_ResetData(TEXT_TRANSFER_LIST);
00553 UI_ResetData(TEXT_TRANSFER_LIST_AMOUNT);
00554 UI_ResetData(TEXT_TRANSFER_LIST_TRANSFERED);
00555
00556
00557 for (i = 0; i < MAX_EMPL; i++) {
00558 trempl[i] = numempl[i] = 0;
00559 for (j = 0; j < MAX_EMPLOYEES; j++) {
00560 if (td.trEmployeesTmp[i][j])
00561 trempl[i]++;
00562 }
00563 }
00564
00565 switch (transferType) {
00566 case TRANS_TYPE_ITEM:
00567 if (B_GetBuildingStatus(destbase, B_ANTIMATTER)) {
00568 const objDef_t *od = INVSH_GetItemByID(ANTIMATTER_TECH_ID);
00569 if (B_AntimatterInBase(srcbase) || td.trItemsTmp[od->idx]) {
00570 if (td.trItemsTmp[od->idx] > 0)
00571 LIST_AddString(&transferListTransfered, va("%i", td.trItemsTmp[od->idx]));
00572 else
00573 LIST_AddString(&transferListTransfered, "");
00574 Com_sprintf(str, sizeof(str), "%s", _(od->name));
00575 LIST_AddString(&transferList, str);
00576 LIST_AddString(&transferListAmount, va("%i", B_AntimatterInBase(srcbase)));
00577 cnt++;
00578 }
00579 }
00580 if (B_GetBuildingStatus(destbase, B_STORAGE)) {
00581 for (i = 0; i < csi.numODs; i++) {
00582 const objDef_t *od = INVSH_GetItemByIDX(i);
00583 if (!B_ItemIsStoredInBaseStorage(od))
00584 continue;
00585 if (od->isVirtual)
00586 continue;
00587 if (td.trItemsTmp[od->idx] || B_ItemInBase(od, srcbase) > 0) {
00588 if (td.trItemsTmp[od->idx] > 0)
00589 LIST_AddString(&transferListTransfered, va("%i", td.trItemsTmp[od->idx]));
00590 else
00591 LIST_AddString(&transferListTransfered, "");
00592 Com_sprintf(str, sizeof(str), "%s", _(od->name));
00593 LIST_AddString(&transferList, str);
00594 LIST_AddString(&transferListAmount, va("%i", srcbase->storage.numItems[od->idx]));
00595 cnt++;
00596 }
00597 }
00598 if (!cnt) {
00599 LIST_AddString(&transferList, _("Storage is empty."));
00600 LIST_AddString(&transferListAmount, "");
00601 LIST_AddString(&transferListTransfered, "");
00602 }
00603 } else if (B_GetBuildingStatus(destbase, B_POWER) && cnt == 0) {
00604 LIST_AddString(&transferList, _("Transfer is not possible - the base doesn't have a Storage."));
00605 LIST_AddString(&transferListAmount, "");
00606 LIST_AddString(&transferListTransfered, "");
00607 } else if (cnt == 0) {
00608 LIST_AddString(&transferList, _("Transfer is not possible - the base does not have power supplies."));
00609 LIST_AddString(&transferListAmount, "");
00610 LIST_AddString(&transferListTransfered, "");
00611 }
00612 UI_ExecuteConfunc("trans_display_spinners %i", cnt);
00613 break;
00614 case TRANS_TYPE_EMPLOYEE:
00615 if (B_GetBuildingStatus(destbase, B_QUARTERS)) {
00616 employeeType_t emplType;
00617 for (emplType = 0; emplType < MAX_EMPL; emplType++) {
00618 employee_t *employee = NULL;
00619 while ((employee = E_GetNextFromBase(emplType, employee, srcbase))) {
00620 if (td.trEmployeesTmp[emplType][employee->idx])
00621 continue;
00622 if (emplType == EMPL_SOLDIER || emplType == EMPL_PILOT) {
00623 if (emplType == EMPL_SOLDIER) {
00624 const rank_t *rank = CL_GetRankByIdx(employee->chr.score.rank);
00625 Com_sprintf(str, sizeof(str), _("Soldier %s %s"), rank->shortname, employee->chr.name);
00626 } else
00627 Com_sprintf(str, sizeof(str), _("Pilot %s"), employee->chr.name);
00628 LIST_AddString(&transferList, str);
00629 LIST_AddString(&transferListAmount, "1");
00630 LIST_AddString(&transferListTransfered, "");
00631 cnt++;
00632 }
00633 numempl[emplType]++;
00634 }
00635 }
00636 for (i = 0; i < MAX_EMPL; i++) {
00637 if (i == EMPL_SOLDIER || i == EMPL_PILOT)
00638 continue;
00639 if (numempl[i] > 0) {
00640 LIST_AddString(&transferList, E_GetEmployeeString(i));
00641 LIST_AddString(&transferListAmount, va("%i", numempl[i]));
00642 if (trempl[i] > 0)
00643 LIST_AddString(&transferListTransfered, va("%i", trempl[i]));
00644 else
00645 LIST_AddString(&transferListTransfered, "");
00646 cnt++;
00647 }
00648 }
00649 if (!cnt) {
00650 LIST_AddString(&transferList, _("Living Quarters empty."));
00651 LIST_AddString(&transferListAmount, "");
00652 LIST_AddString(&transferListTransfered, "");
00653 }
00654 } else {
00655 LIST_AddString(&transferList, _("Transfer is not possible - the base doesn't have Living Quarters."));
00656 LIST_AddString(&transferListAmount, "");
00657 LIST_AddString(&transferListTransfered, "");
00658 }
00659 UI_ExecuteConfunc("trans_display_spinners 0");
00660 break;
00661 case TRANS_TYPE_ALIEN:
00662 if (B_GetBuildingStatus(destbase, B_ALIEN_CONTAINMENT)) {
00663 for (i = 0; i < ccs.numAliensTD; i++) {
00664 const aliensCont_t *alienCont = &srcbase->alienscont[i];
00665 if (alienCont->teamDef && alienCont->amountDead > 0) {
00666 Com_sprintf(str, sizeof(str), _("Corpse of %s"),
00667 _(AL_AlienTypeToName(AL_GetAlienGlobalIDX(i))));
00668 LIST_AddString(&transferList, str);
00669 LIST_AddString(&transferListAmount, va("%i", alienCont->amountDead));
00670 if (td.trAliensTmp[i][TRANS_ALIEN_DEAD] > 0)
00671 LIST_AddString(&transferListTransfered, va("%i", td.trAliensTmp[i][TRANS_ALIEN_DEAD]));
00672 else
00673 LIST_AddString(&transferListTransfered, "");
00674 cnt++;
00675 }
00676 if (alienCont->teamDef && alienCont->amountAlive > 0) {
00677 Com_sprintf(str, sizeof(str), _("Alive %s"),
00678 _(AL_AlienTypeToName(AL_GetAlienGlobalIDX(i))));
00679 LIST_AddString(&transferList, str);
00680 LIST_AddString(&transferListAmount, va("%i", alienCont->amountAlive));
00681 if (td.trAliensTmp[i][TRANS_ALIEN_ALIVE] > 0)
00682 LIST_AddString(&transferListTransfered, va("%i", td.trAliensTmp[i][TRANS_ALIEN_ALIVE]));
00683 else
00684 LIST_AddString(&transferListTransfered, "");
00685 cnt++;
00686 }
00687 }
00688 if (!cnt) {
00689 LIST_AddString(&transferList, _("Alien Containment is empty."));
00690 LIST_AddString(&transferListAmount, "");
00691 LIST_AddString(&transferListTransfered, "");
00692 }
00693 } else if (B_GetBuildingStatus(destbase, B_POWER)) {
00694 LIST_AddString(&transferList, _("Transfer is not possible - the base doesn't have an Alien Containment."));
00695 LIST_AddString(&transferListAmount, "");
00696 LIST_AddString(&transferListTransfered, "");
00697 } else {
00698 LIST_AddString(&transferList, _("Transfer is not possible - the base does not have power supplies."));
00699 LIST_AddString(&transferListAmount, "");
00700 LIST_AddString(&transferListTransfered, "");
00701 }
00702 UI_ExecuteConfunc("trans_display_spinners 0");
00703 break;
00704 case TRANS_TYPE_AIRCRAFT:
00705 if (B_GetBuildingStatus(destbase, B_HANGAR) || B_GetBuildingStatus(destbase, B_SMALL_HANGAR)) {
00706 for (i = 0; i < MAX_AIRCRAFT; i++) {
00707 aircraft_t *aircraft = AIR_AircraftGetFromIDX(i);
00708 if (aircraft) {
00709 if (aircraft->homebase == srcbase && TR_AircraftListSelect(i)) {
00710 Com_sprintf(str, sizeof(str), _("Aircraft %s"), aircraft->name);
00711 LIST_AddString(&transferList, str);
00712 LIST_AddString(&transferListAmount, "1");
00713 LIST_AddString(&transferListTransfered, "");
00714 cnt++;
00715 }
00716 }
00717 }
00718 if (!cnt) {
00719 LIST_AddString(&transferList, _("No aircraft available for transfer."));
00720 LIST_AddString(&transferListAmount, "");
00721 LIST_AddString(&transferListTransfered, "");
00722 }
00723 } else {
00724 LIST_AddString(&transferList, _("Transfer is not possible - the base doesn't have a functional hangar."));
00725 LIST_AddString(&transferListAmount, "");
00726 LIST_AddString(&transferListTransfered, "");
00727 }
00728 UI_ExecuteConfunc("trans_display_spinners 0");
00729 break;
00730 default:
00731 Com_Printf("TR_TransferSelect: Unknown transferType id %i\n", transferType);
00732 UI_ExecuteConfunc("trans_display_spinners 0");
00733 return;
00734 }
00735
00736
00737 TR_CargoList();
00738
00739 td.currentTransferType = transferType;
00740 UI_RegisterLinkedListText(TEXT_TRANSFER_LIST, transferList);
00741 UI_RegisterLinkedListText(TEXT_TRANSFER_LIST_AMOUNT, transferListAmount);
00742 UI_RegisterLinkedListText(TEXT_TRANSFER_LIST_TRANSFERED, transferListTransfered);
00743 }
00744
00750 static void TR_TransferSelect_f (void)
00751 {
00752 int type;
00753 base_t *base = B_GetCurrentSelectedBase();
00754
00755 if (!td.transferBase || !base)
00756 return;
00757
00758 if (Cmd_Argc() < 2)
00759 type = td.currentTransferType;
00760 else
00761 type = TR_GetTransferType(Cmd_Argv(1));
00762
00763 if (type < TRANS_TYPE_ITEM || type >= TRANS_TYPE_MAX)
00764 return;
00765
00766 TR_TransferSelect(base, td.transferBase, type);
00767 }
00768
00773 static void TR_TransferListClear_f (void)
00774 {
00775 int i;
00776 base_t *base = B_GetCurrentSelectedBase();
00777
00778 if (!base)
00779 return;
00780
00781 for (i = 0; i < csi.numODs; i++) {
00782 const objDef_t *od = INVSH_GetItemByIDX(i);
00783 if (td.trItemsTmp[od->idx] > 0) {
00784 if (!strcmp(od->id, ANTIMATTER_TECH_ID))
00785 B_ManageAntimatter(base, td.trItemsTmp[od->idx], qtrue);
00786 else
00787 B_UpdateStorageAndCapacity(base, od, td.trItemsTmp[od->idx], qfalse, qfalse);
00788 }
00789 }
00790 for (i = 0; i < ccs.numAliensTD; i++) {
00791 if (td.trAliensTmp[i][TRANS_ALIEN_ALIVE] > 0)
00792 AL_ChangeAliveAlienNumber(base, &(base->alienscont[i]), td.trAliensTmp[i][TRANS_ALIEN_ALIVE]);
00793 if (td.trAliensTmp[i][TRANS_ALIEN_DEAD] > 0)
00794 base->alienscont[i].amountDead += td.trAliensTmp[i][TRANS_ALIEN_DEAD];
00795 }
00796
00797
00798 memset(td.trItemsTmp, 0, sizeof(td.trItemsTmp));
00799 memset(td.trAliensTmp, 0, sizeof(td.trAliensTmp));
00800 memset(td.trEmployeesTmp, 0, sizeof(td.trEmployeesTmp));
00801 memset(td.trAircraftsTmp, TRANS_LIST_EMPTY_SLOT, sizeof(td.trAircraftsTmp));
00802
00803 TR_CargoList();
00804 TR_TransferSelect(base, td.transferBase, td.currentTransferType);
00805 UI_ExecuteConfunc("trans_resetscroll");
00806 }
00807
00811 static int TR_GetTransferFactor (void)
00812 {
00813 return 1;
00814 }
00815
00816 static qboolean TR_GetTransferEmployee (employeeType_t emplType, int *cnt, const base_t *base, int num)
00817 {
00818 employee_t *employee = NULL;
00819 while ((employee = E_GetNextFromBase(emplType, employee, base))) {
00820 if (td.trEmployeesTmp[employee->type][employee->idx])
00821 continue;
00822 if (*cnt == num) {
00823 if (TR_CheckEmployee(employee, td.transferBase)) {
00824 td.trEmployeesTmp[employee->type][employee->idx] = employee;
00825 return qtrue;
00826 }
00831 return qfalse;
00832 }
00833 (*cnt)++;
00834 }
00835 return qfalse;
00836 }
00837
00843 static void TR_TransferListSelect_f (void)
00844 {
00845 int num, cnt = 0, i;
00846 employeeType_t emplType;
00847 int numEmployees[MAX_EMPL];
00848 base_t *base = B_GetCurrentSelectedBase();
00849
00850 if (Cmd_Argc() < 2)
00851 return;
00852
00853 if (!base)
00854 return;
00855
00856 if (!td.transferBase) {
00857 UI_Popup(_("No target base selected"), _("Please select the target base from the list"));
00858 return;
00859 }
00860
00861 num = atoi(Cmd_Argv(1));
00862 if (num < 0 || num >= csi.numODs)
00863 return;
00864
00865 switch (td.currentTransferType) {
00866 case TRANS_TYPE_INVALID:
00867 return;
00868 case TRANS_TYPE_ITEM:
00869 if (B_GetBuildingStatus(td.transferBase, B_ANTIMATTER)) {
00870 const objDef_t *od = INVSH_GetItemByID(ANTIMATTER_TECH_ID);
00871 if (B_AntimatterInBase(base) || td.trItemsTmp[od->idx]) {
00872 if (cnt == num) {
00873 int amount;
00874
00875 if (Cmd_Argc() == 3)
00876 amount = atoi(Cmd_Argv(2));
00877 else
00878 amount = TR_GetTransferFactor();
00879
00880
00881 if (amount > 0) {
00882 amount = min(amount, B_AntimatterInBase(base));
00883 if (amount == 0)
00884 return;
00885
00886 amount = TR_CheckItem(od, td.transferBase, amount);
00887 } else if (amount < 0) {
00888 amount = max(amount, - td.trItemsTmp[od->idx]);
00889 }
00890
00891 if (amount) {
00892 td.trItemsTmp[od->idx] += amount;
00893 B_ManageAntimatter(base, amount, qfalse);
00894 break;
00895 } else
00896 return;
00897 }
00898 cnt++;
00899 }
00900 }
00901 for (i = 0; i < csi.numODs; i++) {
00902 const objDef_t *od = INVSH_GetItemByIDX(i);
00903 if (!B_ItemIsStoredInBaseStorage(od))
00904 continue;
00905 if (od->isVirtual)
00906 continue;
00907 if (td.trItemsTmp[od->idx] || B_ItemInBase(od, base) > 0) {
00908 if (cnt == num) {
00909 int amount;
00910
00911 if (Cmd_Argc() == 3)
00912 amount = atoi(Cmd_Argv(2));
00913 else
00914 amount = TR_GetTransferFactor();
00915
00916
00917 if (amount > 0) {
00918 amount = min(amount, base->storage.numItems[od->idx]);
00919 if (amount == 0)
00920 return;
00921
00922 amount = TR_CheckItem(od, td.transferBase, amount);
00923 } else if (amount < 0) {
00924 amount = max(amount, - td.trItemsTmp[od->idx]);
00925 }
00926
00927 if (amount) {
00928 td.trItemsTmp[od->idx] += amount;
00929 B_UpdateStorageAndCapacity(base, od, -amount, qfalse, qfalse);
00930 break;
00931 } else
00932 return;
00933 }
00934 cnt++;
00935 }
00936 }
00937 break;
00938 case TRANS_TYPE_EMPLOYEE:
00939 if (TR_GetTransferEmployee(EMPL_SOLDIER, &cnt, base, num))
00940 break;
00941
00942 if (TR_GetTransferEmployee(EMPL_PILOT, &cnt, base, num))
00943 break;
00944
00945
00946 for (emplType = 0; emplType < MAX_EMPL; emplType++) {
00947 numEmployees[emplType] = E_CountHired(base, emplType);
00948 for (i = 0; i < MAX_EMPLOYEES; i++) {
00949 if (td.trEmployeesTmp[emplType][i])
00950 numEmployees[emplType]--;
00951 }
00952 }
00953
00954 for (emplType = 0; emplType < MAX_EMPL; emplType++) {
00955 if (emplType == EMPL_SOLDIER || emplType == EMPL_PILOT)
00956 continue;
00957
00958 if (numEmployees[emplType] < 1)
00959 continue;
00960 if (cnt == num) {
00961 int amount = min(E_CountHired(base, emplType), TR_GetTransferFactor());
00962 employee_t *employee = NULL;
00963 while ((employee = E_GetNextFromBase(emplType, employee, base))) {
00964 if (td.trEmployeesTmp[emplType][employee->idx])
00965 continue;
00966 if (TR_CheckEmployee(employee, td.transferBase)) {
00967 td.trEmployeesTmp[emplType][employee->idx] = employee;
00968 amount--;
00969 if (amount == 0)
00970 break;
00971 } else
00972 return;
00973 }
00974 }
00975 cnt++;
00976 }
00977 break;
00978 case TRANS_TYPE_ALIEN:
00979 if (!B_GetBuildingStatus(td.transferBase, B_ALIEN_CONTAINMENT))
00980 return;
00981 for (i = 0; i < ccs.numAliensTD; i++) {
00982 if (base->alienscont[i].teamDef && base->alienscont[i].amountDead > 0) {
00983 if (cnt == num) {
00984 td.trAliensTmp[i][TRANS_ALIEN_DEAD]++;
00985
00986 base->alienscont[i].amountDead--;
00987 break;
00988 }
00989 cnt++;
00990 }
00991 if (base->alienscont[i].teamDef && base->alienscont[i].amountAlive > 0) {
00992 if (cnt == num) {
00993 if (TR_CheckAlien(td.transferBase)) {
00994 td.trAliensTmp[i][TRANS_ALIEN_ALIVE]++;
00995
00996 AL_ChangeAliveAlienNumber(base, &(base->alienscont[i]), -1);
00997 break;
00998 } else
00999 return;
01000 }
01001 cnt++;
01002 }
01003 }
01004 break;
01005 case TRANS_TYPE_AIRCRAFT:
01006 if (!B_GetBuildingStatus(td.transferBase, B_HANGAR) && !B_GetBuildingStatus(td.transferBase, B_SMALL_HANGAR))
01007 return;
01008 for (i = 0; i < MAX_AIRCRAFT; i++) {
01009 const aircraft_t *aircraft = AIR_AircraftGetFromIDX(i);
01010 if (!aircraft)
01011 return;
01012 if (aircraft->homebase == base && TR_AircraftListSelect(i)) {
01013 if (cnt == num) {
01014 if (TR_CheckAircraft(aircraft, td.transferBase)) {
01015 td.trAircraftsTmp[i] = i;
01016 break;
01017 } else
01018 return;
01019 }
01020 cnt++;
01021 }
01022 }
01023 break;
01024 default:
01025 return;
01026 }
01027
01028 TR_TransferSelect(base, td.transferBase, td.currentTransferType);
01029 }
01030
01037 static void TR_TransferBaseSelect (base_t *srcbase, base_t *destbase)
01038 {
01039 static char baseInfo[1024];
01040 qboolean powercomm = qfalse;
01041
01042 if (!destbase || !srcbase)
01043 return;
01044
01045 baseInfo[0] = '\0';
01046 powercomm = B_GetBuildingStatus(destbase, B_POWER);
01047
01048
01049 if (B_GetBuildingStatus(destbase, B_STORAGE)) {
01050 Q_strcat(baseInfo, _("You can transfer equipment - this base has a Storage.\n"), sizeof(baseInfo));
01051 } else if (powercomm) {
01052
01053 Q_strcat(baseInfo, _("No Storage in this base.\n"), sizeof(baseInfo));
01054 }
01055
01056 if (B_GetBuildingStatus(destbase, B_QUARTERS)) {
01057 Q_strcat(baseInfo, _("You can transfer employees - this base has Living Quarters.\n"), sizeof(baseInfo));
01058 } else {
01059 Q_strcat(baseInfo, _("No Living Quarters in this base.\n"), sizeof(baseInfo));
01060 }
01061
01062 if (B_GetBuildingStatus(destbase, B_ALIEN_CONTAINMENT)) {
01063 Q_strcat(baseInfo, _("You can transfer Aliens - this base has an Alien Containment.\n"), sizeof(baseInfo));
01064 } else if (powercomm) {
01065 Q_strcat(baseInfo, _("No Alien Containment in this base.\n"), sizeof(baseInfo));
01066 }
01067
01068 if (B_GetBuildingStatus(destbase, B_ANTIMATTER)) {
01069 Q_strcat(baseInfo, _("You can transfer antimatter - this base has an Antimatter Storage.\n"), sizeof(baseInfo));
01070 } else if (powercomm) {
01071 Q_strcat(baseInfo, _("No Antimatter Storage in this base.\n"), sizeof(baseInfo));
01072 }
01073
01074 if (B_GetBuildingStatus(destbase, B_HANGAR) || B_GetBuildingStatus(destbase, B_SMALL_HANGAR)) {
01075 Q_strcat(baseInfo, _("You can transfer aircraft - this base has a Hangar.\n"), sizeof(baseInfo));
01076 } else if (!B_GetBuildingStatus(destbase, B_COMMAND)) {
01077 Q_strcat(baseInfo, _("Aircraft transfer not possible - this base does not have a Command Centre.\n"), sizeof(baseInfo));
01078 } else if (powercomm) {
01079 Q_strcat(baseInfo, _("No Hangar in this base.\n"), sizeof(baseInfo));
01080 }
01081
01082 if (!powercomm)
01083 Q_strcat(baseInfo, _("No power supplies in this base.\n"), sizeof(baseInfo));
01084
01085 UI_RegisterText(TEXT_BASE_INFO, baseInfo);
01086
01087
01088 td.transferBase = destbase;
01089 Cvar_Set("mn_trans_base_name", destbase->name);
01090 Cvar_SetValue("mn_trans_base_id", destbase->idx);
01091
01092
01093 TR_TransferSelect(srcbase, destbase, td.currentTransferType);
01094 }
01095
01099 static void TR_InitBaseList (void)
01100 {
01101 int baseIdx;
01102 const base_t const *currentBase = B_GetCurrentSelectedBase();
01103 uiNode_t *baseList = NULL;
01104
01105 for (baseIdx = 0; baseIdx < ccs.numBases; baseIdx++) {
01106 const base_t const *base = B_GetFoundedBaseByIDX(baseIdx);
01107 if (!base)
01108 continue;
01109 if (base == currentBase)
01110 continue;
01111
01112 UI_AddOption(&baseList, va("base%i", baseIdx), base->name, va("%i", baseIdx));
01113 }
01114
01115 UI_RegisterOption(OPTION_BASELIST, baseList);
01116 }
01117
01121 static void TR_SelectBase_f (void)
01122 {
01123 int baseIdx;
01124 base_t *base = B_GetCurrentSelectedBase();
01125 base_t *destbase;
01126
01127 if (Cmd_Argc() < 2) {
01128 Com_Printf("Usage: %s <baseIdx>\n", Cmd_Argv(0));
01129 return;
01130 }
01131
01132 baseIdx = atoi(Cmd_Argv(1));
01133 destbase = B_GetFoundedBaseByIDX(baseIdx);
01134
01135 TR_TransferBaseSelect(base, destbase);
01136 }
01137
01141 static void TR_CargoListSelect_f (void)
01142 {
01143 int num, cnt = 0, entries = 0, i, j;
01144 qboolean removed = qfalse;
01145 int numempl[MAX_EMPL];
01146 employeeType_t emplType;
01147 base_t *base = B_GetCurrentSelectedBase();
01148
01149 if (Cmd_Argc() < 2)
01150 return;
01151
01152 if (!base)
01153 return;
01154
01155 num = atoi(Cmd_Argv(1));
01156 if (num < 0 || num >= MAX_CARGO)
01157 return;
01158
01159 switch (td.cargo[num].type) {
01160 case CARGO_TYPE_ITEM:
01161 for (i = 0; i < csi.numODs; i++) {
01162 const objDef_t *od = INVSH_GetItemByIDX(i);
01163 if (td.trItemsTmp[od->idx] > 0) {
01164 if (cnt == num) {
01165 const int amount = min(TR_GetTransferFactor(), td.trItemsTmp[od->idx]);
01166
01167 td.trItemsTmp[i] -= amount;
01168 if (!strcmp(od->id, ANTIMATTER_TECH_ID))
01169 B_ManageAntimatter(base, amount, qfalse);
01170 else
01171 B_UpdateStorageAndCapacity(base, od, amount, qfalse, qfalse);
01172 break;
01173 }
01174 cnt++;
01175 }
01176 }
01177 break;
01178 case CARGO_TYPE_EMPLOYEE:
01179 for (i = 0; i < MAX_CARGO; i++) {
01180
01181 switch (td.cargo[i].type) {
01182 case CARGO_TYPE_ITEM:
01183 entries++;
01184 default:
01185 break;
01186 }
01187 }
01188
01189 cnt = entries;
01190 for (i = 0; i < ccs.numEmployees[EMPL_SOLDIER]; i++) {
01191 if (td.trEmployeesTmp[EMPL_SOLDIER][i]) {
01192 if (cnt == num) {
01193 td.trEmployeesTmp[EMPL_SOLDIER][i] = NULL;
01194 removed = qtrue;
01195 break;
01196 }
01197 cnt++;
01198 }
01199 }
01200 if (removed)
01201 break;
01202 for (i = 0; i < ccs.numEmployees[EMPL_PILOT]; i++) {
01203 if (td.trEmployeesTmp[EMPL_PILOT][i]) {
01204 if (cnt == num) {
01205 td.trEmployeesTmp[EMPL_PILOT][i] = NULL;
01206 removed = qtrue;
01207 break;
01208 }
01209 cnt++;
01210 }
01211 }
01212 if (removed)
01213 break;
01214
01215 Com_DPrintf(DEBUG_CLIENT, "TR_CargoListSelect_f: cnt: %i, num: %i\n", cnt, num);
01216
01217
01218 for (emplType = 0; emplType < MAX_EMPL; emplType++) {
01219 numempl[emplType] = 0;
01222 for (i = 0; i < MAX_EMPLOYEES; i++) {
01223 if (td.trEmployeesTmp[emplType][i])
01224 numempl[emplType]++;
01225 }
01226 }
01227
01228 for (emplType = 0; emplType < MAX_EMPL; emplType++) {
01229 if (numempl[emplType] < 1 || emplType == EMPL_SOLDIER || emplType == EMPL_PILOT)
01230 continue;
01231 if (cnt == num) {
01232 int amount = min(TR_GetTransferFactor(), E_CountHired(base, emplType));
01233 for (j = 0; j < ccs.numEmployees[emplType]; j++) {
01234 if (td.trEmployeesTmp[emplType][j]) {
01235 td.trEmployeesTmp[emplType][j] = NULL;
01236 amount--;
01237 removed = qtrue;
01238 if (amount == 0)
01239 break;
01240 } else
01241 continue;
01242 }
01243 }
01244 if (removed)
01245 break;
01246 cnt++;
01247 }
01248 break;
01249 case CARGO_TYPE_ALIEN_DEAD:
01250 for (i = 0; i < MAX_CARGO; i++) {
01251
01252 switch (td.cargo[i].type) {
01253 case CARGO_TYPE_ITEM:
01254 case CARGO_TYPE_EMPLOYEE:
01255 entries++;
01256 default:
01257 break;
01258 }
01259 }
01260
01261 cnt = entries;
01262 for (i = 0; i < ccs.numAliensTD; i++) {
01263 if (td.trAliensTmp[i][TRANS_ALIEN_DEAD] > 0) {
01264 if (cnt == num) {
01265 td.trAliensTmp[i][TRANS_ALIEN_DEAD]--;
01266 base->alienscont[i].amountDead++;
01267 break;
01268 }
01269 cnt++;
01270 }
01271 }
01272 break;
01273 case CARGO_TYPE_ALIEN_ALIVE:
01274 for (i = 0; i < MAX_CARGO; i++) {
01275
01276 switch (td.cargo[i].type) {
01277 case CARGO_TYPE_ITEM:
01278 case CARGO_TYPE_EMPLOYEE:
01279 case CARGO_TYPE_ALIEN_DEAD:
01280 entries++;
01281 default:
01282 break;
01283 }
01284 }
01285
01286 cnt = entries;
01287 for (i = 0; i < ccs.numAliensTD; i++) {
01288 if (td.trAliensTmp[i][TRANS_ALIEN_ALIVE] > 0) {
01289 if (cnt == num) {
01290 td.trAliensTmp[i][TRANS_ALIEN_ALIVE]--;
01291 AL_ChangeAliveAlienNumber(base, &(base->alienscont[i]), 1);
01292 break;
01293 }
01294 cnt++;
01295 }
01296 }
01297 break;
01298 case CARGO_TYPE_AIRCRAFT:
01299 for (i = 0; i < MAX_CARGO; i++) {
01300
01301 switch (td.cargo[i].type) {
01302 case CARGO_TYPE_ITEM:
01303 case CARGO_TYPE_EMPLOYEE:
01304 case CARGO_TYPE_ALIEN_DEAD:
01305 case CARGO_TYPE_ALIEN_ALIVE:
01306 entries++;
01307 default:
01308 break;
01309 }
01310 }
01311
01312 cnt = entries;
01313 for (i = 0; i < ccs.numAircraft; i++) {
01314 if (td.trAircraftsTmp[i] > TRANS_LIST_EMPTY_SLOT) {
01315 if (cnt == num) {
01316 td.trAircraftsTmp[i] = TRANS_LIST_EMPTY_SLOT;
01317 break;
01318 }
01319 cnt++;
01320 }
01321 }
01322 break;
01323 default:
01324 return;
01325 }
01326
01327 TR_TransferSelect(base, td.transferBase, td.currentTransferType);
01328 }
01329
01335 static void TR_Init_f (void)
01336 {
01337 base_t *base = B_GetCurrentSelectedBase();
01338
01339
01340 memset(td.trEmployeesTmp, 0, sizeof(td.trEmployeesTmp));
01341
01342 memset(td.trAircraftsTmp, TRANS_LIST_EMPTY_SLOT, sizeof(td.trAircraftsTmp));
01343
01344
01345 TR_InitBaseList();
01346
01347
01348 td.transferBase = B_GetFoundedBaseByIDX((base->idx + 1) % ccs.numBases);
01349 TR_TransferBaseSelect(base, td.transferBase);
01350
01351 if (td.transferBase) {
01352 Cvar_Set("mn_trans_base_name", td.transferBase->name);
01353 Cvar_SetValue("mn_trans_base_id", td.transferBase->idx);
01354 } else {
01355 Cvar_Set("mn_trans_base_id", "");
01356 }
01357
01358
01359 Cvar_Set("mn_itemtype", transferTypeIDs[0]);
01360
01361 Cmd_ExecuteString(va("trans_type %s", transferTypeIDs[0]));
01362
01363
01364 UI_ExecuteConfunc("trans_resetscroll");
01365 }
01366
01370 static void TR_TransferClose_f (void)
01371 {
01372 base_t *base = B_GetCurrentSelectedBase();
01373
01374 if (!base)
01375 return;
01376
01377
01378 TR_TransferListClear_f();
01379
01380
01381 memset(td.trItemsTmp, 0, sizeof(td.trItemsTmp));
01382 memset(td.trAliensTmp, 0, sizeof(td.trAliensTmp));
01383 memset(td.trEmployeesTmp, 0, sizeof(td.trEmployeesTmp));
01384 memset(td.trAircraftsTmp, TRANS_LIST_EMPTY_SLOT, sizeof(td.trAircraftsTmp));
01385 }
01386
01390 static void TR_TransferList_Scroll_f (void)
01391 {
01392 int i;
01393 int cnt = 0;
01394 int transferType;
01395 int viewPos;
01396 base_t *srcBase = B_GetCurrentSelectedBase();
01397 const objDef_t *od = INVSH_GetItemByID(ANTIMATTER_TECH_ID);
01398
01399 if (!srcBase)
01400 return;
01401
01402 if (Cmd_Argc() < 3) {
01403 Com_Printf("Usage: %s <transferType> <viewPos>\n", Cmd_Argv(0));
01404 return;
01405 }
01406
01407 transferType = TR_GetTransferType(Cmd_Argv(1));
01408 viewPos = atoi(Cmd_Argv(2));
01409
01410
01411 if (transferType != TRANS_TYPE_ITEM)
01412 return;
01413
01414 if (B_GetBuildingStatus(td.transferBase, B_ANTIMATTER) && (td.trItemsTmp[od->idx] || B_AntimatterInBase(srcBase))) {
01415 if (cnt >= viewPos && cnt < viewPos + MAX_TRANSLIST_MENU_ENTRIES)
01416 UI_ExecuteConfunc("trans_updatespinners %i %i %i %i", cnt - viewPos,
01417 td.trItemsTmp[od->idx], 0, B_AntimatterInBase(srcBase) + td.trItemsTmp[od->idx]);
01418 cnt++;
01419 }
01420 for (i = 0; i < csi.numODs; i++) {
01421 const objDef_t *od = INVSH_GetItemByIDX(i);
01422 if (!B_ItemIsStoredInBaseStorage(od))
01423 continue;
01424 if (od->isVirtual)
01425 continue;
01426 if (srcBase->storage.numItems[od->idx] || td.trItemsTmp[od->idx]) {
01427 if (cnt >= viewPos + MAX_TRANSLIST_MENU_ENTRIES)
01428 break;
01429 if (cnt >= viewPos)
01430 UI_ExecuteConfunc("trans_updatespinners %i %i %i %i", cnt - viewPos,
01431 td.trItemsTmp[od->idx], 0, srcBase->storage.numItems[od->idx] + td.trItemsTmp[od->idx]);
01432 cnt++;
01433 }
01434 }
01435 }
01436
01437 void TR_InitCallbacks (void)
01438 {
01439 memset(&td, 0, sizeof(td));
01440 memset(td.trAircraftsTmp, TRANS_LIST_EMPTY_SLOT, sizeof(td.trAircraftsTmp));
01441 Cmd_AddCommand("trans_init", TR_Init_f, "Init function for Transfer menu");
01442 Cmd_AddCommand("trans_list_scroll", TR_TransferList_Scroll_f, "Scrolls the transferlist");
01443 Cmd_AddCommand("trans_close", TR_TransferClose_f, "Callback for closing Transfer Menu");
01444 Cmd_AddCommand("trans_start", TR_TransferStart_f, "Starts the transfer");
01445 Cmd_AddCommand("trans_type", TR_TransferSelect_f, "Switch between transfer types (employees, techs, items)");
01446 Cmd_AddCommand("trans_emptyairstorage", TR_TransferListClear_f, "Unload everything from transfer cargo back to base");
01447 Cmd_AddCommand("trans_list_click", TR_TransferListSelect_f, "Callback for transfer list node click");
01448 Cmd_AddCommand("trans_cargolist_click", TR_CargoListSelect_f, "Callback for cargo list node click");
01449 Cmd_AddCommand("trans_selectbase", TR_SelectBase_f, "Callback for selecting a base");
01450 Cmd_AddCommand("trans_baselist_click", TR_TransferBaseListClick_f, "Callback for choosing base while recovering alien after mission");
01451
01452 Cmd_AddCommand("trans_aliens", TR_TransferAliensFromMission_f, "Transfer aliens collected at missions");
01453 }
01454
01455 void TR_ShutdownCallbacks (void)
01456 {
01457 Cmd_RemoveCommand("trans_init");
01458 Cmd_RemoveCommand("trans_list_scroll");
01459 Cmd_RemoveCommand("trans_close");
01460 Cmd_RemoveCommand("trans_start");
01461 Cmd_RemoveCommand("trans_type");
01462 Cmd_RemoveCommand("trans_emptyairstorage");
01463 Cmd_RemoveCommand("trans_list_click");
01464 Cmd_RemoveCommand("trans_cargolist_click");
01465 Cmd_RemoveCommand("trans_selectbase");
01466 Cmd_RemoveCommand("trans_baselist_click");
01467 Cmd_RemoveCommand("trans_aliens");
01468 }
01469