00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 )
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 )
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
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 }