diff --git a/include/bedrock/world/scores/objective.h b/include/bedrock/world/scores/objective.h index 8e2bf5aba..1d5abdc03 100644 --- a/include/bedrock/world/scores/objective.h +++ b/include/bedrock/world/scores/objective.h @@ -24,17 +24,19 @@ class Objective : public Bedrock::EnableNonOwnerReferences { public: + Objective(const std::string &name, const ObjectiveCriteria &criteria); + [[nodiscard]] const std::unordered_map &getScores() const; [[nodiscard]] const std::string &getName() const; [[nodiscard]] const std::string &getDisplayName() const; - [[nodiscard]] const ObjectiveCriteria *getCriteria() const; + [[nodiscard]] const ObjectiveCriteria &getCriteria() const; [[nodiscard]] ObjectiveRenderType getRenderType() const; void setDisplayName(const std::string &display_name); [[nodiscard]] bool hasScore(const ScoreboardId &id) const; [[nodiscard]] int getPlayerScore(const ScoreboardId &id) const; - bool setPlayerScore(const ScoreboardId &id, int value); // Endstone + bool setPlayerScore(const ScoreboardId &id, int value); // Endstone private: bool _modifyPlayerScore(int &result, const ScoreboardId &id, int value, PlayerScoreSetFunction action); // NOLINT @@ -42,5 +44,5 @@ class Objective : public Bedrock::EnableNonOwnerReferences { std::unordered_map scores_; // +24 std::string name_; // +88 std::string display_name_; // +120 - const ObjectiveCriteria *criteria_; // +152 + const ObjectiveCriteria &criteria_; // +152 }; diff --git a/include/bedrock/world/scores/scoreboard.h b/include/bedrock/world/scores/scoreboard.h index a219d0d7e..7178098da 100644 --- a/include/bedrock/world/scores/scoreboard.h +++ b/include/bedrock/world/scores/scoreboard.h @@ -52,6 +52,7 @@ class Scoreboard { virtual void writeToLevelStorage() = 0; [[nodiscard]] virtual bool isClientSide() const = 0; + Objective *Scoreboard::addObjective(const std::string &, const std::string &, const ObjectiveCriteria &criteria); bool removeObjective(Objective *); [[nodiscard]] Objective *getObjective(const std::string &name) const; [[nodiscard]] const DisplayObjective *getDisplayObjective(const std::string &name) const; @@ -60,16 +61,17 @@ class Scoreboard { [[nodiscard]] const ScoreboardId &getScoreboardId(const std::string &fake) const; [[nodiscard]] bool hasIdentityFor(const ScoreboardId &id) const; [[nodiscard]] ScoreboardIdentityRef *getScoreboardIdentityRef(const ScoreboardId &id); + [[nodiscard]] ObjectiveCriteria *getCriteria(const std::string &name) const; private: - CommandSoftEnumRegistry registry_; // +8 - std::unordered_map display_objectives_; // +16 - IdentityDictionary identity_dictionary_; // +80 - std::unordered_map identity_refs_; // +336 (+216) - bool should_update_ui_; // +400 (+256) - std::unordered_map> objectives_; // +408 (+264) - std::unordered_map> objectives_lookup_; // +472 (+304) - std::unordered_map> criteria_; // +536 (+344) - ScoreboardEventCoordinator scoreboard_event_coordinator_; // +600 (+384) + CommandSoftEnumRegistry registry_; // +8 + std::unordered_map display_objectives_; // +16 + IdentityDictionary identity_dictionary_; // +80 + std::unordered_map identity_refs_; // +336 (+216) + bool should_update_ui_; // +400 (+256) + std::unordered_map> objectives_; // +408 (+264) + std::unordered_map> objectives_lookup_; // +472 (+304) + std::unordered_map> criteria_; // +536 (+344) + ScoreboardEventCoordinator scoreboard_event_coordinator_; // +600 (+384) // PlayerScoreboardEventListener player_listener_; // +712 (+504) }; diff --git a/src/endstone_core/scoreboard/objective.cpp b/src/endstone_core/scoreboard/objective.cpp index 15f6dd37b..bbf33af43 100644 --- a/src/endstone_core/scoreboard/objective.cpp +++ b/src/endstone_core/scoreboard/objective.cpp @@ -26,7 +26,7 @@ namespace endstone::detail { EndstoneObjective::EndstoneObjective(EndstoneScoreboard &scoreboard, ::Objective &objective) - : name_(objective.getName()), scoreboard_(scoreboard), objective_(objective), criteria_(*objective.getCriteria()) + : name_(objective.getName()), scoreboard_(scoreboard), objective_(objective), criteria_(objective.getCriteria()) { } diff --git a/src/endstone_runtime/bedrock/world/scores/objective.cpp b/src/endstone_runtime/bedrock/world/scores/objective.cpp index 5a16cefbf..f5f1a0c64 100644 --- a/src/endstone_runtime/bedrock/world/scores/objective.cpp +++ b/src/endstone_runtime/bedrock/world/scores/objective.cpp @@ -16,6 +16,11 @@ #include +Objective::Objective(const std::string &name, const ObjectiveCriteria &criteria) + : name_(name), criteria_(criteria), display_name_(name) +{ +} + const std::unordered_map &Objective::getScores() const { return scores_; @@ -31,14 +36,14 @@ const std::string &Objective::getDisplayName() const return display_name_; } -const ObjectiveCriteria *Objective::getCriteria() const +const ObjectiveCriteria &Objective::getCriteria() const { return criteria_; } ObjectiveRenderType Objective::getRenderType() const { - return criteria_->getRenderType(); + return criteria_.getRenderType(); } void Objective::setDisplayName(const std::string &display_name) @@ -68,7 +73,7 @@ bool Objective::setPlayerScore(const ScoreboardId &id, int value) bool Objective::_modifyPlayerScore(int &result, const ScoreboardId &id, int value, PlayerScoreSetFunction action) { - if (criteria_->isReadOnly()) { + if (criteria_.isReadOnly()) { result = 0; return false; } diff --git a/src/endstone_runtime/bedrock/world/scores/scoreboard.cpp b/src/endstone_runtime/bedrock/world/scores/scoreboard.cpp index 2ed92636e..a2b58a97c 100644 --- a/src/endstone_runtime/bedrock/world/scores/scoreboard.cpp +++ b/src/endstone_runtime/bedrock/world/scores/scoreboard.cpp @@ -16,6 +16,22 @@ #include "bedrock/world/actor/player/player.h" +Objective *Scoreboard::addObjective(const std::string &name, const std::string &display_name, + const ObjectiveCriteria &criteria) +{ + if (getObjective(name)) { + return nullptr; // already exist + } + + auto objective = std::make_unique(name, criteria); + objectives_[name] = std::move(objective); + auto &ref = *objectives_[name]; + objectives_lookup_.emplace(HashedString::computeHash(name), ref); + ref.setDisplayName(display_name); + onObjectiveAdded(ref); + return &ref; +} + bool Scoreboard::removeObjective(Objective *objective) { if (!objective) { @@ -102,3 +118,12 @@ ScoreboardIdentityRef *Scoreboard::getScoreboardIdentityRef(const ScoreboardId & } return nullptr; } + +ObjectiveCriteria *Scoreboard::getCriteria(const std::string &name) const +{ + auto it = criteria_.find(name); + if (it != criteria_.end()) { + return it->second.get(); + } + return nullptr; +}