diff --git a/src/Client.cc b/src/Client.cc index 71641c56..8b9a8acb 100644 --- a/src/Client.cc +++ b/src/Client.cc @@ -334,7 +334,7 @@ shared_ptr Client::team() const { return team; } -bool Client::can_see_quest(shared_ptr q, uint8_t difficulty, size_t num_players) const { +bool Client::can_see_quest(shared_ptr q, uint8_t event, uint8_t difficulty, size_t num_players) const { if (this->license && (this->license->flags & License::Flag::DISABLE_QUEST_REQUIREMENTS)) { return true; } @@ -348,13 +348,14 @@ bool Client::can_see_quest(shared_ptr q, uint8_t difficulty, size_t .challenge_records = &p->challenge_records, .team = this->team(), .num_players = num_players, + .event = event, }; int64_t ret = q->available_expression->evaluate(env); this->log.info("Evaluated quest availability expression %s => %s", expr.c_str(), ret ? "TRUE" : "FALSE"); return ret; } -bool Client::can_play_quest(shared_ptr q, uint8_t difficulty, size_t num_players) const { +bool Client::can_play_quest(shared_ptr q, uint8_t event, uint8_t difficulty, size_t num_players) const { if (this->license && (this->license->flags & License::Flag::DISABLE_QUEST_REQUIREMENTS)) { return true; } @@ -368,6 +369,7 @@ bool Client::can_play_quest(shared_ptr q, uint8_t difficulty, size_ .challenge_records = &p->challenge_records, .team = this->team(), .num_players = num_players, + .event = event, }; bool ret = q->enabled_expression->evaluate(env); this->log.info("Evaluating quest enabled expression %s => %s", expr.c_str(), ret ? "TRUE" : "FALSE"); diff --git a/src/Client.hh b/src/Client.hh index 8c3332ad..84322ec3 100644 --- a/src/Client.hh +++ b/src/Client.hh @@ -282,8 +282,8 @@ public: std::shared_ptr team() const; - bool can_see_quest(std::shared_ptr q, uint8_t difficulty, size_t num_players) const; - bool can_play_quest(std::shared_ptr q, uint8_t difficulty, size_t num_players) const; + bool can_see_quest(std::shared_ptr q, uint8_t event, uint8_t difficulty, size_t num_players) const; + bool can_play_quest(std::shared_ptr q, uint8_t event, uint8_t difficulty, size_t num_players) const; static void dispatch_save_game_data(evutil_socket_t, short, void* ctx); void save_game_data(); diff --git a/src/Lobby.cc b/src/Lobby.cc index d63d0e21..9bbfed8b 100644 --- a/src/Lobby.cc +++ b/src/Lobby.cc @@ -729,8 +729,8 @@ Lobby::JoinError Lobby::join_error_for_client(std::shared_ptr c, const s } if (this->quest) { size_t num_clients = this->count_clients() + 1; - if (!c->can_see_quest(this->quest, this->difficulty, num_clients) || - !c->can_play_quest(this->quest, this->difficulty, num_clients)) { + if (!c->can_see_quest(this->quest, this->event, this->difficulty, num_clients) || + !c->can_play_quest(this->quest, this->event, this->difficulty, num_clients)) { return JoinError::NO_ACCESS_TO_QUEST; } } @@ -855,10 +855,10 @@ QuestIndex::IncludeCondition Lobby::quest_include_condition() const { return [this, num_players](shared_ptr q) -> QuestIndex::IncludeState { bool is_enabled = true; for (const auto& lc : this->clients) { - if (lc && !lc->can_see_quest(q, this->difficulty, num_players)) { + if (lc && !lc->can_see_quest(q, this->event, this->difficulty, num_players)) { return QuestIndex::IncludeState::HIDDEN; } - if (lc && !lc->can_play_quest(q, this->difficulty, num_players)) { + if (lc && !lc->can_play_quest(q, this->event, this->difficulty, num_players)) { is_enabled = false; } } diff --git a/src/QuestAvailabilityExpression.cc b/src/QuestAvailabilityExpression.cc index e5ca65c1..5e18bb61 100644 --- a/src/QuestAvailabilityExpression.cc +++ b/src/QuestAvailabilityExpression.cc @@ -245,6 +245,20 @@ string QuestAvailabilityExpression::NumPlayersLookupNode::str() const { return "V_NumPlayers"; } +QuestAvailabilityExpression::EventLookupNode::EventLookupNode() {} + +bool QuestAvailabilityExpression::EventLookupNode::operator==(const Node& other) const { + return dynamic_cast(&other) != nullptr; +} + +int64_t QuestAvailabilityExpression::EventLookupNode::evaluate(const Env& env) const { + return env.num_players; +} + +string QuestAvailabilityExpression::EventLookupNode::str() const { + return "V_Event"; +} + QuestAvailabilityExpression::ConstantNode::ConstantNode(bool value) : value(value) {} @@ -395,6 +409,9 @@ unique_ptr QuestAvailabilityExpression: if (text == "V_NumPlayers") { return make_unique(); } + if (text == "V_Event") { + return make_unique(); + } // Check for constants if (text == "true") { diff --git a/src/QuestAvailabilityExpression.hh b/src/QuestAvailabilityExpression.hh index 405d5b60..9b5869cb 100644 --- a/src/QuestAvailabilityExpression.hh +++ b/src/QuestAvailabilityExpression.hh @@ -20,6 +20,7 @@ public: const PlayerRecordsBB_Challenge* challenge_records; std::shared_ptr team; size_t num_players; + uint8_t event; }; QuestAvailabilityExpression(const std::string& text); @@ -150,6 +151,15 @@ protected: virtual std::string str() const; }; + class EventLookupNode : public Node { + public: + EventLookupNode(); + virtual ~EventLookupNode() = default; + virtual bool operator==(const Node& other) const; + virtual int64_t evaluate(const Env& env) const; + virtual std::string str() const; + }; + class ConstantNode : public Node { public: ConstantNode(bool value); diff --git a/system/quests/events/q124.json b/system/quests/events/q124.json new file mode 100644 index 00000000..f006769d --- /dev/null +++ b/system/quests/events/q124.json @@ -0,0 +1,3 @@ +{ + "AvailableIf": "V_Event == 3", +} diff --git a/system/quests/events/q125.json b/system/quests/events/q125.json new file mode 100644 index 00000000..30723687 --- /dev/null +++ b/system/quests/events/q125.json @@ -0,0 +1,3 @@ +{ + "AvailableIf": "V_Event == 9", +} diff --git a/system/quests/events/q207.json b/system/quests/events/q207.json new file mode 100644 index 00000000..680bab92 --- /dev/null +++ b/system/quests/events/q207.json @@ -0,0 +1,3 @@ +{ + "AvailableIf": "V_Event == 5", +} diff --git a/system/quests/events/q240.json b/system/quests/events/q240.json index ae1c6c16..baa63c67 100644 --- a/system/quests/events/q240.json +++ b/system/quests/events/q240.json @@ -1,3 +1,3 @@ { - "AvailableIf": "V_NumPlayers == 1", + "AvailableIf": "V_NumPlayers == 1 && V_Event == 1", }