From c3d3c57a7144aa79588a01860dbcc760191dbd4c Mon Sep 17 00:00:00 2001 From: DualFroz Date: Wed, 9 Sep 2026 16:17:31 +0200 Subject: [PATCH] feat: extend Scoreboard --- core/src/Scoreboard.cpp | 109 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/core/src/Scoreboard.cpp b/core/src/Scoreboard.cpp index cbc11ef..5718de5 100644 --- a/core/src/Scoreboard.cpp +++ b/core/src/Scoreboard.cpp @@ -324,3 +324,112 @@ std::vector Scoreboard::entries(const std::string& objectiveName) co return out; } +void Scoreboard::setDisplay(DisplaySlot slot, const std::string& objectiveName) { + if (slot == DisplaySlot::Count) return; + if (objectives.count(objectiveName) == 0u) return; + slots[static_cast(slot)] = objectiveName; +} + +void Scoreboard::clearDisplay(DisplaySlot slot) { + if (slot == DisplaySlot::Count) return; + slots[static_cast(slot)].clear(); +} + +const std::string& Scoreboard::displayedObjective(DisplaySlot slot) const { + static const std::string none; + if (slot == DisplaySlot::Count) return none; + return slots[static_cast(slot)]; +} + +std::vector Scoreboard::displayLines(DisplaySlot slot, int limit) const { + std::vector lines = entries(displayedObjective(slot)); + if (limit >= 0 && static_cast(lines.size()) > limit) + lines.resize(static_cast(limit)); + return lines; +} + +bool Scoreboard::addTeam(const ScoreTeam& team) { + if (team.name.empty()) return false; + if (teams.count(team.name) > 0u) return false; + ScoreTeam stored = team; + stored.members.clear(); + teams[team.name] = stored; + for (const std::string& member : team.members) joinTeam(team.name, member); + return true; +} + +bool Scoreboard::removeTeam(const std::string& name) { + auto found = teams.find(name); + if (found == teams.end()) return false; + for (const std::string& member : found->second.members) teamByPlayer.erase(member); + teams.erase(found); + return true; +} + +const ScoreTeam* Scoreboard::team(const std::string& name) const { + auto found = teams.find(name); + return found == teams.end() ? nullptr : &found->second; +} + +const ScoreTeam* Scoreboard::teamOf(const std::string& player) const { + auto membership = teamByPlayer.find(player); + if (membership == teamByPlayer.end()) return nullptr; + return team(membership->second); +} + +bool Scoreboard::joinTeam(const std::string& teamName, const std::string& player) { + auto found = teams.find(teamName); + if (found == teams.end() || player.empty()) return false; + leaveTeam(player); + found->second.members.push_back(player); + std::sort(found->second.members.begin(), found->second.members.end()); + teamByPlayer[player] = teamName; + return true; +} + +bool Scoreboard::leaveTeam(const std::string& player) { + auto membership = teamByPlayer.find(player); + if (membership == teamByPlayer.end()) return false; + auto found = teams.find(membership->second); + if (found != teams.end()) { + std::vector& members = found->second.members; + members.erase(std::remove(members.begin(), members.end(), player), members.end()); + } + teamByPlayer.erase(membership); + return true; +} + +std::vector Scoreboard::teamNames() const { + std::vector out; + out.reserve(teams.size()); + for (const auto& entry : teams) out.push_back(entry.first); + return out; +} + +bool Scoreboard::friendlyFireAllowed(const std::string& attacker, const std::string& victim) const { + const ScoreTeam* attackerTeam = teamOf(attacker); + if (attackerTeam == nullptr) return true; + if (!attackerTeam->hasMember(victim)) return true; + return attackerTeam->friendlyFire; +} + +bool Scoreboard::nameVisibleTo(const std::string& viewer, const std::string& target) const { + const ScoreTeam* targetTeam = teamOf(target); + if (targetTeam == nullptr) return true; + const bool sameTeam = targetTeam->hasMember(viewer); + switch (targetTeam->nameVisibility) { + case ScoreTeam::Visibility::Always: return true; + case ScoreTeam::Visibility::Never: return false; + case ScoreTeam::Visibility::HideForOtherTeams: return sameTeam; + case ScoreTeam::Visibility::HideForOwnTeam: return !sameTeam; + } + return true; +} + +std::string Scoreboard::displayNameOf(const std::string& player) const { + const ScoreTeam* membership = teamOf(player); + if (membership == nullptr) return player; + return membership->prefix + player + membership->suffix; +} + +} // namespace vf