cp_aliencont.c

Go to the documentation of this file.
00001 
00008 /*
00009 Copyright (C) 2002-2010 UFO: Alien Invasion.
00010 
00011 This program is free software; you can redistribute it and/or
00012 modify it under the terms of the GNU General Public License
00013 as published by the Free Software Foundation; either version 2
00014 of the License, or (at your option) any later version.
00015 
00016 This program is distributed in the hope that it will be useful,
00017 but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00019 
00020 See the GNU General Public License for more details.
00021 
00022 You should have received a copy of the GNU General Public License
00023 along with this program; if not, write to the Free Software
00024 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00025 
00026 */
00027 
00028 #include "../client.h"
00029 #include "cp_campaign.h"
00030 #include "cp_aliencont_callbacks.h"
00031 #include "save/save_aliencont.h"
00032 
00044 static inline int AL_GetCargoIndexForTeamDefintion (const aircraft_t *aircraft, const teamDef_t *teamDef)
00045 {
00046     const aliensTmp_t *cargo = AL_GetAircraftAlienCargo(aircraft);
00047     const int alienCargoTypes = AL_GetAircraftAlienCargoTypes(aircraft);
00048     int i;
00049 
00050     for (i = 0; i < alienCargoTypes; i++, cargo++) {
00051         if (cargo->teamDef == teamDef)
00052             break;
00053     }
00054 
00055     /* in case teamdef wasn't found, return the next free index */
00056     assert(i < MAX_CARGO);
00057     return i;
00058 }
00059 
00072 qboolean AL_AddAlienTypeToAircraftCargo (aircraft_t *aircraft, const teamDef_t *teamDef, int amount, qboolean dead)
00073 {
00074     aliensTmp_t *cargo = AL_GetAircraftAlienCargo(aircraft);
00075     const int alienCargoTypes = AL_GetAircraftAlienCargoTypes(aircraft);
00076     const int index = AL_GetCargoIndexForTeamDefintion(aircraft, teamDef);
00077 
00078     if (!cargo[index].teamDef)
00079         AL_SetAircraftAlienCargoTypes(aircraft, alienCargoTypes + 1);
00080     cargo[index].teamDef = teamDef;
00081 
00082     if (dead)
00083         cargo[index].amountDead += amount;
00084     else
00085         cargo[index].amountAlive += amount;
00086 
00087     return qtrue;
00088 }
00089 
00100 void AL_FillInContainment (base_t *base)
00101 {
00102     int i, counter = 0;
00103     aliensCont_t *containment;
00104 
00105     assert(base);
00106     containment = base->alienscont;
00107 
00108     for (i = 0; i < csi.numTeamDefs; i++) {
00109         const teamDef_t *td = &csi.teamDef[i];
00110         if (!CHRSH_IsTeamDefAlien(td))
00111             continue;
00112         if (counter >= MAX_ALIENCONT_CAP)
00113             Com_Error(ERR_DROP, "Overflow in AL_FillInContainment");
00114         containment->teamDef = td;  /* Link to global race index. */
00115         containment->amountAlive = 0;
00116         containment->amountDead = 0;
00117         /* for sanity checking */
00118         containment->tech = ccs.teamDefTechs[td->idx];
00119         if (!containment->tech)
00120             Com_Error(ERR_DROP, "Could not find a valid tech for '%s'\n", td->name);
00121         Com_DPrintf(DEBUG_CLIENT, "AL_FillInContainment: type: %s tech-index: %i\n", td->name, containment->tech->idx);
00122         containment++;
00123         counter++;
00124     }
00125     base->capacities[CAP_ALIENS].cur = 0;
00126 }
00127 
00133 const char *AL_AlienTypeToName (int teamDefIdx)
00134 {
00135     if (teamDefIdx < 0 || teamDefIdx >= csi.numTeamDefs) {
00136         Com_Printf("AL_AlienTypeToName: invalid team index %i\n", teamDefIdx);
00137         return NULL;
00138     }
00139     return csi.teamDef[teamDefIdx].name;
00140 }
00141 
00148 void AL_CollectingAliens (aircraft_t *aircraft)
00149 {
00150     le_t *le = NULL;
00151 
00152     while ((le = LE_GetNextInUse(le))) {
00153         if (LE_IsActor(le) && LE_IsAlien(le)) {
00154             assert(le->teamDef);
00155 
00156             if (LE_IsStunned(le))
00157                 AL_AddAlienTypeToAircraftCargo(aircraft, le->teamDef, 1, qfalse);
00158             else if (LE_IsDead(le))
00159                 AL_AddAlienTypeToAircraftCargo(aircraft, le->teamDef, 1, qtrue);
00160         }
00161     }
00162 }
00163 
00171 void AL_AddAliens (aircraft_t *aircraft)
00172 {
00173     base_t *toBase;
00174     const aliensTmp_t *cargo;
00175     int alienCargoTypes;
00176     int i;
00177     int j;
00178     qboolean limit = qfalse;
00179     qboolean messageAlreadySet = qfalse;
00180     technology_t *breathingTech;
00181     qboolean alienBreathing = qfalse;
00182     const objDef_t *alienBreathingObjDef;
00183 
00184     assert(aircraft);
00185     toBase = aircraft->homebase;
00186     assert(toBase);
00187 
00188     cargo = AL_GetAircraftAlienCargo(aircraft);
00189     alienCargoTypes = AL_GetAircraftAlienCargoTypes(aircraft);
00190 
00191     if (alienCargoTypes == 0)
00192         return;
00193     
00194     if (!B_GetBuildingStatus(toBase, B_ALIEN_CONTAINMENT)) {
00195         MS_AddNewMessage(_("Notice"), _("You cannot process aliens yet. Alien Containment not ready in this base."), qfalse, MSG_STANDARD, NULL);
00196         return;
00197     }
00198 
00199     breathingTech = RS_GetTechByID(BREATHINGAPPARATUS_TECH);
00200     if (!breathingTech)
00201         Com_Error(ERR_DROP, "AL_AddAliens: Could not get breathing apparatus tech definition");
00202     alienBreathing = RS_IsResearched_ptr(breathingTech);
00203     alienBreathingObjDef = INVSH_GetItemByID(breathingTech->provides);
00204     if (!alienBreathingObjDef)
00205         Com_Error(ERR_DROP, "AL_AddAliens: Could not get breathing apparatus item definition");
00206 
00207     for (i = 0; i < alienCargoTypes; i++) {
00208         for (j = 0; j < ccs.numAliensTD; j++) {
00209             assert(toBase->alienscont[j].teamDef);
00210             assert(cargo[i].teamDef);
00211 
00212             if (toBase->alienscont[j].teamDef == cargo[i].teamDef) {
00213                 toBase->alienscont[j].amountDead += cargo[i].amountDead;
00214                 /* Add breathing apparatuses to aircraft cargo so that they are processed with other collected items */
00215                 AII_CollectItem(aircraft, alienBreathingObjDef, cargo[i].amountDead);
00216                 if (cargo[i].amountAlive <= 0)
00217                     continue;
00218                 if (!alienBreathing && !CHRSH_IsTeamDefRobot(cargo[i].teamDef)) {
00219                     /* We can not store living (i.e. no robots or dead bodies) aliens without rs_alien_breathing tech */
00220                     toBase->alienscont[j].amountDead += cargo[i].amountAlive;
00221                     /* Add breathing apparatuses as well */
00222                     AII_CollectItem(aircraft, alienBreathingObjDef, cargo[i].amountAlive);
00223                     /* only once */
00224                     if (!messageAlreadySet) {
00225                         MS_AddNewMessage(_("Notice"), _("You can't hold live aliens yet. Aliens died."), qfalse, MSG_DEATH, NULL);
00226                         messageAlreadySet = qtrue;
00227                     }
00228                     if (!ccs.breathingMailSent) {
00229                         Cmd_ExecuteString("addeventmail alienbreathing");
00230                         ccs.breathingMailSent = qtrue;
00231                     }
00232                 } else {
00233                     int k;
00234 
00235                     for (k = 0; k < cargo[i].amountAlive; k++) {
00236                         /* Check base capacity. */
00237                         if (AL_CheckAliveFreeSpace(toBase, NULL, 1)) {
00238                             AL_ChangeAliveAlienNumber(toBase, &(toBase->alienscont[j]), 1);
00239                         } else {
00240                             /* Every exceeding alien is killed
00241                              * Display a message only when first one is killed */
00242                             if (!limit) {
00243                                 toBase->capacities[CAP_ALIENS].cur = toBase->capacities[CAP_ALIENS].max;
00244                                 MS_AddNewMessage(_("Notice"), _("You don't have enough space in Alien Containment. Some aliens got killed."), qfalse, MSG_STANDARD, NULL);
00245                                 limit = qtrue;
00246                             }
00247                             /* Just kill aliens which don't fit the limit. */
00248                             toBase->alienscont[j].amountDead++;
00249                             AII_CollectItem(aircraft, alienBreathingObjDef, 1);
00250                         }
00251                     }
00252                     /* only once */
00253                     if (!messageAlreadySet) {
00254                         MS_AddNewMessage(_("Notice"), _("You've captured new aliens."), qfalse, MSG_STANDARD, NULL);
00255                         messageAlreadySet = qtrue;
00256                     }
00257                 }
00258                 break;
00259             }
00260         }
00261     }
00262 
00263     for (i = 0; i < ccs.numAliensTD; i++) {
00264         technology_t *tech = toBase->alienscont[i].tech;
00265 #ifdef DEBUG
00266         if (!tech)
00267             Sys_Error("AL_AddAliens: Failed to initialize the tech for '%s'\n", toBase->alienscont[i].teamDef->name);
00268 #endif
00269         /* we need this to let RS_Collected_ return true */
00270         if (toBase->alienscont[i].amountAlive + toBase->alienscont[i].amountDead > 0)
00271             RS_MarkCollected(tech);
00272 #ifdef DEBUG
00273         /* print all of them */
00274         if (toBase->alienscont[i].amountAlive > 0)
00275             Com_DPrintf(DEBUG_CLIENT, "AL_AddAliens alive: %s amount: %i\n", toBase->alienscont[i].teamDef->name, toBase->alienscont[i].amountAlive);
00276         if (toBase->alienscont[i].amountDead > 0)
00277             Com_DPrintf(DEBUG_CLIENT, "AL_AddAliens bodies: %s amount: %i\n", toBase->alienscont[i].teamDef->name, toBase->alienscont[i].amountDead);
00278 #endif
00279     }
00280 
00281     /* we shouldn't have any more aliens on the aircraft after this */
00282     AL_SetAircraftAlienCargoTypes(aircraft, 0);
00283 }
00284 
00296 void AL_RemoveAliens (base_t *base, const teamDef_t *alienType, int amount, const alienCalcType_t action)
00297 {
00298     int j, toremove;
00299     aliensCont_t *containment;
00300 
00301     assert(base);
00302     containment = base->alienscont;
00303 
00304     switch (action) {
00305     case AL_RESEARCH:
00306         if (!alienType) {
00307             int maxidx = 0;
00308             int maxamount = 0; /* amount (of alien type), which is max in Containment) */
00309             /* Search for the type of alien, which has max amount
00310              * in Alien Containment, then remove (amount). */
00311             while (amount > 0) {
00312                 /* Find the type with maxamount. */
00313                 for (j = 0; j < ccs.numAliensTD; j++) {
00314                     if (maxamount < containment[j].amountAlive) {
00315                         maxamount = containment[j].amountAlive;
00316                         maxidx = j;
00317                     }
00318                 }
00319                 if (maxamount == 0) {
00320                     /* That should never happen. */
00321                     Com_Printf("AL_RemoveAliens: unable to find alive aliens\n");
00322                     return;
00323                 }
00324                 if (maxamount == 1) {
00325                     /* If only one here, just remove. */
00326                     AL_ChangeAliveAlienNumber(base, &containment[maxidx], -1);
00327                     containment[maxidx].amountDead++;
00328                     --amount;
00329                 } else {
00330                     /* If more than one, remove the amount. */
00331                     toremove = maxamount - 1;
00332                     if (toremove > amount)
00333                         toremove = amount;
00334                     AL_ChangeAliveAlienNumber(base, &containment[maxidx], -toremove);
00335                     containment[maxidx].amountDead += toremove;
00336                     amount -= toremove;
00337                 }
00338             }
00339         }
00340         break;
00341     case AL_KILL:
00342         /* We ignore 2nd and 3rd parameter of AL_RemoveAliens() here. */
00343         for (j = 0; j < ccs.numAliensTD; j++) {
00344             if (containment[j].amountAlive > 0) {
00345                 containment[j].amountDead += containment[j].amountAlive;
00346                 AL_ChangeAliveAlienNumber(base, &containment[j], -containment[j].amountAlive);
00347             }
00348         }
00349         break;
00350     case AL_KILLONE:
00351         /* We ignore 3rd parameter of AL_RemoveAliens() here. */
00352         for (j = 0; j < ccs.numAliensTD; j++) {
00353             assert(containment[j].teamDef);
00354             if (containment[j].teamDef == alienType) {
00355                 if (containment[j].amountAlive == 0)
00356                     return;
00357                 /* We are killing only one here, so we
00358                  * don't care about amount param. */
00359                 AL_ChangeAliveAlienNumber(base, &containment[j], -1);
00360                 containment[j].amountDead++;
00361                 break;
00362             }
00363         }
00364         break;
00365     default:
00366         Sys_Error("AL_RemoveAliens: Use AL_AddAliens for action %i", action);
00367     }
00368 }
00369 
00370 #ifdef DEBUG
00371 
00376 static void AL_AddAliens2 (base_t *base, const teamDef_t *alienType, const qboolean dead)
00377 {
00378     int j;
00379     aliensCont_t *containment;
00380 
00381     assert(base);
00382     containment = base->alienscont;
00383 
00384     if (dead) {
00385         for (j = 0; j < ccs.numAliensTD; j++) {
00386             assert(containment[j].teamDef);
00387             if (containment[j].teamDef == alienType) {
00388                 containment[j].amountDead++;
00389                 break;
00390             }
00391         }
00392     } else {
00393         /* We ignore 3rd parameter of AL_RemoveAliens() here: add only 1 alien */
00394         if (!AL_CheckAliveFreeSpace(base, NULL, 1)) {
00395             return; /* stop because we will else exceed the max of aliens */
00396         }
00397         for (j = 0; j < ccs.numAliensTD; j++) {
00398             assert(containment[j].teamDef);
00399             if (containment[j].teamDef == alienType) {
00400                 AL_ChangeAliveAlienNumber(base, &containment[j], 1);
00401                 break;
00402             }
00403         }
00404     }
00405 }
00406 #endif
00407 
00417 static int AL_GetAlienIDX (const teamDef_t *alienType)
00418 {
00419     int i, index;
00420 
00421     index = 0;
00422     for (i = 0; i < csi.numTeamDefs; i++) {
00423         if (alienType == &csi.teamDef[i])
00424             return index;
00425         if (CHRSH_IsTeamDefAlien(&csi.teamDef[i]))
00426             index++;
00427     }
00428 
00429     Com_Printf("AL_GetAlienIDX: Alien \"%s\" not found!\n", alienType->id);
00430     return -1;
00431 }
00432 
00439 int AL_GetAlienGlobalIDX (int idx)
00440 {
00441     int i, counter = 0;
00442 
00443     for (i = 0; i < csi.numTeamDefs; i++) {
00444         if (CHRSH_IsTeamDefAlien(&csi.teamDef[i])) {
00445             if (counter == idx)
00446                 return i;
00447             counter++;
00448         }
00449     }
00450     Com_Printf("AL_GetAlienGlobalIDX: Alien with AC index %i not found!\n", idx);
00451     return -1;
00452 }
00453 
00463 int AL_GetAlienAmount (const teamDef_t *alienType, requirementType_t reqtype, const base_t *base)
00464 {
00465     const aliensCont_t *containment;
00466     int alienTypeIndex;
00467 
00468     assert(alienType);
00469     assert(base);
00470     alienTypeIndex = AL_GetAlienIDX(alienType);
00471     assert(alienTypeIndex >= 0);
00472     containment = &base->alienscont[alienTypeIndex];
00473 
00474     switch (reqtype) {
00475     case RS_LINK_ALIEN:
00476         return containment->amountAlive;
00477     case RS_LINK_ALIEN_DEAD:
00478         return containment->amountDead;
00479     default:
00480         return containment->amountDead;
00481     }
00482 }
00483 
00492 int AL_CountInBase (const base_t *base)
00493 {
00494     int j;
00495     int amount = 0;
00496 
00497     assert(base);
00498 
00499     for (j = 0; j < ccs.numAliensTD; j++) {
00500         if (base->alienscont[j].teamDef)
00501             amount += base->alienscont[j].amountAlive;
00502     }
00503 
00504     return amount;
00505 }
00506 
00515 void AL_ChangeAliveAlienNumber (base_t *base, aliensCont_t *containment, int num)
00516 {
00517     assert(base);
00518     assert(containment);
00519 
00520     /* Just a sanity check -- should never be reached */
00521     if (!AL_CheckAliveFreeSpace(base, containment, num))
00522         Com_Error(ERR_DROP, "AL_ChangeAliveAlienNumber: Can't add/remove %i live aliens, (capacity: %i/%i, Alien Containment Status: %i)\n",
00523             num, base->capacities[CAP_ALIENS].cur, base->capacities[CAP_ALIENS].max,
00524             B_GetBuildingStatus(base, B_ALIEN_CONTAINMENT));
00525 
00526     containment->amountAlive += num;
00527     base->capacities[CAP_ALIENS].cur += num;
00528 
00529 #ifdef DEBUG
00530     if (base->capacities[CAP_ALIENS].cur != AL_CountInBase(base))
00531         Com_Printf("AL_ChangeAliveAlienNumber: Wrong capacity in Alien containment: %i instead of %i\n",
00532             base->capacities[CAP_ALIENS].cur, AL_CountInBase(base));
00533 #endif
00534 }
00535 
00544 qboolean AL_CheckAliveFreeSpace (const base_t *base, const aliensCont_t *containment, const int num)
00545 {
00546     if (num > 0) {
00547         /* We add aliens */
00548         /* you need Alien Containment and it's dependencies to handle aliens */
00549         if (!B_GetBuildingStatus(base, B_ALIEN_CONTAINMENT))
00550             return qfalse;
00551         if (base->capacities[CAP_ALIENS].cur + num > base->capacities[CAP_ALIENS].max)
00552             return qfalse;
00553     } else {
00554         /* @note don't check building status here.
00555          * dependencies may have been destroyed before alien container (B_Destroy) */
00556         if (base->capacities[CAP_ALIENS].cur + num < 0)
00557             return qfalse;
00558         if (containment && (containment->amountAlive + num < 0))
00559             return qfalse;
00560     }
00561 
00562     return qtrue;
00563 }
00564 
00577 int AL_CountAll (void)
00578 {
00579     int i, j;
00580     int amount = 0;
00581 
00582     for (i = 0; i < MAX_BASES; i++) {
00583         const base_t const *base = B_GetFoundedBaseByIDX(i);
00584         if (!base)
00585             continue;
00586         if (!B_GetBuildingStatus(base, B_ALIEN_CONTAINMENT))
00587             continue;
00588         for (j = 0; j < ccs.numAliensTD; j++) {
00589             if (base->alienscont[j].teamDef)
00590                 amount += base->alienscont[j].amountAlive;
00591         }
00592     }
00593     return amount;
00594 }
00595 
00601 void AC_KillAll (base_t *base)
00602 {
00603     int i;
00604     qboolean aliens = qfalse;
00605 
00606     assert(base);
00607 
00608     /* Are there aliens here at all? */
00609     for (i = 0; i < ccs.numAliensTD; i++) {
00610         if (base->alienscont[i].amountAlive > 0) {
00611             aliens = qtrue;
00612             break;
00613         }
00614     }
00615 
00616     /* No aliens, return. */
00617     if (!aliens)
00618         return;
00619 
00620     AL_RemoveAliens(base, NULL, 0, AL_KILL);
00621 }
00622 
00623 #ifdef DEBUG
00624 
00627 static void AC_AddOne_f (void)
00628 {
00629     const char *alienName;
00630     teamDef_t *alienType;
00631     aliensCont_t *containment;
00632     qboolean updateAlive = qtrue;
00633     int j;
00634     base_t *base = B_GetCurrentSelectedBase();
00635 
00636     /* Can be called from everywhere. */
00637     if (!base)
00638         return;
00639 
00640     /* arg parsing */
00641     if (Cmd_Argc() < 2) {
00642         Com_Printf("Usage: %s <alientype> [dead:true|false]\n", Cmd_Argv(0));
00643         return;
00644     }
00645 
00646     alienName = Cmd_Argv(1);
00647     alienType = Com_GetTeamDefinitionByID(alienName);
00648 
00649     if (!alienType) {
00650         Com_Printf("AC_AddOne_f: Team definition '%s' does not exist.\n", alienName);
00651         return;
00652     }
00653 
00654     /* Check that alientType exists */
00655     containment = base->alienscont;
00656     for (j = 0; j < ccs.numAliensTD; j++) {
00657         assert(containment[j].teamDef);
00658         if (containment[j].teamDef == alienType)
00659             break;
00660     }
00661     if (j == ccs.numAliensTD) {
00662         Com_Printf("AC_AddOne_f: Alien Type '%s' does not exist. Available choices are:\n", alienName);
00663         for (j = 0; j < ccs.numAliensTD; j++)
00664             Com_Printf("\t* %s\n", containment[j].teamDef->name);
00665         return;
00666     }
00667 
00668     if (Cmd_Argc() == 3)
00669         updateAlive = Com_ParseBoolean(Com_Argv(2));
00670 
00671     /* update alien counter*/
00672     if (B_GetBuildingStatus(base, B_ALIEN_CONTAINMENT)) {
00673         containment = base->alienscont;
00674     } else {
00675         return;
00676     }
00677 
00678     /* call the function that actually changes the persistent datastructure */
00679     AL_AddAliens2(base, alienType, !updateAlive);
00680 }
00681 #endif
00682 
00687 void AC_InitStartup (void)
00688 {
00689     /* add commands */
00690 #ifdef DEBUG
00691     Cmd_AddCommand("debug_addalientocont", AC_AddOne_f, "Add one alien of a given type");
00692 #endif
00693     AC_InitCallbacks();
00694 }
00695 
00702 qboolean AC_SaveXML (mxml_node_t * parent)
00703 {
00704     mxml_node_t *aliencont;
00705     int i;
00706 
00707     aliencont = mxml_AddNode(parent, SAVE_ALIENCONT_ALIENCONT);
00708     mxml_AddBoolValue(aliencont, SAVE_ALIENCONT_BREATHINGMAILSENT, ccs.breathingMailSent);
00709 
00710     for (i = 0; i < MAX_BASES; i++) {
00711         base_t *base = B_GetFoundedBaseByIDX(i);
00712         mxml_node_t *node;
00713         int k;
00714 
00715         if (!base)
00716             continue;
00717         if (!AC_ContainmentAllowed(base))
00718             continue;
00719 
00720         node = mxml_AddNode(aliencont, SAVE_ALIENCONT_CONT);
00721         mxml_AddInt(node, SAVE_ALIENCONT_BASEIDX, i);
00722         for (k = 0; k < MAX_ALIENCONT_CAP && k < ccs.numAliensTD; k++) {
00723             mxml_node_t * snode = mxml_AddNode(node, SAVE_ALIENCONT_ALIEN);
00724             
00725             assert(base->alienscont);
00726             assert(base->alienscont[k].teamDef);
00727             assert(base->alienscont[k].teamDef->id);
00728             
00729             mxml_AddString(snode, SAVE_ALIENCONT_TEAMID, base->alienscont[k].teamDef->id);
00730             mxml_AddIntValue(snode, SAVE_ALIENCONT_AMOUNTALIVE, base->alienscont[k].amountAlive);
00731             mxml_AddIntValue(snode, SAVE_ALIENCONT_AMOUNTDEAD, base->alienscont[k].amountDead);
00732         }
00733     }
00734 
00735     return qtrue;
00736 }
00737 
00744 qboolean AC_LoadXML (mxml_node_t * parent)
00745 {
00746     mxml_node_t *aliencont;
00747     mxml_node_t *contNode;
00748     int i;
00749 
00750     aliencont = mxml_GetNode(parent, SAVE_ALIENCONT_ALIENCONT);
00751     ccs.breathingMailSent = mxml_GetBool(aliencont, SAVE_ALIENCONT_BREATHINGMAILSENT, qfalse);
00752 
00753     /* Init alienContainers */
00754     for (i = 0; i < MAX_BASES; i++) {
00755         base_t *base = B_GetBaseByIDX(i);
00756 
00757         AL_FillInContainment(base);
00758     }
00759     /* Load data */
00760     for (contNode = mxml_GetNode(aliencont, SAVE_ALIENCONT_CONT); contNode;
00761             contNode = mxml_GetNextNode(contNode, aliencont, SAVE_ALIENCONT_CONT)) {
00762         int j = mxml_GetInt(contNode, SAVE_ALIENCONT_BASEIDX, MAX_BASES);
00763         base_t *base = B_GetFoundedBaseByIDX(j);
00764         int k;
00765         mxml_node_t *alienNode;
00766 
00767         if (!base) {
00768             Com_Printf("AC_LoadXML: Invalid base idx '%i'\n", j);
00769             continue;
00770         }
00771 
00772         for (k = 0, alienNode = mxml_GetNode(contNode, SAVE_ALIENCONT_ALIEN); alienNode && k < MAX_ALIENCONT_CAP; alienNode = mxml_GetNextNode(alienNode, contNode, SAVE_ALIENCONT_ALIEN), k++) {
00773             const char *const s = mxml_GetString(alienNode, SAVE_ALIENCONT_TEAMID);
00774             /* Fill Alien Containment with default values like the tech pointer. */
00775             base->alienscont[k].teamDef = Com_GetTeamDefinitionByID(s);
00776             if (base->alienscont[k].teamDef) {
00777                 base->alienscont[k].amountAlive = mxml_GetInt(alienNode, SAVE_ALIENCONT_AMOUNTALIVE, 0);
00778                 base->alienscont[k].amountDead = mxml_GetInt(alienNode, SAVE_ALIENCONT_AMOUNTDEAD, 0);
00779             }
00780         }
00781     }
00782 
00783     return qtrue;
00784 }
00785 
00791 qboolean AC_ContainmentAllowed (const base_t* base)
00792 {
00793     if (B_GetBuildingStatus(base, B_ALIEN_CONTAINMENT)) {
00794         return qtrue;
00795     } else {
00796         return qfalse;
00797     }
00798 }
00799 

Generated by  doxygen 1.6.2