cp_aliencont_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 
00026 #include "../cl_shared.h"
00027 #include "../ui/ui_main.h"
00028 #include "cp_campaign.h"
00029 #include "cp_aliencont.h"
00030 #include "cp_aliencont_callbacks.h"
00031 
00036 #define MAX_AC_MENU_ENTRIES 12
00037 
00039 static const aliensCont_t* aliencontCurrent;        
00040 static int numAliensOnList = 0;         
00048 static int AL_CountForMenu (int alienidx, qboolean alive)
00049 {
00050     int i;
00051     int amount = 0;
00052 
00053     assert(alienidx >= 0);
00054     assert(alienidx < MAX_ALIENCONT_CAP);
00055 
00056     for (i = 0; i < MAX_BASES; i++) {
00057         const base_t const *base = B_GetFoundedBaseByIDX(i);
00058         if (!base)
00059             continue;
00060         if (!B_GetBuildingStatus(base, B_ALIEN_CONTAINMENT))
00061             continue;
00062         if (base->alienscont[alienidx].teamDef) {
00063             if (!alive)
00064                 amount += base->alienscont[alienidx].amountDead;
00065             else
00066                 amount += base->alienscont[alienidx].amountAlive;
00067         }
00068     }
00069     return amount;
00070 }
00071 
00075 static void AC_OpenUFOpedia_f (void)
00076 {
00077     const technology_t *tech;
00078 
00079     /* Can be called from everywhere. */
00080     if (!aliencontCurrent)
00081         return;
00082 
00083     tech = aliencontCurrent->tech;
00084 
00085     /* Should never happen. */
00086     if (!tech) {
00087         Com_Printf("AC_OpenUFOpedia_f: No tech pointer set!\n");
00088         return;
00089     }
00090 
00091     if (RS_IsResearched_ptr(tech))
00092         UP_OpenWith(tech->id);
00093 }
00094 
00095 
00099 static void AC_ResearchAlien_f (void)
00100 {
00101     const technology_t *tech;
00102 
00103     /* Can be called from everywhere. */
00104     if (!aliencontCurrent)
00105         return;
00106 
00107     tech = aliencontCurrent->tech;
00108     if (!tech)
00109         Com_Error(ERR_DROP, "aliencontCurrent without tech pointer");
00110 
00111     if (!RS_IsResearched_ptr(tech))
00112         UI_PushWindow("research", NULL);
00113 }
00114 
00120 static void AC_AlienClick (const base_t *base, int num)
00121 {
00122     if (num >= numAliensOnList || num < 0) {
00123         Com_DPrintf(DEBUG_CLIENT, "AC_AlienClick: max exceeded %i/%i\n", num, numAliensOnList);
00124         return;
00125     }
00126 
00127     if (B_GetBuildingStatus(base, B_ALIEN_CONTAINMENT)) {
00128         const aliensCont_t *containment = base->alienscont;
00129         int i, step;
00130 
00131         for (i = 0, step = 0; i < ccs.numAliensTD; i++) {
00132             if (!containment[i].amountAlive && !containment[i].amountDead)
00133                 continue;
00134             if (step == num) {
00135                 num = i;
00136                 break;
00137             }
00138             step++;
00139         }
00140 
00141         aliencontCurrent = &base->alienscont[num];
00142         assert(aliencontCurrent->tech);
00143         Cvar_Set("mn_al_alienimage", aliencontCurrent->tech->image);
00144         assert(aliencontCurrent->teamDef);
00145         Cvar_Set("mn_al_alientype", _(aliencontCurrent->teamDef->name));
00146         Cvar_Set("mn_al_alive", va("%i (%i)", aliencontCurrent->amountAlive, AL_CountForMenu(aliencontCurrent->teamDef->idx, qtrue)));
00147         Cvar_Set("mn_al_dead",  va("%i (%i)", aliencontCurrent->amountDead, AL_CountForMenu(aliencontCurrent->teamDef->idx, qfalse)));
00148     }
00149 }
00150 
00155 static void AC_AlienClick_f (void)
00156 {
00157     int num;
00158     base_t *base = B_GetCurrentSelectedBase();
00159 
00160     if (Cmd_Argc() < 2 || !base) {
00161         Com_Printf("Usage: %s <alien list index>\n", Cmd_Argv(0));
00162         return;
00163     }
00164 
00165     /* which item from the list? */
00166     num = atoi(Cmd_Argv(1));
00167 
00168     Com_DPrintf(DEBUG_CLIENT, "AC_AlienClick_f: listnumber %i\n", num);
00169     AC_AlienClick(base, num);
00170 }
00171 
00175 static void AC_UpdateMenu (const base_t *base)
00176 {
00177 
00178     Cvar_Set("mn_al_alientype", "");
00179     Cvar_Set("mn_al_alienimage", "");
00180     Cvar_SetValue("mn_al_dead", 0);
00181     Cvar_SetValue("mn_al_alive", 0);
00182     Cvar_SetValue("mn_al_capacity", base->capacities[CAP_ALIENS].cur);
00183     Cvar_SetValue("mn_al_capacity_max", base->capacities[CAP_ALIENS].max);
00184 
00185     /* Reset list. */
00186     UI_ExecuteConfunc("aliencont_clear");
00187     if (B_GetBuildingStatus(base, B_ALIEN_CONTAINMENT)) {
00188         const aliensCont_t *containment = base->alienscont;
00189         int i, j;
00190         for (i = 0, j = 0; i < ccs.numAliensTD; i++) {
00191             if (j < MAX_AC_MENU_ENTRIES) {
00192                 if (containment[i].teamDef) {
00193                     const technology_t *tech = containment[i].tech;
00194                     if (!tech) {
00195                         Com_Printf("AC_UpdateMenu: Tech entry for containment %i not set!\n", i);
00196                         /* to let the click function still work */
00197                         continue;
00198                     }
00199                     if (!aliencontCurrent) {
00200                         aliencontCurrent = &containment[i];
00201                     }
00202                     if (containment[i].amountAlive > 0 || containment[i].amountDead > 0) {
00203                         /* Generate a list entry. */
00204                         if (RS_IsResearched_ptr(tech)) {
00205                             Cvar_Set(va("mn_ac_statusstr%i", j), _("Already researched"));
00206                         } else {
00207                             Cvar_Set(va("mn_ac_statusstr%i", j), _("Needs autopsy!"));
00208                             if (!containment[i].amountDead) {
00209                                 UI_ExecuteConfunc("aliencontkill %i", j);
00210                             } else {
00211                                 UI_ExecuteConfunc("aliencontneedautopsy %i", j);
00212                             }
00213                         }
00214                         Cvar_SetValue(va("mn_ac_progress%i", j), (1 - tech->time / tech->overallTime) * 100);
00215                         /* Display name in the correct list-entry. */
00216                         Cvar_Set(va("mn_ac_name%i", j), _(containment[i].teamDef->name));
00217                         /* Display amount of dead aliens in the correct list-entry. */
00218                         Cvar_SetValue(va("mn_ac_dead%i", j), containment[i].amountDead);
00219                         /* Display number of live aliens in the correct list-entry. */
00220                         Cvar_SetValue(va("mn_ac_alive%i", j), containment[i].amountAlive);
00221                         j++;
00222                     }
00223                 }
00224             }
00225         }
00226 
00227         numAliensOnList = j;
00228 
00229         for (; j < MAX_AC_MENU_ENTRIES; j++) {
00230             Cvar_Set(va("mn_ac_statusstr%i", j), _("Free slot"));
00231             Cvar_Set(va("mn_ac_name%i", j), _("None"));
00232             Cvar_Set(va("mn_ac_dead%i", j), "");
00233             Cvar_Set(va("mn_ac_alive%i", j), "");
00234             Cvar_SetValue(va("mn_ac_progress%i", j), 0);
00235         }
00236     }
00237 
00239     AC_AlienClick(base, 0);
00240 }
00241 
00247 static void AC_Init_f (void)
00248 {
00249     base_t *base = B_GetCurrentSelectedBase();
00250 
00251     /* Reset the aliencont list. */
00252     numAliensOnList = 0;
00253 
00254     if (!base) {
00255         Com_Printf("No base selected\n");
00256         return;
00257     }
00258 
00259     AC_UpdateMenu(base);
00260 }
00261 
00266 static void AC_KillAll_f (void)
00267 {
00268     base_t *base = B_GetCurrentSelectedBase();
00269 
00270     /* Can be called from everywhere. */
00271     if (!base)
00272         return;
00273 
00274     AC_KillAll(base);
00275     /* Reinit menu to display proper values. */
00276     AC_UpdateMenu(base);
00277 }
00278 
00282 static void AC_KillOne_f (void)
00283 {
00284     int num;
00285     base_t *base = B_GetCurrentSelectedBase();
00286 
00287     /* Can be called from everywhere. */
00288     if (!base)
00289         return;
00290 
00291     if (Cmd_Argc() < 2) {
00292         Com_Printf("Usage: %s <alien list index>\n", Cmd_Argv(0));
00293         return;
00294     }
00295 
00296     /* which item from the list? */
00297     num = atoi(Cmd_Argv(1));
00298     if (num >= numAliensOnList || num < 0) {
00299         Com_DPrintf(DEBUG_CLIENT, "AC_KillOne_f: max exceeded %i/%i\n", num, numAliensOnList);
00300         return;
00301     }
00302 
00303     if (B_GetBuildingStatus(base, B_ALIEN_CONTAINMENT)) {
00304         aliensCont_t *containment = base->alienscont;
00305         int i, step;
00306         for (i = 0, step = 0; i < ccs.numAliensTD; i++) {
00307             if (!containment[i].amountAlive && !containment[i].amountDead)
00308                 continue;
00309             if (step == num) {
00310                 num = i;
00311                 break;
00312             }
00313             step++;
00314         }
00315         AL_RemoveAliens(base, containment[num].teamDef, 1, AL_KILLONE);
00316         /* Reinit menu to display proper values. */
00317         AC_UpdateMenu(base);
00318     }
00319 }
00320 
00321 void AC_InitCallbacks (void)
00322 {
00323     Cmd_AddCommand("aliencont_init", AC_Init_f, "Init function for alien containment menu");
00324     Cmd_AddCommand("aliencont_killall", AC_KillAll_f, "Kills all aliens in current base");
00325     Cmd_AddCommand("aliencont_killone", AC_KillOne_f, "Kills one alien of a given type");
00326     Cmd_AddCommand("aliencont_research", AC_ResearchAlien_f, "Opens research menu");
00327     Cmd_AddCommand("aliencont_pedia", AC_OpenUFOpedia_f, "Opens UFOpedia entry for selected alien");
00328     Cmd_AddCommand("aliencont_click", AC_AlienClick_f, "Click function for aliencont list");
00329     aliencontCurrent = NULL;
00330 
00331     if (ccs.numAliensTD > MAX_AC_MENU_ENTRIES) {
00332         Com_Printf("Warning: More alien team definitions than we are able to display in the menus\n");
00333         ccs.numAliensTD = MAX_AC_MENU_ENTRIES;
00334     }
00335 }
00336 
00337 void AC_ShutdownCallbacks (void)
00338 {
00339     Cmd_RemoveCommand("aliencont_init");
00340     Cmd_RemoveCommand("aliencont_killall");
00341     Cmd_RemoveCommand("aliencont_killone");
00342     Cmd_RemoveCommand("aliencont_research");
00343     Cmd_RemoveCommand("aliencont_pedia");
00344     Cmd_RemoveCommand("aliencont_click");
00345 }

Generated by  doxygen 1.6.2