00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <algorithm>
00020 #include <ctime>
00021 #include <cmath>
00022
00023 #include "global.h"
00024 #include "misc.h"
00025 #include "typen.h"
00026 #include "vehicletype.h"
00027 #include "buildingtype.h"
00028 #include "player.h"
00029 #include "gamemap.h"
00030 #include "cannedmessages.h"
00031
00032
00033 PlayerID::PlayerID( const Player& p ) : num( p.getPosition() ) {};
00034
00035
00036 const char* diplomaticStateNames[diplomaticStateNum+1] =
00037 {
00038 "War",
00039 "Truce",
00040 "Peace",
00041 "Association",
00042 "Alliance",
00043 NULL
00044 };
00045
00046
00047
00048 DiplomaticStateVector::DiplomaticStateVector( Player& _player ) : player( _player )
00049 {
00050 }
00051
00052
00053 void DiplomaticStateVector::turnBegins()
00054 {
00055 for ( QueuedStateChanges::iterator i = queuedStateChanges.begin(); i != queuedStateChanges.end(); ++i ) {
00056 if ( getState(i->first) > i->second ) {
00057
00058 setState( i->first, i->second );
00059 player.getParentMap()->player[ i->first ].diplomacy.setState( player.getPosition(), i->second);
00060 } else {
00061
00062
00063 DiplomaticStateVector& target = player.getParentMap()->player[ i->first ].diplomacy;
00064 QueuedStateChanges::iterator t = target.queuedStateChanges.find( player.getPosition() );
00065 if ( t != target.queuedStateChanges.end() ) {
00066
00067 } else {
00068
00069
00070 }
00071 }
00072 }
00073 queuedStateChanges.clear();
00074
00075
00076
00077 for ( int p = 0; p < player.getParentMap()->getPlayerCount(); ++p ) {
00078 Player& pl = player.getParentMap()->getPlayer(p);
00079 if ( pl.exist() && p != player.getPosition() ) {
00080 DiplomaticStates state;
00081 if ( getProposal(p, &state ) )
00082 if ( state < getState(p)) {
00083 setState( p, state );
00084 pl.diplomacy.setState( player.getPosition(), state );
00085 }
00086 }
00087 }
00088 }
00089
00090
00091
00092 DiplomaticStates DiplomaticStateVector::getState( PlayerID towardsPlayer ) const
00093 {
00094 if ( towardsPlayer.getID() < 0 )
00095 return WAR;
00096
00097 if ( player.getPosition() == towardsPlayer.getID() )
00098 return ALLIANCE;
00099
00100 if ( towardsPlayer.getID() < states.size() )
00101 return states[towardsPlayer.getID()];
00102 else
00103 return WAR;
00104 }
00105
00106 void DiplomaticStateVector::resize( int size )
00107 {
00108 int oldsize = states.size();
00109 states.resize(size);
00110 for ( int i = oldsize; i < size; ++i )
00111 states[i] = WAR;
00112 }
00113
00114
00115 void DiplomaticStateVector::setState( PlayerID towardsPlayer, DiplomaticStates s )
00116 {
00117 assert( towardsPlayer.getID() >= 0 );
00118
00119 if ( towardsPlayer.getID() >= states.size() )
00120 resize(towardsPlayer.getID()+1);
00121
00122 states[towardsPlayer.getID()] = s;
00123 }
00124
00125
00126
00127 bool DiplomaticStateVector::getProposal( int fromPlayer, DiplomaticStates* state )
00128 {
00129 assert( fromPlayer >= 0 );
00130
00131 DiplomaticStateVector& targ = player.getParentMap()->player[ fromPlayer ].diplomacy;
00132
00133 QueuedStateChanges::iterator i = targ.queuedStateChanges.find( player.getPosition() );
00134
00135 if ( i != targ.queuedStateChanges.end() ) {
00136 if ( state )
00137 *state = i->second;
00138 return true;
00139 } else
00140 return false;
00141 }
00142
00143
00144
00145 void DiplomaticStateVector::read ( tnstream& stream )
00146 {
00147 stream.readInt();
00148 int size = stream.readInt();
00149 states.resize( size );
00150 for ( int i = 0; i < size; ++i )
00151 states[i] = DiplomaticStates( stream.readInt() );
00152
00153 queuedStateChanges.clear();
00154
00155 size = stream.readInt();
00156 for ( int i = 0; i< size; ++i ) {
00157 int p = stream.readInt();
00158 DiplomaticStates s = DiplomaticStates( stream.readInt() );
00159 queuedStateChanges[p] = s;
00160 }
00161 }
00162
00163 void DiplomaticStateVector::write ( tnstream& stream ) const
00164 {
00165 stream.writeInt( 1 );
00166 stream.writeInt( states.size() );
00167 for ( int i = 0; i< states.size(); ++i )
00168 stream.writeInt( int( states[i]));
00169
00170 stream.writeInt( queuedStateChanges.size() );
00171 for ( QueuedStateChanges::const_iterator i = queuedStateChanges.begin(); i != queuedStateChanges.end(); ++i ) {
00172 stream.writeInt( i->first );
00173 stream.writeInt( int(i->second) );
00174 }
00175 }
00176
00177
00178
00179
00180
00181
00182
00183
00184 const char* Player :: playerStatusNames[6] = { "Human Player",
00185 "AI player",
00186 "off",
00187 "Supervisor",
00188 "suspended",
00189 NULL };
00190
00191
00192 Player :: Player()
00193 : diplomacy( *this )
00194 {
00195 ai = NULL;
00196 parentMap = NULL;
00197 queuedEvents = 0;
00198 ASCversion = 0;
00199 color = 0;
00200 serverPlayerID = 0;
00201 }
00202
00203 void Player :: setParentMap( GameMap* map, int pos )
00204 {
00205 parentMap = map;
00206 player = pos;
00207 parentMap->sigPlayerTurnBegins.connect( SigC::slot( *this, &Player::turnBegins ));
00208 parentMap->sigPlayerUserInteractionBegins.connect( SigC::slot( *this, &Player::userInteractionBegins ));
00209 parentMap->sigPlayerTurnEnds.connect( SigC::slot( *this, &Player::turnEnds ));
00210 }
00211
00212
00213 void Player :: turnBegins( Player& p )
00214 {
00215 if ( &p == this ) {
00216 diplomacy.turnBegins();
00217 }
00218
00219 if ( stat == supervisor ) {
00220 parentMap->supervisorpasswordcrc = passwordcrc;
00221 }
00222 }
00223
00224 void Player :: userInteractionBegins( Player& p )
00225 {
00226 if ( &p == this ) {
00227 }
00228 }
00229
00230 void Player :: turnEnds( Player& p )
00231 {
00232 if ( &p == this ) {
00233 sendQueuedMessages();
00234
00235 if ( !exist() && stat != off ) {
00236 stat = off;
00237 resetView();
00238 resetResearch();
00239 resetTribute();
00240 resetPassword();
00241 email = "";
00242 name += " (removed)";
00243 }
00244 }
00245 }
00246
00247
00248
00249 DI_Color Player :: getColor() const
00250 {
00251 if ( color == DI_Color(0)) {
00252 switch ( player ) {
00253 case 0: return DI_Color( 0xe0, 0, 0 );
00254 case 1: return DI_Color( 0, 0x71, 0xdb );
00255 case 2: return DI_Color( 0xbc, 0xb3, 0 );
00256 case 3: return DI_Color( 0, 0xaa, 0 );
00257 case 4: return DI_Color( 0xbc, 0, 0 );
00258 case 5: return DI_Color( 0xb2, 0, 0xb2 );
00259 case 6: return DI_Color( 0,0, 0xaa );
00260 case 7: return DI_Color( 0xbc, 0x67, 0 );
00261 case 8: return DI_Color( 0xaa, 0xaa, 0xaa );
00262 };
00263 return DI_Color(0, 0, 0);
00264 } else
00265 return color;
00266 }
00267
00268 PlayerColor Player::getPlayerColor() const
00269 {
00270 return PlayerColor(getPosition(), getColor() );
00271 }
00272
00273
00274 ASCString Player :: getName( ) const
00275 {
00276 if ( name.length() )
00277 return name;
00278
00279 if ( stat == off )
00280 return "off";
00281
00282 return ASCString("Player ") + ASCString::toString(getPosition() );
00283 }
00284
00285 int Player::getHumanPlayerNum( const GameMap* gamemap )
00286 {
00287 int h = 0;
00288 for ( int p = 0; p < gamemap->getPlayerCount(); ++p )
00289 if ( gamemap->getPlayer(p).exist() && gamemap->getPlayer(p).isHuman() )
00290 ++h;
00291 return h;
00292 }
00293
00294
00295
00296 void Player :: sendQueuedMessages()
00297 {
00298 MessagePntrContainer::iterator mi = getParentMap()->unsentmessage.begin();
00299 while ( mi != getParentMap()->unsentmessage.end() ) {
00300 sentmessage.push_back ( *mi );
00301 for ( int i = 0; i < 8; i++ ) {
00302 if ( (*mi)->to & ( 1 << i ))
00303 getParentMap()->player[ i ].unreadmessage.push_back ( *mi );
00304 if ( (*mi)->cc & ( 1 << i ))
00305 getParentMap()->player[ i ].unreadmessage.push_back ( *mi );
00306 }
00307
00308 mi = getParentMap()->unsentmessage.erase ( mi );
00309 }
00310 }
00311
00312
00313 bool Player::exist() const
00314 {
00315 return !(buildingList.empty() && vehicleList.empty());
00316 }
00317
00318
00319 const int playerVersion = 3;
00320
00321 void Player::read ( tnstream& stream )
00322 {
00323 int version = stream.readInt();
00324 if ( version > playerVersion )
00325 throw tinvalidversion ( "Player", playerVersion, version );
00326
00327 if ( version >= 3 )
00328 serverPlayerID = stream.readInt();
00329 }
00330
00331 void Player::write ( tnstream& stream ) const
00332 {
00333 stream.writeInt( playerVersion );
00334 stream.writeInt( serverPlayerID );
00335 }
00336
00337
00338
00339
00340
00341
00342
00343 template <typename T> void swapData( T& t1, T& t2 )
00344 {
00345 T temp = t1;
00346 t1 = t2;
00347 t2 = temp;
00348 }
00349
00350 void Player::swap ( Player& secondPlayer )
00351 {
00352 if ( &secondPlayer == this)
00353 return;
00354
00355 typedef VehicleList VL;
00356 typedef VehicleList::iterator VLI;
00357
00358 VL vl;
00359 for ( VLI i = vehicleList.begin(); i != vehicleList.end(); ) {
00360 (*i)->color = secondPlayer.player*8;
00361 vl.push_back ( *i );
00362 i = vehicleList.erase( i );
00363 }
00364
00365 for ( VLI i = secondPlayer.vehicleList.begin(); i != secondPlayer.vehicleList.end(); ) {
00366 (*i)->color = player*8;
00367 vehicleList.push_back ( *i );
00368 i = secondPlayer.vehicleList.erase( i );
00369 }
00370
00371 for ( VLI i = vl.begin(); i != vl.end(); ) {
00372 secondPlayer.vehicleList.push_back ( *i );
00373 i = vl.erase( i );
00374 }
00375
00376
00377 typedef Player::BuildingList BL;
00378 typedef Player::BuildingList::iterator BLI;
00379
00380 BL bl;
00381 for ( BLI i = buildingList.begin(); i != buildingList.end(); ++i)
00382 bl.push_back ( *i );
00383
00384 BL bl2 = secondPlayer.buildingList;
00385 for ( BLI i = bl2.begin(); i != bl2.end(); ++i)
00386 (*i)->convert( player, false );
00387
00388 for ( BLI i = bl.begin(); i != bl.end(); ++i)
00389 (*i)->convert( secondPlayer.player, false );
00390
00391 for (int i =0; i < parentMap->xsize * parentMap->ysize ;i++ ) {
00392 MapField* fld = &parentMap->field[i];
00393
00394 VisibilityStates temp = fld->getVisibility( player );
00395 fld->setVisibility( fld->getVisibility( secondPlayer.player), player);
00396 fld->setVisibility( temp, secondPlayer.player);
00397
00398
00399 for ( MapField::MineContainer::iterator i = fld->mines.begin(); i != fld->mines.end(); i++ )
00400 if ( i->player == player )
00401 i->player = secondPlayer.player;
00402 else
00403 if ( i->player == secondPlayer.player )
00404 i->player = player;
00405 if ( fld->resourceview ) {
00406 bool b = fld->resourceview->visible & (1 << player);
00407 int m = fld->resourceview->materialvisible[player];
00408 int f = fld->resourceview->fuelvisible[player];
00409
00410 if ( fld->resourceview->visible & (1 << secondPlayer.player ) )
00411 fld->resourceview->setview( player, fld->resourceview->materialvisible[secondPlayer.player], fld->resourceview->fuelvisible[secondPlayer.player] );
00412 else
00413 fld->resourceview->resetview( player );
00414
00415 if ( b )
00416 fld->resourceview->setview( secondPlayer.player, m, f );
00417 else
00418 fld->resourceview->resetview( secondPlayer.player );
00419 }
00420 }
00421
00422 swapData( research, secondPlayer.research );
00423 swapData( existanceAtBeginOfTurn, secondPlayer.existanceAtBeginOfTurn );
00424
00425 delete ai;
00426 ai = NULL;
00427
00428 delete secondPlayer.ai;
00429 secondPlayer.ai = NULL;
00430
00431 swapData( stat, secondPlayer.stat );
00432 swapData( passwordcrc, secondPlayer.passwordcrc );
00433 swapData( dissections, secondPlayer.dissections );
00434 swapData( unreadmessage, secondPlayer.unreadmessage );
00435 swapData( oldmessage, secondPlayer.oldmessage );
00436 swapData( sentmessage, secondPlayer.sentmessage );
00437 swapData( queuedEvents, secondPlayer.queuedEvents );
00438 swapData( ASCversion, secondPlayer.ASCversion );
00439 swapData( playTime, secondPlayer.playTime );
00440 swapData( cursorPos, secondPlayer.cursorPos );
00441 swapData( email, secondPlayer.email );
00442 swapData( name, secondPlayer.name );
00443 swapData( color, secondPlayer.color );
00444
00445 diplomacy.swap( secondPlayer.player );
00446
00447
00448 int a = player;
00449 int b = secondPlayer.player;
00450 for ( int i= 0; i < parentMap->getPlayerCount(); ++i )
00451 if ( i != a ) {
00452 swapData( parentMap->tribute.paid[i][a], parentMap->tribute.paid[i][b] );
00453 swapData( parentMap->tribute.paid[a][i], parentMap->tribute.paid[b][i] );
00454 swapData( parentMap->tribute.avail[i][a], parentMap->tribute.avail[i][b] );
00455 swapData( parentMap->tribute.avail[a][i], parentMap->tribute.avail[b][i] );
00456 swapData( parentMap->tribute.payStatusLastTurn[i][a], parentMap->tribute.payStatusLastTurn[i][b] );
00457 swapData( parentMap->tribute.payStatusLastTurn[a][i], parentMap->tribute.payStatusLastTurn[b][i] );
00458 }
00459
00460 }
00461
00462 void DiplomaticStateVector::swap( int secondPlayer )
00463 {
00464 DiplomaticStateVector& secondDSV = player.getParentMap()->getPlayer(secondPlayer).diplomacy;
00465
00466 swapData( states, secondDSV.states );
00467 swapData( queuedStateChanges, secondDSV.queuedStateChanges );
00468
00469
00470
00471 for ( int i= 0; i < player.getParentMap()->getPlayerCount(); ++i ) {
00472 DiplomaticStates sec = player.getParentMap()->getPlayer(i).diplomacy.getState(secondPlayer);
00473 DiplomaticStates fir = player.getParentMap()->getPlayer(i).diplomacy.getState(player.getPosition());
00474
00475 player.getParentMap()->getPlayer(i).diplomacy.setState(secondPlayer, fir );
00476 player.getParentMap()->getPlayer(i).diplomacy.setState(player.getPosition(), sec );
00477 }
00478
00479 }
00480
00481
00482 void Player::merge ( Player& secondPlayer )
00483 {
00484
00485 }
00486
00487
00488 void Player::resetView()
00489 {
00490 for ( int x = 0; x < getParentMap()->xsize; x++ )
00491 for ( int y = 0; y < getParentMap()->ysize; y++ ) {
00492 MapField* fld = getParentMap()->getField(x,y);
00493 fld->setVisibility( visible_not, player );
00494 if ( fld->resourceview )
00495 fld->resourceview->visible &= ~(1<<player);
00496 }
00497
00498 }
00499 void Player::resetResearch()
00500 {
00501 research.clear();
00502 }
00503
00504 void Player::resetTribute()
00505 {
00506 for ( int j = 0; j< getParentMap()->getPlayerCount(); ++j ) {
00507 getParentMap()->tribute.avail[player][j] = Resources();
00508 getParentMap()->tribute.avail[j][player]= Resources();
00509 getParentMap()->tribute.paid[player][j] = Resources();
00510 getParentMap()->tribute.paid[j][player]= Resources();
00511 getParentMap()->tribute.payStatusLastTurn[player][j] = Resources();
00512 getParentMap()->tribute.payStatusLastTurn[j][player]= Resources();
00513 }
00514 }
00515
00516 void Player::resetPassword()
00517 {
00518 passwordcrc.reset();
00519 }
00520
00521 bool Player::operator==( const Player& otherPlayer) const
00522 {
00523 return parentMap == otherPlayer.parentMap && player == otherPlayer.player;
00524 }