void RandomDataTester::handleMyMemoryWrite(thrID myself, void * iid, void * addr) { if (iid == target1 || iid == target2) { ActiveRaceInfo tmp(myself, addr, true); vector<thrID> racers = isRacing(tmp); if (((int) racers.size()) > 0) { raceFound = true; if (log->getPrint()) { printf("Racing access discovered\n"); } enableSpecificActiveTestingPaused(racers); } else { active_testing_paused[myself] = true; active_testing_info[myself] = tmp; disableThread(myself); } } }
/** Updates the world time and clock (which might be running backwards), and * all status information, called once per frame at the end of the main * loop. * \param ticks Number of ticks (physics time steps) - should be 1. */ void WorldStatus::updateTime(int ticks) { switch (m_phase.load()) { // Note: setup phase must be a separate phase, since the race_manager // checks the phase when updating the camera: in the very first time // step dt is large (it includes loading time), so the camera might // tilt way too much. A separate setup phase for the first frame // simplifies this handling case SETUP_PHASE: m_auxiliary_ticks= 0; m_phase = TRACK_INTRO_PHASE; if (m_play_track_intro_sound) { m_track_intro_sound->play(); } if (Weather::getInstance()) { Weather::getInstance()->playSound(); } return; // Do not increase time case TRACK_INTRO_PHASE: m_auxiliary_ticks++; if (UserConfigParams::m_artist_debug_mode && !NetworkConfig::get()->isNetworking() && race_manager->getNumberOfKarts() - race_manager->getNumSpareTireKarts() == 1 && race_manager->getTrackName() != "tutorial") { m_auxiliary_ticks += 6; } if (!m_play_track_intro_sound) { startEngines(); } // Wait before ready phase if (m_auxiliary_ticks < stk_config->time2Ticks(3.0f)) return; m_auxiliary_ticks = 0; // In a networked game the client needs to wait for a notification // from the server that all clients and the server are ready to // start the game. The server will actually wait for all clients // to confirm that they have started the race before starting // itself. In a normal race, this phase is skipped and the race // starts immediately. if (NetworkConfig::get()->isNetworking()) { m_phase = WAIT_FOR_SERVER_PHASE; // In networked races, inform the start game protocol that // the world has been setup if (!m_live_join_world) { auto lobby = LobbyProtocol::get<LobbyProtocol>(); assert(lobby); lobby->finishedLoadingWorld(); } } else { if (m_play_ready_set_go_sounds) m_prestart_sound->play(); m_phase = READY_PHASE; } return; // Don't increase time case WAIT_FOR_SERVER_PHASE: { if (m_live_join_world) { m_auxiliary_ticks++; // Add 3 seconds delay before telling server finish loading // world, so previous (if any) disconnected player has left // fully if (m_auxiliary_ticks == stk_config->time2Ticks(3.0f)) { auto cl = LobbyProtocol::get<ClientLobby>(); assert(cl); cl->finishedLoadingWorld(); #ifndef ANDROID static bool helper_msg_shown = false; if (!helper_msg_shown && cl->isSpectator()) { helper_msg_shown = true; cl->addSpectateHelperMessage(); } #endif } return; } return; // Don't increase time } case SERVER_READY_PHASE: { auto lobby = LobbyProtocol::get<LobbyProtocol>(); if (lobby && lobby->isRacing()) { if (m_play_ready_set_go_sounds) m_prestart_sound->play(); m_phase = READY_PHASE; } return; // Don't increase time } case READY_PHASE: startEngines(); // One second if (m_auxiliary_ticks > stk_config->getPhysicsFPS()) { if (m_play_ready_set_go_sounds) { m_prestart_sound->play(); } m_phase = SET_PHASE; } m_auxiliary_ticks++; // In artist debug mode, when without opponents, skip the // ready/set/go counter faster if (UserConfigParams::m_artist_debug_mode && !NetworkConfig::get()->isNetworking() && race_manager->getNumberOfKarts() - race_manager->getNumSpareTireKarts() == 1 && race_manager->getTrackName() != "tutorial") { m_auxiliary_ticks += 6; } return; // Do not increase time case SET_PHASE: if (m_auxiliary_ticks > 2*stk_config->getPhysicsFPS()) { // set phase is over, go to the next one m_phase = GO_PHASE; if (m_play_ready_set_go_sounds) { m_start_sound->play(); } // event onGo(); // In artist debug mode, when without opponents, // skip the ready/set/go counter faster m_start_music_ticks = UserConfigParams::m_artist_debug_mode && !NetworkConfig::get()->isNetworking() && race_manager->getNumberOfKarts() - race_manager->getNumSpareTireKarts() == 1 && race_manager->getTrackName() != "tutorial" ? stk_config->time2Ticks(0.2f) : stk_config->time2Ticks(1.0f); // how long to display the 'music' message // no graphics mode goes race phase at 3 seconds; m_race_ticks = ProfileWorld::isNoGraphics() ? stk_config->time2Ticks(3.0f) : stk_config->time2Ticks(stk_config->m_music_credit_time); } m_auxiliary_ticks++; // In artist debug mode, when without opponents, // skip the ready/set/go counter faster if (UserConfigParams::m_artist_debug_mode && !NetworkConfig::get()->isNetworking() && race_manager->getNumberOfKarts() - race_manager->getNumSpareTireKarts() == 1 && race_manager->getTrackName() != "tutorial") { m_auxiliary_ticks += 6; } return; // Do not increase time case GO_PHASE: { if (m_start_music_ticks != -1 && m_count_up_ticks >= m_start_music_ticks) { m_start_music_ticks = -1; if (music_manager->getCurrentMusic() && !music_manager->getCurrentMusic()->isPlaying()) { music_manager->startMusic(); } m_phase = MUSIC_PHASE; } break; // Now the world time starts } case MUSIC_PHASE: { // Start the music here when starting fast if (UserConfigParams::m_race_now) { music_manager->startMusic(); UserConfigParams::m_race_now = false; } if (m_race_ticks != -1 && m_count_up_ticks >= m_race_ticks) { m_race_ticks = -1; m_phase = RACE_PHASE; } break; } case RACE_PHASE: // Nothing to do for race phase, switch to delay finish phase // happens when break; case DELAY_FINISH_PHASE: { m_auxiliary_ticks++; // Change to next phase if delay is over if (m_auxiliary_ticks > stk_config->time2Ticks(stk_config->m_delay_finish_time)) { m_phase = RESULT_DISPLAY_PHASE; terminateRace(); } break; } case RESULT_DISPLAY_PHASE: { break; } case FINISH_PHASE: case IN_GAME_MENU_PHASE: // Nothing to do here. break; case GOAL_PHASE: // Nothing to do here as well. break; default: break; } IrrlichtDevice *device = irr_driver->getDevice(); switch (m_clock_mode) { case CLOCK_CHRONO: if (!device->getTimer()->isStopped()) { m_time_ticks++; m_time = stk_config->ticks2Time(m_time_ticks); m_count_up_ticks++; } break; case CLOCK_COUNTDOWN: // stop countdown when race is over if (m_phase == RESULT_DISPLAY_PHASE || m_phase == FINISH_PHASE) { m_time_ticks = 0; m_time = 0.0f; m_count_up_ticks = 0; break; } if (!device->getTimer()->isStopped()) { m_time_ticks--; m_time = stk_config->ticks2Time(m_time_ticks); m_count_up_ticks++; } if (m_time_ticks <= 0) { // event countdownReachedZero(); } break; default: break; } // switch m_phase } // update