Advanced Strategic Command
admingame.cpp
Go to the documentation of this file.
1 /*
2  This file is part of Advanced Strategic Command; http://www.asc-hq.de
3  Copyright (C) 1994-2010 Martin Bickel and Marc Schellenberger
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; see the file COPYING. If not, write to the
17  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  Boston, MA 02111-1307 USA
19 */
20 
21 
22 #include <sstream>
23 #include <pgimage.h>
24 
25 #include "admingame.h"
26 #include "../paradialog.h"
27 #include "../gamemap.h"
28 #include "../spfst.h"
29 #include "../loaders.h"
30 #include "playersetup.h"
31 #include "fileselector.h"
32 #include "pwd_dlg.h"
33 
34 #include "../widgets/multilistbox.h"
35 
36 
37 
38 
40  private:
41  PG_ListBox* playerlistbox;
42  PG_ListBox* actionlistbox;
43  vector<PG_ListBoxItem*> players;
44  GameMap* gamemap;
45  PG_LineEdit* turn;
46  PG_LineEdit* currentPlayer;
47  PG_LineEdit* filename;
48 
49  typedef Loki::Functor<void, LOKI_TYPELIST_1(int) > PlayerActionFunctor;
51 
52  PG_ScrollWidget* scrollwidget;
53 
54  PlayerSetupWidget* playerSetup;
55  TurnSkipper* turnSkipper;
56 
57  bool successfullyClosed;
58 
59  void updateTurn()
60  {
61  if ( turn )
62  turn->SetText( ASCString::toString( gamemap->time.turn() ));
63 
64  if ( currentPlayer ) {
65  if ( gamemap->actplayer >= 0 )
66  currentPlayer->SetText( gamemap->player[gamemap->actplayer].getName() );
67  else
68  currentPlayer->SetText( ASCString::toString( gamemap->actplayer ) );
69  }
70  }
71 
72  bool skipPlayer()
73  {
74  if ( turnSkipper ) {
75  (*turnSkipper)(gamemap);
76  }
77 
78  updateTurn();
79  return true;
80  }
81 
82  bool apply()
83  {
84  for ( int i = 0; i < playerlistbox->GetWidgetCount(); ++i ) {
85  PG_ListBoxBaseItem* bi = dynamic_cast<PG_ListBoxBaseItem*>(playerlistbox->FindWidget(i));
86  if ( bi && bi->IsSelected() )
87  applyForPlayer( i );
88  }
89  repaintMap();
90  mapChanged( gamemap );
91  return true;
92  }
93 
94  void applyForPlayer( int player )
95  {
96  for ( int i = 0; i < actionlistbox->GetWidgetCount(); ++i ) {
97  ActionItem* bi = dynamic_cast<ActionItem*>(actionlistbox->FindWidget(i));
98  if ( bi && bi->IsSelected() )
99  bi->getData()(player);
100  }
101  }
102 
103  void resetView( int player )
104  {
105  gamemap->getPlayer(player).resetView();
106  }
107  void resetResearch( int player )
108  {
109  gamemap->getPlayer(player).resetResearch();
110  }
111 
112  void resetTribute( int player )
113  {
114  gamemap->getPlayer(player).resetTribute();
115  }
116 
117  void resetPassword( int player )
118  {
119  gamemap->getPlayer(player).resetPassword();
120  }
121 
122  void newPassword( int player )
123  {
124  enterpassword( gamemap->player[player].passwordcrc, true, true, false);
125  }
126 
127  void newEmail( int player )
128  {
129  gamemap->player[player].email = editString2( "Mail Address for " + gamemap->player[player].getName(), gamemap->player[player].email);
130  }
131 
132 
133  void resetDiplomacy( int player )
134  {
135  for ( int j = 0; j< gamemap->getPlayerCount(); ++j ) {
136  if ( j != player ) {
137  gamemap->getPlayer(player).diplomacy.setState( j, WAR );
138  gamemap->getPlayer(j).diplomacy.setState( player, WAR );
139  }
140  }
141  }
142 
143  void deleteUnits( int player )
144  {
145  while ( gamemap->player[player].vehicleList.begin() != gamemap->player[player].vehicleList.end() )
146  delete *gamemap->player[player].vehicleList.begin();
147 
148  }
149 
150  void deleteMines( int player )
151  {
152  for ( int y = 0; y < gamemap->ysize; ++y )
153  for ( int x = 0; x < gamemap->xsize; ++x ) {
154  MapField* fld = gamemap->getField(x,y);
155  for ( MapField::MineContainer::iterator i = fld->mines.begin(); i != fld->mines.end(); )
156  if ( i->player == player )
157  i = fld->mines.erase( i );
158  else
159  ++i;
160  }
161 
162  }
163 
164  void deleteBuildings( int player )
165  {
166  while ( gamemap->player[player].buildingList.begin() != gamemap->player[player].buildingList.end() )
167  delete *gamemap->player[player].buildingList.begin();
168 
169  }
170 
171  void neutralBuildings( int player )
172  {
173  while ( gamemap->player[player].buildingList.begin() != gamemap->player[player].buildingList.end() )
174  gamemap->player[player].buildingList.front()->convert(8);
175 
176  }
177 
178 
179  void deleteProduction( int player )
180  {
181  for ( Player::BuildingList::iterator i = gamemap->player[player].buildingList.begin(); i != gamemap->player[player].buildingList.end(); ++i )
182  (*i)->deleteAllProductionLines();
183 
184  }
185 
186  void deleteResources( int player )
187  {
188  for ( Player::BuildingList::iterator i = gamemap->player[player].buildingList.begin(); i != gamemap->player[player].buildingList.end(); ++i ) {
189  for ( int j = 0; j < waffenanzahl; ++j )
190  (*i)->ammo[j] = 0;
191 
192  (*i)->actstorage = Resources();
193  }
194  gamemap->bi_resource[player] = Resources();
195 
196  resetTribute( player );
197  }
198 
199  static const int techID = 0xE1C8;
200 
201  void exportTechs( int player )
202  {
203  ASCString filename = selectFile( "*.asctechs", false );
204  if ( filename.empty() )
205  return;
206 
207  tnfilestream stream( filename, tnstream::writing );
208  stream.writeInt( techID );
209  stream.writeInt( 1 );
210  writeClassContainer( gamemap->player[player].research.developedTechnologies, stream );
211  }
212 
213  void importTechs( int player )
214  {
215  ASCString filename = selectFile( "*.asctechs", true );
216  if ( filename.empty() )
217  return;
218 
219  tnfilestream stream( filename, tnstream::reading );
220  if ( stream.readInt() != techID ) {
221  errorMessage("invalid file contents");
222  return;
223  }
224 
225  if ( stream.readInt() != 1 ) {
226  errorMessage("invalid file version");
227  return;
228  }
229  vector<int> dt;
230  readClassContainer( dt, stream );
231  vector<int>& techs = gamemap->player[player].research.developedTechnologies;
232  copy( dt.begin(), dt.end(), back_inserter( techs ));
233  sort( techs.begin(), techs.end() );
234  techs.erase( unique( techs.begin(), techs.end()), techs.end() );
235  }
236 
237 
238  bool saveAsMap()
239  {
240  apply();
241  if ( playerSetup->Apply() ) {
242  GameTransferMechanism* gtm = gamemap->network;
243  gamemap->network = NULL;
244 
245  if ( gamemap->_resourcemode == 1)
246  warningMessage("This map uses BI resource mode. Saving as map will delete all global resources of all players");
247 
248  ASCString name = selectFile( mapextension, false);
249  if ( !name.empty() ) {
250  StatusMessageWindowHolder smw = MessagingHub::Instance().infoMessageWindow( "saving " + name );
251  savemap( name, gamemap );
252  }
253 
254  gamemap->network = gtm;
255  QuitModal();
256  return true;
257  } else
258  return false;
259  return true;
260  }
261 
262  bool turnEdited()
263  {
264  gamemap->time.set( atoi( turn->GetText() ), 0 );
265  updateTurn();
266  return true;
267  }
268 
269  bool netSetup()
270  {
271  if ( gamemap && gamemap->network )
272  gamemap->network->setup();
273  return true;
274  }
275 
276 
277  public:
278  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)
279  {
280  this->turnSkipper = turnSkipper;
281 
282  scrollwidget = new PG_ScrollWidget( this, PG_Rect( 1, GetTitlebarHeight(), Width() - 2, Height() - GetTitlebarHeight() - 2 ));
283  scrollwidget->SetTransparency(255);
284 
285  const int selectorHeight = 250;
286  const int selectorWidth = 200;
287  const int gap = 20;
288  int ypos = gap;
289  playerlistbox = (new MultiListBox( scrollwidget, PG_Rect( gap, ypos, selectorWidth, selectorHeight )))->getListBox();
290 
291  int lastPlayer = 0;
292  for ( int i = 0; i < actmap->getPlayerCount(); ++i )
293  if ( actmap->player[i].exist() )
294  lastPlayer = i;
295 
296  for ( int i = 0; i <= lastPlayer; ++i ) {
297  if ( actmap->player[i].exist() )
298  players.push_back( new PG_ListBoxItem( playerlistbox, 20, actmap->player[i].getName() ));
299  else
300  players.push_back ( new PG_ListBoxItem( playerlistbox, 20, "-" ) );
301  }
302 
303  actionlistbox = (new MultiListBox( scrollwidget, PG_Rect( 2*gap + selectorWidth, gap, selectorWidth, selectorHeight )))->getListBox();
304  new ActionItem( actionlistbox, 20, "reset view", PlayerActionFunctor( this, &AdminGameWindow::resetView) );
305  new ActionItem( actionlistbox, 20, "reset research", PlayerActionFunctor( this, &AdminGameWindow::resetResearch));
306  new ActionItem( actionlistbox, 20, "reset tribute", PlayerActionFunctor( this, &AdminGameWindow::resetTribute));
307  new ActionItem( actionlistbox, 20, "reset diplomacy (->war)", PlayerActionFunctor( this, &AdminGameWindow::resetDiplomacy));
308  new ActionItem( actionlistbox, 20, "reset password", PlayerActionFunctor( this, &AdminGameWindow::resetPassword));
309  new ActionItem( actionlistbox, 20, "delete units", PlayerActionFunctor( this, &AdminGameWindow::deleteUnits));
310  new ActionItem( actionlistbox, 20, "delete buildings", PlayerActionFunctor( this, &AdminGameWindow::deleteBuildings));
311  new ActionItem( actionlistbox, 20, "delete production", PlayerActionFunctor( this, &AdminGameWindow::deleteProduction));
312  new ActionItem( actionlistbox, 20, "delete resources + ammo", PlayerActionFunctor( this, &AdminGameWindow::deleteResources));
313  new ActionItem( actionlistbox, 20, "delete mines", PlayerActionFunctor( this, &AdminGameWindow::deleteMines));
314  new ActionItem( actionlistbox, 20, "make buildings neutral", PlayerActionFunctor( this, &AdminGameWindow::neutralBuildings));
315  new ActionItem( actionlistbox, 20, "enter new password", PlayerActionFunctor( this, &AdminGameWindow::newPassword));
316  new ActionItem( actionlistbox, 20, "edit email", PlayerActionFunctor( this, &AdminGameWindow::newEmail));
317  new ActionItem( actionlistbox, 20, "export technology", PlayerActionFunctor( this, &AdminGameWindow::exportTechs));
318  new ActionItem( actionlistbox, 20, "import technology", PlayerActionFunctor( this, &AdminGameWindow::importTechs));
319 
320  (new PG_Button( scrollwidget, PG_Rect( 3*gap+2*selectorWidth, ypos, 50, selectorHeight ), "Apply" ))->sigClick.connect( sigc::hide( sigc::mem_fun( *this, &AdminGameWindow::apply )));
321 
322  ypos += 270;
323 
324  new PG_Label( scrollwidget, PG_Rect( 20, ypos, 100, 20 ), "Turn:" );
325  turn = new PG_LineEdit( scrollwidget, PG_Rect( 130, ypos, 50, 20));
326  turn->SetEditable( true );
327  turn->sigEditEnd.connect( sigc::mem_fun( *this, &AdminGameWindow::turnEdited ));
328  turn->sigEditReturn.connect( sigc::mem_fun( *this, &AdminGameWindow::turnEdited ));
329 
330  if ( turnSkipper ) {
331  PG_Button* b = new PG_Button ( scrollwidget, PG_Rect( 200, ypos, 100, 50 ), "skip player" );
332  b->sigClick.connect( sigc::hide( sigc::mem_fun( *this, &AdminGameWindow::skipPlayer )));
333  }
334 
335  ypos += 30;
336  new PG_Label( scrollwidget, PG_Rect( 20, ypos, 100, 20 ), "Player:" );
337  currentPlayer = new PG_LineEdit( scrollwidget, PG_Rect( 130, ypos, 50, 20));
338  currentPlayer->SetEditable( false );
339 
340 
341 
342  if ( actmap->network ) {
343  ypos += 30;
344  (new PG_Button( scrollwidget, PG_Rect( 20, ypos, 200, 20 ), "Setup data transfer" ))->sigClick.connect( sigc::hide( sigc::mem_fun( *this, &AdminGameWindow::netSetup ))) ;
345  }
346 
347  ypos += 30;
348  playerSetup = new PlayerSetupWidget( gamemap, PlayerSetupWidget::AllEditable, scrollwidget, PG_Rect(gap, ypos, Width() - 3*gap, PlayerSetupWidget::guessHeight(gamemap) ) );
349 
350  ypos += PlayerSetupWidget::guessHeight(gamemap) + gap;
351 
352 
353  (new PG_Button( scrollwidget, PG_Rect( gap, ypos, Width() - 3* gap, 30), "OK" ))->sigClick.connect( sigc::hide( sigc::mem_fun( *this, &AdminGameWindow::ok)));
354  ypos += 40;
355 
357  (new PG_Button( scrollwidget, PG_Rect( gap, ypos, Width() - 3* gap, 30), "Save as Map" ))->sigClick.connect( sigc::hide( sigc::mem_fun( *this, &AdminGameWindow::saveAsMap)));
358  ypos += 40;
359  }
360 
361  updateTurn();
362  }
363 
364 
365  bool ok()
366  {
367  apply();
368  if ( playerSetup->Apply() ) {
369  successfullyClosed = true;
370  QuitModal();
371  return true;
372  } else
373  return false;
374  }
375 
376 
377  bool GetStatus()
378  {
379  return successfullyClosed;
380  }
381 };
382 
383 
384 
385 
386 
387 bool adminGame( GameMap* actmap, TurnSkipper* turnSkipper )
388 {
389  AdminGameWindow agw( actmap, NULL, turnSkipper);
390  agw.Show();
391  agw.RunModal();
392  return agw.GetStatus();
393 }
sigc::signal< void, GameMap * > mapChanged
Definition: spfst.cpp:52
Player & getPlayer(PlayerID p)
Definition: gamemap.h:257
int xsize
the size of the map
Definition: gamemap.h:201
virtual void writeInt(int i)
Writes a 32 bit signed Integer. In the stream little-endian byte order is used and a translation is p...
Definition: basestrm.cpp:363
Loki::Functor< void, LOKI_TYPELIST_1(GameMap *) > TurnSkipper
Definition: admingame.h:27
const int waffenanzahl
The number of different weapon types.
Definition: typen.h:58
Definition: player.h:53
virtual int readInt(void)
Reads a 32 bit signed Integer. In the stream little-endian byte order is used and a translation is pe...
Definition: basestrm.cpp:284
AdminGameWindow(GameMap *actmap, PG_Widget *parent, TurnSkipper *turnSkipper)
Definition: admingame.cpp:278
ASCString getName() const
returns the name of the player
Definition: player.cpp:274
DiplomaticStateVector diplomacy
Definition: player.h:209
int turn() const
Definition: typen.h:181
vector< int > developedTechnologies
Definition: research.h:183
void savemap(const ASCString &name, GameMap *gamemap)
saves the map located in actmap to the map file name
Definition: loaders.cpp:1428
void resetResearch()
Definition: player.cpp:499
void warningMessage(const ASCString &str)
sigc::signal< void > repaintMap
}@
Definition: spfst.cpp:45
a single field of the map
Definition: mapfield.h:26
bool enterpassword(Password &pwd, bool firstTime, bool cancelAllowed, bool defaultAllowed, const ASCString &username)
Definition: pwd_dlg.cpp:158
A class that hols a MessageWindow. This class ensures that the window is removed if the last copy of ...
Definition: messaginghub.h:34
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
void resetPassword()
Definition: player.cpp:516
static ASCString toString(int i)
converts the parameter to a String
Definition: ascstring.cpp:193
void setState(PlayerID towardsPlayer, DiplomaticStates s)
Definition: player.cpp:115
void resetView()
Definition: player.cpp:488
VehicleList vehicleList
a list of all units
Definition: player.h:135
Resources bi_resource[8]
in BI resource mode ( see _resourcemode , isResourceGlobal ) , this is where the globally available r...
Definition: gamemap.h:416
const char * mapextension
Definition: loaders.cpp:79
Adapter class for using Paragui Dialogs in ASC. This class transfers the event control from ASC to Pa...
Definition: paradialog.h:127
bool adminGame(GameMap *actmap, TurnSkipper *turnSkipper)
Definition: admingame.cpp:387
int _resourcemode
how are Resources handled on this map 0= "ASC mode": complex system with mineral resources etc 1= "BI...
Definition: gamemap.h:250
ASCString email
Definition: player.h:211
signed char actplayer
the player who is currently making his moves (may be human or AI)
Definition: gamemap.h:232
void readClassContainer(C &c, tnstream &stream)
Definition: basestrm.h:752
Player player[9]
Definition: gamemap.h:253
void errorMessage(const ASCString &string)
int ysize
Definition: gamemap.h:201
void resetTribute()
Definition: player.cpp:504
MineContainer mines
Definition: mapfield.h:117
ASCString selectFile(const ASCString &ext, bool load, bool overwriteMessage)
int getgameparameter(GameParameter num) const
Definition: gamemap.cpp:1047
BuildingList buildingList
a list of all units
Definition: player.h:139
int atoi(const std::string &s)
Definition: misc.cpp:152
Research research
the status of the scientific research
Definition: player.h:142
static int guessHeight(GameMap *gamemap)
Definition: playersetup.cpp:31
GameMap * actmap
Definition: spfst.cpp:64
GameTransferMechanism * network
Definition: gamemap.h:576
void writeClassContainer(const C &c, tnstream &stream)
Definition: basestrm.h:742
const T & min(const T &a, const T &b, const T &c)
Definition: misc.h:80
Password passwordcrc
the Password required for playing this player
Definition: player.h:160
Resources are basically the currency of ASC.
Definition: typen.h:97
int getPlayerCount() const
Definition: gamemap.h:255
ASCString editString2(const ASCString &title, const ASCString &defaultValue)
uses the new dialog engine
Definition: paradialog.cpp:798
bool exist() const
does the player exist at all
Definition: player.cpp:313
virtual void setup()=0
GameTime time
the time in the game, mesured in a turns and moves
Definition: gamemap.h:235
The map. THE central structure of ASC, which holds everything not globally available together...
Definition: gamemap.h:182
void set(int turn, int move)
Definition: typen.h:183
MapField * getField(int x, int y)
Definition: gamemap.h:465