00001 /* 00002 This file is part of Advanced Strategic Command; http://www.asc-hq.de 00003 Copyright (C) 1994-2010 Martin Bickel and Marc Schellenberger 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; see the file COPYING. If not, write to the 00017 Free Software Foundation, Inc., 59 Temple Place, Suite 330, 00018 Boston, MA 02111-1307 USA 00019 */ 00020 00021 #include <stdio.h> 00022 #include <cstring> 00023 #include <math.h> 00024 #include <stdarg.h> 00025 #include <ctime> 00026 00027 #include "buildingtype.h" 00028 #include "vehicletype.h" 00029 #include "typen.h" 00030 00031 #include "newfont.h" 00032 #include "spfst.h" 00033 #include "loaders.h" 00034 #include "misc.h" 00035 #include "controls.h" 00036 #include "stack.h" 00037 #include "dlg_box.h" 00038 #include "dialog.h" 00039 #include "attack.h" 00040 #include "gamedlg.h" 00041 #include "gameoptions.h" 00042 #include "ai/ai.h" 00043 #include "errors.h" 00044 #include "viewcalculation.h" 00045 #include "replay.h" 00046 #include "resourcenet.h" 00047 #include "itemrepository.h" 00048 #include "strtmesg.h" 00049 #include "messagedlg.h" 00050 #include "gameevent_dialogs.h" 00051 #include "cannedmessages.h" 00052 #include "mapdisplay.h" 00053 #include "player.h" 00054 00055 #include "dialogs/choosetech.h" 00056 00057 static TechnologyPresenter* techPresenter = NULL; 00058 00059 SuppressTechPresentation::SuppressTechPresentation() 00060 { 00061 presenter = techPresenter; 00062 techPresenter = NULL; 00063 } 00064 00065 SuppressTechPresentation::~SuppressTechPresentation() 00066 { 00067 techPresenter = presenter; 00068 } 00069 00070 void setResearchPresenter( TechnologyPresenter* presenter ) 00071 { 00072 techPresenter = presenter; 00073 } 00074 00075 00076 static bool anyTechAvailable( const Player& player ) 00077 { 00078 for (int i = 0; i < technologyRepository.getNum(); i++) { 00079 const Technology* tech = technologyRepository.getObject_byPos( i ); 00080 if ( tech ) { 00081 ResearchAvailabilityStatus a = player.research.techAvailable ( tech ); 00082 if ( a == Available ) 00083 return true; 00084 } 00085 } 00086 return false; 00087 } 00088 00089 00091 class NewGadgetDetection { 00092 std::list<const VehicleType*> units; 00093 std::list<const BuildingType*> buildings; 00094 Player& p; 00095 public: 00096 NewGadgetDetection( Player& player ) : p(player ) 00097 { 00098 for ( int i=0; i < vehicleTypeRepository.getNum() ; i++ ) { 00099 const VehicleType* v = vehicleTypeRepository.getObject_byPos ( i ); 00100 if ( !v->techDependency.available( p.research )) 00101 units.push_back( v ); 00102 } 00103 00104 for ( int i=0; i < buildingTypeRepository.getNum() ; i++ ) { 00105 const BuildingType* b = buildingTypeRepository.getObject_byPos ( i ); 00106 if ( !b->techDependency.available( p.research )) 00107 buildings.push_back( b ); 00108 } 00109 00110 } 00111 00113 void evaluate( TechnologyPresenter::Gadgets& storage ) 00114 { 00115 for ( int i=0; i < vehicleTypeRepository.getNum() ; i++ ) { 00116 const VehicleType* v = vehicleTypeRepository.getObject_byPos ( i ); 00117 if ( !v->techDependency.available( p.research )) 00118 units.remove( v ); 00119 } 00120 00121 for ( int i=0; i < buildingTypeRepository.getNum() ; i++ ) { 00122 const BuildingType* b = buildingTypeRepository.getObject_byPos ( i ); 00123 if ( !b->techDependency.available( p.research )) 00124 buildings.remove( b ); 00125 } 00126 00127 storage.buildings = buildings; 00128 storage.units = units; 00129 } 00130 }; 00131 00132 00133 00134 00135 const Technology* getNextTechnologyTowardsGoal( Player& player ) 00136 { 00137 if ( !player.research.goal ) 00138 return NULL; 00139 00140 if ( player.research.techResearched( player.research.goal->id )) { 00141 player.research.goal = NULL; 00142 return NULL; 00143 } 00144 00145 list<const Technology*> techs; 00146 if ( player.research.goal->eventually_available( player.research, &techs )) 00147 return *techs.begin(); 00148 else 00149 return NULL; 00150 } 00151 00152 00153 void runResearch( Player& player, vector<const Technology*>* newTechs, vector<ASCString>* newTechAdapter ) 00154 { 00155 Research& research = player.research; 00156 00157 if ( research.activetechnology && research.techResearched( research.activetechnology->id ) ) { 00158 /* the current research may suddenly be researched already if the map was modified by the ditor */ 00159 research.progress = max( 0, research.progress - research.activetechnology->researchpoints ) ; 00160 research.activetechnology = NULL; 00161 if ( !anyTechAvailable( player ) ) 00162 return; 00163 } 00164 00165 while ( research.activetechnology && (research.progress >= research.activetechnology->researchpoints)) { 00166 00167 const Technology* newTech = research.activetechnology; 00168 research.activetechnology = NULL; 00169 00170 if ( newTechs ) 00171 newTechs->push_back( newTech ); 00172 00173 NewGadgetDetection ngd( player ); 00174 00175 vector<ASCString> techAdapters = research.addanytechnology( newTech ); 00176 if( newTechAdapter ) 00177 newTechAdapter->insert( newTechAdapter->end(), techAdapters.begin(), techAdapters.end() ); 00178 00179 if ( techPresenter ) { 00180 TechnologyPresenter::Gadgets newItemsAvailable; 00181 ngd.evaluate( newItemsAvailable ); 00182 techPresenter->showTechnology( newTech, newItemsAvailable ); 00183 } 00184 00185 research.progress -= newTech->researchpoints; 00186 00187 research.activetechnology = getNextTechnologyTowardsGoal( player ); 00188 } 00189 00190 } 00191 00192 00193 void checkForNewResearch( Player& player ) 00194 { 00195 Research& research = player.research; 00196 00197 while ( research.activetechnology == NULL && research.progress && anyTechAvailable( player ) ) 00198 if ( !chooseSingleTechnology( player )) 00199 return; 00200 } 00201 00202 00203
1.5.1