#include <gGame.h>
Public Member Functions | |
gGame () | |
gGame (nMessage &m) | |
virtual | ~gGame () |
virtual void | WriteSync (nMessage &m) |
virtual void | ReadSync (nMessage &m) |
virtual nDescriptor & | CreatorDescriptor () const |
virtual void | Verify () |
virtual void | StateUpdate () |
virtual void | SetState (unsigned short act, unsigned short next) |
virtual short | GetState () |
void | SyncState (unsigned short state) |
virtual void | Timestep (REAL time, bool cam=false) |
virtual void | Analysis (REAL time) |
virtual bool | GameLoop (bool input=true) |
bool | GridIsReady (int c) |
eGrid * | Grid () const |
void | NoLongerGoOn () |
void | StartNewMatch () |
void | StartNewMatchNow () |
Static Public Member Functions | |
static void | NetSync () |
static void | NetSyncIdle () |
Public Attributes | |
eSoundMixer * | m_Mixer |
Private Member Functions | |
tCONTROLLED_PTR (eGrid) grid | |
void | Init () |
Private Attributes | |
unsigned short | state |
unsigned short | stateNext |
tJUST_CONTROLLED_PTR< gZone > | winDeathZone_ |
bool | goon |
int | rounds |
double | startTime |
int | warning |
bool | synced_ |
flag indicating whether the game is considered synced | |
gParser * | aParser |
Definition at line 61 of file gGame.h.
gGame::gGame | ( | ) |
Definition at line 2374 of file gGame.cpp.
References Init(), nCLIENT, nNetObject::RequestSync(), gLogo::SetDisplayed(), sn_GetNetState(), and synced_.
02375 { 02376 synced_ = true; 02377 gLogo::SetDisplayed(false); 02378 if (sn_GetNetState()!=nCLIENT) 02379 RequestSync(); 02380 Init();
gGame::gGame | ( | nMessage & | m | ) |
gGame::~gGame | ( | ) | [virtual] |
Definition at line 2388 of file gGame.cpp.
References aParser, exit_game_objects(), tASSERT, and ePlayerNetID::ThrowOutDisconnected().
02389 { 02390 #ifdef DEBUG 02391 //con << "deleting game...\n"; 02392 #endif 02393 //stateNext=GS_CREATE_GRID; 02394 //StateUpdate(); 02395 02396 tASSERT( sg_currentGame != this ); 02397 02398 exit_game_objects(grid); 02399 grid->Clear(); 02400 ePlayerNetID::ThrowOutDisconnected(); 02401 02402 delete aParser;
gGame::tCONTROLLED_PTR | ( | eGrid | ) | [private] |
void gGame::Init | ( | void | ) | [private] |
Definition at line 2279 of file gGame.cpp.
References aParser, eSoundMixer::GetMixer(), goon, GS_CREATED, GS_TRANSFER_SETTINGS, m_Mixer, rounds, StartNewMatchNow(), state, stateNext, and tNEW.
Referenced by gGame().
02280 { 02281 m_Mixer = eSoundMixer::GetMixer(); 02282 grid = tNEW(eGrid()); 02283 state=GS_CREATED; 02284 stateNext=GS_TRANSFER_SETTINGS; 02285 goon=true; 02286 02287 sg_currentGame=this; 02288 #ifdef DEBUG 02289 // con << "Game created.\n"; 02290 #endif 02291 aParser = tNEW(gParser)(&Arena, grid); 02292 02293 rounds = 0; 02294 StartNewMatchNow();
void gGame::WriteSync | ( | nMessage & | m | ) | [virtual] |
Reimplemented from nNetObject.
Definition at line 2405 of file gGame.cpp.
References stateNext, nMessage::Write(), and nNetObject::WriteSync().
02406 { 02407 nNetObject::WriteSync(m); 02408 m.Write(stateNext); 02409 #ifdef DEBUG 02410 //con << "Wrote game state " << stateNext << ".\n"; 02411 #endif
void gGame::ReadSync | ( | nMessage & | m | ) | [virtual] |
Reimplemented from nNetObject.
Definition at line 2413 of file gGame.cpp.
References con, nMessage::Read(), nNetObject::ReadSync(), sg_AbeforeB(), and stateNext.
02414 { 02415 nNetObject::ReadSync(m); 02416 02417 unsigned short newState; 02418 m.Read(newState); 02419 02420 #ifdef DEBUG 02421 con << "Read gamestate " << newState << ".\n"; 02422 #endif 02423 02424 // only update the state if it does not go back a few steps 02425 if ( sg_AbeforeB( stateNext, newState ) ) 02426 stateNext = newState; 02427 02428 #ifdef DEBUG 02429 //con << "Read game state " << stateNext << ".\n"; 02430 #endif
nDescriptor & gGame::CreatorDescriptor | ( | void | ) | const [virtual] |
Implements nNetObject.
Definition at line 2274 of file gGame.cpp.
References game_init.
02275 { 02276 return game_init;
void gGame::NetSync | ( | ) | [static] |
Definition at line 2433 of file gGame.cpp.
References tRecorder::Playback(), ePlayer::PlayerConfig(), uMenu::quickexit, tRecorder::Record(), sg_Receive(), sn_SendPlanned(), sr_glOut, nNetObject::SyncAll(), tAdvanceFrame(), and tERR_ERROR_INT.
Referenced by NetSyncIdle().
02434 { 02435 // find end of recording in playback 02436 if ( tRecorder::Playback("END") ) 02437 { 02438 tRecorder::Record("END"); 02439 uMenu::quickexit=true; 02440 } 02441 02442 #ifdef DEDICATED 02443 if (!sr_glOut && ePlayer::PlayerConfig(0)->cam) 02444 tERR_ERROR_INT("Someone messed with the camera!"); 02445 #endif 02446 sg_Receive(); 02447 nNetObject::SyncAll(); 02448 tAdvanceFrame(); 02449 sn_SendPlanned();
void gGame::NetSyncIdle | ( | ) | [static] |
Definition at line 2451 of file gGame.cpp.
References NetSync(), and sn_Delay().
Referenced by SetState(), sg_FullscreenMessage(), sg_HostGame(), StateUpdate(), SyncState(), and update_settings().
void gGame::Verify | ( | ) | [virtual] |
Definition at line 2366 of file gGame.cpp.
References aParser, exit_game_grid(), init_game_grid(), and sg_ParseMap().
02368 { 02369 // test map and load map settings 02370 sg_ParseMap( aParser ); 02371 init_game_grid(grid, aParser); 02372 exit_game_grid(grid);
void gGame::StateUpdate | ( | ) | [virtual] |
Definition at line 2556 of file gGame.cpp.
References Analysis(), aParser, rConsole::autoDisplayAtNewline, ePlayerNetID::ChatFlags_Away, nNetObject::ClearAllDeleted(), client_gs, con, tDirectories::Config(), exit_game_objects(), rConsole::fullscreen, eGrid::GameObjects(), tRandomizer::Get(), tRandomizer::GetInstance(), goon, Grid(), GS_CAMERA, GS_CREATE_GRID, GS_CREATE_OBJECTS, GS_CREATED, GS_DELETE_GRID, GS_DELETE_OBJECTS, GS_PLAY, GS_SYNCING, GS_TRANSFER_OBJECTS, GS_TRANSFER_SETTINGS, gRotation::HandleNewRound(), init_game_camera(), init_game_grid(), init_game_objects(), init_second_pass_zones(), just_connected, nMachine::KickSpectators(), GrowingArrayBase::Len(), gGameSettings::limitRounds, tConfItemBase::LoadAll(), rITexture::LoadAll(), tConfItemBase::LoadPlayback(), ePlayerNetID::LogScoreDifferences(), MAX_PLAYERS, MAXCLIENTS, nCLIENT, NetSyncIdle(), nSERVER, NULL, nAuthentication::OnBreak(), eGameObject::OnRoundBegin(), ePlayerNetID::RankingLadderLog(), ePlayerNetID::RemoveChatbots(), nNetObject::RequestSync(), rotate(), rotationtype, rounds, nConfItemBase::s_SendConfig(), s_Timestep(), se_ChatState(), se_GameTime(), se_PauseGameTimer(), se_SaveToLadderLog(), se_SaveToScoreFile(), se_sendEventNotification(), se_SyncGameTimer(), se_UserShowScores(), nMessage::Send(), SetState(), tOutput::SetTemplateParameter(), nPingAverager::SetWeight(), sg_AbeforeB(), sg_NumUsers(), sg_ParseMap(), sg_roundCenterMessage, sg_roundConsoleMessage, sg_Timeout, sg_Timestamp(), sg_VoteMenuIdle(), sn_CenterMessage(), sn_Connections, sn_ConsoleOut(), sn_GetNetState(), sn_netObjects, sn_Statistics(), sn_Sync(), sr_con, st_ToDo(), StartNewMatchNow(), state, stateNext, synced_, tAdvanceFrame(), tSysTimeFloat(), ePlayerNetID::Update(), rViewport::Update(), update_settings(), tDirectories::Var(), ePlayerNetID::WaitToLeaveChat(), winDeathZone_, and nMessage::Write().
Referenced by GameLoop().
02557 { 02558 02559 // if (state==GS_CREATED) 02560 // stateNext=GS_CREATE_GRID; 02561 02562 while ( sg_AbeforeB( state, stateNext ) && goon ) 02563 { 02564 #ifdef CONNECTION_STRESS 02565 if ( sg_ConnectionStress ) 02566 { 02567 tRandomizer & randomizer = tRandomizer::GetInstance(); 02568 int random = randomizer.Get( 16 ); 02569 if ( random == 0 ) 02570 { 02571 sg_RequestedDisconnection = true; 02572 // sn_SetNetState( nSTANDALONE ); 02573 goon = false; 02574 } 02575 02576 se_ChatState( ePlayerNetID::ChatFlags_Away, 1 ); 02577 } 02578 #endif 02579 02580 // unsigned short int mes1 = 1, mes2 = 1, mes3 = 1, mes4 = 1, mes5 = 1; 02581 02582 switch (state){ 02583 case GS_DELETE_GRID: 02584 // sr_con.autoDisplayAtNewline=true; 02585 02586 con << tOutput("$gamestate_deleting_grid"); 02587 // sn_ConsoleOut(sg_roundCenterMessage + "\n"); 02588 sn_CenterMessage(sg_roundCenterMessage); 02589 02590 // for (unsigned short int mycy = 0; mycy > sg_roundConsoleMessage5.Len(); c++) 02591 02592 exit_game_objects(grid); 02593 nNetObject::ClearAllDeleted(); 02594 02595 if (goon) 02596 SetState(GS_TRANSFER_SETTINGS,GS_CREATE_GRID); 02597 else 02598 state=GS_CREATE_GRID; 02599 break; 02600 case GS_CREATED: 02601 case GS_TRANSFER_SETTINGS: 02602 // sr_con.autoDisplayAtNewline=true; 02603 02604 // transfer game settings 02605 if ( nCLIENT != sn_GetNetState() ) 02606 { 02607 update_settings(); 02608 ePlayerNetID::RemoveChatbots(); 02609 } 02610 02611 rViewport::Update(MAX_PLAYERS); 02612 02613 // log scores before players get renamed 02614 ePlayerNetID::LogScoreDifferences(); 02615 se_SaveToLadderLog(tString("NEW_ROUND\n")); 02616 se_sendEventNotification(tString("New Round"), tString("Starting a new round")); 02617 02618 // kick spectators 02619 nMachine::KickSpectators(); 02620 02621 // rename players as per request 02622 if ( synced_ && sn_GetNetState() != nSERVER ) 02623 ePlayerNetID::Update(); 02624 02625 // delete game objects again (in case new ones were spawned) 02626 exit_game_objects(grid); 02627 02628 nConfItemBase::s_SendConfig(false); 02629 02630 // wait extra long for the clients to delete the grid; they really need to be 02631 // synced this time 02632 sn_Sync( sg_Timeout*.4, true ); 02633 02634 SetState(GS_CREATE_GRID,GS_CAMERA); 02635 break; 02636 02637 case GS_CREATE_GRID: 02638 // sr_con.autoDisplayAtNewline=true; 02639 02640 sg_ParseMap( aParser ); 02641 02642 sn_Statistics(); 02643 sg_Timestamp(); 02644 02645 con << tOutput("$gamestate_creating_grid"); 02646 02647 tAdvanceFrame(); 02648 02649 init_game_grid(grid, aParser); 02650 02651 nNetObject::ClearAllDeleted(); 02652 02653 SetState(GS_CREATE_OBJECTS,GS_CAMERA); 02654 break; 02655 case GS_CREATE_OBJECTS: 02656 // con << "Creating objects...\n"; 02657 02658 lastdeath = -100; 02659 roundOver = false; 02660 02661 // rename players as per request 02662 if ( synced_ ) 02663 ePlayerNetID::Update(); 02664 02665 init_game_objects(grid); 02666 02667 ePlayerNetID::RankingLadderLog(); 02668 02669 // do round begin stuff 02670 { 02671 const tList<eGameObject>& gameObjects = Grid()->GameObjects(); 02672 for (int i=gameObjects.Len()-1;i>=0;i--) 02673 { 02674 eGameObject * e = gameObjects(i); 02675 if ( e ) 02676 { 02677 e->OnRoundBegin(); 02678 } 02679 } 02680 } 02681 02682 // do the first analysis of the round, now is the time to get it used to the number of teams 02683 Analysis( -1000 ); 02684 02685 s_Timestep(grid, se_GameTime(), false); 02686 SetState(GS_TRANSFER_OBJECTS,GS_CAMERA); 02687 02688 if (sn_GetNetState() == nCLIENT && just_connected){ 02689 sn_Sync(sg_Timeout*.1,true); 02690 sn_Sync(sg_Timeout*.1,true); 02691 } 02692 just_connected=false; 02693 02694 #ifdef ENABLE_ZONESV2 02695 init_second_pass_zones(grid, aParser); 02696 #endif 02697 break; 02698 case GS_TRANSFER_OBJECTS: 02699 // con << "Transferring objects...\n"; 02700 rITexture::LoadAll(); 02701 // se_ResetGameTimer(); 02702 // se_PauseGameTimer(true); 02703 02704 02705 // push all data 02706 if (sn_GetNetState()==nSERVER){ 02707 bool goon=true; 02708 double timeout=tSysTimeFloat()+sg_Timeout*.4; 02709 while (goon && tSysTimeFloat()<timeout){ 02710 NetSyncIdle(); 02711 goon=false; 02712 for (int i=MAXCLIENTS;i>0;i--) 02713 if (sn_Connections[i].socket) 02714 for (int j=sn_netObjects.Len()-1;j>=0;j--) 02715 if (sn_netObjects(j) && 02716 !sn_netObjects(j)->HasBeenTransmitted(i) && 02717 sn_netObjects(j)->syncRequested(i)) 02718 goon=true; 02719 } 02720 if (tSysTimeFloat()<timeout) 02721 con << tOutput("$gamestate_done"); 02722 else{ 02723 con << tOutput("$gamestate_timeout_intro"); 02724 for (int i=MAXCLIENTS;i>0;i--) 02725 if (sn_Connections[i].socket) 02726 for (int j=sn_netObjects.Len()-1;j>=0;j--) 02727 if (sn_netObjects(j) && !sn_netObjects(j)->HasBeenTransmitted(i)) 02728 { 02729 tOutput o; 02730 tString name; 02731 sn_netObjects(j)->PrintName( name ); 02732 o.SetTemplateParameter(1, i); 02733 o.SetTemplateParameter(2, j); 02734 o.SetTemplateParameter(3, name); 02735 o << "$gamestate_timeout_message"; 02736 con << o; 02737 } 02738 con << "\n\n\n"; 02739 } 02740 } 02741 02742 // wait for players to ready 02743 if ( sn_GetNetState() == nSERVER ) 02744 while ( ePlayerNetID::WaitToLeaveChat() ) 02745 { 02746 NetSyncIdle(); 02747 se_SyncGameTimer(); 02748 } 02749 02750 SetState(GS_CAMERA,GS_SYNCING); 02751 break; 02752 case GS_CAMERA: 02753 // con << "Setting camera position...\n"; 02754 rITexture::LoadAll(); 02755 // se_ResetGameTimer(-PREPARE_TIME); 02756 // se_PauseGameTimer(true); 02757 init_game_camera(grid); 02758 SetState(GS_SYNCING,GS_PLAY); 02759 break; 02760 case GS_SYNCING: 02761 // con << "Syncing timer...\n"; 02762 rITexture::LoadAll(); 02763 SetState(GS_PLAY,GS_PLAY); 02764 if (sn_GetNetState()!=nCLIENT){ 02765 if (rounds<=0){ 02766 sn_ConsoleOut("$gamestate_resetnow_console"); 02767 StartNewMatchNow(); 02768 sn_CenterMessage("$gamestate_resetnow_center"); 02769 se_SaveToScoreFile("$gamestate_resetnow_log"); 02770 } 02771 02772 tOutput mess; 02773 if (rounds < sg_currentSettings->limitRounds) 02774 { 02775 mess.SetTemplateParameter(1, rounds+1); 02776 mess.SetTemplateParameter(2, sg_currentSettings->limitRounds); 02777 mess << "$gamestate_newround_console"; 02778 02779 if (strlen(sg_roundConsoleMessage) > 2) 02780 sn_ConsoleOut(sg_roundConsoleMessage + "\n"); 02781 } 02782 else 02783 mess << "$gamestate_newround_goldengoal"; 02784 sn_ConsoleOut(mess); 02785 02786 se_SaveToScoreFile("$gamestate_newround_log"); 02787 } 02788 //con << ePlayerNetID::Ranking(); 02789 02790 se_PauseGameTimer(false); 02791 se_SyncGameTimer(); 02792 sr_con.fullscreen=false; 02793 sr_con.autoDisplayAtNewline=false; 02794 02795 break; 02796 case GS_PLAY: 02797 sr_con.autoDisplayAtNewline=false; 02798 #ifdef DEDICATED 02799 { 02800 // safe current players in a file 02801 cp(); 02802 02803 if ( sg_NumUsers() <= 0 ) 02804 goon = 0; 02805 02806 Analysis(0); 02807 02808 { 02809 std::ifstream s; 02810 02811 // load contents of everytime.cfg for real 02812 if ( tDirectories::Config().Open(s, "everytime.cfg" ) ) 02813 tConfItemBase::LoadAll(s); 02814 02815 s.close(); 02816 02817 if ( tDirectories::Var().Open(s, "everytime.cfg" ) ) 02818 tConfItemBase::LoadAll(s); 02819 02820 // load contents of everytime.cfg from playback 02821 tConfItemBase::LoadPlayback(); 02822 } 02823 } 02824 #endif 02825 // pings should not count as much in the between-round phase 02826 nPingAverager::SetWeight(1E-20); 02827 02828 se_UserShowScores(false); 02829 02830 // rotate, if rotate is once per round 02831 if (rotationtype == 1) 02832 rotate(); 02833 gRotation::HandleNewRound(); 02834 02835 //con.autoDisplayAtNewline=true; 02836 sr_con.fullscreen=true; 02837 SetState(GS_DELETE_OBJECTS,GS_DELETE_GRID); 02838 break; 02839 case GS_DELETE_OBJECTS: 02840 02841 winDeathZone_ = NULL; 02842 02843 rViewport::Update(MAX_PLAYERS); 02844 if ( synced_ && sn_GetNetState() != nSERVER ) 02845 ePlayerNetID::Update(); 02846 02847 // sr_con.autoDisplayAtNewline=true; 02848 02849 //gStatistics - save all 02850 02851 con << tOutput("$gamestate_deleting_objects"); 02852 exit_game_objects(grid); 02853 st_ToDo( sg_VoteMenuIdle ); 02854 nNetObject::ClearAllDeleted(); 02855 SetState(GS_DELETE_GRID,GS_TRANSFER_SETTINGS); 02856 break; 02857 default: 02858 break; 02859 } 02860 02861 // now would be a good time to tend for pending tasks 02862 nAuthentication::OnBreak(); 02863 02864 if (sn_GetNetState()==nSERVER){ 02865 NetSyncIdle(); 02866 RequestSync(); 02867 NetSyncIdle(); 02868 } 02869 else if (sn_GetNetState()==nCLIENT){ // inform the server of our progress 02870 NetSyncIdle(); 02871 nMessage *m=new nMessage(client_gs); 02872 m->Write(state); 02873 m->Send(0); 02874 #ifdef DEBUG 02875 // con << "sending gamestate " << state << '\n'; 02876 #endif 02877 NetSyncIdle(); 02878 } 02879 }
void gGame::SetState | ( | unsigned short | act, | |
unsigned short | next | |||
) | [virtual] |
Definition at line 2513 of file gGame.cpp.
References goon, nCLIENT, NetSyncIdle(), nSERVER, nNetObject::RequestSync(), sn_GetNetState(), state, stateNext, and SyncState().
Referenced by Analysis(), and StateUpdate().
02514 { 02515 state=act; 02516 #ifdef DEBUG 02517 //con << "Entering gamestate " << state 02518 //<< ", next state: " << next << '\n'; 02519 #endif 02520 02521 if (sn_GetNetState()==nSERVER){ 02522 RequestSync(); 02523 NetSyncIdle(); 02524 SyncState(state); 02525 } 02526 02527 if (stateNext!=next){ 02528 if (sn_GetNetState()!=nCLIENT || goon==false){ 02529 02530 stateNext=next; 02531 02532 if (sn_GetNetState()==nSERVER){ 02533 RequestSync(); 02534 NetSyncIdle(); 02535 } 02536 } 02537 }
virtual short gGame::GetState | ( | ) | [inline, virtual] |
Definition at line 104 of file gGame.h.
References state.
Referenced by ingame_menu_cleanup().
00104 {return state;}
void gGame::SyncState | ( | unsigned short | state | ) |
Definition at line 2471 of file gGame.cpp.
References nConnectionInfo::ackPending, con, goon, MAXCLIENTS, NetSyncIdle(), nSERVER, REAL, sg_AbeforeB(), sg_Timeout, sn_Connections, sn_GetNetState(), sn_Sync(), and tSysTimeFloat().
Referenced by SetState().
02472 { 02473 if (sn_GetNetState()==nSERVER){ 02474 02475 bool firsttime=true; 02476 bool goon=true; 02477 REAL timeout=tSysTimeFloat()+sg_Timeout*.1; 02478 02479 sn_Sync(sg_Timeout*.1,true); 02480 NetSyncIdle(); 02481 02482 while (goon && tSysTimeFloat()<timeout){ 02483 /* 02484 if (sg_currentGame) 02485 sg_currentGame->RequestSync(); 02486 */ 02487 02488 sn_Sync(sg_Timeout*.1,true); 02489 NetSyncIdle(); 02490 02491 goon=false; 02492 for (int i=MAXCLIENTS;i>0;i--) 02493 if ( sn_Connections[i].socket ) 02494 { 02495 int clientState = client_gamestate[i]; 02496 if ( sg_AbeforeB( clientState, state ) ) 02497 { 02498 goon=true; 02499 } 02500 } 02501 if (goon && firsttime){ 02502 firsttime=false; 02503 #ifdef DEBUG 02504 con << "Waiting for users to enter gamestate " << state << '\n'; 02505 if (sn_Connections[1].ackPending>2) 02506 con << "Ack_pending=" << sn_Connections[1].ackPending << ".\n"; 02507 #endif 02508 } 02509 } 02510 }
void gGame::Timestep | ( | REAL | time, | |
bool | cam = false | |||
) | [virtual] |
Definition at line 2946 of file gGame.cpp.
References tMemManBase::Check(), dt, lastTimeTimestep, REAL, and s_Timestep().
Referenced by GameLoop().
02947 { 02948 #ifdef DEBUG 02949 tMemManBase::Check(); 02950 #endif 02951 02952 #ifdef RESPAWN_HACK 02953 sg_Respawn(time,grid,Arena); 02954 #endif 02955 02956 // chop timestep into small, managable bits 02957 REAL dt = time - lastTimeTimestep; 02958 if ( dt < 0 ) 02959 return; 02960 REAL lt = lastTimeTimestep; 02961 02962 // determine the number of bits 02963 int number_of_steps=int(fabs((dt)/sg_timestepMax)); 02964 if (number_of_steps<1) 02965 number_of_steps=1; 02966 if ( number_of_steps > sg_timestepMaxCount ) 02967 { 02968 number_of_steps = sg_timestepMaxCount; 02969 } 02970 02971 // chop 02972 for (int i=1;i<=number_of_steps;i++) 02973 { 02974 REAL stepTime = lt + i * dt/number_of_steps; 02975 s_Timestep(grid, stepTime, cam); 02976 }
void gGame::Analysis | ( | REAL | time | ) | [virtual] |
Definition at line 2994 of file gGame.cpp.
References absolute_winner, gStatList::add(), gCycleMovement::Alive(), eTeam::Alive(), gGameSettings::AutoAI(), tColoredString::ColorString(), eGameObject::DeathTime(), DEDICATED, dt, ePlayerNetID::FilterName(), gGameSettings::finishType, eGrid::GameObjects(), gGameSettings::gameType, ePlayerNetID::GetName(), gArena::GetRandomPos(), gFINISH_EXPRESS, gFINISH_IMMEDIATELY, gFINISH_SPEEDUP, gFREESTYLE, goon, gStatList::greater(), Grid(), GS_DELETE_OBJECTS, GS_PLAY, gStats, gRotation::HandleNewMatch(), gStatistics::highscores, ePlayerNetID::IsActive(), ePlayerNetID::IsHuman(), gCycle::Kill(), GrowingArrayBase::Len(), gGameSettings::limitRounds, gGameSettings::limitScore, gGameSettings::limitTime, m_Mixer, MATCH_WINNER, nCLIENT, eTeam::NumAIPlayers(), eTeam::NumHumanPlayers(), eTeam::NumPlayers(), ePlayerNetID::Object(), eGameObject::OnRoundEnd(), eTeam::Player(), players, eSoundMixer::PushButton(), ePlayerNetID::Ranking(), eTeam::Ranking(), REAL, rotate(), rotationtype, ROUND_WINNER, rounds, gGameSettings::scoreWin, se_mainGameTimer, se_PlayerNetIDs, se_SaveToLadderLog(), se_SaveToScoreFile(), se_sendEventNotification(), SetState(), tOutput::SetTemplateParameter(), sg_CreateWinDeathZone(), sg_EnemyExists(), sg_GetCurrentTime(), sg_NumUsers(), sg_singlePlayer, sn_CenterMessage(), sn_ConsoleOut(), sn_GetNetState(), eTeam::SortByScore(), ePlayerNetID::SortByScore(), eTimer::speed, StartNewMatch(), StartNewMatchNow(), startTime, nVersionFeature::Supported(), eTeam::teams, tSysTimeFloat(), warning, winDeathZone_, winner, gGameSettings::winZoneMinLastDeath, gGameSettings::winZoneMinRoundTime, wishWinner, wishWinnerMessage, gStatistics::won_matches, and gStatistics::won_rounds.
Referenced by GameLoop(), and StateUpdate().
02995 { 02996 if ( nCLIENT == sn_GetNetState() ) 02997 return; 02998 02999 static REAL wintimer=0; 03000 03001 // only do this expensive stuff once a second 03002 { 03003 static double nextTime = -1; 03004 if ( tSysTimeFloat() > nextTime || time < -10 ) 03005 { 03006 nextTime = tSysTimeFloat() + 1.0; 03007 } 03008 else 03009 { 03010 return; 03011 } 03012 } 03013 03014 // send timeout warnings 03015 03016 03017 if (tSysTimeFloat()-startTime>10){ 03018 if ((startTime+sg_currentSettings->limitTime*60)-tSysTimeFloat()<10 && warning<6){ 03019 tOutput o("$gamestate_tensecond_warn"); 03020 sn_CenterMessage(o); 03021 sn_ConsoleOut(o); 03022 warning=6; 03023 } 03024 03025 03026 if ((startTime+sg_currentSettings->limitTime*60)-tSysTimeFloat()<30 && warning<5){ 03027 tOutput o("$gamestate_30seconds_warn"); 03028 sn_CenterMessage(o); 03029 sn_ConsoleOut(o); 03030 warning=5; 03031 } 03032 03033 if ((startTime+sg_currentSettings->limitTime*60)-tSysTimeFloat()<60 && warning<4){ 03034 tOutput o("$gamestate_minute_warn"); 03035 sn_CenterMessage(o); 03036 sn_ConsoleOut(o); 03037 warning=4; 03038 } 03039 03040 if ((startTime+sg_currentSettings->limitTime*60)-tSysTimeFloat()<2*60 && warning<3){ 03041 tOutput o("$gamestate_2minutes_warn"); 03042 sn_ConsoleOut(o); 03043 warning=3; 03044 } 03045 03046 if ((startTime+sg_currentSettings->limitTime*60)-tSysTimeFloat()<5*60 && warning<2){ 03047 tOutput o("$gamestate_5minutes_warn"); 03048 sn_ConsoleOut(o); 03049 warning=2; 03050 } 03051 03052 if ((startTime+sg_currentSettings->limitTime*60)-tSysTimeFloat()<10*60 && warning<1){ 03053 tOutput o("$gamestate_10minutes_warn"); 03054 sn_ConsoleOut(o); 03055 warning=1; 03056 } 03057 } 03058 03059 // count active players 03060 int active = 0; 03061 int i; 03062 for (i=se_PlayerNetIDs.Len()-1;i>=0;i--){ 03063 ePlayerNetID *pni=se_PlayerNetIDs(i); 03064 if (pni->IsActive()) 03065 active ++; 03066 } 03067 03068 // count other statistics 03069 int alive_and_not_disconnected = 0; 03070 int alive=0; 03071 int ai_alive=0; 03072 int human_teams=0; 03073 int teams_alive=0; 03074 int last_alive=-1; 03075 int last_team_alive=-1; 03076 int last_alive_and_not_disconnected=-1; 03077 int humans = 0; 03078 int active_humans = 0; 03079 int ais = 0; 03080 REAL deathTime=0; 03081 03082 bool notyetloggedin = true; // are all current users not yet logged in? 03083 03084 for (i=eTeam::teams.Len()-1;i>=0;i--){ 03085 eTeam *t = eTeam::teams(i); 03086 03087 humans += t->NumHumanPlayers(); 03088 ais += t->NumAIPlayers(); 03089 03090 if ( t->Alive() ) 03091 { 03092 teams_alive++; 03093 last_team_alive = i; 03094 } 03095 03096 if ( t->NumHumanPlayers() > 0 ) 03097 { // human players 03098 human_teams++; 03099 03100 for (int j=t->NumPlayers()-1; j>=0; --j) 03101 { 03102 ePlayerNetID* p = t->Player(j); 03103 if (p->IsActive()) 03104 active_humans++; 03105 03106 gCycle *g=dynamic_cast<gCycle *>(p->Object()); 03107 if (g){ 03108 notyetloggedin = false; 03109 03110 if (g->Alive()) 03111 { 03112 03113 if ( p->IsHuman() ) 03114 { 03115 alive++; 03116 if (p->IsActive()) 03117 { 03118 last_alive_and_not_disconnected=i; 03119 alive_and_not_disconnected++; 03120 } 03121 } 03122 else 03123 ai_alive++; 03124 03125 last_alive=i; 03126 } 03127 else 03128 { 03129 REAL dt=g->DeathTime(); 03130 if (dt>deathTime) 03131 deathTime=dt; 03132 } 03133 } 03134 #ifdef KRAWALL_SERVER 03135 else if (p->IsAuthenticated()) 03136 notyetloggedin = false; 03137 #endif 03138 } 03139 } 03140 else 03141 { 03142 for (int j=t->NumPlayers()-1; j>=0; --j) 03143 { 03144 ePlayerNetID* p = t->Player(j); 03145 03146 gCycle *g=dynamic_cast<gCycle *>(p->Object()); 03147 if (g){ 03148 if (g->Alive()) 03149 { 03150 ai_alive++; 03151 } 03152 } 03153 } 03154 } 03155 } 03156 03157 #ifdef DEDICATED 03158 //activeHumans 03159 if (sg_NumUsers() <= 0) 03160 goon = false; 03161 #endif 03162 03163 03164 if (last_alive_and_not_disconnected >= 0) 03165 last_alive = last_alive_and_not_disconnected; 03166 03167 // kill all disconnected players if they are the only reason the round goes on: 03168 if ( alive_and_not_disconnected <= 1 && alive > alive_and_not_disconnected ) 03169 { 03170 for (int i=se_PlayerNetIDs.Len()-1;i>=0;i--) 03171 { 03172 gCycle *g=dynamic_cast<gCycle *>(se_PlayerNetIDs(i)->Object()); 03173 if (g && !se_PlayerNetIDs(i)->IsActive()) 03174 { 03175 g->Kill(); 03176 } 03177 03178 // alive = alive_and_not_disconnected; 03179 } 03180 } 03181 03182 // keep the game running when there are only login processes running 03183 if (notyetloggedin && humans > 0) 03184 alive++; 03185 03186 03187 static int all_alive_last=0; 03188 { 03189 int all_alive = ai_alive+alive; 03190 if (all_alive != all_alive_last) 03191 { 03192 all_alive_last = ai_alive+alive; 03193 lastdeath = time; 03194 } 03195 } 03196 03197 static nVersionFeature winZone(2); 03198 03199 /* 03200 ***************** ===================== ******************** 03201 HACK 03202 THIS HAS SIMPLY BEEN DEACTIVATED. 03203 IT SHOULD BE REACTIVATED WITH THE NEW ZONE CODE 03204 ***************** ===================== ******************** 03205 */ 03206 #ifndef ENABLE_ZONESV2 03207 // activate instant win zone 03208 if ( winZone.Supported() && !bool( winDeathZone_ ) && winner == 0 && time - lastdeath > sg_currentSettings->winZoneMinLastDeath && time > sg_currentSettings->winZoneMinRoundTime ) 03209 { 03210 winDeathZone_ = sg_CreateWinDeathZone( grid, Arena.GetRandomPos( sg_winZoneRandomness ) ); 03211 } 03212 #endif 03213 03214 bool holdBackNextRound = false; 03215 03216 // start a new match if the number of teams changes from 1 to 2 or from 2 to 1 03217 { 03218 static int lastTeams = 0; // the number of teams when this was last called. 03219 03220 // check for relevent status change, form 0 to 1 or 1 to 2 or 2 to 1 or 1 to 0 human teams. 03221 int humanTeamsClamp = human_teams; 03222 if ( humanTeamsClamp > 2 ) 03223 humanTeamsClamp = 2; 03224 if ( humanTeamsClamp != lastTeams ) 03225 { 03226 StartNewMatch(); 03227 // if this is the beginning of a round, just start the match now 03228 if ( time < -100 ) 03229 { 03230 StartNewMatchNow(); 03231 } 03232 else 03233 { 03234 // start a new round and match. 03235 winner=-1; 03236 wintimer=time; 03237 } 03238 } 03239 03240 lastTeams=humanTeamsClamp; // update last team count 03241 } 03242 03243 // who is alive? 03244 if ( time-lastdeath < 1.0f ) 03245 { 03246 holdBackNextRound = true; 03247 } 03248 else if (winner==0 && absolute_winner==0 ){ 03249 if ( teams_alive <= 1 ) 03250 { 03251 if ( sg_currentSettings->gameType!=gFREESTYLE ) 03252 { 03253 if ( eTeam::teams.Len()>1 && teams_alive<=1 ){ 03254 winner=last_team_alive+1; 03255 wintimer=time; 03256 } 03257 } 03258 else 03259 { 03260 if ( teams_alive < 1 ) 03261 winner=-1; 03262 wintimer=time; 03263 } 03264 } 03265 03266 const char* survivor="$player_win_survivor"; 03267 const char* messagetype = survivor; 03268 03269 if ( wishWinner ) 03270 { 03271 wintimer=time; 03272 winner = wishWinner; 03273 wishWinner = 0; 03274 messagetype = wishWinnerMessage; 03275 } 03276 03277 if (winner <= 0 && alive <= 0 && ai_alive <= 0 && teams_alive <= 0){ 03278 if ( se_mainGameTimer ) 03279 se_mainGameTimer->speed = 1; 03280 03281 // emergency 03282 winner=-1; 03283 wintimer=time; 03284 } 03285 else 03286 if (winner){ 03287 if ( se_mainGameTimer ) 03288 se_mainGameTimer->speed = 1; 03289 lastdeath = time; 03290 03291 tOutput message; 03292 message << "$gamestate_winner_winner"; 03293 03294 if ( last_team_alive >= 0 ) 03295 sg_currentSettings->AutoAI( eTeam::teams( last_team_alive )->NumHumanPlayers() > 0 ); 03296 03297 03298 if ( ( sg_currentSettings->scoreWin != 0 || sg_currentSettings->gameType != gFREESTYLE ) && winner > 0 ) 03299 { 03300 // check if the win was legitimate: at least one enemy team needs to be online 03301 if ( sg_EnemyExists( winner-1 ) || sg_currentSettings->gameType==gFREESTYLE ) 03302 { 03303 #ifdef KRAWALL_SERVER_LEAGUE 03304 // send the result to the master server 03305 if (!dynamic_cast<gAIPlayer*>(eTeam::teams(winner-1))) 03306 { 03307 tArray<tString> players; 03308 for (int i = eTeam::teams.Len()-1; i>=0; i--) 03309 if (i != winner-1 && 03310 eTeam::teams(i)->Alive() && 03311 eTeam::teams(i)->IsHuman() ) 03312 { 03313 players[players.Len()] = eTeam::teams(i)->Name(); 03314 } 03315 03316 players[players.Len()] = eTeam::teams(winner-1)->Name(); 03317 if (players.Len() > 1) 03318 nKrawall::ServerRoundEnd(&players(0), players.Len()); 03319 } 03320 #endif 03321 03322 // scoring 03323 eTeam::teams[winner-1]->AddScore 03324 (sg_currentSettings->scoreWin,messagetype, tOutput()); 03325 if (!sg_singlePlayer && eTeam::teams(winner-1)->NumHumanPlayers() >= 1 && gStats && 03326 eTeam::teams(winner-1)->NumPlayers() >= 1 && eTeam::teams[winner-1]->NumHumanPlayers() > 0) 03327 { 03328 //gStatistics - won rounds add 03329 for (int i = eTeam::teams[winner-1]->NumPlayers() - 1; i>=0; --i) //count down in case of mid count changes? 03330 { 03331 if (eTeam::teams[winner-1]->Player(i)->IsHuman()) 03332 { 03333 gStats->won_rounds->add(eTeam::teams[winner-1]->Player(i)->GetName(), 1); 03334 } 03335 } 03336 //gStatistics - ladder add 03337 } 03338 03339 // print winning message 03340 tOutput message; 03341 message << "$gamestate_winner_winner"; 03342 message << eTeam::teams[winner-1]->Name(); 03343 03344 m_Mixer->PushButton(ROUND_WINNER); 03345 03346 sn_CenterMessage(message); 03347 message << '\n'; 03348 se_SaveToScoreFile(message); 03349 03350 tString ladderLog; 03351 ladderLog << "ROUND_WINNER " << ePlayerNetID::FilterName( eTeam::teams[winner-1]->Name() ) << "\n"; 03352 se_SaveToLadderLog( ladderLog ); 03353 tString notificationMessage( ePlayerNetID::FilterName( eTeam::teams[winner-1]->Name() ) ); 03354 notificationMessage << " has won the round"; 03355 se_sendEventNotification(tString("Round winner"), notificationMessage); 03356 } 03357 } 03358 //gStatistics - highscore check 03359 if (sg_singlePlayer && gStats && se_PlayerNetIDs.Len() > 0 && se_PlayerNetIDs(0)->IsHuman()) 03360 { 03361 gStats->highscores->greater(se_PlayerNetIDs(0)->GetName(), se_PlayerNetIDs(0)->Score()); 03362 } 03363 winner = -1; 03364 } 03365 } 03366 03367 int winnerExtraRound = ( winner != 0 || alive == 0 ) ? 1 : 0; 03368 03369 03370 // do round end stuff one second after a winner was declared 03371 if ( winner && !roundOver && time-lastdeath >= 2.0f ) 03372 { 03373 roundOver = true; 03374 03375 const tList<eGameObject>& gameObjects = Grid()->GameObjects(); 03376 for (int i=gameObjects.Len()-1;i>=0;i--) 03377 { 03378 eGameObject * e = gameObjects(i); 03379 if ( e ) 03380 { 03381 e->OnRoundEnd(); 03382 } 03383 } 03384 } 03385 03386 // analyze the ranking list 03387 if ( time-lastdeath < 2.0f ) 03388 { 03389 holdBackNextRound = true; 03390 } 03391 else if (absolute_winner==0 && 03392 sn_GetNetState()!=nCLIENT && se_PlayerNetIDs.Len()){ 03393 ePlayerNetID::SortByScore(); 03394 eTeam::SortByScore(); 03395 if ( eTeam::teams.Len() > 0 ) 03396 if (eTeam::teams.Len() <= 1 03397 || ( eTeam::teams(0)->Score() > eTeam::teams(1)->Score() && sg_EnemyExists(0))){ 03398 03399 // only then we can have a true winner: 03400 if (eTeam::teams(0)->Score() >= sg_currentSettings->limitScore || // the score limit must be hit 03401 rounds + winnerExtraRound >= sg_currentSettings->limitRounds || // or the round limit 03402 tSysTimeFloat()>=startTime+sg_currentSettings->limitTime*60 || // or the time limit 03403 (active <= 1 && eTeam::teams.Len() > 1) // or all but one players must have disconnected. 03404 ) 03405 { 03406 bool declareChampion = true; 03407 if ( winner!=0 && wintimer > time - ( sg_currentSettings->finishType==gFINISH_EXPRESS ? 2.0f : 4.0 ) ) 03408 { 03409 declareChampion = false; 03410 holdBackNextRound= true; 03411 } 03412 03413 if ( declareChampion ) 03414 { 03415 lastdeath = time + ( sg_currentSettings->finishType==gFINISH_EXPRESS ? 2.0f : 6.0f ); 03416 03417 { 03418 tOutput message; 03419 message.SetTemplateParameter(1, eTeam::teams[0]->Name() ); 03420 message << "$gamestate_champ_center"; 03421 sn_CenterMessage(message); 03422 03423 m_Mixer->PushButton(MATCH_WINNER); 03424 } 03425 03426 tOutput message; 03427 tColoredString name; 03428 name << eTeam::teams[0]->Name(); 03429 name << tColoredString::ColorString(1,1,1); 03430 03431 tString ladderLog; 03432 ladderLog << "MATCH_WINNER " << ePlayerNetID::FilterName( eTeam::teams[0]->Name() ) << "\n"; 03433 se_SaveToLadderLog( ladderLog ); 03434 tString notificationMessage( ePlayerNetID::FilterName( eTeam::teams[0]->Name() ) ); 03435 notificationMessage << " has won the match"; 03436 se_sendEventNotification(tString("Match winner"), notificationMessage); 03437 03438 03439 message.SetTemplateParameter(1, name); 03440 message << "$gamestate_champ_console"; 03441 03442 if (eTeam::teams(0)->Score() >=sg_currentSettings->limitScore) 03443 { 03444 message.SetTemplateParameter(1, eTeam::teams(0)->Score()); 03445 message.SetTemplateParameter(2, sg_currentSettings->limitScore); 03446 message << "$gamestate_champ_scorehit"; 03447 } 03448 else if ( tSysTimeFloat()>=startTime+sg_currentSettings->limitTime*60) 03449 { 03450 message.SetTemplateParameter(1, sg_currentSettings->limitTime); 03451 message << "$gamestate_champ_timehit"; 03452 } 03453 else 03454 { 03455 message.SetTemplateParameter(1, rounds + 1); 03456 message << "$gamestate_champ_default"; 03457 } 03458 03459 se_SaveToScoreFile(message); 03460 se_SaveToScoreFile("$gamestate_champ_finalscores"); 03461 se_SaveToScoreFile(eTeam::Ranking( -1, false )); 03462 se_SaveToScoreFile(ePlayerNetID::Ranking( -1, false )); 03463 se_SaveToScoreFile(sg_GetCurrentTime( "Time: %Y/%m/%d %H:%M:%S\n" )); 03464 se_SaveToScoreFile("\n\n"); 03465 03466 eTeam* winningTeam = eTeam::teams(0); 03467 if (!sg_singlePlayer && winningTeam->NumHumanPlayers() > 0 && winningTeam->NumHumanPlayers() > 0 && gStats) 03468 { 03469 //gStatistics - won matches add 03470 for (int i = winningTeam->NumPlayers() - 1; i>=0; --i) //count down in case of mid count changes? 03471 { 03472 if (winningTeam->Player(i)->IsHuman()) 03473 { 03474 gStats->won_matches->add(winningTeam->Player(i)->GetName(), 1); 03475 } 03476 } 03477 } 03478 03479 sn_ConsoleOut(message); 03480 03481 m_Mixer->PushButton(MATCH_WINNER); 03482 03483 wintimer=time; 03484 absolute_winner=1; 03485 03486 if ( se_mainGameTimer ) 03487 se_mainGameTimer->speed = 1; 03488 03489 //check for map rotation, new match... 03490 if (rotationtype == 2) 03491 rotate(); 03492 03493 gRotation::HandleNewMatch(); 03494 03495 StartNewMatch(); 03496 } 03497 } 03498 } 03499 } 03500 03501 03502 // time to wait after last death til we start a new round 03503 REAL fintime=6; 03504 03505 if (sg_currentSettings->finishType==gFINISH_EXPRESS) 03506 fintime=2.5; 03507 03508 if (( ( winner || absolute_winner ) && wintimer+fintime < time) 03509 || (((alive==0 && eTeam::teams.Len()>= 03510 #ifndef DEDICATED 03511 1 03512 #else 03513 0 03514 #endif 03515 )) && time-lastdeath >fintime-2 03516 #ifndef DEDICATED 03517 && humans > 0 03518 #endif 03519 )){ 03520 #ifdef DEBUG 03521 //con << "winner=" << winner << ' '; 03522 //con << "wintimer=" << wintimer << ' '; 03523 //con << "time=" << time << ' '; 03524 //con << "dt=" << deathTime << '\n'; 03525 #endif 03526 if (!holdBackNextRound && 03527 ( 03528 ( sg_currentSettings->finishType==gFINISH_IMMEDIATELY || 03529 sg_currentSettings->finishType==gFINISH_EXPRESS || 03530 absolute_winner || ( teams_alive <= 1 && time-lastdeath>4.0f ) ) || 03531 ( winner && time - wintimer> 4.0f ) 03532 ) 03533 ) 03534 { 03535 rounds++; 03536 SetState(GS_PLAY,GS_DELETE_OBJECTS); 03537 } 03538 03539 if ( !winner && !absolute_winner && sg_currentSettings->finishType==gFINISH_SPEEDUP && se_mainGameTimer) 03540 { 03541 se_mainGameTimer->speed*=1.01; 03542 if (se_mainGameTimer->speed>16) 03543 se_mainGameTimer->speed=16; 03544 } 03545
bool gGame::GameLoop | ( | bool | input = true |
) | [virtual] |
Definition at line 3643 of file gGame.cpp.
References ai, Analysis(), ANNOUNCER_1, ANNOUNCER_2, ANNOUNCER_3, ANNOUNCER_GO, cd, tConsole::CenterDisplay(), eGrid::Check(), rSysDep::ClearGL(), con, tRandomizer::Get(), tRandomizer::GetInstance(), goon, GS_CREATE_GRID, GS_DELETE_OBJECTS, GS_PLAY, ingame_menu(), eTimer::IsSynced(), lastTime, lastTime_gameloop, GrowingArrayBase::Len(), m_Mixer, MAX_PLAYERS, nCLIENT, nSERVER, nSTANDALONE, ePlayerNetID::Object(), ePlayer::PlayerConfig(), PREPARE_TIME, eSoundMixer::PushButton(), REAL, Render(), eCamera::s_Timestep(), se_GameTime(), se_mainGameTimer, se_PauseGameTimer(), se_PlayerNetIDs, se_SaveToLadderLog(), se_SyncGameTimer(), ePlayer::SendAuthNames(), nPingAverager::SetWeight(), sg_gameTimeInterval, sg_lastChatBreakTime, sg_Receive(), eGrid::SimplifyAll(), sn_GetNetState(), sn_SendPlanned(), sr_glOut, st_Breakpoint(), st_ToDo(), state, stateNext, su_GetSDLInput(), su_HandleDelayedEvents(), su_HandleEvent(), su_InputSync(), rSysDep::SwapGL(), nNetObject::SyncAll(), synced_, tDelay(), gAIPlayer::Timestep(), Timestep(), ePlayerNetID::Update(), and ePlayerNetID::WaitToLeaveChat().
Referenced by GameLoop().
03645 { 03646 nNetState netstate = sn_GetNetState(); 03647 03648 #ifdef DEBUG 03649 grid->Check(); 03650 if (simplify_grid) 03651 #endif 03652 grid->SimplifyAll(10); 03653 03654 #ifdef DEBUG 03655 grid->Check(); 03656 #endif 03657 03658 //if (std::cin.good() && !std::cin.underflow()) 03659 //tConfItemBase::LoadAll(std::cin); 03660 // network syncing 03661 REAL gtime=0; 03662 REAL time=0; 03663 se_SyncGameTimer(); 03664 if (state==GS_PLAY){ 03665 if ( netstate != sn_GetNetState() ) 03666 { 03667 return false; 03668 } 03669 gtime=se_GameTime(); 03670 time=gtime; 03671 03672 if (sn_GetNetState()==nSTANDALONE && sg_IngameMenu) 03673 se_PauseGameTimer(true); 03674 03675 static int lastcountdown=0; 03676 int cd=int(floor(-time))+1; 03677 if (cd>=0 && cd<PREPARE_TIME && cd!=lastcountdown && se_mainGameTimer && se_mainGameTimer->IsSynced() ){ 03678 lastcountdown=cd; 03679 tString s; 03680 s << cd; 03681 03682 switch (cd) { 03683 case 3: 03684 m_Mixer->PushButton(ANNOUNCER_3); 03685 break; 03686 case 2: 03687 m_Mixer->PushButton(ANNOUNCER_2); 03688 break; 03689 case 1: 03690 m_Mixer->PushButton(ANNOUNCER_1); 03691 break; 03692 case 0: 03693 m_Mixer->PushButton(ANNOUNCER_GO); 03694 break; 03695 } 03696 con.CenterDisplay(s,0); 03697 } 03698 } 03699 //con << sg_netPlayerWalls.Len() << '\n'; 03700 03701 #ifndef DEDICATED 03702 if (input){ 03703 su_HandleDelayedEvents(); 03704 03705 SDL_Event tEvent; 03706 03707 uInputProcessGuard inputProcessGuard; 03708 while (su_GetSDLInput(tEvent,time)){ 03709 if (time>gtime) time=gtime; 03710 if (time>lastTime_gameloop){ 03711 Timestep(time); 03712 lastTime_gameloop=time; 03713 } 03714 03715 03716 if (!su_HandleEvent(tEvent, false)) 03717 switch (tEvent.type){ 03718 case SDL_MOUSEBUTTONDOWN: 03719 break; 03720 case SDL_KEYDOWN: 03721 switch (tEvent.key.keysym.sym){ 03722 03723 case(27): 03724 // case('q'): 03725 st_ToDo(&ingame_menu); 03726 break; 03727 #ifdef DEBUG 03728 case('d'): 03729 debug_grid=!debug_grid; 03730 break; 03731 03732 case('a'): 03733 simplify_grid=!simplify_grid; 03734 break; 03735 03736 case('l'): 03737 sr_glOut=!sr_glOut; 03738 break; 03739 03740 case('b'): 03741 st_Breakpoint(); 03742 break; 03743 03744 case('t'): 03745 think=!think; 03746 break; 03747 /* #ifndef WIN32 03748 case('f'): 03749 fullscreen=(!fullscreen); 03750 con << fullscreen << "x!\n"; 03751 XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW); 03752 break; 03753 #endif */ 03754 #endif 03755 03756 default: 03757 break; 03758 } 03759 break; 03760 03761 default: 03762 break; 03763 } 03764 } 03765 03766 su_InputSync(); 03767 } 03768 #endif 03769 03770 if ( netstate != sn_GetNetState() ) 03771 { 03772 return false; 03773 } 03774 03775 // do basic network receiving and sending. This pushes out all input the player makes as fast as possible. 03776 sg_Receive(); 03777 sn_SendPlanned(); 03778 03779 bool synced = se_mainGameTimer && ( se_mainGameTimer->IsSynced() || ( stateNext >= GS_DELETE_OBJECTS || stateNext <= GS_CREATE_GRID ) ); 03780 03781 if (!synced) 03782 { 03783 // see if there is a game object owned by this client, if so, declare emergency sync 03784 for (int pi = MAX_PLAYERS-1; pi >= 0; --pi ) 03785 { 03786 ePlayer * p = ePlayer::PlayerConfig(pi); 03787 if ( !p ) 03788 break; 03789 ePlayerNetID * np = p->netPlayer; 03790 if ( !np ) 03791 break; 03792 if ( np->Object() ) 03793 { 03794 synced = true; 03795 break; 03796 } 03797 } 03798 } 03799 else if ( !synced_ ) 03800 { 03801 // synced finally. Send our player info over so we can join the game. 03802 ePlayerNetID::Update(); 03803 03804 // and trigger the scheduled auto-logons. 03805 ePlayer::SendAuthNames(); 03806 03807 synced_ = true; 03808 } 03809 03810 static float lastTime = -1; 03811 03812 if (sg_gameTimeInterval >= 0 && (gtime >= lastTime + sg_gameTimeInterval || (gtime < lastTime && gtime >= 0))) { 03813 tOutput out; 03814 out << "GAME_TIME " << gtime << '\n'; 03815 se_SaveToLadderLog(out); 03816 lastTime = gtime; 03817 } 03818 03819 if (state==GS_PLAY){ 03820 if (gtime<0 && gtime>-PREPARE_TIME+.3) 03821 eCamera::s_Timestep(grid, gtime); 03822 else{ 03823 // keep ping weight high while playing, that gives the best meassurements 03824 nPingAverager::SetWeight(1); 03825 03826 if (gtime>=lastTime_gameloop){ 03827 03828 #ifdef CONNECTION_STRESS 03829 if ( sg_ConnectionStress ) 03830 { 03831 tRandomizer & randomizer = tRandomizer::GetInstance(); 03832 int random = randomizer.Get( 1000 ); 03833 if ( random == 0 ) 03834 { 03835 sg_RequestedDisconnection = true; 03836 // sn_SetNetState( nSTANDALONE ); 03837 goon = false; 03838 } 03839 } 03840 #endif 03841 03842 03843 Timestep(gtime,true); 03844 lastTime_gameloop=gtime; 03845 } 03846 lastTime_gameloop=gtime; 03847 } 03848 // else if (lastTime_gameloop>gtime+10) 03849 // lastTime_gameloop=gtime; 03850 03851 03852 03853 if (sn_GetNetState()!=nCLIENT) 03854 { 03855 // simulate IAs 03856 for (int i=se_PlayerNetIDs.Len()-1;i>=0;i--) 03857 { 03858 gAIPlayer *ai = dynamic_cast<gAIPlayer*>(se_PlayerNetIDs(i)); 03859 if (ai && think) 03860 ai->Timestep(gtime); 03861 } 03862 03863 Analysis(gtime); 03864 03865 // wait for chatting players 03866 if ( sn_GetNetState()==nSERVER && gtime < sg_lastChatBreakTime + 1 ) 03867 se_PauseGameTimer( gtime < sg_lastChatBreakTime && ePlayerNetID::WaitToLeaveChat() ); 03868 } 03869 03870 // send game object updates 03871 nNetObject::SyncAll(); 03872 sn_SendPlanned(); 03873 03874 if ( gtime<=-PREPARE_TIME+.5 || !goon || !synced ) 03875 { 03876 #ifndef DEDICATED 03877 if (input) 03878 { 03879 if ( !synced ) 03880 { 03881 con.CenterDisplay(tString(tOutput("$network_login_sync")),0); 03882 } 03883 03884 if ( sr_glOut ) 03885 rSysDep::ClearGL(); 03886 } 03887 03888 if ( input ) 03889 rSysDep::SwapGL(); 03890 #endif 03891 } 03892 else 03893 Render(grid, gtime, input); 03894 03895 if ( netstate != sn_GetNetState() ) 03896 { 03897 return false; 03898 } 03899 03900 return goon; 03901 } 03902 else{ 03903 // between rounds, assume we're synced 03904 //if ( !synced_ && sn_GetNetState() != nSERVER ) 03905 // ePlayerNetID::Update(); 03906 // synced_ = true; 03907 03908 #ifndef DEDICATED 03909 // send game object updates 03910 nNetObject::SyncAll(); 03911 sn_SendPlanned(); 03912 03913 if (input) 03914 { 03915 if (sr_glOut) 03916 rSysDep::ClearGL(); 03917 rSysDep::SwapGL(); 03918 } 03919 #endif 03920 tDelay( 10000 ); 03921 return goon;
bool gGame::GridIsReady | ( | int | c | ) |
Definition at line 3924 of file gGame.cpp.
References GS_DELETE_OBJECTS, GS_TRANSFER_OBJECTS, and nNetObject::HasBeenTransmitted().
Referenced by notrans().
03926 { 03927 return HasBeenTransmitted(client) && 03928 (client_gamestate[client]>=GS_TRANSFER_OBJECTS &&
eGrid* gGame::Grid | ( | ) | const [inline] |
Definition at line 115 of file gGame.h.
Referenced by Analysis(), and StateUpdate().
void gGame::NoLongerGoOn | ( | ) |
Definition at line 2297 of file gGame.cpp.
References goon, nSERVER, nNetObject::RequestSync(), and sn_GetNetState().
Referenced by ret_to_MainMenu(), and update_settings().
02298 { 02299 goon=false; 02300 // stateNext=GS_DELETE_OBJECTS; 02301 if (sn_GetNetState()==nSERVER) 02302 RequestSync();
void gGame::StartNewMatch | ( | ) |
Definition at line 3562 of file gGame.cpp.
Referenced by Analysis(), StartNewMatch(), and update_settings().
03564 { 03565 //gStatistics - highscore check 03566 if (sg_singlePlayer && gStats && se_PlayerNetIDs.Len() > 0 && se_PlayerNetIDs(0)->IsHuman()) 03567 { 03568 gStats->highscores->greater(se_PlayerNetIDs(0)->GetName(), se_PlayerNetIDs(0)->Score()); 03569 } 03570
void gGame::StartNewMatchNow | ( | ) |
Definition at line 3572 of file gGame.cpp.
Referenced by Analysis(), Init(), and StateUpdate().
03574 { 03575 if ( rounds != 0 ) 03576 { 03577 se_SaveToLadderLog(tString("NEW_MATCH\n")); 03578 se_sendEventNotification(tString("New match"), tString("Starting a new match")); 03579 } 03580 03581 03582 rounds=0; 03583 warning=0; 03584 startTime=tSysTimeFloat()-10; 03585 03586 ePlayerNetID::ThrowOutDisconnected();
unsigned short gGame::state [private] |
Definition at line 62 of file gGame.h.
Referenced by client_gamestate_handler(), GameLoop(), GetState(), Init(), SetState(), and StateUpdate().
unsigned short gGame::stateNext [private] |
Definition at line 63 of file gGame.h.
Referenced by GameLoop(), Init(), ReadSync(), SetState(), StateUpdate(), and WriteSync().
tJUST_CONTROLLED_PTR< gZone > gGame::winDeathZone_ [private] |
bool gGame::goon [private] |
Definition at line 71 of file gGame.h.
Referenced by Analysis(), GameLoop(), GameLoop(), Init(), NoLongerGoOn(), SetState(), StateUpdate(), and SyncState().
int gGame::rounds [private] |
double gGame::startTime [private] |
int gGame::warning [private] |
bool gGame::synced_ [private] |
flag indicating whether the game is considered synced
Definition at line 81 of file gGame.h.
Referenced by GameLoop(), gGame(), and StateUpdate().
gParser* gGame::aParser [private] |