diff --git a/src/Client.cc b/src/Client.cc index b1aab3b5..74b9d2a1 100644 --- a/src/Client.cc +++ b/src/Client.cc @@ -350,6 +350,7 @@ shared_ptr Client::team() const { bool Client::evaluate_quest_availability_expression( shared_ptr expr, + shared_ptr game, uint8_t event, uint8_t difficulty, size_t num_players, @@ -360,10 +361,12 @@ bool Client::evaluate_quest_availability_expression( if (!expr) { return true; } - auto l = this->lobby.lock(); + if (game && !game->quest_flag_values) { + throw logic_error("quest flags are missing from game"); + } auto p = this->character(); QuestAvailabilityExpression::Env env = { - .flags = (l && !l->quest_flags_known) ? &l->quest_flag_values->data.at(difficulty) : &p->quest_flags.data.at(difficulty), + .flags = (game && !game->quest_flags_known) ? &game->quest_flag_values->data.at(difficulty) : &p->quest_flags.data.at(difficulty), .challenge_records = &p->challenge_records, .team = this->team(), .num_players = num_players, @@ -378,12 +381,24 @@ bool Client::evaluate_quest_availability_expression( return ret; } -bool Client::can_see_quest(shared_ptr q, uint8_t event, uint8_t difficulty, size_t num_players, bool v1_present) const { - return this->evaluate_quest_availability_expression(q->available_expression, event, difficulty, num_players, v1_present); +bool Client::can_see_quest( + shared_ptr q, + shared_ptr game, + uint8_t event, + uint8_t difficulty, + size_t num_players, + bool v1_present) const { + return this->evaluate_quest_availability_expression(q->available_expression, game, event, difficulty, num_players, v1_present); } -bool Client::can_play_quest(shared_ptr q, uint8_t event, uint8_t difficulty, size_t num_players, bool v1_present) const { - return this->evaluate_quest_availability_expression(q->enabled_expression, event, difficulty, num_players, v1_present); +bool Client::can_play_quest( + shared_ptr q, + shared_ptr game, + uint8_t event, + uint8_t difficulty, + size_t num_players, + bool v1_present) const { + return this->evaluate_quest_availability_expression(q->enabled_expression, game, event, difficulty, num_players, v1_present); } bool Client::can_use_chat_commands() const { diff --git a/src/Client.hh b/src/Client.hh index 0516c26d..6578c2cd 100644 --- a/src/Client.hh +++ b/src/Client.hh @@ -294,12 +294,25 @@ public: bool evaluate_quest_availability_expression( std::shared_ptr expr, + std::shared_ptr game, + uint8_t event, + uint8_t difficulty, + size_t num_players, + bool v1_present) const; + bool can_see_quest( + std::shared_ptr q, + std::shared_ptr game, + uint8_t event, + uint8_t difficulty, + size_t num_players, + bool v1_present) const; + bool can_play_quest( + std::shared_ptr q, + std::shared_ptr game, uint8_t event, uint8_t difficulty, size_t num_players, bool v1_present) const; - bool can_see_quest(std::shared_ptr q, uint8_t event, uint8_t difficulty, size_t num_players, bool v1_present) const; - bool can_play_quest(std::shared_ptr q, uint8_t event, uint8_t difficulty, size_t num_players, bool v1_present) const; bool can_use_chat_commands() const; diff --git a/src/Lobby.cc b/src/Lobby.cc index b07bc8c4..3f84a569 100644 --- a/src/Lobby.cc +++ b/src/Lobby.cc @@ -816,8 +816,9 @@ Lobby::JoinError Lobby::join_error_for_client(std::shared_ptr c, const s if (this->quest) { size_t num_clients = this->count_clients() + 1; bool v1_present = is_v1(c->version()) || this->any_v1_clients_present(); - if (!c->can_see_quest(this->quest, this->event, this->difficulty, num_clients, v1_present) || - !c->can_play_quest(this->quest, this->event, this->difficulty, num_clients, v1_present)) { + auto this_sh = this->shared_from_this(); + if (!c->can_see_quest(this->quest, this_sh, this->event, this->difficulty, num_clients, v1_present) || + !c->can_play_quest(this->quest, this_sh, this->event, this->difficulty, num_clients, v1_present)) { return JoinError::NO_ACCESS_TO_QUEST; } } @@ -930,10 +931,11 @@ QuestIndex::IncludeCondition Lobby::quest_include_condition() const { return [this, num_players, v1_present](shared_ptr q) -> QuestIndex::IncludeState { bool is_enabled = true; for (const auto& lc : this->clients) { - if (lc && !lc->can_see_quest(q, this->event, this->difficulty, num_players, v1_present)) { + auto this_sh = this->shared_from_this(); + if (lc && !lc->can_see_quest(q, this_sh, this->event, this->difficulty, num_players, v1_present)) { return QuestIndex::IncludeState::HIDDEN; } - if (lc && !lc->can_play_quest(q, this->event, this->difficulty, num_players, v1_present)) { + if (lc && !lc->can_play_quest(q, this_sh, this->event, this->difficulty, num_players, v1_present)) { is_enabled = false; } }