Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

choosetech.cpp

Go to the documentation of this file.
00001 /*
00002      This file is part of Advanced Strategic Command; http://www.asc-hq.de
00003      Copyright (C) 1994-1999  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 
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 

Generated on Tue Jun 24 01:27:37 2008 for Advanced Strategic Command by  doxygen 1.4.2