Skip to content

Commit

Permalink
Added Clan captor badge and clan ranking
Browse files Browse the repository at this point in the history
  • Loading branch information
NSGolova committed Feb 2, 2024
1 parent 1c5bfcf commit bf84151
Show file tree
Hide file tree
Showing 18 changed files with 592 additions and 87 deletions.
2 changes: 2 additions & 0 deletions include/API/PlayerController.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class PlayerController
static bool IsIncognito(Player anotherPlayer);
static void SetIsIncognito(Player anotherPlayer, bool value);

static bool InClan(string tag);

static optional<Player> currentPlayer;
static string lastErrorDescription;
};
13 changes: 13 additions & 0 deletions include/Models/Clan.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@ struct Clan
string icon;
string color;

int rank;
float pp;

Clan(rapidjson::Value const& document);
Clan() = default;
};

struct ClanRankingStatus
{
std::optional<Clan> clan;
bool clanRankingContested;
bool applicable;

ClanRankingStatus(rapidjson::Value const& document);
ClanRankingStatus() = default;
};
24 changes: 24 additions & 0 deletions include/Models/ClanScore.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include "beatsaber-hook/shared/config/rapidjson-utils.hpp"
#include "include/Models/Clan.hpp"

#include <string>
using namespace std;

struct ClanScore
{
int id;
// int baseScore;
int modifiedScore;
float accuracy;
int clanId;
float pp;
// float Weight;
int rank;
string timeset;

Clan clan;
ClanScore();
ClanScore(rapidjson::Value const& document);
};
2 changes: 2 additions & 0 deletions include/Models/Difficulty.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "beatsaber-hook/shared/config/rapidjson-utils.hpp"
#include "include/Models/TriangleRating.hpp"
#include "include/Models/Clan.hpp"

#include <vector>
#include <string>
Expand All @@ -17,6 +18,7 @@ struct Difficulty
unordered_map<string, float> modifierValues;
unordered_map<string, TriangleRating> modifiersRating;
TriangleRating rating;
ClanRankingStatus clanStatus;

Difficulty(rapidjson::Value const& document);
Difficulty(int statusGiven, int typeGiven, vector<float> votesGive, unordered_map<string, float> modifierValuesGiven, unordered_map<string, TriangleRating> modifiersRatingGiven, TriangleRating ratingGiven);
Expand Down
17 changes: 17 additions & 0 deletions include/UI/CaptorClanUI.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include "include/Models/Clan.hpp"

#include "questui/shared/BeatSaberUI.hpp"
#include "questui/shared/QuestUI.hpp"

#include "TMPro/TextMeshProUGUI.hpp"

