cp_research_callbacks.c

Go to the documentation of this file.
00001 
00007 /*
00008 Copyright (C) 2002-2010 UFO: Alien Invasion.
00009 
00010 This program is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU General Public License
00012 as published by the Free Software Foundation; either version 2
00013 of the License, or (at your option) any later version.
00014 
00015 This program is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00018 
00019 See the GNU General Public License for more details.
00020 
00021 You should have received a copy of the GNU General Public License
00022 along with this program; if not, write to the Free Software
00023 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00024 
00025 */
00026 
00027 #include "../cl_shared.h"
00028 #include "../ui/ui_main.h"
00029 #include "../ui/ui_popup.h"
00030 #include "cp_campaign.h"
00031 #include "cp_research_callbacks.h"
00032 
00033 typedef enum {
00034     RSGUI_NOTHING,
00035     RSGUI_RESEARCH,
00036     RSGUI_BASETITLE,
00037     RSGUI_BASEINFO,
00038     RSGUI_RESEARCHOUT,
00039     RSGUI_MISSINGITEM,
00040     RSGUI_MISSINGITEMTITLE,
00041     RSGUI_UNRESEARCHABLEITEM,
00042     RSGUI_UNRESEARCHABLEITEMTITLE
00043 } guiResearchElementType_t;
00044 
00045 typedef struct {
00046     base_t *base;
00047     technology_t *tech;
00048     guiResearchElementType_t type;
00049 } guiResearchElement_t;
00050 
00054 static guiResearchElement_t researchList2[MAX_RESEARCHLIST + MAX_BASES + MAX_BASES];
00055 
00057 static int researchListLength;
00058 
00060 static int researchListPos;
00061 
00065 static void RS_UpdateInfo (const base_t* base)
00066 {
00067     char tmpbuf[128];
00068     technology_t *tech;
00069     int type;
00070 
00071     /* reset cvars */
00072     Cvar_Set("mn_research_imagetop", "");
00073     Cvar_Set("mn_researchitemname", "");
00074     Cvar_Set("mn_researchitem", "");
00075     UI_ResetData(TEXT_STANDARD);
00076 
00077     if (researchListLength <= 0 || researchListPos >= researchListLength)
00078         return;
00079 
00080     /* selection is not a research */
00082     type = researchList2[researchListPos].type;
00083     if (type != RSGUI_RESEARCH && type != RSGUI_RESEARCHOUT && type != RSGUI_UNRESEARCHABLEITEM)
00084         return;
00085 
00086     tech = researchList2[researchListPos].tech;
00087     if (tech == NULL)
00088         return;
00089 
00090     /* Display laboratories limits. */
00091     Com_sprintf(tmpbuf, sizeof(tmpbuf), _("Laboratory space (used/all): %i/%i"),
00092         base->capacities[CAP_LABSPACE].cur,
00093         base->capacities[CAP_LABSPACE].max);
00094     Cvar_Set("mn_research_labs", tmpbuf);
00095 
00096     /* Display scientists amounts. */
00097     Com_sprintf(tmpbuf, sizeof(tmpbuf), _("Scientists (available/all): %i/%i"),
00098         E_CountUnassigned(base, EMPL_SCIENTIST),
00099         E_CountHired(base, EMPL_SCIENTIST));
00100     Cvar_Set("mn_research_scis", tmpbuf);
00101 
00102     Cvar_Set("mn_research_selbase", _("Not researched in any base."));
00103 
00104     /* Display the base this tech is researched in. */
00105     if (tech->scientists > 0) {
00106         assert(tech->base);
00107         if (tech->base != base)
00108             Cvar_Set("mn_research_selbase", va(_("Researched in %s"), tech->base->name));
00109         else
00110             Cvar_Set("mn_research_selbase", _("Researched in this base."));
00111     }
00112 
00113     Cvar_Set("mn_research_selname", _(tech->name));
00114     if (tech->overallTime) {
00115         if (tech->time > tech->overallTime) {
00116             Com_Printf("RS_UpdateInfo: \"%s\" - 'time' (%f) was larger than 'overall-time' (%f). Fixed. Please report this.\n", tech->id, tech->time,
00117                     tech->overallTime);
00118             /* just in case the values got messed up */
00119             tech->time = tech->overallTime;
00120         }
00121         Cvar_SetValue("mn_research_seltimebar", 100 - (tech->time * 100 / tech->overallTime));
00122         Cvar_Set("mn_research_seltime", va(_("Progress: %.1f%%"), 100 - (tech->time * 100 / tech->overallTime)));
00123     } else {
00124         Cvar_SetValue("mn_research_seltimebar", 0);
00125         Cvar_Set("mn_research_seltime", _("Progress: not available."));
00126     }
00127 
00128     switch (tech->statusResearch) {
00129     case RS_RUNNING:
00130         Cvar_Set("mn_research_selstatus", _("Status: under research"));
00131         Cvar_Set("mn_research_selstatus_long", _("Status: this research topic is currently being processed in laboratories"));
00132         break;
00133     case RS_PAUSED:
00134         Cvar_Set("mn_research_selstatus", _("Status: research paused"));
00135         Cvar_Set("mn_research_selstatus_long", _("Status: research topic currently paused."));
00136         break;
00137     case RS_FINISH:
00138         Cvar_Set("mn_research_selstatus", _("Status: research finished"));
00139         Cvar_Set("mn_research_selstatus_long", _("Status: research finished"));
00140         break;
00141     case RS_NONE:
00142         if (tech->statusCollected && !tech->statusResearchable) {
00144             Cvar_Set("mn_research_selstatus", _("Status: not possible to research"));
00145             Cvar_Set("mn_research_selstatus_long", _("Status: We don't currently have all the materials or background knowledge needed to research this topic."));
00146         } else {
00147             Cvar_Set("mn_research_selstatus", _("Status: unknown technology"));
00148             Cvar_Set("mn_research_selstatus_long", _("Status: unknown technology"));
00149         }
00150         break;
00151     default:
00152         break;
00153     }
00154 
00155     /* Set image cvar. */
00156     if (tech->image)
00157         Cvar_Set("mn_research_imagetop", tech->image);
00158 }
00159 
00163 static void RS_UpdateResearchStatus (int row)
00164 {
00165     guiResearchElement_t *element = &researchList2[row];
00166     assert(element->type == RSGUI_RESEARCH || element->type == RSGUI_RESEARCHOUT);
00167 
00168     switch (element->tech->statusResearch) {
00169     case RS_RUNNING:
00170         /* Color the item with 'research running'-color. */
00171         UI_ExecuteConfunc("research_running %i", row);
00172         break;
00173     case RS_PAUSED:
00174         /* Color the item with 'research paused'-color. */
00175         UI_ExecuteConfunc("research_paused %i", row);
00176         break;
00177     case RS_NONE:
00178         /* Color the item with 'research normal'-color. */
00179         UI_ExecuteConfunc("research_normal %i", row);
00180         break;
00181     case RS_FINISH:
00182     default:
00183         break;
00184     }
00185 }
00186 
00194 static void RS_InitGUI (base_t* base, qboolean update)
00195 {
00196     int i = 0;
00197     int available[MAX_BASES];
00198 
00199     assert(base);
00200 
00201     for (i = 0; i < MAX_BASES; i++) {
00202         const base_t const *b = B_GetFoundedBaseByIDX(i);
00203         if (!b)
00204             continue;
00205         available[i] = E_CountUnassigned(b, EMPL_SCIENTIST);
00206     }
00207 
00208     for (i = 0; i < MAX_RESEARCHDISPLAY && i < researchListLength; i++) {
00209         guiResearchElement_t *element = &researchList2[i];
00210 
00211         /* only element of the current base can change */
00212         if (update && (element->base != base && element->type != RSGUI_RESEARCHOUT))
00213             continue;
00214 
00215         switch (element->type) {
00216         case RSGUI_NOTHING:
00217             UI_ExecuteConfunc("research_hide %i", i);
00218             Cvar_Set(va("mn_researchitem%i", i), "");
00219             Cvar_Set(va("mn_rsstatus%i", i), "");
00220             break;
00221         case RSGUI_RESEARCH:
00222             {
00223                 const int value = element->tech->scientists;
00224                 const int max = available[element->base->idx] + element->tech->scientists;
00225                 UI_ExecuteConfunc("research_research %i", i);
00226                 if (!update) {
00227                     Cvar_Set(va("mn_researchitem%i", i), _(element->tech->name));
00228                 }
00229                 UI_ExecuteConfunc("research_updateitem %i %i %i", i, value, max);
00230                 /* How many scis are assigned to this tech. */
00231                 Cvar_SetValue(va("mn_researchassigned%i", i), element->tech->scientists);
00232                 if (element->tech->overallTime) {
00233                     float percentage;
00234                     if (element->tech->time > element->tech->overallTime) {
00235                         Com_Printf("RS_InitGUI: \"%s\" - 'time' (%f) was larger than 'overall-time' (%f). Fixed. Please report this.\n", element->tech->id, element->tech->time,
00236                             element->tech->overallTime);
00237                         /* just in case the values got messed up */
00238                         element->tech->time = element->tech->overallTime;
00239                     }
00240                     percentage = 100 - (element->tech->time * 100 / element->tech->overallTime);
00241                     if (percentage > 0) {
00242                         Cvar_Set(va("mn_rsstatus%i", i), va("%.1f%%", percentage));
00243                     } else {
00244                         Cvar_Set(va("mn_rsstatus%i", i), "");
00245                     }
00246                 } else {
00247                     Cvar_Set(va("mn_rsstatus%i", i), "");
00248                 }
00249                 RS_UpdateResearchStatus(i);
00250             }
00251             break;
00252         case RSGUI_BASETITLE:
00253             UI_ExecuteConfunc("research_basetitle %i", i);
00254             Cvar_Set(va("mn_researchitem%i", i), element->base->name);
00255             Cvar_Set(va("mn_rsstatus%i", i), "");
00256             break;
00257         case RSGUI_BASEINFO:
00258             UI_ExecuteConfunc("research_baseinfo %i", i);
00259             Cvar_Set(va("mn_researchitem%i", i), _("Unassigned scientists"));
00260             /* How many scis are unassigned */
00261             Cvar_SetValue(va("mn_researchassigned%i", i), available[element->base->idx]);
00262             Cvar_Set(va("mn_rsstatus%i", i), "");
00263             break;
00264         case RSGUI_RESEARCHOUT:
00265             UI_ExecuteConfunc("research_outterresearch %i", i);
00266             Cvar_Set(va("mn_researchitem%i", i), _(element->tech->name));
00267             /* How many scis are assigned to this tech. */
00268             Cvar_SetValue(va("mn_researchassigned%i", i), element->tech->scientists);
00269             if (element->tech->overallTime) {
00270                 float percentage;
00271                 if (element->tech->time > element->tech->overallTime) {
00272                     Com_Printf("RS_InitGUI: \"%s\" - 'time' (%f) was larger than 'overall-time' (%f). Fixed. Please report this.\n", element->tech->id, element->tech->time,
00273                         element->tech->overallTime);
00274                     /* just in case the values got messed up */
00275                     element->tech->time = element->tech->overallTime;
00276                 }
00277                 percentage = 100 - (element->tech->time * 100 / element->tech->overallTime);
00278                 if (percentage > 0) {
00279                     Cvar_Set(va("mn_rsstatus%i", i), va("%.1f%%", percentage));
00280                 } else {
00281                     Cvar_Set(va("mn_rsstatus%i", i), "");
00282                 }
00283             } else {
00284                 Cvar_Set(va("mn_rsstatus%i", i), "");
00285             }
00286             RS_UpdateResearchStatus(i);
00287             break;
00288         case RSGUI_MISSINGITEM:
00289             UI_ExecuteConfunc("research_missingitem %i", i);
00290             Cvar_Set(va("mn_researchitem%i", i), _(element->tech->name));
00291             Cvar_Set(va("mn_rsstatus%i", i), "");
00292             break;
00293         case RSGUI_MISSINGITEMTITLE:
00294             UI_ExecuteConfunc("research_missingitemtitle %i", i);
00295             Cvar_Set(va("mn_researchitem%i", i), _("Missing an artifact"));
00296             Cvar_Set(va("mn_rsstatus%i", i), "");
00297             break;
00298         case RSGUI_UNRESEARCHABLEITEM:
00299             UI_ExecuteConfunc("research_unresearchableitem %i", i);
00300             Cvar_Set(va("mn_researchitem%i", i), _(element->tech->name));
00301             Cvar_Set(va("mn_rsstatus%i", i), "");
00302             break;
00303         case RSGUI_UNRESEARCHABLEITEMTITLE:
00304             UI_ExecuteConfunc("research_unresearchableitemtitle %i", i);
00305             Cvar_Set(va("mn_researchitem%i", i), _("Unresearchable collected items"));
00306             Cvar_Set(va("mn_rsstatus%i", i), "");
00307             break;
00308         default:
00309             assert(qfalse);
00310         }
00311     }
00312 
00313     /* Set rest of the list-entries to have no text at all. */
00314     if (!update) {
00315         for (; i < MAX_RESEARCHDISPLAY; i++) {
00316             UI_ExecuteConfunc("research_hide %i", i);
00317         }
00318     }
00319 
00320     /* Select last selected item if possible or the very first one if not. */
00321     if (researchListLength) {
00322         Com_DPrintf(DEBUG_CLIENT, "RS_UpdateData: Pos%i Len%i\n", researchListPos, researchListLength);
00323         if (researchListPos >= 0 && researchListPos < researchListLength && researchListLength < MAX_RESEARCHDISPLAY) {
00324             const int t = researchList2[researchListPos].type;
00325             /* is it a tech row */
00326             if (t == RSGUI_RESEARCH || t == RSGUI_RESEARCHOUT || t == RSGUI_UNRESEARCHABLEITEM) {
00327                 UI_ExecuteConfunc("research_selected %i", researchListPos);
00328             }
00329         }
00330     }
00331 
00332     /* Update the description field/area. */
00333     RS_UpdateInfo(base);
00334 }
00335 
00340 static void CL_ResearchSelect_f (void)
00341 {
00342     int num;
00343     int type;
00344     base_t *base = B_GetCurrentSelectedBase();
00345 
00346     if (!base)
00347         return;
00348 
00349     if (Cmd_Argc() < 2) {
00350         Com_Printf("Usage: %s <num>\n", Cmd_Argv(0));
00351         return;
00352     }
00353 
00354     num = atoi(Cmd_Argv(1));
00355     if (num < 0 || num >= researchListLength) {
00356         UI_ResetData(TEXT_STANDARD);
00357         return;
00358     }
00359 
00360     type = researchList2[num].type;
00361 
00362     /* switch to another team */
00363     if (type == RSGUI_BASETITLE) {
00364         base_t *b = researchList2[num].base;
00365         if (b != NULL && b != base) {
00366             UI_ExecuteConfunc("research_changebase %i %i", b->idx, researchListPos);
00367             return;
00368         }
00369     }
00370 
00371     if (type == RSGUI_RESEARCH || type == RSGUI_RESEARCHOUT || type == RSGUI_UNRESEARCHABLEITEM) {
00372         /* update the selected row */
00373         researchListPos = num;
00374     } else {
00375         return;
00376     }
00377 
00379     /* need to set previous selected tech to proper color */
00380     RS_InitGUI(base, qtrue);
00381 }
00382 
00389 static void RS_ChangeScientist_f (void)
00390 {
00391     int num;
00392     float diff;
00393     base_t *base = B_GetCurrentSelectedBase();
00394 
00395     if (!base)
00396         return;
00397 
00398     if (Cmd_Argc() < 3) {
00399         Com_Printf("Usage: %s <num_in_list> <diff>\n", Cmd_Argv(0));
00400         return;
00401     }
00402 
00403     num = atoi(Cmd_Argv(1));
00404     if (num < 0 || num >= researchListLength)
00405         return;
00406 
00407     diff = atof(Cmd_Argv(2));
00408     if (diff == 0)
00409         return;
00410 
00411     Com_DPrintf(DEBUG_CLIENT, "RS_ChangeScientist_f: num %i, diff %i\n", num, (int) diff);
00412     if (diff > 0) {
00413         RS_AssignScientist(researchList2[num].tech, base, NULL);
00414     } else {
00415         RS_RemoveScientist(researchList2[num].tech, NULL);
00416     }
00417 
00418     /* Update display-list and display-info. */
00419     RS_InitGUI(base, qtrue);
00420 }
00421 
00428 static void RS_MaxOutResearch (base_t *base, technology_t* tech)
00429 {
00430     if (!base || !tech)
00431         return;
00432 
00433     assert(tech->scientists >= 0);
00434 
00435     /* Add as many scientists as possible to this tech. */
00436     do {
00437         if (base->capacities[CAP_LABSPACE].cur < base->capacities[CAP_LABSPACE].max) {
00438             const employee_t *employee = E_GetUnassignedEmployee(base, EMPL_SCIENTIST);
00439             if (!employee)
00440                 break;
00441             RS_AssignScientist(tech, base, NULL);
00442         } else {
00443             /* No free lab-space left. */
00444             break;
00445         }
00446     } while (qtrue);
00447 }
00448 
00454 static void RS_AssignScientist_f (void)
00455 {
00456     int num;
00457     base_t *base = B_GetCurrentSelectedBase();
00458 
00459     if (!base)
00460         return;
00461 
00462     if (Cmd_Argc() < 2) {
00463         Com_Printf("Usage: %s <num_in_list>\n", Cmd_Argv(0));
00464         return;
00465     }
00466 
00467     num = atoi(Cmd_Argv(1));
00468     if (num < 0 || num >= researchListLength)
00469         return;
00470 
00471     Com_DPrintf(DEBUG_CLIENT, "RS_AssignScientist_f: num %i\n", num);
00472     RS_AssignScientist(researchList2[num].tech, base, NULL);
00473 
00474     /* Update display-list and display-info. */
00475     RS_InitGUI(base, qtrue);
00476 }
00477 
00483 static void RS_RemoveScientist_f (void)
00484 {
00485     int num;
00486     base_t *base = B_GetCurrentSelectedBase();
00487 
00488     if (!base)
00489         return;
00490 
00491     if (Cmd_Argc() < 2) {
00492         Com_Printf("Usage: %s <num_in_list>\n", Cmd_Argv(0));
00493         return;
00494     }
00495 
00496     num = atoi(Cmd_Argv(1));
00497     if (num < 0 || num >= researchListLength)
00498         return;
00499 
00500     RS_RemoveScientist(researchList2[num].tech, NULL);
00501 
00502     /* Update display-list and display-info. */
00503     RS_InitGUI(base, qtrue);
00504 }
00505 
00509 static void RS_UpdateData_f (void)
00510 {
00511     base_t *base = B_GetCurrentSelectedBase();
00512 
00513     if (!base)
00514         return;
00515 
00516     RS_InitGUI(base, qtrue);
00517 }
00518 
00522 static void RS_ResearchStart_f (void)
00523 {
00524     technology_t *tech;
00525     base_t *base = B_GetCurrentSelectedBase();
00526 
00527     /* We are not in base view. */
00528     if (!base)
00529         return;
00530 
00531     if (researchListPos < 0 || researchListPos >= researchListLength)
00532         return;
00533 
00534     /* Check if laboratory is available. */
00535     if (!B_GetBuildingStatus(base, B_LAB))
00536         return;
00537 
00538     /* get the currently selected research-item */
00539     tech = researchList2[researchListPos].tech;
00540 
00541     if (!tech)
00542         return;
00543 
00546     if (!tech->statusResearchable) {
00547         Com_DPrintf(DEBUG_CLIENT, "RS_ResearchStart_f: %s was not researchable yet. re-checking\n", tech->id);
00548         /* If all requirements are met (includes a check for "enough-collected") mark this tech as researchable.*/
00549         if (RS_RequirementsMet(&tech->requireAND, &tech->requireOR, base))
00550             RS_MarkOneResearchable(tech);
00551         RS_MarkResearchable(qfalse, base);  /* Re-check all other techs in case they depend on the marked one. */
00552     }
00553 
00554     /* statusResearchable might have changed - check it again */
00555     if (tech->statusResearchable) {
00556         switch (tech->statusResearch) {
00557         case RS_RUNNING:
00558             if (tech->base == base) {
00559                 /* Research already running in current base ... try to add max amount of scis. */
00560                 RS_MaxOutResearch(base, tech);
00561             }else {
00562                 /* Research already running in another base. */
00563                 UI_Popup(_("Notice"), _("This item is currently under research in another base."));
00564             }
00565             break;
00566         case RS_PAUSED:
00567         case RS_NONE:
00568             if (tech->statusResearch == RS_PAUSED) {
00569                 /* UI_Popup(_("Notice"), _("The research on this item continues.")); Removed because it isn't really needed.*/
00570                 Com_Printf("RS_ResearchStart_f: The research on this item continues.\n");
00571             }
00572             /* Add as many scientists as possible to this tech. */
00573             RS_MaxOutResearch(base, tech);
00574 
00575             if (tech->scientists > 0) {
00576                 tech->statusResearch = RS_RUNNING;
00577             }
00578             break;
00579         case RS_FINISH:
00580             /* Should never be executed. */
00581             UI_Popup(_("Notice"), _("The research on this item is complete."));
00582             break;
00583         default:
00584             break;
00585         }
00586     } else
00587         UI_Popup(_("Notice"), _("The research on this item is not yet possible.\nYou need to research the technologies it's based on first."));
00588 
00589     RS_InitGUI(base, qtrue);
00590 }
00591 
00595 static void RS_ResearchStop_f (void)
00596 {
00597     technology_t *tech;
00598     base_t *base = B_GetCurrentSelectedBase();
00599 
00600     /* we are not in base view */
00601     if (!base)
00602         return;
00603 
00604     if (researchListPos < 0 || researchListPos >= researchListLength)
00605         return;
00606 
00607     /* Check if laboratory is available. */
00608     if (!B_GetBuildingStatus(base, B_LAB))
00609         return;
00610 
00611     /* get the currently selected research-item */
00612     tech = researchList2[researchListPos].tech;
00613 
00614     if (!tech)
00615         return;
00616 
00617     switch (tech->statusResearch) {
00618     case RS_RUNNING:
00619         RS_StopResearch(tech);
00620         break;
00621     case RS_PAUSED:
00623         /* tech->statusResearch = RS_RUNNING; */
00624         break;
00625     case RS_FINISH:
00626         UI_Popup(_("Notice"), _("The research on this item is complete."));
00627         break;
00628     case RS_NONE:
00629         Com_Printf("Can't pause research. Research not started.\n");
00630         break;
00631     default:
00632         break;
00633     }
00634     RS_InitGUI(base, qtrue);
00635 }
00636 
00640 static void RS_ShowPedia_f (void)
00641 {
00642     const technology_t *tech;
00643 
00644     if (researchListPos < 0 || researchListPos >= researchListLength)
00645         return;
00646 
00647     /* get the currently selected research-item */
00648     tech = researchList2[researchListPos].tech;
00649 
00650     if (!tech)
00651         return;
00652 
00653     if (tech->preDescription.numDescriptions > 0) {
00654         UP_OpenCopyWith(tech->id);
00655     } else {
00656         UI_Popup(_("Notice"), _("No research proposal available for this project."));
00657     }
00658 }
00659 
00665 static void RS_InitGUIData (base_t* base)
00666 {
00667     int i, j;
00668     int row;
00669     qboolean first;
00670 
00671     assert(base);
00672 
00673     RS_MarkResearchable(qfalse, base);
00674 
00675     /* update tech of the base */
00676     row = 0;
00677     for (i = 0; i < ccs.numTechnologies; i++) {
00678         technology_t *tech = RS_GetTechByIDX(i);
00679 
00680         /* Don't show technologies with time == 0 - those are NOT separate research topics. */
00681         if (tech->time == 0)
00682             continue;
00683 
00684         /* hide finished research */
00685         if (tech->statusResearch == RS_FINISH)
00686             continue;
00687 
00688         /* hide tech we can't search */
00689         if (!tech->statusResearchable)
00690             continue;
00691 
00692         /* In this base or nowhere */
00693         if (tech->base != NULL && tech->base != base)
00694             continue;
00695 
00696         /* Assign the current tech in the global list to the correct entry in the displayed list. */
00697         researchList2[row].tech = tech;
00698         researchList2[row].base = base;
00699         researchList2[row].type = RSGUI_RESEARCH;
00700         row++;
00701     }
00702     researchList2[row].base = base;
00703     researchList2[row].type = RSGUI_BASEINFO;
00704     row++;
00705 
00706     /* Items collected but not yet researchable. */
00707     first = qtrue;
00708     for (i = 0; i < ccs.numTechnologies; i++) {
00709         technology_t *tech = RS_GetTechByIDX(i);
00710 
00711         /* Don't show technologies with time == 0 - those are NOT separate research topics. */
00712         if (tech->time == 0)
00713             continue;
00714 
00715         /* hide finished research */
00716         if (tech->statusResearch == RS_FINISH)
00717             continue;
00718 
00719         /* Hide searchable or uncollected tech */
00720         if (tech->statusResearchable || !tech->statusCollected)
00721             continue;
00722 
00723         /* title */
00724         if (first) {
00725             researchList2[row].type = RSGUI_NOTHING;
00726             row++;
00727             researchList2[row].base = base;
00728             researchList2[row].type = RSGUI_UNRESEARCHABLEITEMTITLE;
00729             row++;
00730             first = qfalse;
00731         }
00732 
00733         /* Assign the current tech in the global list to the correct entry in the displayed list. */
00734         researchList2[row].tech = tech;
00735         researchList2[row].base = base;
00736         researchList2[row].type = RSGUI_UNRESEARCHABLEITEM;
00737         row++;
00738     }
00739 
00740 
00741     /* research from another bases */
00742     for (j = 0; j < MAX_BASES; j++) {
00743         base_t *b = B_GetFoundedBaseByIDX(j);
00744         if (!b || b == base)
00745             continue;
00746 
00747         /* skip bases without labs */
00748         if (B_GetBuildingInBaseByType(b, B_LAB, qtrue) == NULL)
00749             continue;
00750 
00751         researchList2[row].type = RSGUI_NOTHING;
00752         row++;
00753         researchList2[row].type = RSGUI_BASETITLE;
00754         researchList2[row].base = b;
00755         row++;
00756 
00757         for (i = 0; i < ccs.numTechnologies; i++) {
00758             technology_t *tech = RS_GetTechByIDX(i);
00759 
00760             /* Don't show technologies with time == 0 - those are NOT separate research topics. */
00761             if (tech->time == 0)
00762                 continue;
00763 
00764             if (tech->base != b)
00765                 continue;
00766 
00767             /* hide finished research */
00768             if (tech->statusResearch == RS_FINISH)
00769                 continue;
00770 
00771             /* hide tech we can't search */
00772             if (!tech->statusResearchable)
00773                 continue;
00774 
00775             /* Assign the current tech in the global list to the correct entry in the displayed list. */
00776             researchList2[row].tech = tech;
00777             researchList2[row].base = b;
00778             researchList2[row].type = RSGUI_RESEARCHOUT;
00779 
00780             /* counting the numbers of display-list entries. */
00781             row++;
00782         }
00783         researchList2[row].base = b;
00784         researchList2[row].type = RSGUI_BASEINFO;
00785         row++;
00786     }
00787 
00790     researchListLength = row;
00791 }
00792 
00793 
00801 static void CL_ResearchType_f (void)
00802 {
00803     base_t *base = B_GetCurrentSelectedBase();
00804 
00805     if (!base)
00806         return;
00807 
00808     /* Update and display the list. */
00809     RS_InitGUIData(base);
00810 
00811     /* Nothing to research here. */
00813     if (!researchListLength) {
00814         UI_PopWindow(qfalse);
00815         UI_Popup(_("Notice"), _("Nothing to research"));
00816     } else if (!B_GetBuildingStatus(base, B_LAB)) {
00817         UI_PopWindow(qfalse);
00818         UI_Popup(_("Notice"), _("Build a laboratory first"));
00819     }
00820 }
00826 static void UI_ResearchInit_f (void)
00827 {
00828     base_t *base = B_GetCurrentSelectedBase();
00829 
00830     if (!base)
00831         return;
00832 
00833     CL_ResearchType_f();
00834     RS_InitGUI(base, qfalse);
00835 }
00836 
00837 void RS_InitCallbacks (void)
00838 {
00839     Cmd_AddCommand("research_init", UI_ResearchInit_f, "Research menu init function binding");
00840     Cmd_AddCommand("research_select", CL_ResearchSelect_f, "Update current selection with the one that has been clicked");
00841     Cmd_AddCommand("research_update", RS_UpdateData_f, NULL);
00842     Cmd_AddCommand("research_type", CL_ResearchType_f, "Switch between different research types");
00843     Cmd_AddCommand("mn_rs_add", RS_AssignScientist_f, "Assign one scientist to this entry");
00844     Cmd_AddCommand("mn_rs_change", RS_ChangeScientist_f, "Assign or remove scientist from this entry");
00845     Cmd_AddCommand("mn_rs_remove", RS_RemoveScientist_f, "Remove one scientist from this entry");
00846     Cmd_AddCommand("mn_start_research", RS_ResearchStart_f, "Start the research of the selected entry");
00847     Cmd_AddCommand("mn_stop_research", RS_ResearchStop_f, "Pause the research of the selected entry");
00848     Cmd_AddCommand("mn_show_ufopedia", RS_ShowPedia_f, "Show the entry in the UFOpaedia for the selected research topic");
00849 
00850     /* reset some static data - this is needed because we can start several
00851      * campaign games without restarting ufo. */
00852     memset(&researchList2, 0, sizeof(researchList2));
00853     researchListLength = 0;
00854     researchListPos = 0;
00855 }
00856 
00857 void RS_ShutdownCallbacks (void)
00858 {
00859     Cmd_RemoveCommand("research_init");
00860     Cmd_RemoveCommand("research_select");
00861     Cmd_RemoveCommand("research_update");
00862     Cmd_RemoveCommand("research_type");
00863     Cmd_RemoveCommand("mn_rs_add");
00864     Cmd_RemoveCommand("mn_rs_change");
00865     Cmd_RemoveCommand("mn_rs_remove");
00866     Cmd_RemoveCommand("mn_start_research");
00867     Cmd_RemoveCommand("mn_stop_research");
00868     Cmd_RemoveCommand("mn_show_ufopedia");
00869 }

Generated by  doxygen 1.6.2