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

alliancesetup.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 <sstream>
00023 #include <pgimage.h>
00024 #include <pglistboxbaseitem.h>
00025 #include <pgtooltiphelp.h>
00026 
00027 #include "../iconrepository.h"
00028 #include "../gamemap.h"
00029 #include "../paradialog.h"
00030 #include "playersetup.h"
00031 #include "alliancesetup.h"
00032 
00033 
00034 const int diplomaticStateIconSize = 20;
00035 const int diplomaticStateIconSpace = 2;
00036 
00037 
00038 template<typename SelectionType>
00039 int getItemNum() { return 0; };
00040 
00041 template<typename SelectionType>
00042 const char* getStateName(int s) { return NULL; };
00043 
00044 
00045 template<>
00046 int getItemNum<DiplomaticStates>() { return diplomaticStateNum; };
00047 
00048 template<>
00049 const char* getStateName<DiplomaticStates>(int s) { return diplomaticStateNames[s]; };
00050 
00051 
00052 template<>
00053 int getItemNum<AllianceSetupWidget::DiplomaticTransitions>() { return diplomaticStateNum+1; };
00054 
00055 template<>
00056 const char* getStateName<AllianceSetupWidget::DiplomaticTransitions>(int s) 
00057 { 
00058    if ( s == 0 ) 
00059       return "Sneak Attack"; 
00060    else 
00061       return diplomaticStateNames[s-1]; 
00062 };
00063 
00064 
00065 ASCString getDiplomaticStateImage( DiplomaticStates s )
00066 {
00067    ASCString filename = "diplo-" + ASCString::toString(s) + ".png";
00068    return filename;
00069 };
00070 
00071 ASCString getDiplomaticStateImage( AllianceSetupWidget::DiplomaticTransitions s )
00072 {
00073    if ( s == AllianceSetupWidget::SNEAK_ATTACK ) {
00074       ASCString filename = "diplo-sneak.png";
00075       return filename;
00076    } else 
00077       return getDiplomaticStateImage( DiplomaticStates( s-1 ));
00078 };
00079 
00080 
00081 template <typename SelectionType>
00082 class ListBoxImageItem : public PG_ListBoxBaseItem {
00083       SelectionType state;
00084    public:
00085       ListBoxImageItem( PG_ListBox *parent, PG_Point pos, SelectionType s )  : PG_ListBoxBaseItem( parent, diplomaticStateIconSize + 2*diplomaticStateIconSpace ), state(s)
00086       {
00087          new PG_Image( this, PG_Point(diplomaticStateIconSpace,diplomaticStateIconSpace), IconRepository::getIcon( getDiplomaticStateImage(s)).getBaseSurface() , false );
00088          new PG_Label( this, PG_Rect(diplomaticStateIconSize + 5, diplomaticStateIconSpace, 200,diplomaticStateIconSize), getStateName<SelectionType>(s));
00089       }
00090       
00091       SigC::Signal1<void,SelectionType> sigSet;
00092       
00093       bool eventMouseButtonUp(const SDL_MouseButtonEvent* button) 
00094       {
00095             if(button->button != 1) {
00096                      return false;
00097             }
00098             
00099             PG_ListBox* listbox = dynamic_cast<PG_ListBox*>(GetParent());
00100       
00101             if(listbox == NULL || !listbox->IsVisible()) {
00102                      return true;
00103             }
00104       
00105             listbox->SelectItem(this);
00106             listbox->QuitModal();
00107             sigSet(state);
00108       
00109             return true;
00110       }
00111 };
00112 
00113 
00114 
00115 
00116 
00117 template <typename SelectionType>
00118 class DiplomaticModeChooser : public PG_Widget {
00119       SelectionType& mode;
00120       bool writePossible;
00121       
00122    protected:
00123 
00124       void selectMode()
00125       {
00126          PG_ListBox listBox( NULL, PG_Rect( x, y + Height(), 250, getItemNum<SelectionType>() * ( diplomaticStateIconSpace * 2 + diplomaticStateIconSize ) + 4 ));
00127          for ( int i = 0; i < getItemNum<SelectionType>(); ++i) {
00128             ListBoxImageItem<SelectionType>* item = new ListBoxImageItem<SelectionType>( NULL, PG_Point(0,0), SelectionType(i));
00129             item->sigSet.connect( SigC::slot( *this, &DiplomaticModeChooser::SetState));
00130             listBox.AddChild( item );
00131          }
00132          listBox.Show();
00133          listBox.RunModal();
00134       }     
00135             
00136    public:
00137       DiplomaticModeChooser ( PG_Widget *parent, const PG_Rect& pos, SelectionType& dm, bool writeable ) : PG_Widget( parent, pos, true ), mode(dm), writePossible( writeable )
00138       {
00139       };
00140 
00141       SigC::Signal1<void,SelectionType> sigStateChange;
00142             
00143       void eventDraw (SDL_Surface *surface, const PG_Rect &rect)
00144       {
00145          Surface s = Surface::Wrap( surface );
00146          s.Blit(  IconRepository::getIcon( getDiplomaticStateImage(mode) ) );
00147       }
00148       
00149       void SetState( SelectionType state )
00150       {
00151          mode = state;
00152          Redraw();
00153          Update(true);
00154          sigStateChange(state);
00155       }
00156       
00157       bool eventMouseButtonUp(const SDL_MouseButtonEvent* button) 
00158       {
00159          if (button->button != 1) {
00160             return false;
00161          }
00162 
00163          if ( writePossible )   
00164             selectMode();
00165          return true;
00166       }
00167 };      
00168  
00169 
00170 AllianceSetupWidget::AllianceSetupWidget( GameMap* gamemap, bool allEditable, PG_Widget *parent, const PG_Rect &r, const std::string &style ) : PG_ScrollWidget( parent, r, style ) , actmap ( gamemap )
00171 {
00172    this->allEditable = allEditable;
00173    int playerNum = 0;
00174    
00175    for ( int i = 0; i < actmap->getPlayerCount(); ++i ) {
00176       vector<DiplomaticTransitions> t;
00177       vector< DiplomaticStates > s;
00178       
00179       const DiplomaticStateVector& diplo = actmap->player[i].diplomacy;
00180       
00181       for ( int j = 0; j < actmap->getPlayerCount(); ++j )  {
00182          DiplomaticStateVector::QueuedStateChanges::const_iterator change = diplo.queuedStateChanges.find(j);
00183          if ( change != diplo.queuedStateChanges.end() )
00184             t.push_back( DiplomaticTransitions( change->second + 1 ));
00185          else
00186             t.push_back( DiplomaticTransitions( diplo.getState(j) + 1 ));
00187          s.push_back( diplo.getState(j));
00188       }   
00189        
00190       stateChanges.push_back ( t );        
00191       states.push_back ( s );
00192       
00193       if ( actmap->player[i].exist() ) 
00194          ++playerNum;
00195    }      
00196 
00197          
00198    const int colWidth = 40;
00199    const int lineHeight = 30;
00200    const int barSpace = 5;
00201    const int spacing = 10;
00202    const int nameLength = 200;
00203    const int barOverhang = 20;
00204    const int sqaureWidth = lineHeight;
00205    const int lineLength = sqaureWidth + nameLength + playerNum * (colWidth + spacing) + barOverhang;
00206    const int colHeight  =  barOverhang + playerNum * (lineHeight + spacing) - spacing +  barOverhang;
00207 
00208    #define calcx(counter) (sqaureWidth + nameLength + spacing + counter * (colWidth + spacing) )
00209    #define calcy(counter) (barOverhang + counter * (lineHeight + spacing))
00210 
00211    int counter = 0; 
00212    for ( int i = 0; i < actmap->getPlayerCount(); ++i ) 
00213       if ( actmap->player[i].exist() ) {
00214          int x = calcx(counter);
00215          
00216          ColoredBar* verticalBar = new ColoredBar( actmap->player[i].getColor(), this, PG_Rect( x, 0, colWidth, colHeight ));
00217          verticalBar->SetTransparency( 128 );
00218          
00219          ++counter;
00220       }
00221    
00222                         
00223    counter = 0; 
00224    for ( int i = 0; i < actmap->getPlayerCount(); ++i ) // rows
00225       if ( actmap->player[i].exist() ) {
00226       
00227          PlayerWidgets pw;
00228          pw.pos  = i;
00229          
00230          int y = calcy(counter);
00231          
00232          ColoredBar* horizontalBar = new ColoredBar( actmap->player[i].getColor(), this, PG_Rect( 0, y, lineLength, lineHeight ));
00233          horizontalBar->SetTransparency( 128 );
00234          
00235          pw.name = new PG_LineEdit( horizontalBar, PG_Rect( sqaureWidth, barSpace, nameLength, lineHeight-2*barSpace ));
00236          pw.name->SetText( actmap->player[i].getName());
00237          pw.name->SetEditable( false );
00238 
00239          new PG_ToolTipHelp( pw.name, "Position: " + ASCString::toString(i) );
00240 
00241          PG_ThemeWidget* col = new PG_ThemeWidget( horizontalBar, PG_Rect( barSpace, barSpace, sqaureWidth - 2*barSpace, lineHeight - 2*barSpace ));
00242          col->SetSimpleBackground(true);
00243          col->SetBackgroundColor ( actmap->player[i].getColor());
00244          col->SetBorderSize(0);
00245          
00246          int cnt2 = 0;
00247          for ( int j = 0; j < actmap->getPlayerCount(); ++j ) // columns
00248             if ( actmap->player[j].exist() )  {
00249                if ( i != j ) {
00250                   int x = calcx(cnt2) - barSpace;
00251                   PG_Rect rect ( x + (colWidth - diplomaticStateIconSize)/2 ,  (lineHeight - diplomaticStateIconSize)/2,diplomaticStateIconSize,diplomaticStateIconSize); 
00252                   if ( allEditable ) {
00253                      DiplomaticModeChooser<DiplomaticStates>* dmc = new DiplomaticModeChooser<DiplomaticStates>( horizontalBar, rect, getState(i,j), true );
00254                      dmc->sigStateChange.connect( SigC::bind( SigC::slot( *this, &AllianceSetupWidget::setState ), j, i));
00255                      diplomaticWidgets[ linearize( i,j) ] = dmc;
00256                   } else {
00257                      DiplomaticTransitions& s = stateChanges[i][j];
00258                      DiplomaticModeChooser<DiplomaticTransitions>* dmc = new DiplomaticModeChooser<DiplomaticTransitions>( horizontalBar, rect, s, i == gamemap->actplayer );
00259                      // dmc->sigStateChange.connect( SigC::bind( SigC::slot( *this, &AllianceSetupWidget::setState ), j, i));
00260                      diplomaticWidgets[ linearize( i,j) ] = dmc;
00261                   }   
00262                      
00263                }
00264                ++cnt2;
00265             }   
00266                         
00267          playerWidgets.push_back( pw );
00268                         
00269          ++counter;
00270       } 
00271       
00272    SetTransparency(255);
00273 };
00274 
00275 
00276 void AllianceSetupWidget::setState( DiplomaticStates s, int actingPlayer, int secondPlayer )
00277 {
00278    getState( actingPlayer, secondPlayer) = s;
00279    
00280    DiplomaticWidgets::iterator i = diplomaticWidgets.find( linearize( actingPlayer, secondPlayer) );
00281    if ( i != diplomaticWidgets.end() )
00282       i->second->Redraw(true);
00283 }
00284 
00285 DiplomaticStates& AllianceSetupWidget::getState( int actingPlayer, int secondPlayer )
00286 {
00287    return states.at(actingPlayer).at(secondPlayer);
00288 }
00289 
00290 int AllianceSetupWidget::linearize( int actingPlayer, int secondPlayer  )
00291 {
00292    return actingPlayer * actmap->getPlayerCount() + secondPlayer;
00293 }
00294 
00295 
00296 void AllianceSetupWidget::Apply() 
00297 {
00298    for ( int acting = 0; acting < actmap->getPlayerCount(); ++acting )
00299       for ( int second = 0; second < actmap->getPlayerCount(); ++second ) {
00300       
00301          if ( allEditable ) {
00302             if ( getState( acting, second ) != actmap->player[acting].diplomacy.getState( second ))
00303                actmap->player[acting].diplomacy.setState( second, getState( acting, second ));         
00304          } else {
00305             if ( acting == actmap->actplayer ) {
00306                if ( stateChanges[acting][second] == SNEAK_ATTACK ) {
00307                   actmap->player[acting].diplomacy.sneakAttack( second );         
00308                } else {
00309                   DiplomaticStates s = DiplomaticStates( stateChanges[acting][second] - 1);
00310                   DiplomaticStates t;
00311                   DiplomaticStateVector::QueuedStateChanges::iterator q = actmap->player[acting].diplomacy.queuedStateChanges.find( second );
00312                   if ( q == actmap->player[acting].diplomacy.queuedStateChanges.end() )
00313                      t = getState( acting, second );
00314                   else
00315                      t = q->second;   
00316                      
00317                   if ( t != s )
00318                      actmap->player[acting].diplomacy.propose( second, s );         
00319                }   
00320             }
00321          }
00322       }
00323 };
00324 
00325 
00326 AllianceSetupWidget::~AllianceSetupWidget()
00327 {
00328 }   
00329 
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 
00338 
00339 class AllianceSetupWindow : public ASC_PG_Dialog {
00340       AllianceSetupWidget* asw;
00341       bool changed;
00342    public:
00343       AllianceSetupWindow( GameMap* actmap, bool allEditable, PG_Widget *parent, const PG_Rect &r ) : ASC_PG_Dialog( parent, r, "Diplomacy" ), changed(false)
00344       {
00345          asw = new AllianceSetupWidget( actmap, allEditable, this, PG_Rect( 5, 30, r.Width() - 10, r.Height() - 60 ));
00346          PG_Button* ok = new PG_Button( this, PG_Rect( Width() - 200, Height() - 30, 90, 20 ), "OK" );
00347          ok->sigClick.connect( SigC::slot( *this, &AllianceSetupWindow::Apply ));
00348          PG_Button* cancel = new PG_Button( this, PG_Rect( Width() - 100, Height() - 30, 90, 20 ), "Cancel" );
00349          cancel->sigClick.connect( SigC::slot( *this, &AllianceSetupWindow::QuitModal ));
00350       }
00351 
00352       bool Apply()
00353       {
00354          asw->Apply();
00355          QuitModal();
00356          changed = true;
00357          return true;
00358       }
00359 
00360       bool isSomethingChanged() { return changed; };
00361       
00362 };
00363 
00364 bool  setupalliances( GameMap* actmap, bool supervisor  )
00365 {
00366    AllianceSetupWindow asw ( actmap, supervisor, NULL, PG_Rect( 100, 100, 700, 500 ));
00367    asw.Show();
00368    asw.RunModal();
00369    return asw.isSomethingChanged();
00370 }

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