namespace CaptorClanUI {
extern bool showClanRanking;
extern function<void()> showClanRankingCallback;

void initCaptorClan(UnityEngine::GameObject* header, TMPro::TextMeshProUGUI* headerPanelText);
void setClan(ClanRankingStatus clanStatus);
void setActive(bool active);
}
1 change: 1 addition & 0 deletions include/UI/UIUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ namespace UIUtils {
extern SafePtrUnity<HMUI::ImageView> roundRectSprite;

HMUI::ImageView* getRoundRectSprite();
void AddRoundRect(HMUI::ImageView* background);
HMUI::ImageView* GetCopyOf(HMUI::ImageView* comp, HMUI::ImageView* other);
void OpenSettings();
HMUI::ImageView* CreateRoundRectImage(UnityEngine::Transform* parent, UnityEngine::Vector2 anchoredPosition, UnityEngine::Vector2 sizeDelta);
Expand Down
41 changes: 26 additions & 15 deletions include/Utils/FormatUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "include/Models/Player.hpp"
#include "include/Models/Clan.hpp"
#include "include/Models/Score.hpp"
#include "include/Models/ClanScore.hpp"
#include "include/API/PlayerController.hpp"
#include <regex>
using namespace std;
Expand Down Expand Up @@ -104,23 +105,24 @@ namespace FormatUtils {
return "<alpha=#00>.<alpha=#FF><b><noparse>" + tag + "</noparse></b><alpha=#00>.<alpha=#FF>";
}

inline string FormatNameWithClans(Player const& player, int limit) {
string clansLabel = "<size=90%>";
inline string FormatNameWithClans(Player const& player, int limit, bool withClans) {
string clansLabel = withClans ? "<size=90%>" : "";
int clanCount = player.clans.size();

if (clanCount == 2) {
clansLabel = "<size=80%>";
}
else if (clanCount == 3) {
clansLabel = "<size=70%>";
if (withClans) {
if (clanCount == 2) {
clansLabel = "<size=80%>";
}
else if (clanCount == 3) {
clansLabel = "<size=70%>";
}

for (size_t i = 0; i < clanCount; i++) {
Clan clan = player.clans[i];
clansLabel += " <color=" + clan.color + ">" + clan.tag + "</color>";
}
clansLabel += "</size>";
}

for (size_t i = 0; i < clanCount; i++) {
Clan clan = player.clans[i];
clansLabel += " <color=" + clan.color + ">" + clan.tag + "</color>";
}
clansLabel += "</size>";

string name = "";
if (!player.name.empty() && player.name != "<blank>") {
name = player.name;
Expand All @@ -136,7 +138,7 @@ namespace FormatUtils {
string name = "";

if (!PlayerController::IsIncognito(score.player)) {
name = getModConfig().ClansActive.GetValue() ? FormatNameWithClans(score.player, 24) : "<noparse>" + truncate(score.player.name, 24) + "</noparse>";
name = getModConfig().ClansActive.GetValue() ? FormatNameWithClans(score.player, 24, true) : "<noparse>" + truncate(score.player.name, 24) + "</noparse>";
}
else {
name = "[REDACTED]";
Expand All @@ -147,6 +149,15 @@ namespace FormatUtils {
return name + "<pos=40%>" + FormatPP(score.pp) + " " + formatAcc(score.accuracy) + " " + fcLabel + time;
}

inline string FormatClanScore(ClanScore const& score) {
string name = "";

name = "<noparse>" + truncate(score.clan.name, 24) + "</noparse> <color=" + score.clan.color + ">" + score.clan.tag + "</color>";

string time = getModConfig().TimesetActive.GetValue() ? " <size=60%>" + GetRelativeTimeString(score.timeset) + "</size>" : "";

return name + "<pos=40%>" + FormatPP(score.pp) + " " + formatAcc(score.accuracy) + " " + time;
}

inline string GetFullPlatformName(string serverPlatform) {

Expand Down
3 changes: 2 additions & 1 deletion include/Utils/ModConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ DECLARE_CONFIG(ModConfig,
CONFIG_VALUE(ShowReplaySettings, bool, "Show replay settings", true);
CONFIG_VALUE(ShowBeatleader, bool, "Show BeatLeader", true, "Priority for BeatLeader or SS");
CONFIG_VALUE(StarValueToShow, int, "Display Stars", 0);
CONFIG_VALUE(Context, int, "Selected Context", static_cast<int>(LeaderboardUI::Context::Standard))
CONFIG_VALUE(Context, int, "Selected Context", static_cast<int>(LeaderboardUI::Context::Standard));
CONFIG_VALUE(CaptureActive, bool, "Show Leaderboard clan capture status", true);
)

inline bool UploadEnabled() {
Expand Down
10 changes: 10 additions & 0 deletions src/API/PlayerController.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "include/API/PlayerController.hpp"
#include "include/Utils/WebUtils.hpp"
#include "include/Utils/ModConfig.hpp"
#include "include/Utils/StringUtils.hpp"
#include "include/main.hpp"
#include "include/UI/LeaderboardUI.hpp"

Expand Down Expand Up @@ -122,6 +123,15 @@ bool PlayerController::IsFriend(Player anotherPlayer) {
return std::find(currentPlayer->friends.begin(), currentPlayer->friends.end(), anotherPlayer.id) != currentPlayer->friends.end();
}

bool PlayerController::InClan(string tag) {
if (currentPlayer == nullopt) return false;

auto it = std::find_if(currentPlayer->clans.begin(), currentPlayer->clans.end(),
[&tag](const auto& clan) { return toLower(clan.tag) == toLower(tag); });

return it != currentPlayer->clans.end();
}

bool PlayerController::IsIncognito(Player anotherPlayer) {
Document incognitoList;
incognitoList.Parse(getModConfig().IncognitoList.GetValue().c_str());
Expand Down
29 changes: 29 additions & 0 deletions src/Models/Clan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,33 @@
Clan::Clan(rapidjson::Value const& document) {
tag = document["tag"].GetString();
color = document["color"].GetString();

if (document.HasMember("name") && !document["name"].IsNull()) {
name = document["name"].GetString();
} else {
name = "No name";
}

if (document.HasMember("avatar")) {
icon = document["avatar"].GetString();
} else {
icon = "";
}
if (document.HasMember("rank")) {
rank = document["rank"].GetInt();
}
if (document.HasMember("pp")) {
pp = document["pp"].GetFloat();
}
}

ClanRankingStatus::ClanRankingStatus(rapidjson::Value const& document) {
if (document["clan"].IsNull()) {
clan = nullopt;
} else {
clan = Clan(document["clan"].GetObject());
}

applicable = document["applicable"].GetBool();
clanRankingContested = document["clanRankingContested"].GetBool();
}
14 changes: 14 additions & 0 deletions src/Models/ClanScore.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "include/Models/ClanScore.hpp"

ClanScore::ClanScore() {}

ClanScore::ClanScore(rapidjson::Value const& document) {
auto const& clanObject = document["clan"];
clan = Clan(clanObject);

pp = document["pp"].GetFloat();
rank = document["rank"].GetInt();
modifiedScore = document["modifiedScore"].GetInt();
timeset = document["timepost"].GetString();
accuracy = document["accuracy"].GetFloat();
}
6 changes: 6 additions & 0 deletions src/Models/Difficulty.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ Difficulty::Difficulty(rapidjson::Value const& document) {
rating.passRating = document["passRating"].GetFloat();
rating.accRating = document["accRating"].GetFloat();
rating.techRating = document["techRating"].GetFloat();

if (document.HasMember("clanStatus") && !document["clanStatus"].IsNull()) {
clanStatus = ClanRankingStatus(document["clanStatus"].GetObject());
} else {
clanStatus = ClanRankingStatus();
}
}

Difficulty::Difficulty(int statusGiven, int typeGiven, vector<float> votesGiven, unordered_map<string, float> modifierValuesGiven,unordered_map<string, TriangleRating> modifiersRatingGiven, TriangleRating ratingGiven) {
Expand Down
12 changes: 9 additions & 3 deletions src/Models/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,18 @@ Player::Player(rapidjson::Value const& userModInterface) {

// For standard context and players from v3/scores (where contextExtension is null cause we request for one context) we use the main player
int currentContext = getModConfig().Context.GetValue();
std::optional<rapidjson::GenericArray<true, rapidjson::Value>> contextExtensions = userModInterface.HasMember("contextExtensions") && !userModInterface["contextExtensions"].IsNull() ? userModInterface["contextExtensions"].GetArray() : std::optional<rapidjson::GenericArray<true, rapidjson::Value>>();
std::optional<rapidjson::GenericArray<true, rapidjson::Value>> contextExtensions =
userModInterface.HasMember("contextExtensions") && !userModInterface["contextExtensions"].IsNull()
? userModInterface["contextExtensions"].GetArray()
: std::optional<rapidjson::GenericArray<true, rapidjson::Value>>();
// If we are Standard Context or we have no contexts or our selected context is not in contextextensions we use the normal rank. Else we use the correct context extension rank
rapidjson::Value const& contextRank = currentContext == 0 || !contextExtensions || currentContext - 1 >= contextExtensions.value().Size() ? userModInterface : contextExtensions.value()[currentContext - 1];
rapidjson::Value const& contextRank =
currentContext == 0 ||
!contextExtensions ||
currentContext - 1 >= contextExtensions.value().Size() ? userModInterface : contextExtensions.value()[currentContext - 1];

rank = contextRank["rank"].GetInt();
countryRank = contextRank["countryRank"].GetInt();
countryRank = contextRank["countryRank"].GetInt();
pp = contextRank["pp"].GetFloat();

auto clansList = userModInterface["clans"].GetArray();
Expand Down
Loading

0 comments on commit bf84151

Please sign in to comment.