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 SigC::Signal4<void,GameMap*,int,int,DiplomaticStates> DiplomaticStateVector::anyStateChanged;
00037 SigC::Signal3<void,GameMap*,int,int> DiplomaticStateVector::shareViewChanged;
00038
00039
00040 const char* diplomaticStateNames[diplomaticStateNum+1] =
00041 {
00042 "War",
00043 "Truce",
00044 "Peace",
00045 "Association",
00046 "Alliance",
00047 NULL
00048 };
00049
00050
00051
00052 DiplomaticStateVector::DiplomaticStateVector( Player& _player ) : player( _player )
00053 {
00054 }
00055
00056
00057 void DiplomaticStateVector::turnBegins()
00058 {
00059 for ( QueuedStateChanges::iterator i = queuedStateChanges.begin(); i != queuedStateChanges.end(); ++i ) {
00060 if ( getState(i->first) > i->second ) {
00061
00062 setState( i->first, i->second );
00063 player.getParentMap()->player[ i->first ].diplomacy.setState( player.getPosition(), i->second);
00064 } else {
00065
00066
00067 DiplomaticStateVector& target = player.getParentMap()->player[ i->first ].diplomacy;
00068 QueuedStateChanges::iterator t = target.queuedStateChanges.find( player.getPosition() );
00069 if ( t != target.queuedStateChanges.end() ) {
00070
00071 } else {
00072
00073 }
00074 }
00075 }
00076 queuedStateChanges.clear();
00077 }
00078
00079
00080
00081 DiplomaticStates DiplomaticStateVector::getState( int towardsPlayer ) const
00082 {
00083 if ( towardsPlayer < 0 )
00084 return WAR;
00085
00086 if ( player.getPosition() == towardsPlayer )
00087 return ALLIANCE;
00088
00089 if ( towardsPlayer < states.size() )
00090 return states[towardsPlayer];
00091 else
00092 return WAR;
00093 }
00094
00095 void DiplomaticStateVector::resize( int size )
00096 {
00097 int oldsize = states.size();
00098 states.resize(size);
00099 for ( int i = oldsize; i < size; ++i )
00100 states[i] = WAR;
00101 }
00102
00103
00104 void DiplomaticStateVector::setState( int towardsPlayer, DiplomaticStates s, bool fireSignal )
00105 {
00106 assert( towardsPlayer >= 0 );
00107
00108 if ( towardsPlayer >= states.size() )
00109 resize(towardsPlayer+1);
00110
00111 states[towardsPlayer] = s;
00112
00113 if ( fireSignal )
00114 anyStateChanged( player.getParentMap(), player.getPosition(), towardsPlayer,s);
00115 }
00116
00117 void DiplomaticStateVector::sneakAttack( int towardsPlayer )
00118 {
00119 assert( towardsPlayer >= 0 );
00120
00121 setState( towardsPlayer, WAR );
00122 player.getParentMap()->player[ towardsPlayer ].diplomacy.setState( player.getPosition(), WAR );
00123
00124 int to = 0;
00125 for ( int j = 0; j < 8; j++ )
00126 if ( j != player.getPosition() )
00127 to |= 1 << j;
00128
00129 ASCString txt;
00130 txt.format ( getmessage( 10001 ), player.getName().c_str(), player.getParentMap()->player[towardsPlayer].getName().c_str() );
00131 new Message ( txt, player.getParentMap(), to );
00132 }
00133
00134
00135 void DiplomaticStateVector::changeToState( int towardsPlayer, DiplomaticStates s, bool mail )
00136 {
00137 assert( towardsPlayer >= 0 );
00138
00139 int msgid;
00140 if ( s > getState( towardsPlayer ))
00141 msgid = 10003;
00142 else
00143 msgid = 10002;
00144
00145
00146 bool oldShareView = sharesView(towardsPlayer);
00147
00148 setState( towardsPlayer, s );
00149
00150 DiplomaticStateVector& targ = player.getParentMap()->player[ towardsPlayer ].diplomacy;
00151 targ.setState( player.getPosition(), s );
00152
00153 if( sharesView(towardsPlayer) != oldShareView )
00154 shareViewChanged( player.getParentMap(), player.getPosition(), towardsPlayer );
00155
00156 if ( mail ) {
00157 ASCString txt;
00158 txt.format( getmessage( msgid ), player.getName().c_str(), diplomaticStateNames[s] );
00159 new Message ( txt, player.getParentMap(), 1 << towardsPlayer );
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 }
00181
00182
00183 void DiplomaticStateVector::propose( int towardsPlayer, DiplomaticStates s )
00184 {
00185 assert( towardsPlayer >= 0 );
00186
00187 DiplomaticStateVector& targ = player.getParentMap()->player[ towardsPlayer ].diplomacy;
00188
00189 QueuedStateChanges::iterator i = targ.queuedStateChanges.find( player.getPosition() );
00190
00191 DiplomaticStates currentState = getState( towardsPlayer ) ;
00192
00193 if ( i == targ.queuedStateChanges.end() || (s < currentState && i->second > currentState)) {
00194
00195
00196 ASCString txt;
00197 int msgid;
00198 if ( s > getState( towardsPlayer ))
00199 msgid = 10003;
00200 else
00201 msgid = 10002;
00202
00203 txt.format( getmessage( msgid ), player.getName().c_str(), diplomaticStateNames[s] );
00204 new Message ( txt, player.getParentMap(), 1 << towardsPlayer );
00205
00206 queuedStateChanges[towardsPlayer] = s;
00207 } else {
00208
00209
00210 if ( s > getState( towardsPlayer )) {
00211
00212
00213 if ( s > i->second ) {
00214
00215 changeToState( towardsPlayer, i->second );
00216 } else {
00217
00218 changeToState( towardsPlayer, s, true );
00219 targ.queuedStateChanges.erase( i );
00220 }
00221 } else {
00222 if ( s < i->second ) {
00223
00224 changeToState( towardsPlayer, i->second );
00225 targ.queuedStateChanges.erase( i );
00226 } else {
00227
00228 changeToState( towardsPlayer, s, false );
00229 }
00230
00231 }
00232 }
00233
00234 }
00235
00236 bool DiplomaticStateVector::getProposal( int fromPlayer, DiplomaticStates* state )
00237 {
00238 assert( fromPlayer >= 0 );
00239
00240 DiplomaticStateVector& targ = player.getParentMap()->player[ fromPlayer ].diplomacy;
00241
00242 QueuedStateChanges::iterator i = targ.queuedStateChanges.find( player.getPosition() );
00243
00244 if ( i != targ.queuedStateChanges.end() ) {
00245 if ( state )
00246 *state = i->second;
00247 return true;
00248 } else
00249 return false;
00250 }
00251
00252
00253
00254 void DiplomaticStateVector::read ( tnstream& stream )
00255 {
00256 stream.readInt();
00257 int size = stream.readInt();
00258 states.resize( size );
00259 for ( int i = 0; i < size; ++i )
00260 states[i] = DiplomaticStates( stream.readInt() );
00261
00262 queuedStateChanges.clear();
00263
00264 size = stream.readInt();
00265 for ( int i = 0; i< size; ++i ) {
00266 int p = stream.readInt();
00267 DiplomaticStates s = DiplomaticStates( stream.readInt() );
00268 queuedStateChanges[p] = s;
00269 }
00270 }
00271
00272 void DiplomaticStateVector::write ( tnstream& stream ) const
00273 {
00274 stream.writeInt( 1 );
00275 stream.writeInt( states.size() );
00276 for ( int i = 0; i< states.size(); ++i )
00277 stream.writeInt( int( states[i]));
00278
00279 stream.writeInt( queuedStateChanges.size() );
00280 for ( QueuedStateChanges::const_iterator i = queuedStateChanges.begin(); i != queuedStateChanges.end(); ++i ) {
00281 stream.writeInt( i->first );
00282 stream.writeInt( int(i->second) );
00283 }
00284 }
00285
00286
00287
00288
00289
00290
00291
00292
00293 const char* Player :: playerStatusNames[6] = { "Human Player",
00294 "AI player",
00295 "off",
00296 "Supervisor",
00297 "suspended",
00298 NULL };
00299
00300
00301 Player :: Player()
00302 : diplomacy( *this )
00303 {
00304 ai = NULL;
00305 parentMap = NULL;
00306 queuedEvents = 0;
00307 ASCversion = 0;
00308 color = 0;
00309 }
00310
00311 void Player :: setParentMap( GameMap* map, int pos )
00312 {
00313 parentMap = map;
00314 player = pos;
00315 parentMap->sigPlayerTurnBegins.connect( SigC::slot( *this, &Player::turnBegins ));
00316 parentMap->sigPlayerUserInteractionBegins.connect( SigC::slot( *this, &Player::userInteractionBegins ));
00317 parentMap->sigPlayerTurnEnds.connect( SigC::slot( *this, &Player::turnEnds ));
00318 }
00319
00320
00321 void Player :: turnBegins( Player& p )
00322 {
00323 if ( &p == this ) {
00324 diplomacy.turnBegins();
00325 }
00326 }
00327
00328 void Player :: userInteractionBegins( Player& p )
00329 {
00330 if ( &p == this ) {
00331 }
00332 }
00333
00334 void Player :: turnEnds( Player& p )
00335 {
00336 if ( &p == this ) {
00337 sendQueuedMessages();
00338
00339 if ( !exist() && stat != off ) {
00340 stat = off;
00341 resetView();
00342 resetResearch();
00343 resetTribute();
00344 resetPassword();
00345 email = "";
00346 name += " (removed)";
00347 }
00348 }
00349 }
00350
00351
00352
00353 DI_Color Player :: getColor() const
00354 {
00355 if ( color == DI_Color(0)) {
00356 switch ( player ) {
00357 case 0: return DI_Color( 0xe0, 0, 0 );
00358 case 1: return DI_Color( 0, 0x71, 0xdb );
00359 case 2: return DI_Color( 0xbc, 0xb3, 0 );
00360 case 3: return DI_Color( 0, 0xaa, 0 );
00361 case 4: return DI_Color( 0xbc, 0, 0 );
00362 case 5: return DI_Color( 0xb2, 0, 0xb2 );
00363 case 6: return DI_Color( 0,0, 0xaa );
00364 case 7: return DI_Color( 0xbc, 0x67, 0 );
00365 case 8: return DI_Color( 0xaa, 0xaa, 0xaa );
00366 };
00367 return DI_Color(0, 0, 0);
00368 } else
00369 return color;
00370 }
00371
00372 PlayerColor Player::getPlayerColor() const
00373 {
00374 return PlayerColor(getPosition(), getColor() );
00375 }
00376
00377
00378 ASCString Player :: getName( ) const
00379 {
00380 if ( name.length() )
00381 return name;
00382
00383 if ( stat == off )
00384 return "off";
00385
00386 return ASCString("Player ") + ASCString::toString(getPosition() );
00387 }
00388
00389 int Player::getHumanPlayerNum( const GameMap* gamemap )
00390 {
00391 int h = 0;
00392 for ( int p = 0; p < gamemap->getPlayerCount(); ++p )
00393 if ( gamemap->getPlayer(p).exist() && gamemap->getPlayer(p).isHuman() )
00394 ++h;
00395 return h;
00396 }
00397
00398
00399
00400 void Player :: sendQueuedMessages()
00401 {
00402 MessagePntrContainer::iterator mi = getParentMap()->unsentmessage.begin();
00403 while ( mi != getParentMap()->unsentmessage.end() ) {
00404 sentmessage.push_back ( *mi );
00405 for ( int i = 0; i < 8; i++ ) {
00406 if ( (*mi)->to & ( 1 << i ))
00407 getParentMap()->player[ i ].unreadmessage.push_back ( *mi );
00408 if ( (*mi)->cc & ( 1 << i ))
00409 getParentMap()->player[ i ].unreadmessage.push_back ( *mi );
00410 }
00411
00412 mi = getParentMap()->unsentmessage.erase ( mi );
00413 }
00414 }
00415
00416
00417 bool Player::exist() const
00418 {
00419 return !(buildingList.empty() && vehicleList.empty());
00420 }
00421
00422
00423 const int playerVersion = 2;
00424
00425 void Player::read ( tnstream& stream )
00426 {
00427 int version = stream.readInt();
00428 if ( version > playerVersion )
00429 throw tinvalidversion ( "Player", playerVersion, version );
00430
00431
00432 }
00433
00434 void Player::write ( tnstream& stream ) const
00435 {
00436 stream.writeInt( playerVersion );
00437
00438 }
00439
00440
00441
00442
00443
00444
00445
00446 template <typename T> void swapData( T& t1, T& t2 )
00447 {
00448 T temp = t1;
00449 t1 = t2;
00450 t2 = temp;
00451 }
00452
00453 void Player::swap ( Player& secondPlayer )
00454 {
00455 if ( &secondPlayer == this)
00456 return;
00457
00458 typedef VehicleList VL;
00459 typedef VehicleList::iterator VLI;
00460
00461 VL vl;
00462 for ( VLI i = vehicleList.begin(); i != vehicleList.end(); ) {
00463 (*i)->color = secondPlayer.player*8;
00464 vl.push_back ( *i );
00465 i = vehicleList.erase( i );
00466 }
00467
00468 for ( VLI i = secondPlayer.vehicleList.begin(); i != secondPlayer.vehicleList.end(); ) {
00469 (*i)->color = player*8;
00470 vehicleList.push_back ( *i );
00471 i = secondPlayer.vehicleList.erase( i );
00472 }
00473
00474 for ( VLI i = vl.begin(); i != vl.end(); ) {
00475 secondPlayer.vehicleList.push_back ( *i );
00476 i = vl.erase( i );
00477 }
00478
00479
00480 typedef Player::BuildingList BL;
00481 typedef Player::BuildingList::iterator BLI;
00482
00483 BL bl;
00484 for ( BLI i = buildingList.begin(); i != buildingList.end(); ++i)
00485 bl.push_back ( *i );
00486
00487 BL bl2 = secondPlayer.buildingList;
00488 for ( BLI i = bl2.begin(); i != bl2.end(); ++i)
00489 (*i)->convert( player );
00490
00491 for ( BLI i = bl.begin(); i != bl.end(); ++i)
00492 (*i)->convert( secondPlayer.player );
00493
00494 for (int i =0; i < parentMap->xsize * parentMap->ysize ;i++ ) {
00495 tfield* fld = &parentMap->field[i];
00496
00497 VisibilityStates temp = fld->getVisibility( player );
00498 fld->setVisibility( fld->getVisibility( secondPlayer.player), player);
00499 fld->setVisibility( temp, secondPlayer.player);
00500
00501
00502 for ( tfield::MineContainer::iterator i = fld->mines.begin(); i != fld->mines.end(); i++ )
00503 if ( i->player == player )
00504 i->player = secondPlayer.player;
00505 else
00506 if ( i->player == secondPlayer.player )
00507 i->player = player;
00508 if ( fld->resourceview ) {
00509 bool b = fld->resourceview->visible & (1 << player);
00510 int m = fld->resourceview->materialvisible[player];
00511 int f = fld->resourceview->fuelvisible[player];
00512
00513 if ( fld->resourceview->visible & (1 << secondPlayer.player ) )
00514 fld->resourceview->setview( player, fld->resourceview->materialvisible[secondPlayer.player], fld->resourceview->fuelvisible[secondPlayer.player] );
00515 else
00516 fld->resourceview->resetview( player );
00517
00518 if ( b )
00519 fld->resourceview->setview( secondPlayer.player, m, f );
00520 else
00521 fld->resourceview->resetview( secondPlayer.player );
00522 }
00523 }
00524
00525 swapData( research, secondPlayer.research );
00526 swapData( existanceAtBeginOfTurn, secondPlayer.existanceAtBeginOfTurn );
00527
00528 delete ai;
00529 ai = NULL;
00530
00531 delete secondPlayer.ai;
00532 secondPlayer.ai = NULL;
00533
00534 swapData( stat, secondPlayer.stat );
00535 swapData( passwordcrc, secondPlayer.passwordcrc );
00536 swapData( dissections, secondPlayer.dissections );
00537 swapData( unreadmessage, secondPlayer.unreadmessage );
00538 swapData( oldmessage, secondPlayer.oldmessage );
00539 swapData( sentmessage, secondPlayer.sentmessage );
00540 swapData( queuedEvents, secondPlayer.queuedEvents );
00541 swapData( ASCversion, secondPlayer.ASCversion );
00542 swapData( playTime, secondPlayer.playTime );
00543 swapData( cursorPos, secondPlayer.cursorPos );
00544 swapData( email, secondPlayer.email );
00545 swapData( name, secondPlayer.name );
00546 swapData( color, secondPlayer.color );
00547
00548 diplomacy.swap( secondPlayer.player );
00549
00550
00551 int a = player;
00552 int b = secondPlayer.player;
00553 for ( int i= 0; i < parentMap->getPlayerCount(); ++i )
00554 if ( i != a ) {
00555 swapData( parentMap->tribute.paid[i][a], parentMap->tribute.paid[i][b] );
00556 swapData( parentMap->tribute.paid[a][i], parentMap->tribute.paid[b][i] );
00557 swapData( parentMap->tribute.avail[i][a], parentMap->tribute.avail[i][b] );
00558 swapData( parentMap->tribute.avail[a][i], parentMap->tribute.avail[b][i] );
00559 swapData( parentMap->tribute.payStatusLastTurn[i][a], parentMap->tribute.payStatusLastTurn[i][b] );
00560 swapData( parentMap->tribute.payStatusLastTurn[a][i], parentMap->tribute.payStatusLastTurn[b][i] );
00561 }
00562
00563 }
00564
00565 void DiplomaticStateVector::swap( int secondPlayer )
00566 {
00567 DiplomaticStateVector& secondDSV = player.getParentMap()->getPlayer(secondPlayer).diplomacy;
00568
00569 swapData( states, secondDSV.states );
00570 swapData( queuedStateChanges, secondDSV.queuedStateChanges );
00571
00572 resize( max(player.getPosition(), secondPlayer));
00573
00574 for ( int i= 0; i < player.getParentMap()->getPlayerCount(); ++i )
00575 swapData( player.getParentMap()->getPlayer(i).diplomacy.states[secondPlayer], player.getParentMap()->getPlayer(i).diplomacy.states[player.getPosition()] );
00576
00577 }
00578
00579
00580 void Player::merge ( Player& secondPlayer )
00581 {
00582
00583 }
00584
00585
00586 void Player::resetView()
00587 {
00588 for ( int x = 0; x < getParentMap()->xsize; x++ )
00589 for ( int y = 0; y < getParentMap()->ysize; y++ ) {
00590 tfield* fld = getParentMap()->getField(x,y);
00591 fld->setVisibility( visible_not, player );
00592 if ( fld->resourceview )
00593 fld->resourceview->visible &= ~(1<<player);
00594 }
00595
00596 }
00597 void Player::resetResearch()
00598 {
00599 research.clear();
00600 }
00601
00602 void Player::resetTribute()
00603 {
00604 for ( int j = 0; j< getParentMap()->getPlayerCount(); ++j ) {
00605 getParentMap()->tribute.avail[player][j] = Resources();
00606 getParentMap()->tribute.avail[j][player]= Resources();
00607 getParentMap()->tribute.paid[player][j] = Resources();
00608 getParentMap()->tribute.paid[j][player]= Resources();
00609 getParentMap()->tribute.payStatusLastTurn[player][j] = Resources();
00610 getParentMap()->tribute.payStatusLastTurn[j][player]= Resources();
00611 }
00612 }
00613
00614 void Player::resetPassword()
00615 {
00616 passwordcrc.reset();
00617 }