cp_fightequip_callbacks.c

Go to the documentation of this file.
00001 
00006 /*
00007 All original material Copyright (C) 2002-2010 UFO: Alien Invasion.
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018 See the GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00023 
00024 */
00025 #include "../cl_shared.h"
00026 #include "../ui/ui_main.h"
00027 #include "cp_campaign.h"
00028 #include "cp_fightequip_callbacks.h"
00029 #include "cp_mapfightequip.h"
00030 #include "cp_ufo.h"
00031 
00032 static int airequipID = -1;             
00034 static int airequipSelectedZone = ZONE_NONE;        
00035 static int airequipSelectedSlot = ZONE_NONE;            
00036 static technology_t *aimSelectedTechnology = NULL;      
00041 static void AIM_CheckAirequipID (void)
00042 {
00043     switch (airequipID) {
00044     case AC_ITEM_AMMO:
00045     case AC_ITEM_WEAPON:
00046     case AC_ITEM_SHIELD:
00047     case AC_ITEM_ELECTRONICS:
00048         return;
00049     default:
00050         airequipID = AC_ITEM_WEAPON;
00051     }
00052 }
00053 
00059 static void AIM_CheckAirequipSelectedSlot (const aircraft_t *aircraft)
00060 {
00061     switch (airequipID) {
00062     case AC_ITEM_AMMO:
00063     case AC_ITEM_WEAPON:
00064         if (airequipSelectedSlot >= aircraft->maxWeapons) {
00065             airequipSelectedSlot = 0;
00066             return;
00067         }
00068         break;
00069     case AC_ITEM_ELECTRONICS:
00070         if (airequipSelectedSlot >= aircraft->maxElectronics) {
00071             airequipSelectedSlot = 0;
00072             return;
00073         }
00074         break;
00075     }
00076 }
00077 
00085 aircraftSlot_t *AII_SelectAircraftSlot (aircraft_t *aircraft, aircraftItemType_t type)
00086 {
00087     aircraftSlot_t *slot;
00088 
00089     AIM_CheckAirequipSelectedSlot(aircraft);
00090     switch (type) {
00091     case AC_ITEM_SHIELD:
00092         slot = &aircraft->shield;
00093         break;
00094     case AC_ITEM_ELECTRONICS:
00095         slot = aircraft->electronics + airequipSelectedSlot;
00096         break;
00097     case AC_ITEM_AMMO:
00098     case AC_ITEM_WEAPON:
00099         slot = aircraft->weapons + airequipSelectedSlot;
00100         break;
00101     default:
00102         Com_Printf("AII_SelectAircraftSlot: Unknown airequipID: %i\n", type);
00103         return NULL;
00104     }
00105 
00106     return slot;
00107 }
00108 
00113 static void AIM_CheckAirequipSelectedZone (aircraftSlot_t *slot)
00114 {
00115     assert(slot);
00116 
00117     if (airequipSelectedZone == ZONE_AMMO && airequipID < AC_ITEM_AMMO && airequipID > AC_ITEM_WEAPON) {
00118         /* you can select ammo only for weapons and ammo */
00119         airequipSelectedZone = ZONE_MAIN;
00120     }
00121 
00122     /* You can choose an ammo only if a weapon has already been selected */
00123     if (airequipID >= AC_ITEM_AMMO && !slot->item) {
00124         airequipSelectedZone = ZONE_MAIN;
00125     }
00126 }
00127 
00131 static inline const char *AIM_AircraftItemtypeName (const int equiptype)
00132 {
00133     switch (equiptype) {
00134     case AC_ITEM_WEAPON:
00135         return _("Weapons");
00136     case AC_ITEM_SHIELD:
00137         return _("Armour");
00138     case AC_ITEM_ELECTRONICS:
00139         return _("Items");
00140     case AC_ITEM_AMMO:
00141         /* ammo - only available from weapons */
00142         return _("Ammo");
00143     default:
00144         return _("Unknown");
00145     }
00146 }
00147 
00151 static qboolean AIM_CrafttypeFilter (const base_t *base, aircraftItemType_t filterType, const technology_t *tech)
00152 {
00153     objDef_t *item;
00154     if (!base)
00155         return qfalse;
00156 
00157     if (!RS_IsResearched_ptr(tech))
00158         return qfalse;
00159 
00160     item = INVSH_GetItemByID(tech->provides);
00161     if (!item)
00162         return qfalse;
00163     if (item->isVirtual)
00164         return qfalse;
00165     if (!B_BaseHasItem(base, item))
00166         return qfalse;
00167 
00168     /* filter by type: special case for ammo because more than 1 type is an ammo type */
00169     if (filterType != AC_ITEM_AMMO) {
00170         if (item->craftitem.type != filterType)
00171             return qfalse;
00172     } else {
00173         if (item->craftitem.type < AC_ITEM_AMMO)
00174             return qfalse;
00175     }
00176 
00177     /* you can't install an item that does not have an installation time (alien item)
00178      * except for ammo which does not have installation time */
00179     if (item->craftitem.installationTime == -1 && filterType >= AC_ITEM_AMMO)
00180         return qfalse;
00181 
00182     return qtrue;
00183 }
00184 
00189 static void AIM_UpdateAircraftItemList (const aircraftSlot_t *slot)
00190 {
00191     linkedList_t *amountList = NULL;
00192     technology_t **techList;
00193     technology_t **currentTech;
00194     const base_t *base = slot->aircraft->homebase;
00195     int count = 0;
00196     uiNode_t *AIM_items = NULL;
00197 
00198     /* Add all items corresponding to airequipID to list */
00199     techList = AII_GetCraftitemTechsByType(airequipID);
00200 
00201     /* Count only those which are researched to buffer */
00202     currentTech = techList;
00203     while (*currentTech) {
00204         if (AIM_CrafttypeFilter(base, airequipID, *currentTech))
00205             count++;
00206         currentTech++;
00207     }
00208 
00209     /* List only those which are researched to buffer */
00210     currentTech = techList;
00211     while (*currentTech) {
00212         if (AIM_CrafttypeFilter(base, airequipID, *currentTech)) {
00213             int amount;
00214             uiNode_t *option;
00215             objDef_t *item = INVSH_GetItemByID((*currentTech)->provides);
00216             assert(item);
00217             amount = base->storage.numItems[item->idx];
00218 
00219             LIST_AddString(&amountList, va("%d", amount));
00220             option = UI_AddOption(&AIM_items, (*currentTech)->name, _((*currentTech)->name), va("%d", (*currentTech)->idx));
00221             if (!AIM_SelectableCraftItem(slot, *currentTech))
00222                 option->disabled = qtrue;
00223         }
00224         currentTech++;
00225     }
00226 
00227     UI_RegisterOption(TEXT_LIST, AIM_items);
00228     UI_RegisterLinkedListText(TEXT_LIST2, amountList);
00229 }
00230 
00235 static void AIM_DrawAircraftSlots (const aircraft_t *aircraft)
00236 {
00237     itemPos_t i;
00238 
00239     /* initialise model cvars */
00240     for (i = 0; i < AIR_POSITIONS_MAX; i++)
00241         Cvar_Set(va("mn_aircraft_item_model_slot%i", i), "");
00242 
00243     for (i = 0; i < AIR_POSITIONS_MAX; i++) {
00244         const aircraftSlot_t *slot;
00245         int max, j;
00246 
00247         /* Default value */
00248         UI_ExecuteConfunc("airequip_display_slot %i 0", i);
00249 
00250         /* Draw available slots */
00251         switch (airequipID) {
00252         case AC_ITEM_AMMO:
00253         case AC_ITEM_WEAPON:
00254             max = aircraft->maxWeapons;
00255             slot = aircraft->weapons;
00256             break;
00257         case AC_ITEM_ELECTRONICS:
00258             max = aircraft->maxElectronics;
00259             slot = aircraft->electronics;
00260             break;
00261         /* do nothing for shield: there is only one slot */
00262         default:
00263             continue;
00264         }
00265         for (j = 0; j < max; j++, slot++) {
00266             /* check if one of the aircraft slots is at this position */
00267             if (slot->pos == i) {
00268                 /* draw in white if this is the selected slot */
00269                 if (j == airequipSelectedSlot) {
00270                     UI_ExecuteConfunc("airequip_display_slot %i 2", i);
00271                 } else {
00272                     UI_ExecuteConfunc("airequip_display_slot %i 1", i);
00273                 }
00274                 if (slot->item) {
00275                     Cvar_Set(va("mn_aircraft_item_model_slot%i", i), RS_GetTechForItem(slot->item)->mdl);
00276                 } else
00277                     Cvar_Set(va("mn_aircraft_item_model_slot%i", i), "");
00278             }
00279         }
00280     }
00281 }
00282 
00288 static inline void AIM_EmphazeAmmoSlotText (void)
00289 {
00290     UI_ExecuteConfunc("airequip_zone2_color \"1 0 0 1\"");
00291 }
00292 
00298 static inline void AIM_NoEmphazeAmmoSlotText (void)
00299 {
00300     UI_ExecuteConfunc("airequip_zone2_color \"1 1 1 1\"");
00301 }
00302 
00303 static void AIM_AircraftEquipMenuUpdate (void)
00304 {
00305     static char smallbuffer1[256];
00306     static char smallbuffer2[128];
00307     const char *typeName;
00308     aircraft_t *aircraft;
00309     aircraftSlot_t *slot;
00310     base_t *base = B_GetCurrentSelectedBase();
00311 
00312     if (!base)
00313         return;
00314 
00315     /* don't let old links appear on this menu */
00316     UI_ResetData(TEXT_AIREQUIP_1);
00317     UI_ResetData(TEXT_AIREQUIP_2);
00318     UI_ResetData(TEXT_ITEMDESCRIPTION);
00319     UI_ResetData(TEXT_LIST);
00320 
00321     aircraft = base->aircraftCurrent;
00322 
00323     assert(aircraft);
00324 
00325     /* Check that airequipSelectedSlot corresponds to an existing slot for this aircraft */
00326     AIM_CheckAirequipSelectedSlot(aircraft);
00327 
00328     /* Select slot */
00329     slot = AII_SelectAircraftSlot(aircraft, airequipID);
00330 
00331     /* Check that the selected zone is OK */
00332     AIM_CheckAirequipSelectedZone(slot);
00333 
00334     /* Fill the list of item you can equip your aircraft with */
00335     AIM_UpdateAircraftItemList(slot);
00336 
00337     Cvar_Set("mn_equip_itemtype_name", AIM_AircraftItemtypeName(airequipID));
00338     switch (airequipID) {
00339     case AC_ITEM_ELECTRONICS:
00340         typeName = "item";
00341         break;
00342     case AC_ITEM_SHIELD:
00343         typeName = "armour";
00344         break;
00345     case AC_ITEM_AMMO:
00346         typeName = "ammo";
00347         break;
00348     case AC_ITEM_WEAPON:
00349         typeName = "weapon";
00350         break;
00351     default:
00352         typeName = "unknown";
00353         break;
00354     }
00355     Cvar_Set("mn_equip_itemtype", typeName);
00356 
00357     /* First slot: item currently assigned */
00358     if (!slot->item) {
00359         Com_sprintf(smallbuffer1, sizeof(smallbuffer1), "%s", _("No item assigned.\n"));
00360         Q_strcat(smallbuffer1, va(_("This slot is for %s or smaller items."),
00361             AII_WeightToName(slot->size)), sizeof(smallbuffer1));
00362     } else {
00363         technology_t *tech = RS_GetTechForItem(slot->nextItem ? slot->nextItem : slot->item);
00364         /* Print next item if we are removing item currently installed and a new item has been added. */
00365         Com_sprintf(smallbuffer1, sizeof(smallbuffer1), "%s\n", _(tech->name));
00366         if (!slot->installationTime)
00367             Q_strcat(smallbuffer1, _("This item is functional.\n"), sizeof(smallbuffer1));
00368         else if (slot->installationTime > 0)
00369             Q_strcat(smallbuffer1, va(_("This item will be installed in %i hours.\n"),
00370                 slot->installationTime), sizeof(smallbuffer1));
00371         else if (slot->nextItem) {
00372             Q_strcat(smallbuffer1, va(_("%s will be removed in %i hours.\n"), _(tech->name),
00373                 - slot->installationTime), sizeof(smallbuffer1));
00374             Q_strcat(smallbuffer1, va(_("%s will be installed in %i hours.\n"), _(tech->name),
00375                 slot->nextItem->craftitem.installationTime - slot->installationTime), sizeof(smallbuffer1));
00376         } else
00377             Q_strcat(smallbuffer1, va(_("This item will be removed in %i hours.\n"),
00378                 -slot->installationTime), sizeof(smallbuffer1));
00379     }
00380     UI_RegisterText(TEXT_AIREQUIP_1, smallbuffer1);
00381 
00382     /* Second slot: ammo slot (only used for weapons) */
00383     if ((airequipID == AC_ITEM_WEAPON || airequipID == AC_ITEM_AMMO) && slot->item) {
00384         if (!slot->ammo) {
00385             AIM_EmphazeAmmoSlotText();
00386             Com_sprintf(smallbuffer2, sizeof(smallbuffer2), "%s", _("No ammo assigned to this weapon."));
00387         } else {
00388             const objDef_t *ammo = slot->nextAmmo ? slot->nextAmmo : slot->ammo;
00389             const technology_t *tech = RS_GetTechForItem(ammo);
00390             AIM_NoEmphazeAmmoSlotText();
00391             if (!ammo->isVirtual)
00392                 Q_strncpyz(smallbuffer2, _(tech->name), sizeof(smallbuffer2));
00393             else
00394                 Q_strncpyz(smallbuffer2, _("No ammo needed"), sizeof(smallbuffer2));
00395         }
00396     } else
00397         *smallbuffer2 = '\0';
00398 
00399     UI_RegisterText(TEXT_AIREQUIP_2, smallbuffer2);
00400 
00401     /* Draw existing slots for this aircraft */
00402     AIM_DrawAircraftSlots(aircraft);
00403 }
00404 
00405 #define AIM_LOADING_OK                          0
00406 #define AIM_LOADING_NOSLOTSELECTED              1
00407 #define AIM_LOADING_NOTECHNOLOGYSELECTED        2
00408 #define AIM_LOADING_ALIENTECH                   3
00409 #define AIM_LOADING_TECHNOLOGYNOTRESEARCHED     4
00410 #define AIM_LOADING_TOOHEAVY                    5
00411 #define AIM_LOADING_UNKNOWNPROBLEM              6
00412 #define AIM_LOADING_NOWEAPON                    7
00413 #define AIM_LOADING_NOTUSABLEWITHWEAPON         8
00414 
00421 static int AIM_CheckTechnologyIntoSlot (const aircraftSlot_t *slot, const technology_t *tech)
00422 {
00423     objDef_t *item;
00424 
00425     if (!tech)
00426         return AIM_LOADING_NOTECHNOLOGYSELECTED;
00427 
00428     if (!slot)
00429         return AIM_LOADING_NOSLOTSELECTED;
00430 
00431     if (!RS_IsResearched_ptr(tech))
00432         return AIM_LOADING_TECHNOLOGYNOTRESEARCHED;
00433 
00434     item = INVSH_GetItemByID(tech->provides);
00435     if (!item)
00436         return AIM_LOADING_NOTECHNOLOGYSELECTED;
00437 
00438     if (item->craftitem.type >= AC_ITEM_AMMO) {
00439         const objDef_t *weapon = slot->item;
00440         int k;
00441         if (slot->nextItem != NULL)
00442             weapon = slot->nextItem;
00443 
00444         if (weapon == NULL)
00445             return AIM_LOADING_NOWEAPON;
00446 
00447         /* Is the ammo is usable with the slot */
00448         for (k = 0; k < weapon->numAmmos; k++) {
00449             const objDef_t *usable = weapon->ammos[k];
00450             if (usable && item->idx == usable->idx)
00451                 break;
00452         }
00453         if (k >= weapon->numAmmos)
00454             return AIM_LOADING_NOTUSABLEWITHWEAPON;
00455 
00456 #if 0
00457 
00459         if (!slot->nextItem && item->weapons[0] != slot->item)
00460             return AIM_LOADING_UNKNOWNPROBLEM;
00461 
00462         /* are we trying to change ammos for nextItem? */
00463         if (slot->nextItem && item->weapons[0] != slot->nextItem)
00464             return AIM_LOADING_UNKNOWNPROBLEM;
00465 #endif
00466     }
00467 
00468     /* you can install an item only if its weight is small enough for the slot */
00469     if (AII_GetItemWeightBySize(item) > slot->size)
00470         return AIM_LOADING_TOOHEAVY;
00471 
00472     /* you can't install an item that you don't possess
00473      * virtual ammo don't need to be possessed
00474      * installations always have weapon and ammo */
00475     if (slot->aircraft) {
00476         if (!B_BaseHasItem(slot->aircraft->homebase, item))
00477             return AIM_LOADING_UNKNOWNPROBLEM;
00478     } else if (slot->base) {
00479         if (!B_BaseHasItem(slot->base, item))
00480             return AIM_LOADING_UNKNOWNPROBLEM;
00481     }
00482 
00483     /* you can't install an item that does not have an installation time (alien item)
00484      * except for ammo which does not have installation time */
00485     if (item->craftitem.installationTime == -1 && slot->type < AC_ITEM_AMMO)
00486         return AIM_LOADING_ALIENTECH;
00487 
00488     return AIM_LOADING_OK;
00489 }
00490 
00494 static void AIM_UpdateItemDescription (qboolean fromList, qboolean fromSlot)
00495 {
00496     int status;
00497     aircraft_t *aircraft;
00498     aircraftSlot_t *slot;
00499     base_t *base = B_GetCurrentSelectedBase();
00500     assert(base);
00501 
00502     aircraft = base->aircraftCurrent;
00503     assert(aircraft);
00504     slot = AII_SelectAircraftSlot(aircraft, airequipID);
00505 
00506     /* update mini ufopedia */
00508     if (fromList)
00509         UP_AircraftItemDescription(INVSH_GetItemByIDSilent(aimSelectedTechnology ? aimSelectedTechnology->provides : NULL));
00510     else if (fromSlot) {
00511         if (airequipID == AC_ITEM_AMMO)
00512             UP_AircraftItemDescription(slot->ammo);
00513         else
00514             UP_AircraftItemDescription(slot->item);
00515     }
00516 
00517     /* update status */
00518     status = AIM_CheckTechnologyIntoSlot(slot, aimSelectedTechnology);
00519     switch (status) {
00520     case AIM_LOADING_NOSLOTSELECTED:
00521         Cvar_Set("mn_aircraft_item_warning", _("No slot selected."));
00522         break;
00523     case AIM_LOADING_NOTECHNOLOGYSELECTED:
00524         Cvar_Set("mn_aircraft_item_warning", _("No item selected."));
00525         break;
00526     case AIM_LOADING_ALIENTECH:
00527         Cvar_Set("mn_aircraft_item_warning", _("You can't equip an alien technology."));
00528         break;
00529     case AIM_LOADING_TECHNOLOGYNOTRESEARCHED:
00530         Cvar_Set("mn_aircraft_item_warning", _("Technology requested is not yet completed."));
00531         break;
00532     case AIM_LOADING_TOOHEAVY:
00533         Cvar_Set("mn_aircraft_item_warning", _("This item is too heavy for the selected slot."));
00534         break;
00535     case AIM_LOADING_NOWEAPON:
00536         Cvar_Set("mn_aircraft_item_warning", _("Equip a weapon first."));
00537         break;
00538     case AIM_LOADING_NOTUSABLEWITHWEAPON:
00539         Cvar_Set("mn_aircraft_item_warning", _("Ammo not usable with current weapon."));
00540         break;
00541     case AIM_LOADING_UNKNOWNPROBLEM:
00542         Cvar_Set("mn_aircraft_item_warning", _("Unknown problem."));
00543         break;
00544     case AIM_LOADING_OK:
00545         Cvar_Set("mn_aircraft_item_warning", _("Ok"));
00546         break;
00547     }
00548 
00549     if (*Cvar_GetString("mn_item") == '\0') {
00550         UI_ExecuteConfunc("airequip_no_item");
00551     } else {
00552         if (fromSlot) {
00553             UI_ExecuteConfunc("airequip_installed_item");
00554         } else {
00555             if (status == AIM_LOADING_OK)
00556                 UI_ExecuteConfunc("airequip_installable_item");
00557             else
00558                 UI_ExecuteConfunc("airequip_noinstallable_item");
00559         }
00560     }
00561 }
00562 
00567 static void AIM_AircraftEquipMenuUpdate_f (void)
00568 {
00569     if (Cmd_Argc() != 2) {
00570         if (airequipID == -1) {
00571             Com_Printf("Usage: %s <num>\n", Cmd_Argv(0));
00572             return;
00573         }
00574         AIM_CheckAirequipID();
00575     } else {
00576         const int type = atoi(Cmd_Argv(1));
00577         switch (type) {
00578         case AC_ITEM_ELECTRONICS:
00579         case AC_ITEM_SHIELD:
00580             airequipID = type;
00581             UI_ExecuteConfunc("airequip_zone2_off");
00582             break;
00583         case AC_ITEM_AMMO:
00584         case AC_ITEM_WEAPON:
00585             airequipID = type;
00586             UI_ExecuteConfunc("airequip_zone2_on");
00587             break;
00588         default:
00589             airequipID = AC_ITEM_WEAPON;
00590             break;
00591         }
00592     }
00593 
00594     AIM_AircraftEquipMenuUpdate();
00595 }
00596 
00601 static void AIM_AircraftEquipSlotSelect_f (void)
00602 {
00603     int i;
00604     itemPos_t pos;
00605     aircraft_t *aircraft;
00606     base_t *base = B_GetCurrentSelectedBase();
00607     int updateZone = 0;
00608 
00609     if (!base)
00610         return;
00611 
00612     if (Cmd_Argc() < 2) {
00613         Com_Printf("Usage: %s <arg> <zone1|zone2|item>\n", Cmd_Argv(0));
00614         return;
00615     }
00616 
00617     aircraft = base->aircraftCurrent;
00618     assert(aircraft);
00619 
00620     pos = atoi(Cmd_Argv(1));
00621 
00622     if (Cmd_Argc() == 3) {
00623         if (!strcmp(Cmd_Argv(2), "zone1")) {
00624             updateZone = 1;
00625         } else if (!strcmp(Cmd_Argv(2), "zone2")) {
00626             updateZone = 2;
00627         }
00628     }
00629 
00630     airequipSelectedSlot = ZONE_NONE;
00631 
00632     /* select the slot corresponding to pos, and set airequipSelectedSlot to this slot */
00633     switch (airequipID) {
00634     case AC_ITEM_ELECTRONICS:
00635         /* electronics selected */
00636         for (i = 0; i < aircraft->maxElectronics; i++) {
00637             if (aircraft->electronics[i].pos == pos) {
00638                 airequipSelectedSlot = i;
00639                 break;
00640             }
00641         }
00642         if (i == aircraft->maxElectronics)
00643             Com_Printf("this slot hasn't been found in aircraft electronics slots\n");
00644         break;
00645     case AC_ITEM_AMMO:
00646     case AC_ITEM_WEAPON:
00647         /* weapon selected */
00648         for (i = 0; i < aircraft->maxWeapons; i++) {
00649             if (aircraft->weapons[i].pos == pos) {
00650                 airequipSelectedSlot = i;
00651                 break;
00652             }
00653         }
00654         if (i == aircraft->maxWeapons)
00655             Com_Printf("this slot hasn't been found in aircraft weapon slots\n");
00656         break;
00657     default:
00658         Com_Printf("AIM_AircraftEquipSlotSelect_f : only weapons and electronics have several slots\n");
00659     }
00660 
00661     /* Update menu after changing slot */
00662     AIM_AircraftEquipMenuUpdate();
00663 
00664     /* update description with the selected slot */
00665     if (updateZone > 0)
00666         AIM_UpdateItemDescription(qfalse, qtrue);
00667     else
00668         AIM_UpdateItemDescription(qtrue, qfalse);
00669 }
00670 
00674 static void AIM_AircraftEquipZoneSelect_f (void)
00675 {
00676     int zone;
00677     aircraft_t *aircraft;
00678     aircraftSlot_t *slot;
00679     base_t *base = B_GetCurrentSelectedBase();
00680 
00681     if (!base)
00682         return;
00683 
00684     if (Cmd_Argc() < 2) {
00685         Com_Printf("Usage: %s <arg>\n", Cmd_Argv(0));
00686         return;
00687     }
00688 
00689     zone = atoi(Cmd_Argv(1));
00690 
00691     aircraft = base->aircraftCurrent;
00692     assert(aircraft);
00693     /* Select slot */
00694     slot = AII_SelectAircraftSlot(aircraft, airequipID);
00695 
00696     /* ammos are only available for weapons */
00697     switch (airequipID) {
00698     /* a weapon was selected - select ammo type corresponding to this weapon */
00699     case AC_ITEM_WEAPON:
00700         if (zone == ZONE_AMMO) {
00701             if (slot->item)
00702                 airequipID = AC_ITEM_AMMO;
00703         }
00704         break;
00705     /* an ammo was selected - select weapon type corresponding to this ammo */
00706     case AC_ITEM_AMMO:
00707         if (zone != ZONE_AMMO)
00708             airequipID = AC_ITEM_WEAPON;
00709         break;
00710     default :
00711         /* ZONE_AMMO is not available for electronics and shields */
00712         if (zone == ZONE_AMMO)
00713             return;
00714     }
00715     airequipSelectedZone = zone;
00716 
00717     /* update menu */
00718     AIM_AircraftEquipMenuUpdate();
00719     /* Check that the selected zone is OK */
00720     AIM_CheckAirequipSelectedZone(slot);
00721 
00722     AIM_UpdateItemDescription(qfalse, qtrue);
00723 }
00724 
00730 static void AIM_AircraftEquipAddItem_f (void)
00731 {
00732     int zone;
00733     aircraftSlot_t *slot;
00734     aircraft_t *aircraft = NULL;
00735     base_t *base = B_GetCurrentSelectedBase();
00736 
00737     zone = (airequipID == AC_ITEM_AMMO)?2:1;
00738 
00739     /* proceed only if an item has been selected */
00740     if (!aimSelectedTechnology)
00741         return;
00742 
00743     assert(base);
00744     aircraft = base->aircraftCurrent;
00745     assert(aircraft);
00746     base = aircraft->homebase;  /* we need to know where items will be removed */
00747     slot = AII_SelectAircraftSlot(aircraft, airequipID);
00748 
00749     /* the clicked button doesn't correspond to the selected zone */
00750     if (zone != airequipSelectedZone)
00751         return;
00752 
00753     /* check if the zone exists */
00754     if (zone >= ZONE_MAX)
00755         return;
00756 
00757     /* update the new item to slot */
00758 
00759     switch (zone) {
00760     case ZONE_MAIN:
00761         if (!slot->nextItem) {
00762             /* we add the weapon, shield, item if slot is free or the installation of current item just began */
00763             if (!slot->item || (slot->item && slot->installationTime == slot->item->craftitem.installationTime)) {
00764                 AII_RemoveItemFromSlot(base, slot, qfalse);
00765                 AII_AddItemToSlot(base, aimSelectedTechnology, slot, qfalse); /* Aircraft stats are updated below */
00766                 AII_AutoAddAmmo(slot);
00767                 break;
00768             } else if (slot->item == INVSH_GetItemByID(aimSelectedTechnology->provides)) {
00769                 /* the added item is the same than the one in current slot */
00770                 if (slot->installationTime == -slot->item->craftitem.installationTime) {
00771                     /* player changed his mind: he just want to re-add the item he just removed */
00772                     slot->installationTime = 0;
00773                     break;
00774                 } else if (!slot->installationTime) {
00775                     /* player try to add a weapon he already have: just skip */
00776                     return;
00777                 }
00778             } else {
00779                 /* We start removing current item in slot, and the selected item will be installed afterwards */
00780                 slot->installationTime = -slot->item->craftitem.installationTime;
00781                 /* more below */
00782             }
00783         } else {
00784             /* remove weapon and ammo of next item */
00785             AII_RemoveNextItemFromSlot(base, slot, qfalse);
00786             /* more below */
00787         }
00788 
00789         /* we change the weapon, shield, item, or base defence that will be installed AFTER the removal
00790          * of the one in the slot atm */
00791         AII_AddItemToSlot(base, aimSelectedTechnology, slot, qtrue);
00792         AII_AutoAddAmmo(slot);
00793         break;
00794     case ZONE_AMMO:
00795         /* we can change ammo only if the selected item is an ammo (for weapon or base defence system) */
00796         if (airequipID >= AC_ITEM_AMMO) {
00797             AII_AddAmmoToSlot(base, aimSelectedTechnology, slot);
00798         }
00799         break;
00800     default:
00801         /* Zone higher than ZONE_AMMO shouldn't exist */
00802         return;
00803     }
00804 
00805     /* Update the values of aircraft stats (just in case an item has an installationTime of 0) */
00806     AII_UpdateAircraftStats(aircraft);
00807 
00808     AIM_AircraftEquipMenuUpdate();
00809 }
00810 
00814 static void AIM_AircraftEquipRemoveItem_f (void)
00815 {
00816     int zone;
00817     aircraftSlot_t *slot;
00818     aircraft_t *aircraft = NULL;
00819     base_t *base = B_GetCurrentSelectedBase();
00820 
00821     zone = (airequipID == AC_ITEM_AMMO)?2:1;
00822 
00823     assert(base);
00824     aircraft = base->aircraftCurrent;
00825     assert(aircraft);
00826     slot = AII_SelectAircraftSlot(aircraft, airequipID);
00827 
00828     /* no item in slot: nothing to remove */
00829     if (!slot->item)
00830         return;
00831 
00832     /* update the new item to slot */
00833 
00834     switch (zone) {
00835     case ZONE_MAIN:
00836         if (!slot->nextItem) {
00837             /* we change the weapon, shield, item, or base defence that is already in the slot */
00838             /* if the item has been installed since less than 1 hour, you don't need time to remove it */
00839             if (slot->installationTime < slot->item->craftitem.installationTime) {
00840                 slot->installationTime = -slot->item->craftitem.installationTime;
00841                 AII_RemoveItemFromSlot(base, slot, qtrue); /* we remove only ammo, not item */
00842             } else {
00843                 AII_RemoveItemFromSlot(base, slot, qfalse); /* we remove weapon and ammo */
00844             }
00845             /* aircraft stats are updated below */
00846         } else {
00847             /* we change the weapon, shield, item, or base defence that will be installed AFTER the removal
00848              * of the one in the slot atm */
00849             AII_RemoveNextItemFromSlot(base, slot, qfalse); /* we remove weapon and ammo */
00850             /* if you canceled next item for less than 1 hour, previous item is still functional */
00851             if (slot->installationTime == -slot->item->craftitem.installationTime) {
00852                 slot->installationTime = 0;
00853             }
00854         }
00855         break;
00856     case ZONE_AMMO:
00857         /* we can change ammo only if the selected item is an ammo (for weapon or base defence system) */
00858         if (airequipID >= AC_ITEM_AMMO) {
00859             if (slot->nextAmmo)
00860                 AII_RemoveNextItemFromSlot(base, slot, qtrue);
00861             else
00862                 AII_RemoveItemFromSlot(base, slot, qtrue);
00863         }
00864         break;
00865     default:
00866         /* Zone higher than ZONE_AMMO shouldn't exist */
00867         return;
00868     }
00869 
00870     /* Update the values of aircraft stats */
00871     AII_UpdateAircraftStats(aircraft);
00872 
00873     AIM_AircraftEquipMenuUpdate();
00874 }
00875 
00880 static void AIM_AircraftEquipMenuClick_f (void)
00881 {
00882     int techIdx;
00883 
00884     if (Cmd_Argc() < 2) {
00885         Com_Printf("Usage: %s <num>\n", Cmd_Argv(0));
00886         return;
00887     }
00888 
00889     /* Which tech? */
00890     techIdx = atoi(Cmd_Argv(1));
00891 
00892     aimSelectedTechnology = (techIdx >= 0) ? &ccs.technologies[techIdx] : NULL;
00893     AIM_UpdateItemDescription(qtrue, qfalse);
00894 }
00895 
00899 static void AIM_AircraftItemtypeByName_f (void)
00900 {
00901     int i;
00902     const char *name;
00903 
00904     if (Cmd_Argc() != 2) {
00905         Com_Printf("Usage: %s <weapon|ammo|armour|item>\n", Cmd_Argv(0));
00906         return;
00907     }
00908 
00909     name = Cmd_Argv(1);
00910 
00911     if (!strcmp(name, "weapon"))
00912         i = AC_ITEM_WEAPON;
00913     else if (!strcmp(name, "ammo"))
00914         i = AC_ITEM_AMMO;
00915     else if (!strcmp(name, "armour"))
00916         i = AC_ITEM_SHIELD;
00917     else if (!strcmp(name, "item"))
00918         i = AC_ITEM_ELECTRONICS;
00919     else {
00920         Com_Printf("AIM_AircraftItemtypeByName_f: Invalid itemtype!\n");
00921         return;
00922     }
00923 
00924     airequipID = i;
00925     Cmd_ExecuteString(va("airequip_updatemenu %d", airequipID));
00926 }
00927 
00928 void AIM_InitCallbacks (void)
00929 {
00930     Cmd_AddCommand("airequip_updatemenu", AIM_AircraftEquipMenuUpdate_f, "Init function for the aircraft equip menu");
00931     Cmd_AddCommand("airequip_selectcategory", AIM_AircraftItemtypeByName_f, "Select an item category and update the GUI");
00932     Cmd_AddCommand("airequip_list_click", AIM_AircraftEquipMenuClick_f, NULL);
00933     Cmd_AddCommand("airequip_slot_select", AIM_AircraftEquipSlotSelect_f, NULL);
00934     Cmd_AddCommand("airequip_add_item", AIM_AircraftEquipAddItem_f, "Add item to slot");
00935     Cmd_AddCommand("airequip_remove_item", AIM_AircraftEquipRemoveItem_f, "Remove item from slot");
00936     Cmd_AddCommand("airequip_zone_select", AIM_AircraftEquipZoneSelect_f, NULL);
00937 }
00938 
00939 void AIM_ShutdownCallbacks (void)
00940 {
00941     Cmd_RemoveCommand("airequip_updatemenu");
00942     Cmd_RemoveCommand("airequip_selectcategory");
00943     Cmd_RemoveCommand("airequip_list_click");
00944     Cmd_RemoveCommand("airequip_slot_select");
00945     Cmd_RemoveCommand("airequip_add_item");
00946     Cmd_RemoveCommand("airequip_remove_item");
00947     Cmd_RemoveCommand("airequip_zone_select");
00948 }

Generated by  doxygen 1.6.2