Advanced Strategic Command
player.cpp
Go to the documentation of this file.
1 
2 /***************************************************************************
3  gamemap.cpp - description
4  -------------------
5  begin : Tue Oct 24 2000
6  copyright : (C) 2000 by Martin Bickel
7  email : bickel@asc-hq.org
8  ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 
19 #include <algorithm>
20 #include <ctime>
21 #include <cmath>
22 
23 #include "global.h"
24 #include "misc.h"
25 #include "typen.h"
26 #include "vehicletype.h"
27 #include "buildingtype.h"
28 #include "player.h"
29 #include "gamemap.h"
30 #include "cannedmessages.h"
31 
32 
33 PlayerID::PlayerID( const Player& p ) : num( p.getPosition() ) {};
34 
35 
37 {
38  "War",
39  "Truce",
40  "Peace",
41  "Association",
42  "Alliance",
43  NULL
44 };
45 
46 
47 
49 {
50 }
51 
52 
54 {
55  for ( QueuedStateChanges::iterator i = queuedStateChanges.begin(); i != queuedStateChanges.end(); ++i ) {
56  if ( getState(i->first) > i->second ) {
57  // we are changing to a more aggressive state, which doesn't need the confirmation of the counterpart
58  setState( i->first, i->second );
59  player.getParentMap()->player[ i->first ].diplomacy.setState( player.getPosition(), i->second);
60  } else {
61  // we are browsing through the queued changes of the target player to look if he accepted our proposal
62 
63  DiplomaticStateVector& target = player.getParentMap()->player[ i->first ].diplomacy;
64  QueuedStateChanges::iterator t = target.queuedStateChanges.find( player.getPosition() );
65  if ( t != target.queuedStateChanges.end() ) {
66  // this should have been handled when the other player set his proposal
67  } else {
68  // he did not answer
69  // we are still doing nothing and deleting the request with the .clear below
70  }
71  }
72  }
73  queuedStateChanges.clear();
74 
75  // changes to war will be effective as soon as a new player is active,
76  // so that the other player will get reaction fire if he approaches the war-declaring player
77  for ( int p = 0; p < player.getParentMap()->getPlayerCount(); ++p ) {
78  Player& pl = player.getParentMap()->getPlayer(p);
79  if ( pl.exist() && p != player.getPosition() ) {
80  DiplomaticStates state;
81  if ( getProposal(p, &state ) )
82  if ( state < getState(p)) {
83  setState( p, state );
84  pl.diplomacy.setState( player.getPosition(), state );
85  }
86  }
87  }
88 }
89 
90 
91 
93 {
94  if ( towardsPlayer.getID() < 0 )
95  return WAR;
96 
97  if ( player.getPosition() == towardsPlayer.getID() )
98  return ALLIANCE;
99 
100  if ( towardsPlayer.getID() < states.size() )
101  return states[towardsPlayer.getID()];
102  else
103  return WAR;
104 }
105 
106 void DiplomaticStateVector::resize( int size )
107 {
108  int oldsize = states.size();
109  states.resize(size);
110  for ( int i = oldsize; i < size; ++i )
111  states[i] = WAR;
112 }
113 
114 
116 {
117  assert( towardsPlayer.getID() >= 0 );
118 
119  if ( towardsPlayer.getID() >= states.size() )
120  resize(towardsPlayer.getID()+1);
121 
122  states[towardsPlayer.getID()] = s;
123 }
124 
125 
126 
128 {
129  assert( fromPlayer >= 0 );
130 
131  DiplomaticStateVector& targ = player.getParentMap()->player[ fromPlayer ].diplomacy;
132 
133  QueuedStateChanges::iterator i = targ.queuedStateChanges.find( player.getPosition() );
134 
135  if ( i != targ.queuedStateChanges.end() ) {
136  if ( state )
137  *state = i->second;
138  return true;
139  } else
140  return false;
141 }
142 
143 
144 
146 {
147  stream.readInt();
148  int size = stream.readInt();
149  states.resize( size );
150  for ( int i = 0; i < size; ++i )
151  states[i] = DiplomaticStates( stream.readInt() );
152 
153  queuedStateChanges.clear();
154 
155  size = stream.readInt();
156  for ( int i = 0; i< size; ++i ) {
157  int p = stream.readInt();
158  DiplomaticStates s = DiplomaticStates( stream.readInt() );
159  queuedStateChanges[p] = s;
160  }
161 }
162 
164 {
165  stream.writeInt( 1 );
166  stream.writeInt( states.size() );
167  for ( int i = 0; i< states.size(); ++i )
168  stream.writeInt( int( states[i]));
169 
170  stream.writeInt( queuedStateChanges.size() );
171  for ( QueuedStateChanges::const_iterator i = queuedStateChanges.begin(); i != queuedStateChanges.end(); ++i ) {
172  stream.writeInt( i->first );
173  stream.writeInt( int(i->second) );
174  }
175 }
176 
177 
178 
179 
180 
181 
182 
183 
184 const char* Player :: playerStatusNames[6] = { "Human Player",
185  "AI player",
186  "off",
187  "Supervisor",
188  "suspended",
189  NULL };
190 
191 
193  : diplomacy( *this )
194 {
195  ai = NULL;
196  parentMap = NULL;
197  queuedEvents = 0;
198  ASCversion = 0;
199  color = 0;
200  serverPlayerID = 0;
201 }
202 
203 void Player :: setParentMap( GameMap* map, int pos )
204 {
205  parentMap = map;
206  player = pos;
207  parentMap->sigPlayerTurnBegins.connect( sigc::mem_fun( *this, &Player::turnBegins ));
208  parentMap->sigPlayerUserInteractionBegins.connect( sigc::mem_fun( *this, &Player::userInteractionBegins ));
209  parentMap->sigPlayerTurnEnds.connect( sigc::mem_fun( *this, &Player::turnEnds ));
210 }
211 
212 
213 void Player :: turnBegins( Player& p )
214 {
215  if ( &p == this ) {
217  }
218 
219  if ( stat == supervisor ) {
220  parentMap->supervisorpasswordcrc = passwordcrc;
221  }
222 }
223 
224 void Player :: userInteractionBegins( Player& p )
225 {
226  if ( &p == this ) {
227  }
228 }
229 
230 void Player :: turnEnds( Player& p )
231 {
232  if ( &p == this ) {
233  sendQueuedMessages();
234 
235  if ( !exist() && stat != off ) {
236  stat = off;
237  resetView();
238  resetResearch();
239  resetTribute();
240  resetPassword();
241  email = "";
242  name += " (removed)";
243  }
244  }
245 }
246 
247 
248 
250 {
251  if ( color == DI_Color(0)) {
252  switch ( player ) {
253  case 0: return DI_Color( 0xe0, 0, 0 );
254  case 1: return DI_Color( 0, 0x71, 0xdb );
255  case 2: return DI_Color( 0xbc, 0xb3, 0 );
256  case 3: return DI_Color( 0, 0xaa, 0 );
257  case 4: return DI_Color( 0xbc, 0, 0 );
258  case 5: return DI_Color( 0xb2, 0, 0xb2 );
259  case 6: return DI_Color( 0,0, 0xaa );
260  case 7: return DI_Color( 0xbc, 0x67, 0 );
261  case 8: return DI_Color( 0xaa, 0xaa, 0xaa );
262  };
263  return DI_Color(0, 0, 0);
264  } else
265  return color;
266 }
267 
269 {
270  return PlayerColor(getPosition(), getColor() );
271 }
272 
273 
275 {
276  if ( name.length() )
277  return name;
278 
279  if ( stat == off )
280  return "off";
281 
282  return ASCString("Player ") + ASCString::toString(getPosition() );
283 }
284 
285 int Player::getHumanPlayerNum( const GameMap* gamemap )
286 {
287  int h = 0;
288  for ( int p = 0; p < gamemap->getPlayerCount(); ++p )
289  if ( gamemap->getPlayer(p).exist() && gamemap->getPlayer(p).isHuman() )
290  ++h;
291  return h;
292 }
293 
294 
295 
296 void Player :: sendQueuedMessages()
297 {
298  MessagePntrContainer::iterator mi = getParentMap()->unsentmessage.begin();
299  while ( mi != getParentMap()->unsentmessage.end() ) {
300  sentmessage.push_back ( *mi );
301  for ( int i = 0; i < 8; i++ ) {
302  if ( (*mi)->to & ( 1 << i ))
303  getParentMap()->player[ i ].unreadmessage.push_back ( *mi );
304  if ( (*mi)->cc & ( 1 << i ))
305  getParentMap()->player[ i ].unreadmessage.push_back ( *mi );
306  }
307 
308  mi = getParentMap()->unsentmessage.erase ( mi );
309  }
310 }
311 
312 
313 bool Player::exist() const
314 {
315  return !(buildingList.empty() && vehicleList.empty());
316 }
317 
318 
319 const int playerVersion = 3;
320 
321 void Player::read ( tnstream& stream )
322 {
323  int version = stream.readInt();
324  if ( version > playerVersion )
325  throw tinvalidversion ( "Player", playerVersion, version );
326 
327  if ( version >= 3 )
328  serverPlayerID = stream.readInt();
329 }
330 
331 void Player::write ( tnstream& stream ) const
332 {
333  stream.writeInt( playerVersion );
334  stream.writeInt( serverPlayerID );
335 }
336 
337 
338 
339 
340 
341 
342 
343 template <typename T> void swapData( T& t1, T& t2 )
344 {
345  T temp = t1;
346  t1 = t2;
347  t2 = temp;
348 }
349 
350 void Player::swap ( Player& secondPlayer )
351 {
352  if ( &secondPlayer == this)
353  return;
354 
355  typedef VehicleList VL;
356  typedef VehicleList::iterator VLI;
357 
358  VL vl;
359  for ( VLI i = vehicleList.begin(); i != vehicleList.end(); ) {
360  (*i)->color = secondPlayer.player*8;
361  vl.push_back ( *i );
362  i = vehicleList.erase( i );
363  }
364 
365  for ( VLI i = secondPlayer.vehicleList.begin(); i != secondPlayer.vehicleList.end(); ) {
366  (*i)->color = player*8;
367  vehicleList.push_back ( *i );
368  i = secondPlayer.vehicleList.erase( i );
369  }
370 
371  for ( VLI i = vl.begin(); i != vl.end(); ) {
372  secondPlayer.vehicleList.push_back ( *i );
373  i = vl.erase( i );
374  }
375 
376 
377  typedef Player::BuildingList BL;
378  typedef Player::BuildingList::iterator BLI;
379 
380  BL bl;
381  for ( BLI i = buildingList.begin(); i != buildingList.end(); ++i)
382  bl.push_back ( *i );
383 
384  BL bl2 = secondPlayer.buildingList;
385  for ( BLI i = bl2.begin(); i != bl2.end(); ++i)
386  (*i)->convert( player, false );
387 
388  for ( BLI i = bl.begin(); i != bl.end(); ++i)
389  (*i)->convert( secondPlayer.player, false );
390 
391  for (int i =0; i < parentMap->xsize * parentMap->ysize ;i++ ) {
392  MapField* fld = &parentMap->field[i];
393 
394  VisibilityStates temp = fld->getVisibility( player );
395  fld->setVisibility( fld->getVisibility( secondPlayer.player), player);
396  fld->setVisibility( temp, secondPlayer.player);
397 
398 
399  for ( MapField::MineContainer::iterator i = fld->mines.begin(); i != fld->mines.end(); i++ )
400  if ( i->player == player )
401  i->player = secondPlayer.player;
402  else
403  if ( i->player == secondPlayer.player )
404  i->player = player;
405  if ( fld->resourceview ) {
406  bool b = fld->resourceview->visible & (1 << player);
407  int m = fld->resourceview->materialvisible[player];
408  int f = fld->resourceview->fuelvisible[player];
409 
410  if ( fld->resourceview->visible & (1 << secondPlayer.player ) )
411  fld->resourceview->setview( player, fld->resourceview->materialvisible[secondPlayer.player], fld->resourceview->fuelvisible[secondPlayer.player] );
412  else
413  fld->resourceview->resetview( player );
414 
415  if ( b )
416  fld->resourceview->setview( secondPlayer.player, m, f );
417  else
418  fld->resourceview->resetview( secondPlayer.player );
419  }
420  } /* endfor */
421 
422  swapData( research, secondPlayer.research );
424 
425  delete ai;
426  ai = NULL;
427 
428  delete secondPlayer.ai;
429  secondPlayer.ai = NULL;
430 
431  swapData( stat, secondPlayer.stat );
432  swapData( passwordcrc, secondPlayer.passwordcrc );
433  swapData( dissections, secondPlayer.dissections );
434  swapData( unreadmessage, secondPlayer.unreadmessage );
435  swapData( oldmessage, secondPlayer.oldmessage );
436  swapData( sentmessage, secondPlayer.sentmessage );
437  swapData( queuedEvents, secondPlayer.queuedEvents );
438  swapData( ASCversion, secondPlayer.ASCversion );
439  swapData( playTime, secondPlayer.playTime );
440  swapData( cursorPos, secondPlayer.cursorPos );
441  swapData( email, secondPlayer.email );
442  swapData( name, secondPlayer.name );
443  swapData( color, secondPlayer.color );
444 
445  diplomacy.swap( secondPlayer.player );
446 
447 
448  int a = player;
449  int b = secondPlayer.player;
450  for ( int i= 0; i < parentMap->getPlayerCount(); ++i )
451  if ( i != a ) {
452  swapData( parentMap->tribute.paid[i][a], parentMap->tribute.paid[i][b] );
453  swapData( parentMap->tribute.paid[a][i], parentMap->tribute.paid[b][i] );
454  swapData( parentMap->tribute.avail[i][a], parentMap->tribute.avail[i][b] );
455  swapData( parentMap->tribute.avail[a][i], parentMap->tribute.avail[b][i] );
456  swapData( parentMap->tribute.payStatusLastTurn[i][a], parentMap->tribute.payStatusLastTurn[i][b] );
457  swapData( parentMap->tribute.payStatusLastTurn[a][i], parentMap->tribute.payStatusLastTurn[b][i] );
458  }
459 
460 }
461 
462 void DiplomaticStateVector::swap( int secondPlayer )
463 {
464  DiplomaticStateVector& secondDSV = player.getParentMap()->getPlayer(secondPlayer).diplomacy;
465 
466  swapData( states, secondDSV.states );
467  swapData( queuedStateChanges, secondDSV.queuedStateChanges );
468 
469 
470 
471  for ( int i= 0; i < player.getParentMap()->getPlayerCount(); ++i ) {
472  DiplomaticStates sec = player.getParentMap()->getPlayer(i).diplomacy.getState(secondPlayer);
474 
475  player.getParentMap()->getPlayer(i).diplomacy.setState(secondPlayer, fir );
476  player.getParentMap()->getPlayer(i).diplomacy.setState(player.getPosition(), sec );
477  }
478 
479 }
480 
481 
482 void Player::merge ( Player& secondPlayer )
483 {
484 
485 }
486 
487 
489 {
490  for ( int x = 0; x < getParentMap()->xsize; x++ )
491  for ( int y = 0; y < getParentMap()->ysize; y++ ) {
492  MapField* fld = getParentMap()->getField(x,y);
493  fld->setVisibility( visible_not, player );
494  if ( fld->resourceview )
495  fld->resourceview->visible &= ~(1<<player);
496  }
497 
498 }
500 {
501  research.clear();
502 }
503 
505 {
506  for ( int j = 0; j< getParentMap()->getPlayerCount(); ++j ) {
507  getParentMap()->tribute.avail[player][j] = Resources();
508  getParentMap()->tribute.avail[j][player]= Resources();
509  getParentMap()->tribute.paid[player][j] = Resources();
510  getParentMap()->tribute.paid[j][player]= Resources();
513  }
514 }
515 
517 {
518  passwordcrc.reset();
519 }
520 
521 bool Player::operator==( const Player& otherPlayer) const
522 {
523  return parentMap == otherPlayer.parentMap && player == otherPlayer.player;
524 }
DiplomaticStates getState(PlayerID towardsPlayer) const
Definition: player.cpp:92
MessagePntrContainer sentmessage
the list of messages that have been sent yet
Definition: player.h:189
Uint8 materialvisible[8]
Definition: mapfield.h:110
int queuedEvents
if ASC should check all events for fullfilled triggers, this variable will be set to true...
Definition: player.h:193
void setVisibility(VisibilityStates valtoset, int actplayer)
The visibility status for all players is stored in a bitmapped variable.
Definition: mapfield.cpp:404
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
miscellaneous functions which are used by ASC and all its tools
DiplomaticStates
Definition: player.h:53
const int playerVersion
Definition: player.cpp:319
A Device Independent color. Shamelessly pinched from Paragui to reduce coupling.
Definition: surface.h:30
const char * diplomaticStateNames[diplomaticStateNum+1]
Definition: player.cpp:36
void clear()
Definition: research.cpp:747
Definition: player.h:53
void setParentMap(GameMap *map, int pos)
Definition: player.cpp:203
static const char * playerStatusNames[]
Definition: player.h:156
void read(tnstream &stream)
Definition: player.cpp:321
BaseAI * ai
if the player is run by an AI, this is the pointer to it
Definition: player.h:144
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
int getPosition() const
Definition: player.h:112
const GameMap * getParentMap() const
Definition: player.h:114
ASCString getName() const
returns the name of the player
Definition: player.cpp:274
DiplomaticStateVector diplomacy
Definition: player.h:209
Player()
Definition: player.cpp:192
void read(tnstream &stream)
Definition: player.cpp:145
VisibilityStates
the different states that a player's view on a field can have
Definition: typen.h:403
PlayerColor getPlayerColor() const
Definition: player.cpp:268
bool isHuman() const
Definition: player.h:152
void resetResearch()
Definition: player.cpp:499
MessagePntrContainer oldmessage
the list of messages that already have been read by the player yet
Definition: player.h:185
void swap(int secondPlayer)
Definition: player.cpp:462
Resources avail[8][8]
Definition: gamemap.h:339
Global platform dependant definitions. This file just branches to the platform specific files in thei...
The interface for all kinds of IO stream.
a single field of the map
Definition: mapfield.h:26
Resources paid[8][8]
Definition: gamemap.h:340
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
bool operator==(const Player &otherPlayer) const
Definition: player.cpp:521
void resetPassword()
Definition: player.cpp:516
const int diplomaticStateNum
Definition: player.h:52
void setview(int player, int material, int fuel)
Definition: mapfield.cpp:116
void resetview(int player)
Definition: mapfield.cpp:123
static ASCString toString(int i)
converts the parameter to a String
Definition: ascstring.cpp:193
sigc::signal< void, Player & > sigPlayerTurnEnds
Definition: gamemap.h:496
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
enum Player::PlayerStatus stat
class GameMap::ResourceTribute tribute
Definition of THE central asc class: GameMap.
MapCoordinate cursorPos
Definition: player.h:207
The interface for the buildingtype class.
sigc::signal< void, Player & > sigPlayerTurnBegins
Definition: gamemap.h:493
void write(tnstream &stream) const
Definition: player.cpp:163
list< Vehicle * > VehicleList
Definition: player.h:133
ASCString email
Definition: player.h:211
DI_Color getColor() const
Definition: player.cpp:249
void merge(Player &secondPlayer)
merges all units, buildings etc from secondplayer to this one
Definition: player.cpp:482
Player player[9]
Definition: gamemap.h:253
static int getHumanPlayerNum(const GameMap *gamemap)
Definition: player.cpp:285
void swap(Player &secondPlayer)
swaps all information, units, buildings etc with the given player
Definition: player.cpp:350
int ysize
Definition: gamemap.h:201
void resetTribute()
Definition: player.cpp:504
MineContainer mines
Definition: mapfield.h:117
void write(tnstream &stream) const
Definition: player.cpp:331
BuildingList buildingList
a list of all units
Definition: player.h:139
Research research
the status of the scientific research
Definition: player.h:142
MapField * field
the array of fields
Definition: gamemap.h:204
PlayerID(int num)
Definition: player.h:43
void reset()
Definition: password.cpp:120
void swapData(T &t1, T &t2)
Definition: player.cpp:343
bool existanceAtBeginOfTurn
did the player exist when the turn started? Required for checking if a player has been terminated ...
Definition: player.h:131
Password supervisorpasswordcrc
Definition: gamemap.h:368
list< Building * > BuildingList
Definition: player.h:137
MessagePntrContainer unsentmessage
the list of messages that were written this turn and are waiting to be processed at the end of the tu...
Definition: gamemap.h:350
int getID() const
Definition: player.h:48
the different players in ASC. There may be 8 players (0..7) and neutral units (8) ...
Definition: player.h:99
Password passwordcrc
the Password required for playing this player
Definition: player.h:160
Resources are basically the currency of ASC.
Definition: typen.h:97
sigc::signal< void, Player & > sigPlayerUserInteractionBegins
Definition: gamemap.h:494
PlayTimeContainer playTime
The time this player ended his turns. This is very informative in email games with > 2 players to fin...
Definition: player.h:205
DissectionContainer dissections
Definition: player.h:176
VisibilityStates getVisibility(int actplayer)
Definition: mapfield.h:240
bool getProposal(int fromPlayer, DiplomaticStates *state)
Definition: player.cpp:127
convenience-class which automatically determines the Player of units, buildings and other game object...
Definition: player.h:40
int getPlayerCount() const
Definition: gamemap.h:255
DiplomaticStateVector(Player &_player)
Definition: player.cpp:48
int ASCversion
the version of ASC that this player has used to make his last turn
Definition: player.h:196
bool exist() const
does the player exist at all
Definition: player.cpp:313
Resourceview * resourceview
the mineral resources that were seen by a player on this field; since the actual amount may have decr...
Definition: mapfield.h:114
Resources payStatusLastTurn[8][8]
for the messages that are send each turn it is necessary to record how much of the transfer happend d...
Definition: gamemap.h:343
The map. THE central structure of ASC, which holds everything not globally available together...
Definition: gamemap.h:182
MessagePntrContainer unreadmessage
the list of messages that haven't been read by the player yet
Definition: player.h:181
MapField * getField(int x, int y)
Definition: gamemap.h:465