void GameScene::OnRaceFinish() { // Check if all players are finished. // If not all players have finished, then we're just entering postgame. bool done = true; for (int i = 0; i < session->GetNbPlayers(); i++) { auto player = session->GetPlayer(i); if (!player) continue; // Player slot may have been vacated. auto mchar = player->GetMainCharacter(); assert(mchar); if (!mchar->HasFinish()) { done = false; break; } } if (done) { HR_LOG(info) << "Ending completed session."; session->AdvancePhase(ClientSession::Phase::DONE); director.GetSessionChangedSignal()(nullptr); } else { session->AdvancePhase(ClientSession::Phase::POSTGAME); } }
AircraftState OrderedTask::GetFinishState() const { if (HasFinish() && TaskFinished()) return taskpoint_finish->GetEnteredState(); AircraftState null_state; return null_state; }
void OrderedTask::UpdateGeometry() { ScanStartFinish(); if (!HasStart() || !task_points[0]) return; // scan location of task points for (auto begin = task_points.cbegin(), end = task_points.cend(), i = begin; i != end; ++i) { if (i == begin) task_projection.reset((*i)->GetLocation()); (*i)->ScanProjection(task_projection); } // ... and optional start points for (auto i = optional_start_points.cbegin(), end = optional_start_points.cend(); i != end; ++i) (*i)->ScanProjection(task_projection); // projection can now be determined task_projection.update_fast(); // update OZ's for items that depend on next-point geometry UpdateObservationZones(task_points, task_projection); UpdateObservationZones(optional_start_points, task_projection); // now that the task projection is stable, and oz is stable, // calculate the bounding box in projected coordinates for (auto i = task_points.cbegin(), end = task_points.cend(); i != end; ++i) (*i)->UpdateBoundingBox(task_projection); for (auto i = optional_start_points.cbegin(), end = optional_start_points.cend(); i != end; ++i) (*i)->UpdateBoundingBox(task_projection); // update stats so data can be used during task construction /// @todo this should only be done if not flying! (currently done with has_entered) if (!taskpoint_start->HasEntered()) { GeoPoint loc = taskpoint_start->GetLocation(); UpdateStatsDistances(loc, true); if (HasFinish()) { /// @todo: call AbstractTask::update stats methods with fake state /// so stats are updated } } }
void OrderedTask::UpdateGeometry() { UpdateStatsGeometry(); if (task_points.empty()) return; auto &first = *task_points.front(); first.ScanActive(*task_points[active_task_point]); // scan location of task points GeoBounds bounds(first.GetLocation()); for (const auto *tp : task_points) tp->ScanBounds(bounds); // ... and optional start points for (const OrderedTaskPoint *tp : optional_start_points) tp->ScanBounds(bounds); // projection can now be determined task_projection = TaskProjection(bounds); // update OZ's for items that depend on next-point geometry UpdateObservationZones(task_points, task_projection); UpdateObservationZones(optional_start_points, task_projection); // now that the task projection is stable, and oz is stable, // calculate the bounding box in projected coordinates for (const auto tp : task_points) tp->UpdateBoundingBox(task_projection); for (const auto tp : optional_start_points) tp->UpdateBoundingBox(task_projection); // update stats so data can be used during task construction /// @todo this should only be done if not flying! (currently done with has_entered) if (!task_points.front()->HasEntered()) { UpdateStatsDistances(GeoPoint::Invalid(), true); if (HasFinish()) { /// @todo: call AbstractTask::update stats methods with fake state /// so stats are updated } } force_full_update = true; }
bool OrderedTask::ScanStartFinish() { /// @todo also check there are not more than one start/finish point if (!task_points.size()) { taskpoint_start = NULL; taskpoint_finish = NULL; return false; } taskpoint_start = task_points[0]->GetType() == TaskPoint::START ? (StartPoint *)task_points[0] : NULL; taskpoint_finish = task_points.size() > 1 && task_points[task_points.size() - 1]->GetType() == TaskPoint::FINISH ? (FinishPoint *)task_points[task_points.size() - 1] : NULL; return HasStart() && HasFinish(); }
inline bool OrderedTask::ScanStartFinish() { /// @todo also check there are not more than one start/finish point if (task_points.empty()) { taskpoint_start = nullptr; taskpoint_finish = nullptr; return false; } taskpoint_start = task_points.front()->GetType() == TaskPointType::START ? (StartPoint *)task_points.front() : nullptr; taskpoint_finish = task_points.size() > 1 && task_points.back()->GetType() == TaskPointType::FINISH ? (FinishPoint *)task_points.back() : nullptr; return HasStart() && HasFinish(); }