00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "choosetech.h"
00023
00024 #include "../player.h"
00025 #include "../gamemap.h"
00026
00027 #include "../paradialog.h"
00028 #include "../itemrepository.h"
00029 #include "../iconrepository.h"
00030 #include "../vehicletype.h"
00031 #include "unitinfodialog.h"
00032
00033 #include "selectionwindow.h"
00034
00035 #include "pgmultilineedit.h"
00036 #include "../widgets/textrenderer.h"
00037
00038 class TechWidget: public SelectionWidget {
00039 const Technology* tech;
00040 static Surface clippingSurface;
00041 Surface& getClippingSurface() { return clippingSurface; };
00042 int actplayer;
00043 static const int widgetHeight = 60;
00044 bool info();
00045 public:
00046 TechWidget( PG_Widget* parent, const PG_Point& pos, int width, const Technology* technology, int player = 0 );
00047 ASCString getName() const;
00048 const Technology* getTechnology() const { return tech; };
00049 protected:
00050 void display( SDL_Surface * surface, const PG_Rect & src, const PG_Rect & dst );
00051 };
00052
00053 TechWidget :: TechWidget( PG_Widget* parent, const PG_Point& pos, int width, const Technology* technology, int player ) : SelectionWidget( parent, PG_Rect( pos.x, pos.y, width, widgetHeight )), tech( technology ), actplayer(player)
00054 {
00055
00056 int lineheight = 20;
00057
00058 int xoffs = 20;
00059 if ( tech->relatedUnitID > 0 )
00060 xoffs += 40;
00061
00062 int www = width - xoffs - 20 - 2 * lineheight;
00063
00064 new PG_Label( this, PG_Rect( xoffs, 10, www, 25 ), tech->name );
00065 new PG_Label( this, PG_Rect( xoffs, 30, www, 25 ), ASCString::toString( tech->researchpoints) + " RP" );
00066
00067 if ( tech->relatedUnitID > 0 ) {
00068 PG_Button* b = new PG_Button( this, PG_Rect( width - 2 * lineheight - 10, Height()/2-lineheight, 2*lineheight, 2*lineheight ));
00069 b->SetIcon( IconRepository::getIcon( "blue-i.png").getBaseSurface() );
00070 b->sigClick.connect( SigC::slot( *this, &TechWidget::info ));
00071 }
00072
00073 SetTransparency( 255 );
00074 };
00075
00076 bool TechWidget::info()
00077 {
00078 const Vehicletype* vt = vehicleTypeRepository.getObject_byID( tech->relatedUnitID );
00079 if ( vt )
00080 unitInfoDialog( vt );
00081 return true;
00082 }
00083
00084
00085
00086 ASCString TechWidget::getName() const
00087 {
00088 return tech->name;
00089 };
00090
00091 void TechWidget::display( SDL_Surface * surface, const PG_Rect & src, const PG_Rect & dst )
00092 {
00093 Vehicletype* vt = NULL;
00094 if ( tech->relatedUnitID > 0 )
00095 if ( (vt = vehicleTypeRepository.getObject_byID( tech->relatedUnitID ))) {
00096 if ( !getClippingSurface().valid() )
00097 getClippingSurface() = Surface::createSurface( fieldsizex + 10, fieldsizey + 10, 32, 0 );
00098
00099 getClippingSurface().Fill(0);
00100
00101 vt->paint( getClippingSurface(), SPoint(5,5) );
00102 PG_Draw::BlitSurface( getClippingSurface().getBaseSurface(), src, surface, dst);
00103 }
00104 }
00105
00106 Surface TechWidget::clippingSurface;
00107
00108
00109
00110
00111
00112 class TechnologySelectionItemFactory: public SelectionItemFactory, public SigC::Object {
00113 Player& player;
00114 bool allTechs;
00115 public:
00116 typedef vector<const Technology*> Container;
00117
00118 protected:
00119 Container::iterator it;
00120 Container items;
00121
00122 public:
00123 TechnologySelectionItemFactory( Player& player );
00124
00125
00126 bool showAllTechs( bool all) { allTechs = all; return true; };
00127
00128 void restart();
00129 SigC::Signal1<void,const Technology*> techSelected;
00130
00131 SelectionWidget* spawnNextItem( PG_Widget* parent, const PG_Point& pos );
00132
00133 void itemSelected( const SelectionWidget* widget, bool mouse );
00134 };
00135
00136
00137
00138 TechnologySelectionItemFactory :: TechnologySelectionItemFactory( Player& theplayer ) : player(theplayer), allTechs(false)
00139 {
00140 restart();
00141 };
00142
00143 bool techComp ( const Technology* t1, const Technology* t2 )
00144 {
00145 return (t1->relatedUnitID > 0 && t2->relatedUnitID < 0 ) ||
00146 (t1->techlevel < t2->techlevel) ||
00147 (t1->techlevel == t2->techlevel && t1->name < t2->name );
00148 }
00149
00150 void TechnologySelectionItemFactory::restart()
00151 {
00152 items.clear();
00153
00154 for (int i = 0; i < technologyRepository.getNum(); i++) {
00155 const Technology* tech = technologyRepository.getObject_byPos( i );
00156 if ( tech ) {
00157 if ( allTechs ) {
00158 if ( tech->eventually_available( player.research, NULL ))
00159 items.push_back( tech );
00160 } else {
00161 ResearchAvailabilityStatus a = player.research.techAvailable ( tech );
00162 if ( a == Available )
00163 items.push_back ( tech );
00164 }
00165 }
00166 }
00167
00168 sort( items.begin(), items.end(), techComp );
00169 it = items.begin();
00170 };
00171
00172
00173 SelectionWidget* TechnologySelectionItemFactory::spawnNextItem( PG_Widget* parent, const PG_Point& pos )
00174 {
00175 if ( it != items.end() ) {
00176 const Technology* v = *(it++);
00177
00178 return new TechWidget( parent, pos, parent->Width() - 15, v, player.getPosition() );
00179 } else
00180 return NULL;
00181 };
00182
00183
00184 void TechnologySelectionItemFactory::itemSelected( const SelectionWidget* widget, bool mouse )
00185 {
00186 if ( !widget )
00187 return;
00188
00189 const TechWidget* tw = dynamic_cast<const TechWidget*>(widget);
00190 assert( tw );
00191
00192 techSelected(tw->getTechnology());
00193 }
00194
00195
00196
00197 class ChooseTech : public ASC_PG_Dialog
00198 {
00199 ItemSelectorWidget* itemSelector;
00200 TechnologySelectionItemFactory* factory;
00201 PG_MultiLineEdit* techList;
00202 Player& player;
00203
00204 PG_Label* pointsLabel;
00205 PG_Label* availLabel;
00206 const Technology* goal;
00207
00208 bool changeTechView( bool all )
00209 {
00210 factory->showAllTechs ( all );
00211 itemSelector->reLoad( true );
00212 return true;
00213
00214 }
00215
00216 void techSelected( const Technology* tech )
00217 {
00218 ASCString s;
00219 list<const Technology*> techs;
00220 if ( !tech->eventually_available( player.research , &techs )) {
00221 warning("Inconsistency in ChooseTech::techSelected");
00222 return;
00223 }
00224
00225 assert( techs.begin() != techs.end() );
00226
00227 int points = 0;
00228 for ( list<const Technology*>::iterator i = techs.begin(); i != techs.end(); ++i ) {
00229 s += (*i)->name + "\n";
00230 points += (*i)->researchpoints;
00231 }
00232 techList->SetText( s );
00233
00234 pointsLabel->SetText( ASCString("Sum: ") + ASCString::toString(points) + " Points" );
00235
00236 goal = player.research.goal = tech;
00237 player.research.activetechnology = *techs.begin();
00238 };
00239
00240 protected:
00241 bool handleButtonClick(PG_Button* button)
00242 {
00243 if ( goal )
00244 return ASC_PG_Dialog::handleButtonClick( button );
00245 else
00246 return false;
00247 };
00248
00249 bool ok()
00250 {
00251 if ( goal || !itemSelector->getItemNum() ) {
00252 QuitModal();
00253 return true;
00254 } else
00255 return false;
00256 }
00257
00258 bool showPrerequisites()
00259 {
00260 if ( goal ) {
00261 ASCString msg = "Prerequisites for Technology " + goal->name + ":\n";
00262 msg += goal->techDependency.showDebug( player.research );
00263 ViewFormattedText vft("Technology Prerequisites", msg, PG_Rect( -1, -1, 500, 400 ));
00264 vft.Show();
00265 vft.RunModal();
00266 }
00267 return true;
00268 }
00269
00270
00271 public:
00272 ChooseTech( Player& my_player ) : ASC_PG_Dialog( NULL, PG_Rect( -1, -1, 770, 600), "Choose Technology" ) , factory(NULL), player( my_player ), goal(NULL)
00273 {
00274 factory = new TechnologySelectionItemFactory( player );
00275 factory->techSelected.connect( SigC::slot( *this, &ChooseTech::techSelected ));
00276 itemSelector = new ItemSelectorWidget( this, PG_Rect( 10, 40, 400, Height() - 80 ), factory );
00277
00278 (new PG_CheckButton( this, PG_Rect( 10, Height() - 40, 300, 25 ), "Show All Technologies"))->sigClick.connect( SigC::slot( *this, &ChooseTech::changeTechView));
00279 techList = new PG_MultiLineEdit( this, PG_Rect ( 450, 40, 300, 200 ));
00280 techList->SetEditable(false);
00281 pointsLabel = new PG_Label( this, PG_Rect( 450, 250, 300, 25 ));
00282 availLabel = new PG_Label( this, PG_Rect( 450, 280, 300, 25 ), "Accumulated research points: " + ASCString::toString( player.research.progress) );
00283
00284 (new PG_Button( this, PG_Rect( 450, 320, 300, 20), "List Prerequisites" ))->sigClick.connect( SigC::slot( *this, &ChooseTech::showPrerequisites ));
00285
00286 AddStandardButton("~O~K")->sigClick.connect( SigC::slot( *this, &ChooseTech::ok ));
00287 };
00288 };
00289
00290
00291
00292
00293 void chooseTechnology( Player& player )
00294 {
00295 #if 0
00296 ItemSelectorWindow isw( NULL, );
00297 isw.Show();
00298 isw.RunModal();
00299 #else
00300 ChooseTech ct( player);
00301 ct.Show();
00302 ct.RunModal();
00303 #endif
00304 }
00305
00306
00307