cp_uforecovery.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 "../cl_shared.h"
00029 #include "cp_campaign.h"
00030 #include "cp_ufo.h"
00031 #include "cp_map.h"
00032 #include "cp_uforecovery.h"
00033 #include "cp_uforecovery_callbacks.h"
00034 #include "cp_aircraft.h"
00035 #include "save/save_uforecovery.h"
00036 
00037 /*==================================
00038 Backend functions
00039 ==================================*/
00040 
00045 void UR_ProcessActive (void)
00046 {
00047     storedUFO_t *ufo = NULL;
00048 
00049     while ((ufo = US_GetNext(ufo)) != NULL) {
00050         assert(ufo->ufoTemplate);
00051         assert(ufo->ufoTemplate->tech);
00052 
00053         if (ufo->status == SUFO_STORED)
00054             continue;
00055         if (ufo->arrive.day > ccs.date.day || (ufo->arrive.day == ccs.date.day && ufo->arrive.sec > ccs.date.sec))
00056             continue;
00057 
00058         ufo->status = SUFO_STORED;
00059 
00060         Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer), _("%s was transfered to %s."), UFO_TypeToName(ufo->ufoTemplate->ufotype), ufo->installation->name);
00061         MSO_CheckAddNewMessage(NT_TRANSFER_UFORECOVERY_FINISHED, _("UFO Recovered"), cp_messageBuffer, qfalse, MSG_TRANSFERFINISHED, NULL);
00062 
00063         if (!ufo->ufoTemplate->tech->statusCollected)
00064             RS_MarkCollected(ufo->ufoTemplate->tech);
00065     }
00066 }
00067 
00068 /* ==== UFO Storing stuff ==== */
00069 
00074 storedUFO_t* US_GetNext (storedUFO_t *lastUFO)
00075 {
00076     return (storedUFO_t*)LIST_GetNext(ccs.storedUFOs, lastUFO);
00077 }
00078 
00084 storedUFO_t* US_GetStoredUFOByIDX (const int idx)
00085 {
00086     storedUFO_t *ufo = NULL;
00087 
00088     while ((ufo = US_GetNext(ufo)) != NULL) {
00089         if (ufo->idx == idx)
00090             return ufo;
00091     }
00092     return NULL;
00093 }
00094 
00104 storedUFO_t *US_StoreUFO (const aircraft_t *ufoTemplate, installation_t *installation, date_t date, float condition)
00105 {
00106     storedUFO_t ufo;
00107 
00108     if (!ufoTemplate) {
00109         Com_DPrintf(DEBUG_CLIENT, "US_StoreUFO: Invalid aircraft (UFO) Template.\n");
00110         return NULL;
00111     }
00112 
00113     if (!installation) {
00114         Com_DPrintf(DEBUG_CLIENT, "US_StoreUFO: Invalid Installation\n");
00115         return NULL;
00116     }
00117 
00118     if (installation->ufoCapacity.cur >= installation->ufoCapacity.max) {
00119         Com_DPrintf(DEBUG_CLIENT, "US_StoreUFO: Installation is full with UFOs.\n");
00120         return NULL;
00121     }
00122 
00123     /* we can store it there */
00124     ufo.idx = ccs.campaignStats.ufosStored++;
00125     Q_strncpyz(ufo.id, ufoTemplate->id, sizeof(ufo.id));
00126     ufo.comp = CL_GetComponentsByID(ufo.id);
00127     assert(ufo.comp);
00128 
00129     ufo.installation = installation;
00130     installation->ufoCapacity.cur++;
00131 
00132     assert(ufoTemplate->tech);
00133 
00134     ufo.ufoTemplate = ufoTemplate;
00135     ufo.disassembly = NULL;
00136 
00137     ufo.arrive = date;
00138     if (date.day < ccs.date.day || (date.day == ccs.date.day && date.sec <= ccs.date.sec)) {
00139         ufo.status = SUFO_STORED;
00140         RS_MarkCollected(ufo.ufoTemplate->tech);
00141     } else {
00142         ufo.status = SUFO_RECOVERED;
00143     }
00144     ufo.condition = min(max(0, condition), 1);
00145 
00146     return (storedUFO_t *)(LIST_Add(&ccs.storedUFOs, (void*)&ufo, sizeof(ufo)))->data;
00147 }
00148 
00153 void US_RemoveStoredUFO (storedUFO_t *ufo)
00154 {
00155     int ufoCount;
00156 
00157     assert(ufo);
00158 
00159     /* Stop disassembling */
00160     if (ufo->disassembly) {
00161         base_t *prodBase = PR_ProductionBase(ufo->disassembly);
00162 
00163         assert(prodBase);
00164 
00165         if (ufo->disassembly->idx == 0)
00166             PR_QueueNext(prodBase);
00167         else
00168             PR_QueueDelete(prodBase, &ccs.productions[prodBase->idx], ufo->disassembly->idx);
00169     }
00170 
00171     /* Stop running research if this is the only UFO from this type
00172      * also clear collected status */
00173     assert(ufo->ufoTemplate);
00174     ufoCount = US_UFOsInStorage(ufo->ufoTemplate, NULL);
00175     if (ufoCount <= 1 && ufo->ufoTemplate->tech->statusResearch == RS_RUNNING)
00176         RS_StopResearch(ufo->ufoTemplate->tech);
00177 
00178     /* remove ufo */
00179     ufo->installation->ufoCapacity.cur--;
00180     LIST_Remove(&ccs.storedUFOs, (void*)ufo);
00181 }
00182 
00183 
00191 int US_UFOsInStorage (const aircraft_t *ufoTemplate, const installation_t *installation)
00192 {
00193     storedUFO_t *ufo = NULL;
00194     int count = 0;
00195 
00196     while ((ufo = US_GetNext(ufo)) != NULL) {
00197         if (ufo->ufoTemplate != ufoTemplate)
00198             continue;
00199         if (installation && ufo->installation != installation)
00200             continue;
00201         if (ufo->status != SUFO_STORED)
00202             continue;
00203 
00204         count++;
00205     }
00206 
00207     return count;
00208 }
00209 
00214 void US_RemoveUFOsExceedingCapacity (installation_t *installation)
00215 {
00216     const capacities_t *ufoCap;
00217     storedUFO_t *lastUfo = NULL;
00218     storedUFO_t *ufo = NULL;
00219 
00220     if (!installation)
00221         Com_Error(ERR_DROP, "US_RemoveUFOsExceedingCapacity: No installation given!\n");
00222 
00223     ufoCap = &installation->ufoCapacity;
00224 
00225     while ((ufo = US_GetNext(ufo)) != NULL) {
00226         if (ufoCap->cur <= ufoCap->max)
00227             break;
00228         if (ufo->installation != installation) {
00229             lastUfo = ufo;
00230             continue;
00231         }
00232         US_RemoveStoredUFO(ufo);
00233         /* this ufo is removed from the list, continue iterating from the last */
00234         ufo = lastUfo;
00235     }
00236 }
00237 
00244 storedUFO_t *US_GetClosestStoredUFO (const aircraft_t *ufoTemplate, const base_t *base)
00245 {
00246     float minDistance = -1;
00247     storedUFO_t *ufo = NULL;
00248     storedUFO_t *closestUFO = NULL;
00249 
00250     while ((ufo = US_GetNext(ufo)) != NULL) {
00251         float distance = 0;
00252 
00253         if (ufoTemplate && ufo->ufoTemplate != ufoTemplate)
00254             continue;
00255         if (ufo->status != SUFO_STORED)
00256             continue;
00257         assert(ufo->installation);
00258         if (base)
00259             distance = GetDistanceOnGlobe(ufo->installation->pos, base->pos);
00260 
00261         if (minDistance < 0 || minDistance > distance) {
00262             minDistance = distance;
00263             closestUFO = ufo;
00264         }
00265     }
00266     return closestUFO;
00267 }
00268 
00272 int US_StoredUFOCount (void)
00273 {
00274     return LIST_Count(ccs.storedUFOs);
00275 }
00276 
00283 qboolean US_SaveXML (mxml_node_t *p)
00284 {
00285     storedUFO_t *ufo = NULL;
00286     mxml_node_t *node = mxml_AddNode(p, SAVE_UFORECOVERY_STOREDUFOS);
00287 
00288     Com_RegisterConstList(saveStoredUFOConstants);
00289     while ((ufo = US_GetNext(ufo)) != NULL) {
00290         mxml_node_t * snode = mxml_AddNode(node, SAVE_UFORECOVERY_UFO);
00291 
00292         mxml_AddInt(snode, SAVE_UFORECOVERY_UFOIDX, ufo->idx);
00293         mxml_AddString(snode, SAVE_UFORECOVERY_UFOID, ufo->id);
00294         mxml_AddDate(snode, SAVE_UFORECOVERY_DATE, ufo->arrive.day, ufo->arrive.sec);
00295         mxml_AddString(snode, SAVE_UFORECOVERY_STATUS, Com_GetConstVariable(SAVE_STOREDUFOSTATUS_NAMESPACE, ufo->status));
00296         mxml_AddFloat(snode, SAVE_UFORECOVERY_CONDITION, ufo->condition);
00297 
00298         if (ufo->installation)
00299             mxml_AddInt(snode, SAVE_UFORECOVERY_INSTALLATIONIDX, ufo->installation->idx);
00300     }
00301     Com_UnregisterConstList(saveStoredUFOConstants);
00302     return qtrue;
00303 }
00304 
00311 qboolean US_LoadXML (mxml_node_t *p)
00312 {
00313     int i; 
00314     mxml_node_t *node, *snode;
00315 
00316     node = mxml_GetNode(p, SAVE_UFORECOVERY_STOREDUFOS);
00317 
00318     Com_RegisterConstList(saveStoredUFOConstants);
00319     for (i = 0, snode = mxml_GetNode(node, SAVE_UFORECOVERY_UFO); snode;
00320             snode = mxml_GetNextNode(snode, node, SAVE_UFORECOVERY_UFO), i++) {
00321         const char *id = mxml_GetString(snode, SAVE_UFORECOVERY_STATUS);
00322         storedUFO_t ufo;
00323         int statusIDX;
00324 
00325         /* ufo->idx */
00326         ufo.idx = mxml_GetInt(snode, SAVE_UFORECOVERY_UFOIDX, -1);
00327         /* fallback code for compatibility */
00328         if (ufo.idx == -1) {
00329             Com_Printf("No IDX defined for stored UFO %d. This must be an old save.\n", i);
00330             ufo.idx = i;
00331         }
00332         /* ufo->status */
00333         if (!Com_GetConstIntFromNamespace(SAVE_STOREDUFOSTATUS_NAMESPACE, id, &statusIDX)) {
00334             Com_Printf("Invalid storedUFOStatus '%s'\n", id);
00335             continue;
00336         }
00337         ufo.status = statusIDX;
00338         /* ufo->installation */
00339         ufo.installation = INS_GetFoundedInstallationByIDX(mxml_GetInt(snode, SAVE_UFORECOVERY_INSTALLATIONIDX, MAX_INSTALLATIONS));
00340         if (!ufo.installation) {
00341             Com_Printf("UFO has no/invalid installation assigned\n");
00342             continue;
00343         }
00344         if (ufo.installation->ufoCapacity.cur >= ufo.installation->ufoCapacity.max) {
00345             Com_Printf("UFO Yard %i if full!\n", ufo.installation->idx);
00346             continue;
00347         }
00348         ufo.installation->ufoCapacity.cur++;
00349         /* ufo->id */
00350         Q_strncpyz(ufo.id, mxml_GetString(snode, SAVE_UFORECOVERY_UFOID), sizeof(ufo.id));
00351         /* ufo->ufoTemplate */
00352         ufo.ufoTemplate = AIR_GetAircraft(ufo.id);
00353         if (!ufo.ufoTemplate) {
00354             Com_Printf("UFO has no/invalid aircraftTemplare assigned\n");
00355             continue;
00356         }
00357         ufo.comp = CL_GetComponentsByID(ufo.id);
00358         if (!ufo.comp) {
00359             Com_Printf("UFO has no/invalid components set\n");
00360             continue;
00361         }
00362         mxml_GetDate(snode, SAVE_UFORECOVERY_DATE, &ufo.arrive.day, &ufo.arrive.sec);
00363         ufo.condition = mxml_GetFloat(snode, SAVE_UFORECOVERY_CONDITION, 1.0f);
00364         /* disassembly is set by production savesystem later but only for UFOs that are being disassembled */
00365         ufo.disassembly = NULL;
00366         LIST_Add(&ccs.storedUFOs, (void*)&ufo, sizeof(ufo));
00367     }
00368     Com_UnregisterConstList(saveStoredUFOConstants);
00369     return qtrue;
00370 }
00371 

Generated by  doxygen 1.6.2