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

admingame.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 
00025 #include "admingame.h"
00026 #include "../paradialog.h"
00027 #include "../gamemap.h"
00028 #include "../spfst.h"
00029 #include "../loaders.h"
00030 #include "playersetup.h"
00031 #include "fileselector.h"
00032 #include "pwd_dlg.h"
00033 
00034 #include "../widgets/multilistbox.h"
00035 
00036 
00037 
00038 
00039 class AdminGameWindow : public ASC_PG_Dialog {
00040    private:
00041       PG_ListBox* playerlistbox;
00042       PG_ListBox* actionlistbox;
00043       vector<PG_ListBoxItem*> players;
00044       GameMap* gamemap;
00045       PG_LineEdit* turn;
00046       PG_LineEdit* currentPlayer;
00047       PG_LineEdit* filename;
00048 
00049       typedef Loki::Functor<void, TYPELIST_1(int) > PlayerActionFunctor;
00050       typedef PG_ListBoxDataItem<PlayerActionFunctor> ActionItem;
00051 
00052       PG_ScrollWidget* scrollwidget;
00053 
00054       PlayerSetupWidget* playerSetup;
00055       TurnSkipper* turnSkipper;
00056 
00057       bool successfullyClosed;
00058       
00059       void updateTurn()
00060       {
00061          if ( turn )
00062             turn->SetText( ASCString::toString( gamemap->time.turn() ));
00063 
00064          if ( currentPlayer )
00065             if ( gamemap->actplayer >= 0 )
00066                currentPlayer->SetText( gamemap->player[gamemap->actplayer].getName() );
00067             else
00068                currentPlayer->SetText( ASCString::toString( gamemap->actplayer ) );
00069       }
00070 
00071       bool skipPlayer()
00072       {
00073          if ( turnSkipper ) {
00074             GameMap* temp = actmap;
00075             actmap = gamemap;
00076             (*turnSkipper)(gamemap);
00077             actmap = temp;
00078          }
00079 
00080          updateTurn();
00081          return true;
00082       }
00083 
00084       bool apply()
00085       {
00086          for ( int i = 0; i < playerlistbox->GetWidgetCount(); ++i ) {
00087             PG_ListBoxBaseItem* bi = dynamic_cast<PG_ListBoxBaseItem*>(playerlistbox->FindWidget(i));
00088             if ( bi && bi->IsSelected() )
00089                applyForPlayer( i );
00090          }
00091          repaintMap();
00092          mapChanged( gamemap );
00093          return true;
00094       }
00095 
00096       void applyForPlayer( int player )
00097       {
00098          for ( int i = 0; i < actionlistbox->GetWidgetCount(); ++i ) {
00099             ActionItem* bi = dynamic_cast<ActionItem*>(actionlistbox->FindWidget(i));
00100             if ( bi && bi->IsSelected() )
00101                bi->getData()(player);
00102          }
00103       }
00104 
00105       void resetView( int player )
00106       {
00107          gamemap->getPlayer(player).resetView();
00108       }
00109       void resetResearch( int player )
00110       {
00111          gamemap->getPlayer(player).resetResearch();
00112       }
00113       
00114       void resetTribute( int player )
00115       {
00116          gamemap->getPlayer(player).resetTribute();
00117       }
00118       
00119       void resetPassword( int player )
00120       {
00121          gamemap->getPlayer(player).resetPassword();
00122       }
00123 
00124       void newPassword( int player )
00125       {
00126          enterpassword( gamemap->player[player].passwordcrc, true, true, false);
00127       }
00128 
00129       void newEmail( int player )
00130       {
00131           gamemap->player[player].email = editString2( "Mail Address for " + gamemap->player[player].getName(), gamemap->player[player].email);
00132       }
00133 
00134 
00135       void resetDiplomacy( int player )
00136       {
00137          for ( int j = 0; j< gamemap->getPlayerCount(); ++j ) {
00138             if ( j != player ) {
00139                gamemap->getPlayer(player).diplomacy.setState( j, WAR, false );
00140                gamemap->getPlayer(j).diplomacy.setState( player, WAR, false );
00141             }
00142          }
00143       }
00144 
00145       void deleteUnits( int player )
00146       {
00147          while ( gamemap->player[player].vehicleList.begin() != gamemap->player[player].vehicleList.end() )
00148             delete *gamemap->player[player].vehicleList.begin();
00149 
00150       }
00151 
00152       void deleteMines( int player )
00153       {
00154          for ( int y = 0; y < gamemap->ysize; ++y )
00155             for ( int x = 0; x < gamemap->xsize; ++x ) {
00156                tfield* fld = gamemap->getField(x,y);
00157                for ( tfield::MineContainer::iterator i = fld->mines.begin(); i != fld->mines.end(); )
00158                   if ( i->player == player )
00159                      i = fld->mines.erase( i );
00160                   else
00161                      ++i;
00162             }
00163 
00164       }
00165 
00166       void deleteBuildings( int player )
00167       {
00168          while ( gamemap->player[player].buildingList.begin() != gamemap->player[player].buildingList.end() )
00169             delete *gamemap->player[player].buildingList.begin();
00170 
00171       }
00172 
00173       void neutralBuildings( int player )
00174       {
00175          while ( gamemap->player[player].buildingList.begin() != gamemap->player[player].buildingList.end() )
00176             gamemap->player[player].buildingList.front()->convert(8);
00177 
00178       }
00179       
00180       
00181       void deleteProduction( int player )
00182       {
00183          for ( Player::BuildingList::iterator i = gamemap->player[player].buildingList.begin(); i != gamemap->player[player].buildingList.end(); ++i )
00184             (*i)->deleteAllProductionLines();
00185 
00186       }
00187       
00188       void deleteResources( int player )
00189       {
00190          for ( Player::BuildingList::iterator i = gamemap->player[player].buildingList.begin(); i != gamemap->player[player].buildingList.end(); ++i ) {
00191             for ( int j = 0; j < waffenanzahl; ++j )
00192                (*i)->ammo[j] = 0;
00193 
00194             (*i)->actstorage = Resources();
00195          }
00196          gamemap->bi_resource[player] = Resources();
00197          
00198          resetTribute( player );
00199       }
00200 
00201       static const int techID = 0xE1C8;
00202 
00203       void exportTechs( int player )
00204       {
00205          ASCString filename = selectFile( "*.asctechs", false );
00206          if ( filename.empty() )
00207             return;
00208 
00209          tnfilestream stream( filename, tnstream::writing );
00210          stream.writeInt( techID );
00211          stream.writeInt( 1 );
00212          writeClassContainer( gamemap->player[player].research.developedTechnologies, stream );
00213       }
00214 
00215       void importTechs( int player )
00216       {
00217          ASCString filename = selectFile( "*.asctechs", true );
00218          if ( filename.empty() )
00219             return;
00220 
00221          tnfilestream stream( filename, tnstream::reading );
00222          if ( stream.readInt() != techID ) {
00223             errorMessage("invalid file contents");
00224             return;
00225          }
00226 
00227          if ( stream.readInt() != 1 ) {
00228             errorMessage("invalid file version");
00229             return;
00230          }
00231          vector<int> dt;
00232          readClassContainer( dt, stream );
00233          vector<int>& techs = gamemap->player[player].research.developedTechnologies;
00234          copy( dt.begin(), dt.end(), back_inserter( techs ));
00235          sort( techs.begin(), techs.end() );
00236          techs.erase( unique( techs.begin(), techs.end()), techs.end() );
00237       }
00238 
00239 
00240       bool saveAsMap()
00241       {
00242          apply();
00243          if ( playerSetup->Apply() ) {
00244             gamemap->network = NULL;
00245 
00246             if ( gamemap->_resourcemode == 1)
00247                warning("This map uses BI resource mode. Saving as map will delete all global resources of all players");
00248                
00249             ASCString name = selectFile( mapextension, false);
00250             if ( !name.empty() ) {
00251                StatusMessageWindowHolder smw = MessagingHub::Instance().infoMessageWindow( "saving " + name );
00252                savemap( name.c_str(), gamemap );
00253             }
00254 
00255             QuitModal();
00256             return true;
00257          } else
00258             return false;
00259          return true;
00260       }
00261 
00262       bool turnEdited()
00263       {
00264          gamemap->time.set( atoi( turn->GetText() ), 0 );
00265          updateTurn();
00266          return true;
00267       }
00268       
00269       bool netSetup()
00270       {
00271          if ( gamemap && gamemap->network )
00272             gamemap->network->setup();
00273          return true;
00274       }
00275       
00276       
00277    public:
00278       AdminGameWindow( GameMap* actmap, PG_Widget *parent, TurnSkipper* turnSkipper ) : ASC_PG_Dialog( parent, PG_Rect( -1, -1, 600, min(1000, PG_Application::GetScreenHeight()) ), "Admin Game" ), gamemap( actmap ), successfullyClosed(false)
00279       {
00280          this->turnSkipper = turnSkipper;
00281          
00282          scrollwidget = new PG_ScrollWidget( this, PG_Rect( 1, GetTitlebarHeight(), Width() - 2, Height() - GetTitlebarHeight() - 2 ));
00283          scrollwidget->SetTransparency(255);
00284          
00285          const int selectorHeight = 250;
00286          const int selectorWidth = 200;
00287          const int gap = 20;
00288          int ypos  = gap;
00289          playerlistbox = (new MultiListBox( scrollwidget, PG_Rect( gap, ypos, selectorWidth, selectorHeight )))->getListBox();
00290 
00291          int lastPlayer = 0;
00292          for ( int i = 0; i < actmap->getPlayerCount(); ++i )
00293             if ( actmap->player[i].exist() )
00294                lastPlayer = i;
00295          
00296          for ( int i = 0; i <= lastPlayer; ++i ) {
00297             if ( actmap->player[i].exist() ) 
00298                players.push_back( new PG_ListBoxItem( playerlistbox, 20, actmap->player[i].getName() ));
00299             else
00300                players.push_back ( new PG_ListBoxItem( playerlistbox, 20, "-" ) );
00301          }
00302 
00303          actionlistbox = (new MultiListBox( scrollwidget, PG_Rect( 2*gap + selectorWidth, gap, selectorWidth, selectorHeight )))->getListBox();
00304          new ActionItem( actionlistbox, 20, "reset view", PlayerActionFunctor( this, &AdminGameWindow::resetView) );
00305          new ActionItem( actionlistbox, 20, "reset research", PlayerActionFunctor( this, &AdminGameWindow::resetResearch));
00306          new ActionItem( actionlistbox, 20, "reset tribute", PlayerActionFunctor( this, &AdminGameWindow::resetTribute));
00307          new ActionItem( actionlistbox, 20, "reset diplomacy (->truce)", PlayerActionFunctor( this, &AdminGameWindow::resetDiplomacy));
00308          new ActionItem( actionlistbox, 20, "reset password", PlayerActionFunctor( this, &AdminGameWindow::resetPassword));
00309          new ActionItem( actionlistbox, 20, "delete units", PlayerActionFunctor( this, &AdminGameWindow::deleteUnits));
00310          new ActionItem( actionlistbox, 20, "delete buildings", PlayerActionFunctor( this, &AdminGameWindow::deleteBuildings));
00311          new ActionItem( actionlistbox, 20, "delete production", PlayerActionFunctor( this, &AdminGameWindow::deleteProduction));
00312          new ActionItem( actionlistbox, 20, "delete resources + ammo", PlayerActionFunctor( this, &AdminGameWindow::deleteResources));
00313          new ActionItem( actionlistbox, 20, "delete mines", PlayerActionFunctor( this, &AdminGameWindow::deleteMines));
00314          new ActionItem( actionlistbox, 20, "make buildings neutral", PlayerActionFunctor( this, &AdminGameWindow::neutralBuildings));
00315          new ActionItem( actionlistbox, 20, "enter new password", PlayerActionFunctor( this, &AdminGameWindow::newPassword));
00316          new ActionItem( actionlistbox, 20, "edit email", PlayerActionFunctor( this, &AdminGameWindow::newEmail));
00317          new ActionItem( actionlistbox, 20, "export technology", PlayerActionFunctor( this, &AdminGameWindow::exportTechs));
00318          new ActionItem( actionlistbox, 20, "import technology", PlayerActionFunctor( this, &AdminGameWindow::importTechs));
00319 
00320          (new PG_Button( scrollwidget, PG_Rect( 3*gap+2*selectorWidth, ypos, 50, selectorHeight ), "Apply" ))->sigClick.connect( SigC::slot( *this, &AdminGameWindow::apply ));
00321          
00322          ypos += 270;
00323          
00324          new PG_Label( scrollwidget, PG_Rect( 20, ypos, 100, 20 ), "Turn:" );
00325          turn = new PG_LineEdit( scrollwidget, PG_Rect( 130, ypos, 50, 20));
00326          turn->SetEditable( true );
00327          turn->sigEditEnd.connect( SigC::slot( *this, &AdminGameWindow::turnEdited ));
00328          turn->sigEditReturn.connect( SigC::slot( *this, &AdminGameWindow::turnEdited ));
00329 
00330          if ( turnSkipper ) {
00331              PG_Button* b = new PG_Button ( scrollwidget, PG_Rect( 200, ypos, 100, 50 ), "skip player" );
00332              b->sigClick.connect( SigC::slot( *this, &AdminGameWindow::skipPlayer ));
00333          }
00334 
00335          ypos += 30;
00336          new PG_Label( scrollwidget, PG_Rect( 20, ypos, 100, 20 ), "Player:" );
00337          currentPlayer = new PG_LineEdit( scrollwidget, PG_Rect( 130, ypos, 50, 20));
00338          currentPlayer->SetEditable( false );
00339 
00340 
00341          
00342          if ( actmap->network ) {
00343             ypos += 30;         
00344             (new PG_Button( scrollwidget, PG_Rect( 20, ypos, 200, 20 ), "Setup data transfer" ))->sigClick.connect( SigC::slot( *this, &AdminGameWindow::netSetup )) ;
00345          }
00346          
00347          ypos += 30;
00348          playerSetup = new PlayerSetupWidget( gamemap, PlayerSetupWidget::AllEditable, scrollwidget, PG_Rect(gap, ypos, Width() - 3*gap, PlayerSetupWidget::guessHeight(gamemap) ) );
00349 
00350          ypos += PlayerSetupWidget::guessHeight(gamemap) + gap;
00351 
00352 
00353          (new PG_Button( scrollwidget, PG_Rect( gap, ypos, Width() - 3* gap, 30), "OK" ))->sigClick.connect( SigC::slot( *this, &AdminGameWindow::ok));
00354          ypos += 40;
00355 
00356          if ( actmap->getgameparameter(cgp_superVisorCanSaveMap)) {
00357             (new PG_Button( scrollwidget, PG_Rect( gap, ypos, Width() - 3* gap, 30), "Save as Map" ))->sigClick.connect( SigC::slot( *this, &AdminGameWindow::saveAsMap));
00358             ypos += 40;
00359          }
00360 
00361          updateTurn();
00362       }
00363 
00364 
00365       bool ok()
00366       {
00367          apply();
00368          if ( playerSetup->Apply() ) {
00369             successfullyClosed = true;
00370             QuitModal();
00371             return true;
00372          } else
00373             return false;
00374       }
00375 
00376 
00377       bool GetStatus()
00378       {
00379          return successfullyClosed;
00380       }
00381 };
00382 
00383 
00384 
00385 
00386 
00387 bool adminGame( GameMap* actmap, TurnSkipper* turnSkipper )
00388 {
00389    AdminGameWindow agw( actmap, NULL, turnSkipper );
00390    agw.Show();
00391    agw.RunModal();
00392    return agw.GetStatus();
00393 }

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