00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00080 if (!aliencontCurrent)
00081 return;
00082
00083 tech = aliencontCurrent->tech;
00084
00085
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
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
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
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
00197 continue;
00198 }
00199 if (!aliencontCurrent) {
00200 aliencontCurrent = &containment[i];
00201 }
00202 if (containment[i].amountAlive > 0 || containment[i].amountDead > 0) {
00203
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
00216 Cvar_Set(va("mn_ac_name%i", j), _(containment[i].teamDef->name));
00217
00218 Cvar_SetValue(va("mn_ac_dead%i", j), containment[i].amountDead);
00219
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
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
00271 if (!base)
00272 return;
00273
00274 AC_KillAll(base);
00275
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
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
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
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 }