00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "../cl_shared.h"
00029 #include "cp_campaign.h"
00030 #include "save/save_transfer.h"
00031 #include "cp_transfer_callbacks.h"
00032 #include "../ui/ui_main.h"
00033
00038 transfer_t* TR_GetNext (transfer_t *lastTransfer)
00039 {
00040 transfer_t *endOfTransfers = &ccs.transfers[ccs.numTransfers];
00041 transfer_t* transfer;
00042
00043 if (!ccs.numTransfers)
00044 return NULL;
00045
00046 if (!lastTransfer)
00047 return ccs.transfers;
00048 assert(lastTransfer >= ccs.transfers);
00049 assert(lastTransfer < endOfTransfers);
00050
00051 transfer = lastTransfer;
00052
00053 transfer++;
00054 if (transfer >= endOfTransfers)
00055 return NULL;
00056 else
00057 return transfer;
00058 }
00059
00068 static void TR_EmptyTransferCargo (base_t *destination, transfer_t *transfer, qboolean success)
00069 {
00070 assert(transfer);
00071
00072 if (transfer->hasItems && success) {
00073 const objDef_t *od = INVSH_GetItemByID(ANTIMATTER_TECH_ID);
00074 int i;
00075
00076
00077 if (transfer->itemAmount[od->idx] > 0) {
00078 if (B_GetBuildingStatus(destination, B_ANTIMATTER)) {
00079 B_ManageAntimatter(destination, transfer->itemAmount[od->idx], qtrue);
00080 } else {
00081 Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("%s does not have Antimatter Storage, antimatter are removed!"), destination->name);
00082 MSO_CheckAddNewMessage(NT_TRANSFER_LOST, _("Transport mission"), cp_messageBuffer, qfalse, MSG_TRANSFERFINISHED, NULL);
00083 }
00084 }
00085
00086 for (i = 0; i < csi.numODs; i++) {
00087 od = INVSH_GetItemByIDX(i);
00088
00089 if (transfer->itemAmount[od->idx] <= 0)
00090 continue;
00091 if (!B_ItemIsStoredInBaseStorage(od))
00092 continue;
00093 if (!B_GetBuildingStatus(destination, B_STORAGE)) {
00094 Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("%s does not have Storage, items are removed!"), destination->name);
00095 MSO_CheckAddNewMessage(NT_TRANSFER_LOST, _("Transport mission"), cp_messageBuffer, qfalse, MSG_TRANSFERFINISHED, NULL);
00096 break;
00097 }
00098 B_UpdateStorageAndCapacity(destination, od, transfer->itemAmount[od->idx], qfalse, qtrue);
00099 }
00100 }
00101
00102 if (transfer->hasEmployees && transfer->srcBase) {
00103 if (!success || !B_GetBuildingStatus(destination, B_QUARTERS)) {
00104 int i;
00105 if (success) {
00106 Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("%s does not have Living Quarters, employees got unhired!"), destination->name);
00107 MSO_CheckAddNewMessage(NT_TRANSFER_LOST, _("Transport mission"), cp_messageBuffer, qfalse, MSG_TRANSFERFINISHED, NULL);
00108 }
00109 for (i = 0; i < MAX_EMPL; i++) {
00110 int j;
00111 for (j = 0; j < ccs.numEmployees[i]; j++) {
00112 if (transfer->employeeArray[i][j]) {
00113 employee_t *employee = transfer->employeeArray[i][j];
00114 employee->baseHired = transfer->srcBase;
00115
00116
00117 assert(employee->baseHired);
00118 employee->transfer = qfalse;
00119 E_UnhireEmployee(employee);
00120 }
00121 }
00122 }
00123 } else {
00124 int i;
00125 for (i = 0; i < MAX_EMPL; i++) {
00126 int j;
00127 for (j = 0; j < ccs.numEmployees[i]; j++) {
00128 if (transfer->employeeArray[i][j]) {
00129 employee_t *employee = transfer->employeeArray[i][j];
00130 employee->baseHired = transfer->srcBase;
00131
00132
00133 assert(employee->baseHired);
00134 employee->transfer = qfalse;
00135 E_UnhireEmployee(employee);
00136 E_HireEmployee(destination, employee);
00137 }
00138 }
00139 }
00140 }
00141 }
00142
00143 if (transfer->hasAliens && success) {
00144 if (!B_GetBuildingStatus(destination, B_ALIEN_CONTAINMENT)) {
00145 Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("%s does not have Alien Containment, Aliens are removed!"), destination->name);
00146 MSO_CheckAddNewMessage(NT_TRANSFER_LOST, _("Transport mission"), cp_messageBuffer, qfalse, MSG_TRANSFERFINISHED, NULL);
00147
00148 } else {
00149 int i;
00150 for (i = 0; i < ccs.numAliensTD; i++) {
00151 if (transfer->alienAmount[i][TRANS_ALIEN_ALIVE] > 0) {
00152 AL_ChangeAliveAlienNumber(destination, &(destination->alienscont[i]), transfer->alienAmount[i][TRANS_ALIEN_ALIVE]);
00153 }
00154 if (transfer->alienAmount[i][TRANS_ALIEN_DEAD] > 0) {
00155 destination->alienscont[i].amountDead += transfer->alienAmount[i][TRANS_ALIEN_DEAD];
00156 }
00157 }
00158 }
00159 }
00160
00164 if (transfer->hasAircraft && success && transfer->srcBase) {
00165 int i;
00166 for (i = 0; i < ccs.numAircraft; i++) {
00167 if (transfer->aircraftArray[i] > TRANS_LIST_EMPTY_SLOT) {
00168 aircraft_t *aircraft = AIR_AircraftGetFromIDX(i);
00169 assert(aircraft);
00170
00171 if (AIR_CalculateHangarStorage(aircraft->tpl, destination, 0) > 0) {
00172
00173 AIR_MoveAircraftIntoNewHomebase(aircraft, destination);
00174 } else {
00175
00176 Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("%s does not have enough free space in hangars. Aircraft is lost!"), destination->name);
00177 MSO_CheckAddNewMessage(NT_TRANSFER_LOST, _("Transport mission"), cp_messageBuffer, qfalse, MSG_TRANSFERFINISHED, NULL);
00178 AIR_DeleteAircraft(aircraft);
00179 }
00180 }
00181 }
00182 }
00183 }
00184
00191 void TR_TransferAlienAfterMissionStart (const base_t *base, aircraft_t *transferAircraft)
00192 {
00193 int i, j;
00194 transfer_t *transfer;
00195 float time;
00196 char message[256];
00197 int alienCargoTypes;
00198 aliensTmp_t *cargo;
00199
00200 const technology_t *breathingTech;
00201 qboolean alienBreathing = qfalse;
00202 const objDef_t *alienBreathingObjDef;
00203
00204 breathingTech = RS_GetTechByID(BREATHINGAPPARATUS_TECH);
00205 if (!breathingTech)
00206 Com_Error(ERR_DROP, "AL_AddAliens: Could not get breathing apparatus tech definition");
00207 alienBreathing = RS_IsResearched_ptr(breathingTech);
00208 alienBreathingObjDef = INVSH_GetItemByID(breathingTech->provides);
00209 if (!alienBreathingObjDef)
00210 Com_Error(ERR_DROP, "AL_AddAliens: Could not get breathing apparatus item definition");
00211
00212 if (!base) {
00213 Com_Printf("TR_TransferAlienAfterMissionStart_f: No base selected!\n");
00214 return;
00215 }
00216
00217 if (ccs.numTransfers >= MAX_TRANSFERS) {
00218 Com_DPrintf(DEBUG_CLIENT, "TR_TransferAlienAfterMissionStart: Max transfers reached.");
00219 return;
00220 }
00221
00222 transfer = &ccs.transfers[ccs.numTransfers];
00223
00224 if (transfer->active)
00225 Com_Error(ERR_DROP, "Transfer idx %i shouldn't be active.", ccs.numTransfers);
00226
00227
00228
00229 time = GetDistanceOnGlobe(base->pos, transferAircraft->pos) / 90.0f;
00230 transfer->event.day = ccs.date.day + floor(time);
00231 time = (time - floor(time)) * SECONDS_PER_DAY;
00232 transfer->event.sec = ccs.date.sec + round(time);
00233
00234 if (transfer->event.sec > SECONDS_PER_DAY) {
00235 transfer->event.sec -= SECONDS_PER_DAY;
00236 transfer->event.day++;
00237 }
00238 transfer->destBase = B_GetFoundedBaseByIDX(base->idx);
00239 transfer->srcBase = NULL;
00240 transfer->active = qtrue;
00241 ccs.numTransfers++;
00242
00243 alienCargoTypes = AL_GetAircraftAlienCargoTypes(transferAircraft);
00244 cargo = AL_GetAircraftAlienCargo(transferAircraft);
00245 for (i = 0; i < alienCargoTypes; i++, cargo++) {
00246 if (!alienBreathing) {
00247 cargo->amountDead += cargo->amountAlive;
00248 cargo->amountAlive = 0;
00249 }
00250 if (cargo->amountAlive > 0) {
00251 for (j = 0; j < ccs.numAliensTD; j++) {
00252 if (!CHRSH_IsTeamDefAlien(&csi.teamDef[j]))
00253 continue;
00254 if (base->alienscont[j].teamDef == cargo->teamDef) {
00255 transfer->hasAliens = qtrue;
00256 transfer->alienAmount[j][TRANS_ALIEN_ALIVE] = cargo->amountAlive;
00257 cargo->amountAlive = 0;
00258 break;
00259 }
00260 }
00261 }
00262 if (cargo->amountDead > 0) {
00263 for (j = 0; j < ccs.numAliensTD; j++) {
00264 if (!CHRSH_IsTeamDefAlien(&csi.teamDef[j]))
00265 continue;
00266 if (base->alienscont[j].teamDef == cargo->teamDef) {
00267 transfer->hasAliens = qtrue;
00268 transfer->alienAmount[j][TRANS_ALIEN_DEAD] = cargo->amountDead;
00269
00270
00271 transfer->hasItems = qtrue;
00272 transfer->itemAmount[alienBreathingObjDef->idx] += cargo->amountDead;
00273 cargo->amountDead = 0;
00274 break;
00275 }
00276 }
00277 }
00278 }
00279 AL_SetAircraftAlienCargoTypes(transferAircraft, 0);
00280
00281 Com_sprintf(message, sizeof(message), _("Transport mission started, cargo is being transported to %s"), transfer->destBase->name);
00282 MSO_CheckAddNewMessage(NT_TRANSFER_ALIENBODIES_DEFERED, _("Transport mission"), message, qfalse, MSG_TRANSFERFINISHED, NULL);
00283 UI_PopWindow(qfalse);
00284 }
00285
00290 static void TR_TransferEnd (transfer_t *transfer)
00291 {
00292 base_t* destination = transfer->destBase;
00293 assert(destination);
00294
00295 if (!destination->founded) {
00296 TR_EmptyTransferCargo(NULL, transfer, qfalse);
00297 MSO_CheckAddNewMessage(NT_TRANSFER_LOST, _("Transport mission"), _("The destination base no longer exists! Transfer carge was lost, personnel has been discharged."), qfalse, MSG_TRANSFERFINISHED, NULL);
00299 } else {
00300 char message[256];
00301 TR_EmptyTransferCargo(destination, transfer, qtrue);
00302 Com_sprintf(message, sizeof(message), _("Transport mission ended, unloading cargo in %s"), destination->name);
00303 MSO_CheckAddNewMessage(NT_TRANSFER_COMPLETED_SUCCESS, _("Transport mission"), message, qfalse, MSG_TRANSFERFINISHED, NULL);
00304 }
00305 transfer->active = qfalse;
00306 }
00307
00313 void TR_TransferStart (base_t *srcBase, struct transferData_s *transData)
00314 {
00315 transfer_t *transfer;
00316 float time;
00317 int i;
00318 int j;
00319
00320 if (!transData->transferBase || !srcBase) {
00321 Com_Printf("TR_TransferStart_f: No base selected!\n");
00322 return;
00323 }
00324
00325
00326 if (!transData->trCargoCountTmp) {
00327 return;
00328 }
00329
00330 if (ccs.numTransfers >= MAX_TRANSFERS) {
00331 Com_DPrintf(DEBUG_CLIENT, "TR_TransferStart_f: Max transfers reached.");
00332 return;
00333 }
00334
00335 transfer = &ccs.transfers[ccs.numTransfers];
00336
00337 if (transfer->active)
00338 Com_Error(ERR_DROP, "Transfer idx %i shouldn't be active.", ccs.numTransfers);
00339
00340
00341
00342 time = GetDistanceOnGlobe(transData->transferBase->pos, srcBase->pos) / 90.0f;
00343 transfer->event.day = ccs.date.day + floor(time);
00344 time = (time - floor(time)) * SECONDS_PER_DAY;
00345 transfer->event.sec = ccs.date.sec + round(time);
00346
00347 if (transfer->event.sec > SECONDS_PER_DAY) {
00348 transfer->event.sec -= SECONDS_PER_DAY;
00349 transfer->event.day++;
00350 }
00351 transfer->destBase = transData->transferBase;
00352 assert(transfer->destBase);
00353 transfer->srcBase = srcBase;
00354 transfer->active = qtrue;
00355 ccs.numTransfers++;
00356
00357 for (i = 0; i < csi.numODs; i++) {
00358 if (transData->trItemsTmp[i] > 0) {
00359 transfer->hasItems = qtrue;
00360 transfer->itemAmount[i] = transData->trItemsTmp[i];
00361 }
00362 }
00363
00364
00365 for (i = 0; i < MAX_EMPL; i++) {
00366 for (j = 0; j < ccs.numEmployees[i]; j++) {
00367 if (transData->trEmployeesTmp[i][j]) {
00368 employee_t *employee = transData->trEmployeesTmp[i][j];
00369 transfer->hasEmployees = qtrue;
00370
00371 assert(E_IsInBase(employee, srcBase));
00372
00373 E_ResetEmployee(employee);
00374 transfer->employeeArray[i][j] = employee;
00375 employee->baseHired = NULL;
00376 employee->transfer = qtrue;
00377 }
00378 }
00379 }
00383 for (i = 0; i < ccs.numAliensTD; i++) {
00384 if (!CHRSH_IsTeamDefAlien(&csi.teamDef[i]))
00385 continue;
00386 if (transData->trAliensTmp[i][TRANS_ALIEN_ALIVE] > 0) {
00387 transfer->hasAliens = qtrue;
00388 transfer->alienAmount[i][TRANS_ALIEN_ALIVE] = transData->trAliensTmp[i][TRANS_ALIEN_ALIVE];
00389 }
00390 if (transData->trAliensTmp[i][TRANS_ALIEN_DEAD] > 0) {
00391 transfer->hasAliens = qtrue;
00392 transfer->alienAmount[i][TRANS_ALIEN_DEAD] = transData->trAliensTmp[i][TRANS_ALIEN_DEAD];
00393 }
00394 }
00395 memset(transfer->aircraftArray, TRANS_LIST_EMPTY_SLOT, sizeof(transfer->aircraftArray));
00396 for (i = 0; i < ccs.numAircraft; i++) {
00397 if (transData->trAircraftsTmp[i] > TRANS_LIST_EMPTY_SLOT) {
00398 aircraft_t *aircraft = AIR_AircraftGetFromIDX(i);
00399 aircraft->status = AIR_TRANSFER;
00400 AIR_RemoveEmployees(aircraft);
00401 transfer->hasAircraft = qtrue;
00402 transfer->aircraftArray[i] = i;
00403 } else {
00404 transfer->aircraftArray[i] = TRANS_LIST_EMPTY_SLOT;
00405 }
00406 }
00407
00408
00409 PR_ProductionAllowed(srcBase);
00410 RS_ResearchAllowed(srcBase);
00411 }
00412
00418 void TR_NotifyAircraftRemoved (const aircraft_t *aircraft)
00419 {
00420 transfer_t *transfer = NULL;
00421
00422 assert(aircraft->idx >= 0 && aircraft->idx < MAX_AIRCRAFT);
00423 while ((transfer = TR_GetNext(transfer))) {
00424 int tmp = ccs.numAircraft;
00425
00426 if (!transfer->active)
00427 continue;
00428 if (!transfer->hasAircraft)
00429 continue;
00430 REMOVE_ELEM_MEMSET(transfer->aircraftArray, aircraft->idx, tmp, TRANS_LIST_EMPTY_SLOT);
00431 }
00432 }
00433
00438 void TR_TransferCheck (void)
00439 {
00440 transfer_t *transfer = NULL;
00441 while ((transfer = TR_GetNext(transfer))) {
00442 if (!transfer->active)
00443 continue;
00444 if (transfer->event.day == ccs.date.day && ccs.date.sec >= transfer->event.sec) {
00445 const ptrdiff_t idx = (ptrdiff_t)(transfer - ccs.transfers);
00446 assert(transfer->destBase);
00447 TR_TransferEnd(transfer);
00449 REMOVE_ELEM(ccs.transfers, idx, ccs.numTransfers);
00450 return;
00451 }
00452 }
00453 }
00454
00455 #ifdef DEBUG
00456
00459 static void TR_ListTransfers_f (void)
00460 {
00461 int transIdx = -1;
00462 int i = 0;
00463 transfer_t *transfer = NULL;
00464
00465 if (Cmd_Argc() == 2) {
00466 transIdx = atoi(Cmd_Argv(1));
00467 if (transIdx < 0 || transIdx > MAX_TRANSFERS) {
00468 Com_Printf("Usage: %s [transferIDX]\nWithout parameter it lists all.\n", Cmd_Argv(0));
00469 return;
00470 }
00471 }
00472
00473 if (!ccs.numTransfers)
00474 Com_Printf("No active transfers.\n");
00475
00476 for (; (transfer = TR_GetNext(transfer)); i++) {
00477 dateLong_t date;
00478
00479 if (transIdx >= 0 && i != transIdx)
00480 continue;
00481 if (!transfer->active)
00482 continue;
00483
00484
00485 CL_DateConvertLong(&transfer->event, &date);
00486
00487 Com_Printf("Transfer #%d\n", i);
00488 Com_Printf("...From %d (%s) To %d (%s) Arrival: %04i-%02i-%02i %02i:%02i:%02i\n",
00489 (transfer->srcBase) ? transfer->srcBase->idx : -1,
00490 (transfer->srcBase) ? transfer->srcBase->name : "(null)",
00491 (transfer->destBase) ? transfer->destBase->idx : -1,
00492 (transfer->destBase) ? transfer->destBase->name : "(null)",
00493 date.year, date.month, date.day, date.hour, date.min, date.sec);
00494
00495
00496 if (transfer->hasItems) {
00497 int j;
00498 Com_Printf("...ItemCargo:\n");
00499 for (j = 0; j < csi.numODs; j++) {
00500 const objDef_t *od = INVSH_GetItemByIDX(j);
00501 if (transfer->itemAmount[od->idx])
00502 Com_Printf("......%s: %i\n", od->id, transfer->itemAmount[od->idx]);
00503 }
00504 }
00505
00506 if (transfer->hasEmployees) {
00507 int j;
00508 Com_Printf("...Carried Employee:\n");
00509 for (j = 0; j < MAX_EMPL; j++) {
00510 int k;
00511 for (k = 0; k < MAX_EMPLOYEES; k++) {
00512 const struct employee_s *employee = transfer->employeeArray[j][k];
00513 if (!employee)
00514 continue;
00515 if (employee->ugv) {
00517 Com_Printf("......ugv: %s [idx: %i]\n", employee->ugv->id, employee->idx);
00518 } else {
00519 Com_Printf("......%s (%s) / %s [idx: %i ucn: %i]\n", employee->chr.name,
00520 E_GetEmployeeString(employee->type),
00521 (employee->nation) ? employee->nation->id : "(nonation)",
00522 employee->idx, employee->chr.ucn);
00523 if (!E_IsHired(employee))
00524 Com_Printf("Warning: employee^ not hired!\n");
00525 if (!employee->transfer)
00526 Com_Printf("Warning: employee^ not marked as being transfered!\n");
00527 }
00528 }
00529 }
00530 }
00531
00532 if (transfer->hasAliens) {
00533 int j;
00534 Com_Printf("...AlienCargo:\n");
00535 for (j = 0; j < csi.numTeamDefs; j++) {
00536 if (transfer->alienAmount[j][TRANS_ALIEN_ALIVE] + transfer->alienAmount[j][TRANS_ALIEN_DEAD])
00537 Com_Printf("......%s alive: %i dead: %i\n", csi.teamDef[j].id, transfer->alienAmount[j][TRANS_ALIEN_ALIVE], transfer->alienAmount[j][TRANS_ALIEN_DEAD]);
00538 }
00539 }
00540
00541 if (transfer->hasAircraft) {
00542 int j;
00543 Com_Printf("...Transfered Aircraft:\n");
00544 for (j = 0; j < ccs.numAircraft; j++) {
00545 const aircraft_t *aircraft;
00546 if (transfer->aircraftArray[j] == TRANS_LIST_EMPTY_SLOT)
00547 continue;
00548 aircraft = AIR_AircraftGetFromIDX(transfer->aircraftArray[j]);
00549 Com_Printf("......%s [idx: %i]\n", (aircraft) ? aircraft->id : "(null)", j);
00550 }
00551 }
00552
00553 }
00554 }
00555 #endif
00556
00563 qboolean TR_SaveXML (mxml_node_t *p)
00564 {
00565 transfer_t *transfer = NULL;
00566 mxml_node_t *n = mxml_AddNode(p, SAVE_TRANSFER_TRANSFERS);
00567
00568 while ((transfer = TR_GetNext(transfer))) {
00569 int j;
00570 mxml_node_t *s;
00571
00572 s = mxml_AddNode(n, SAVE_TRANSFER_TRANSFER);
00573 mxml_AddInt(s, SAVE_TRANSFER_DAY, transfer->event.day);
00574 mxml_AddInt(s, SAVE_TRANSFER_SEC, transfer->event.sec);
00575 if (!transfer->destBase) {
00576 Com_Printf("Could not save transfer, no destBase is set\n");
00577 return qfalse;
00578 }
00579 mxml_AddInt(s, SAVE_TRANSFER_DESTBASE, transfer->destBase->idx);
00580
00581
00582 if (transfer->srcBase)
00583 mxml_AddInt(s, SAVE_TRANSFER_SRCBASE, transfer->srcBase->idx);
00584
00585 if (transfer->hasItems) {
00586 for (j = 0; j < MAX_OBJDEFS; j++) {
00587 if (transfer->itemAmount[j] > 0) {
00588 const objDef_t *od = INVSH_GetItemByIDX(j);
00589 mxml_node_t *ss = mxml_AddNode(s, SAVE_TRANSFER_ITEM);
00590
00591 assert(od);
00592 mxml_AddString(ss, SAVE_TRANSFER_ITEMID, od->id);
00593 mxml_AddInt(ss, SAVE_TRANSFER_AMOUNT, transfer->itemAmount[j]);
00594 }
00595 }
00596 }
00597
00598 if (transfer->hasAliens) {
00599 for (j = 0; j < ccs.numAliensTD; j++) {
00600 if (transfer->alienAmount[j][TRANS_ALIEN_ALIVE] > 0
00601 || transfer->alienAmount[j][TRANS_ALIEN_DEAD] > 0)
00602 {
00603 teamDef_t *team = ccs.alienTeams[j];
00604 mxml_node_t *ss = mxml_AddNode(s, SAVE_TRANSFER_ALIEN);
00605
00606 assert(team);
00607 mxml_AddString(ss, SAVE_TRANSFER_ALIENID, team->id);
00608 mxml_AddIntValue(ss, SAVE_TRANSFER_ALIVEAMOUNT, transfer->alienAmount[j][TRANS_ALIEN_ALIVE]);
00609 mxml_AddIntValue(ss, SAVE_TRANSFER_DEADAMOUNT, transfer->alienAmount[j][TRANS_ALIEN_DEAD]);
00610 }
00611 }
00612 }
00613
00614 if (transfer->hasEmployees) {
00615 for (j = 0; j < MAX_EMPL; j++) {
00616 int k;
00617 for (k = 0; k < MAX_EMPLOYEES; k++) {
00618 const employee_t *empl = transfer->employeeArray[j][k];
00619 if (empl) {
00620 mxml_node_t *ss = mxml_AddNode(s, SAVE_TRANSFER_EMPLOYEE);
00621
00622 mxml_AddInt(ss, SAVE_TRANSFER_UCN, empl->chr.ucn);
00623 }
00624 }
00625 }
00626 }
00627
00628 if (transfer->hasAircraft) {
00629 for (j = 0; j < ccs.numAircraft; j++) {
00630 if (transfer->aircraftArray[j] > TRANS_LIST_EMPTY_SLOT) {
00631 mxml_node_t *ss = mxml_AddNode(s, SAVE_TRANSFER_AIRCRAFT);
00632 mxml_AddInt(ss, SAVE_TRANSFER_ID, j);
00633 }
00634 }
00635 }
00636 }
00637 return qtrue;
00638 }
00639
00646 qboolean TR_LoadXML (mxml_node_t *p)
00647 {
00648 mxml_node_t *n, *s;
00649
00650 n = mxml_GetNode(p, SAVE_TRANSFER_TRANSFERS);
00651 if (!n)
00652 return qfalse;
00653
00654 assert(ccs.numBases);
00655
00656 for (s = mxml_GetNode(n, SAVE_TRANSFER_TRANSFER); s && ccs.numTransfers < MAX_TRANSFERS; s = mxml_GetNextNode(s, n, SAVE_TRANSFER_TRANSFER)) {
00657 mxml_node_t *ss;
00658 transfer_t *transfer = &ccs.transfers[ccs.numTransfers];
00659
00660 transfer->destBase = B_GetBaseByIDX(mxml_GetInt(s, SAVE_TRANSFER_DESTBASE, BYTES_NONE));
00661 if (!transfer->destBase) {
00662 Com_Printf("Error: Transfer has no destBase set\n");
00663 return qfalse;
00664 }
00665 transfer->srcBase = B_GetBaseByIDX(mxml_GetInt(s, SAVE_TRANSFER_SRCBASE, BYTES_NONE));
00666
00667 transfer->event.day = mxml_GetInt(s, SAVE_TRANSFER_DAY, 0);
00668 transfer->event.sec = mxml_GetInt(s, SAVE_TRANSFER_SEC, 0);
00669 transfer->active = qtrue;
00670
00671
00672 transfer->hasItems = qfalse;
00673 transfer->hasEmployees = qfalse;
00674 transfer->hasAliens = qfalse;
00675 transfer->hasAircraft = qfalse;
00676 memset(transfer->itemAmount, 0, sizeof(transfer->itemAmount));
00677 memset(transfer->alienAmount, 0, sizeof(transfer->alienAmount));
00678 memset(transfer->employeeArray, 0, sizeof(transfer->employeeArray));
00679 memset(transfer->aircraftArray, TRANS_LIST_EMPTY_SLOT, sizeof(transfer->aircraftArray));
00680
00681
00682
00683 ss = mxml_GetNode(s, SAVE_TRANSFER_ITEM);
00684 if (ss) {
00685 transfer->hasItems = qtrue;
00686 for (; ss; ss = mxml_GetNextNode(ss, s, SAVE_TRANSFER_ITEM)) {
00687 const char *itemId = mxml_GetString(ss, SAVE_TRANSFER_ITEMID);
00688 const objDef_t *od = INVSH_GetItemByID(itemId);
00689
00690 if (od)
00691 transfer->itemAmount[od->idx] = mxml_GetInt(ss, SAVE_TRANSFER_AMOUNT, 1);
00692 }
00693 }
00694
00695 ss = mxml_GetNode(s, SAVE_TRANSFER_ALIEN);
00696 if (ss) {
00697 transfer->hasAliens = qtrue;
00698 for (; ss; ss = mxml_GetNextNode(ss, s, SAVE_TRANSFER_ALIEN)) {
00699 const int alive = mxml_GetInt(ss, SAVE_TRANSFER_ALIVEAMOUNT, 0);
00700 const int dead = mxml_GetInt(ss, SAVE_TRANSFER_DEADAMOUNT, 0);
00701 const char *id = mxml_GetString(ss, SAVE_TRANSFER_ALIENID);
00702 int j;
00703
00704
00705 for (j = 0; j < ccs.numAliensTD; j++) {
00706 if (ccs.alienTeams[j] && !strcmp(id, ccs.alienTeams[j]->id))
00707 break;
00708 }
00709
00710 if (j < ccs.numAliensTD) {
00711 transfer->alienAmount[j][TRANS_ALIEN_ALIVE] = alive;
00712 transfer->alienAmount[j][TRANS_ALIEN_DEAD] = dead;
00713 } else {
00714 Com_Printf("CL_LoadXML: AlienId '%s' is invalid\n", id);
00715 }
00716 }
00717 }
00718
00719 ss = mxml_GetNode(s, SAVE_TRANSFER_EMPLOYEE);
00720 if (ss) {
00721 transfer->hasEmployees = qtrue;
00722 for (; ss; ss = mxml_GetNextNode(ss, s, SAVE_TRANSFER_EMPLOYEE)) {
00723 const int ucn = mxml_GetInt(ss, SAVE_TRANSFER_UCN, -1);
00724 employee_t *empl = E_GetEmployeeFromChrUCN(ucn);
00725
00726 if (!empl) {
00727 Com_Printf("Error: No employee found with UCN: %i\n", ucn);
00728 return qfalse;
00729 }
00730
00731 transfer->employeeArray[empl->type][empl->idx] = empl;
00732 transfer->employeeArray[empl->type][empl->idx]->transfer = qtrue;
00733 }
00734 }
00735
00736 ss = mxml_GetNode(s, SAVE_TRANSFER_AIRCRAFT);
00737 if (ss) {
00738 transfer->hasAircraft = qtrue;
00739 for (; ss; ss = mxml_GetNextNode(ss, s, SAVE_TRANSFER_AIRCRAFT)) {
00740 const int j = mxml_GetInt(ss, SAVE_TRANSFER_ID, -1);
00741
00742 if (j >= 0 && j < ccs.numAircraft)
00743 transfer->aircraftArray[j] = j;
00744 }
00745 }
00746 ccs.numTransfers++;
00747 }
00748
00749 return qtrue;
00750 }
00751
00756 void TR_InitStartup (void)
00757 {
00758
00759 #ifdef DEBUG
00760 Cmd_AddCommand("debug_listtransfers", TR_ListTransfers_f, "Lists an/all active transfer(s)");
00761 #endif
00762 }
00763