Skip to content

Commit

Permalink
Implementation of DualTheme (#46)
Browse files Browse the repository at this point in the history
* Add files via upload

* Add files via upload

* Add files via upload

* Update README.md

* Update README.md

* Add files via upload

* Add files via upload

* Update README.md

* Update README.md

* Update README.md

* Add files via upload

* Add files via upload

* Add files via upload

* Add files via upload

* Update README.md

* Restart fix

* Update README.md

* Add files via upload

Added Checkbox for quick enable and disable of dualtheme.

* Added Checkbox for quick enable and disable of dualtheme.

* Update README.md

* Add files via upload

* Add files via upload

* Update README.md

* Update README.md

* fix: prevent modifying the readme

* fix: use env variable instead of static path

* fix: use rs_theme for retrocompatibility, reset theme when changing settings, load texture and font on theme change, fix reset button

* fix: allow checkbox to change theme in game

* fix: menu text position

* chore: increase version number to 4.2.0

---------

Co-authored-by: Guillaume Guerin <[email protected]>
  • Loading branch information
3lack5ky and Lyliya authored Feb 9, 2025
1 parent 8ac9b46 commit 64b5b5f
Show file tree
Hide file tree
Showing 10 changed files with 291 additions and 137 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# RocketStats

__RocketStats__ is a Plugin working with __BakkesMod__, allowing you to display session information (MMR, win, loss, streak, eg.) __in game__ and/or __in OBS__.
**RocketStats** is a Plugin working with **BakkesMod**, allowing you to display session information (MMR, win, loss, streak, eg.) **in game** and/or **in OBS**.

![](screenshot.png)

Expand All @@ -27,10 +27,12 @@ You can come and ask your questions or discuss with the community in our [discor
Thanks to all the people who helped us during the development.

##### Thanks for ideas and support:

- [Maylie](https://www.twitch.tv/Maylie_tv)

##### Thanks for tests:
- [Daakiii_](https://www.twitch.tv/daakiii_)

- [Daakiii\_](https://www.twitch.tv/daakiii_)
- [Ekon](https://www.twitch.tv/ekonrl)
- [Fuury](https://www.twitch.tv/FuuRy_Off)
- [Loppeur](https://www.twitch.tv/loppeur)
Expand Down
6 changes: 5 additions & 1 deletion RocketStats/Languages.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,5 +137,9 @@ enum LangStringId {
LANG_HIDE_DROPSHOT,
LANG_HIDE_KNOCKOUT,
LANG_HIDE_MISCS,
LANG_HIDE_ACCOLADES
LANG_HIDE_ACCOLADES,
LANG_MENU,
LANG_GAME,
LANG_MENU_THEME,
LANG_GAME_THEME,
};
18 changes: 13 additions & 5 deletions RocketStats/Managements/FileManagement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,14 @@ bool RocketStats::ReadConfig()
rs_mode = config["settings"]["mode"];

if (config["settings"]["theme"].is_string())
SetTheme(config["settings"]["theme"]);
SetTheme(config["settings"]["theme"]);

if (config["settings"]["overlay"].is_boolean())
rs_disp_overlay = config["settings"]["overlay"];

if (config["settings"]["GameTheme"].is_string()) {
SetGameTheme(config["settings"]["GameTheme"]);
}

if (config["settings"]["themes"].is_object() && !config["settings"]["themes"].is_null() && config["settings"]["themes"].size())
{
Expand All @@ -200,11 +207,10 @@ bool RocketStats::ReadConfig()
themes_values = tmp;
}

if (config["settings"]["overlay"].is_boolean())
rs_disp_overlay = config["settings"]["overlay"];

if (config["settings"]["inmenu"].is_boolean())
rs_enable_inmenu = config["settings"]["inmenu"];
if (config["settings"]["enableDualTheme"].is_boolean())
dualtheme = config["settings"]["enableDualTheme"];
if (config["settings"]["ingame"].is_boolean())
rs_enable_ingame = config["settings"]["ingame"];
if (config["settings"]["inscoreboard"].is_boolean())
Expand Down Expand Up @@ -398,7 +404,9 @@ void RocketStats::WriteConfig()

tmp["settings"] = json::object();
tmp["settings"]["mode"] = rs_mode;
tmp["settings"]["theme"] = theme_render.name;
tmp["settings"]["theme"] = themes.at(rs_theme).name.c_str();
tmp["settings"]["GameTheme"] = themes.at(rs_gameTheme).name.c_str();
tmp["settings"]["enableDualTheme"] = dualtheme;
tmp["settings"]["overlay"] = rs_disp_overlay;
tmp["settings"]["inmenu"] = rs_enable_inmenu;
tmp["settings"]["ingame"] = rs_enable_ingame;
Expand Down
46 changes: 42 additions & 4 deletions RocketStats/Managements/OverlayManagement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,26 @@ void RocketStats::LoadThemes()
cvarManager->log("===== !LoadThemes =====");
}

void RocketStats::BacktoMenu()
{
if (!is_in_MainMenu) {
cvarManager->log("===== BackToMenu =====");
SetTheme(themes.at(rs_theme).name.c_str());
ChangeTheme(rs_theme);
cvarManager->log("===== !BackToMenu =====");
}
}

void RocketStats::InGameTheme()
{
cvarManager->log("===== InGameTheme =====");
if (dualtheme) {
SetGameTheme(themes.at(rs_gameTheme).name.c_str());
ChangeTheme(rs_gameTheme);
}
cvarManager->log("===== !InGameTheme =====");
}

bool RocketStats::ChangeTheme(int idx)
{
cvarManager->log("===== ChangeTheme =====");
Expand Down Expand Up @@ -135,11 +155,12 @@ bool RocketStats::ChangeTheme(int idx)
}

cvarManager->log("Theme changed: " + theme.name + " (old: " + theme_render.name + ")");
rs_theme = idx;
SetRefresh(RefreshFlags_RefreshAndImages);
}
else
else {
cvarManager->log("Theme config: " + theme.name + " bad JSON");
return false;
}
}
catch (json::parse_error& e)
{
Expand All @@ -151,10 +172,11 @@ bool RocketStats::ChangeTheme(int idx)
theme_render.version = old.version;
theme_render.date = old.date;
theme_render.fonts = old.fonts;
return false;
}

cvarManager->log("===== !ChangeTheme =====");
return (rs_theme == idx);
return true;
}

void RocketStats::SetTheme(std::string name)
Expand All @@ -172,6 +194,21 @@ void RocketStats::SetTheme(std::string name)
}
}

void RocketStats::SetGameTheme(std::string name)
{
// Search the index of a theme with its name (changes current theme if found)
for (int i = 0; i < themes.size(); ++i)
{
if (themes.at(i).name == name)
{
cvarManager->log("SetGameTheme: [" + std::to_string(i) + "] " + name);

rs_gameTheme = i;
break;
}
}
}

void RocketStats::SetRefresh(unsigned char value)
{
if (theme_refresh < value)
Expand Down Expand Up @@ -252,6 +289,7 @@ void RocketStats::RefreshVars()
UpdateFiles();
}
SetCVar("rs_theme", rs_theme);
SetCVar("rs_gameTheme", rs_gameTheme);

SetCVar("rs_x", rs_x, true);
SetCVar("rs_y", rs_y, true);
Expand Down Expand Up @@ -580,7 +618,7 @@ Element RocketStats::CalculateElement(json& element, Options& options, bool& che
{
// Get the requested image
element_size = { 0, 0 };
std::string image_path = "RocketStats_themes/" + themes.at(rs_theme).name + "/images/" + calculated.value;
std::string image_path = "RocketStats_themes/" + theme_render.name + "/images/" + calculated.value;

cvarManager->log("Load image: " + image_path);
theme_images[calculated.value] = LoadImg(image_path);
Expand Down
94 changes: 87 additions & 7 deletions RocketStats/Managements/WindowManagement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,12 @@ void RocketStats::RenderOverlay()

ImGui::Begin(menu_title.c_str(), (bool*)1, (ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoFocusOnAppearing));

int currentTheme = is_in_MainMenu ? rs_theme : rs_gameTheme;

try
{
// Calculation each element of the theme (only during a modification)
if (overlay_move || theme_refresh || theme_render.name == "" || (themes.size() > rs_theme && theme_render.name != themes.at(rs_theme).name))
if (overlay_move || theme_refresh || theme_render.name == "" || (themes.size() > currentTheme && theme_render.name != themes.at(currentTheme).name))
{
Stats tstats = GetStats();

Expand Down Expand Up @@ -528,20 +530,22 @@ void RocketStats::RenderSettings()
++rs_mode;

ImGui::SetWindowFontScale(1.3f / (font ? 2.f : 1.f));
ImGui::SetCursorPos({ 585.f, 43.f });
ImGui::TextColored(ImVec4{ 0.8f, 0.8f, 0.8f, 1.f }, GetLang(LANG_THEME).c_str());
ImGui::SetCursorPos({ 565.f, 23.f });
ImGui::TextColored(ImVec4{ 0.8f, 0.8f, 0.8f, 1.f }, GetLang(LANG_MENU_THEME).c_str());

ImGui::SetWindowFontScale(1.f / (font ? 2.f : 1.f));
ImGui::SetCursorPos({ 525.f, 68.f });
ImGui::SetCursorPos({ 525.f, 43.f });
ImGui::SetNextItemWidth(142.f);
if (ImGui::BeginCombo("##themes_combo", theme_render.name.c_str(), ImGuiComboFlags_NoArrowButton))
if (ImGui::BeginCombo("##themes_combo", themes.at(rs_theme).name.c_str(), ImGuiComboFlags_NoArrowButton))
{
int Trs_theme = rs_theme;
for (int i = 0; i < themes.size(); ++i)
{
bool is_selected = (Trs_theme == i);
if (ImGui::Selectable(themes.at(i).name.c_str(), is_selected))
{
rs_theme = i;
}

if (is_selected)
ImGui::SetItemDefaultFocus();
Expand All @@ -553,10 +557,86 @@ void RocketStats::RenderSettings()
tooltip = GetLang(LANG_THEME_TOOLTIP);
ImGui::SameLine(0.f, 0.f);
if (ImGui::ArrowButton("##themes_left", ImGuiDir_Left) && rs_theme > 0)
{
--rs_theme;
}
ImGui::SameLine(0.f, 0.f);
if (ImGui::ArrowButton("##themes_right", ImGuiDir_Right) && themes.size() && rs_theme < (themes.size() - 1))
{
++rs_theme;
}

ImGui::SetWindowFontScale(0.8f / (font ? 2.f : 1.f));
ImGui::SetCursorPos({ 545.f, 70.f });
if (ImGui::Checkbox("##dualtheme", &dualtheme)) {
// We activate dualtheme
if (dualtheme && !is_in_MainMenu) {
SetGameTheme(themes.at(rs_gameTheme).name.c_str());
ChangeTheme(rs_gameTheme);
}
else {
// We deactivate dualtheme;
SetTheme(themes.at(rs_theme).name.c_str());
ChangeTheme(rs_theme);
}
};

ImGui::SetWindowFontScale(1.3f / (font ? 2.f : 1.f));
ImGui::SetCursorPos({ 565.f, 68.f });
ImGui::TextColored(ImVec4{ 0.8f, 0.8f, 0.8f, 1.f }, (GetLang(LANG_GAME_THEME)).c_str());

ImGui::SetWindowFontScale(1.f / (font ? 2.f : 1.f));
if (dualtheme) {
ImGui::SetCursorPos({ 525.f, 88.f });
ImGui::SetNextItemWidth(142.f);
if (ImGui::BeginCombo("##themes2_combo", themes.at(rs_gameTheme).name.c_str(), ImGuiComboFlags_NoArrowButton))
{
int Trs_theme2 = rs_gameTheme;
for (int i = 0; i < themes.size(); ++i)
{
bool is_selected = (Trs_theme2 == i);
if (ImGui::Selectable(themes.at(i).name.c_str(), is_selected))
{
rs_gameTheme = i;
}

if (is_selected)
ImGui::SetItemDefaultFocus();
}

ImGui::EndCombo();
}
if (ImGui::IsItemHovered())
tooltip = GetLang(LANG_THEME_TOOLTIP);
ImGui::SameLine(0.f, 0.f);
if (ImGui::ArrowButton("##themes2_left", ImGuiDir_Left) && rs_gameTheme > 0)
--rs_gameTheme;
{
}
ImGui::SameLine(0.f, 0.f);
if (ImGui::ArrowButton("##themes2_right", ImGuiDir_Right) && themes.size() && rs_gameTheme < (themes.size() - 1))
++rs_gameTheme;
{
}
}
else {
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.5f);
ImGui::SetCursorPos({ 525.f, 88.f });
ImGui::SetNextItemWidth(142.f);
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.2f, 0.2f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.3f, 0.3f, 0.3f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.4f, 0.4f, 0.4f, 1.0f));
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.f, 0.5f));
if (ImGui::Button(themes.at(rs_gameTheme).name.c_str(), ImVec2(142.f, ImGui::GetTextLineHeightWithSpacing()))) {
}
ImGui::PopStyleVar();
ImGui::PopStyleColor(3);
ImGui::SameLine(0.f, 0.f);
ImGui::ArrowButton("##themes2_left", ImGuiDir_Left);
ImGui::SameLine(0.f, 0.f);
ImGui::ArrowButton("##themes2_right", ImGuiDir_Right);
ImGui::PopStyleVar();
}

ImGui::SetCursorPos({ 103.f, 120.f });
if (ImGui::Button(GetLang(LANG_X).c_str(), { 65.f, 0.f }))
Expand Down Expand Up @@ -708,7 +788,7 @@ void RocketStats::RenderSettings()
if (ImGui::Button(GetLang(LANG_RELOAD_THEME).c_str(), { 103.f, 0.f }))
{
LoadImgs();
ChangeTheme(rs_theme);
ChangeTheme(dualtheme && !is_in_MainMenu ? rs_gameTheme: rs_theme);
}
if (ImGui::IsItemHovered())
tooltip = GetLang(LANG_RELOAD_THEME_TOOLTIP);
Expand All @@ -718,7 +798,7 @@ void RocketStats::RenderSettings()
LoadImgs();
LoadThemes();
SetTheme(theme_render.name);
ChangeTheme(rs_theme);
ChangeTheme(dualtheme && !is_in_MainMenu ? rs_gameTheme: rs_theme);
}
if (ImGui::IsItemHovered())
tooltip = GetLang(LANG_RELOAD_THEME_A_TOOLTIP);
Expand Down
6 changes: 5 additions & 1 deletion RocketStats/Resources/Languages/FRA.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,5 +135,9 @@
"Masque les Dommages en dropshot",
"Masque les Knockout",
"Masque les Divers",
"Masque les Distinctions"
"Masque les Distinctions",
"Principale",
"Alt. en-Jeu",
"Theme principal",
"Theme en jeu"
]
6 changes: 5 additions & 1 deletion RocketStats/Resources/Languages/INT.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,5 +135,9 @@
"Hide Dropshot",
"Hide Knockout",
"Hide Miscs",
"Hide Assists"
"Hide Assists",
"Main",
"Alt. In-Game",
"Main Theme",
"In-Game Theme"
]
15 changes: 10 additions & 5 deletions RocketStats/RocketStats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

#include "RocketStats.h"

BAKKESMOD_PLUGIN(RocketStats, "RocketStats", "4.1.4", PERMISSION_ALL)
BAKKESMOD_PLUGIN(RocketStats, "RocketStats", "4.2.0", PERMISSION_ALL)

#pragma region Utils
Stats RocketStats::GetStats()
Expand Down Expand Up @@ -426,14 +426,14 @@ void RocketStats::onInit()
gameWrapper->HookEvent("Function TAGame.GFxData_StartMenu_TA.EventTitleScreenClicked", std::bind(&RocketStats::ShowPlugin, this, std::placeholders::_1));
gameWrapper->HookEvent("Function TAGame.GameViewportClient_TA.SetUIScaleModifier", std::bind(&RocketStats::UpdateUIScale, this, std::placeholders::_1));
gameWrapper->HookEvent("Function Engine.GameViewportClient.IsFullScreenViewport", std::bind(&RocketStats::UpdateUIScale, this, std::placeholders::_1));
gameWrapper->HookEvent("Function GameEvent_TA.Countdown.BeginState", std::bind(&RocketStats::GameStart, this, std::placeholders::_1));
gameWrapper->HookEvent("Function GameEvent_TA.Countdown.BeginState", std::bind([this](std::string event) {GameStart(event);InGameTheme();is_in_MainMenu = false;}, std::placeholders::_1));
gameWrapper->HookEvent("Function TAGame.GameEvent_Soccar_TA.OnMatchWinnerSet", std::bind(&RocketStats::GameEnd, this, std::placeholders::_1));
gameWrapper->HookEvent("Function TAGame.GameEvent_TA.Destroyed", std::bind(&RocketStats::GameDestroyed, this, std::placeholders::_1));
gameWrapper->HookEvent("Function TAGame.GameEvent_TA.Destroyed", std::bind([this](std::string event) {GameDestroyed(event);}, std::placeholders::_1));
gameWrapper->HookEvent("Function CarComponent_Boost_TA.Active.BeginState", std::bind(&RocketStats::OnBoostStart, this, std::placeholders::_1));
gameWrapper->HookEvent("Function TAGame.CarComponent_Boost_TA.EventBoostAmountChanged", std::bind(&RocketStats::OnBoostChanged, this, std::placeholders::_1));
gameWrapper->HookEvent("Function CarComponent_Boost_TA.Active.EndState", std::bind(&RocketStats::OnBoostEnd, this, std::placeholders::_1));
gameWrapper->HookEvent("Function TAGame.GameEvent_Soccar_TA.TriggerGoalScoreEvent", std::bind(&RocketStats::onGoalScore, this, std::placeholders::_1));
gameWrapper->HookEvent("Function TAGame.GFxData_MainMenu_TA.OnEnteredMainMenu", std::bind([this]() { menu_stack = 0; is_in_menu = true; }));
gameWrapper->HookEvent("Function TAGame.GFxData_MainMenu_TA.OnEnteredMainMenu", std::bind([this]() { BacktoMenu();menu_stack = 0; is_in_menu = true; is_in_MainMenu = true;}));
gameWrapper->HookEvent("Function TAGame.GFxData_MenuStack_TA.PushMenu", std::bind([this]() { ++menu_stack; is_in_menu = true; }));
gameWrapper->HookEvent("Function TAGame.GFxData_MenuStack_TA.PopMenu", std::bind([this]() { if (menu_stack) --menu_stack; is_in_menu = (menu_stack > 0); }));
gameWrapper->HookEvent("Function TAGame.MenuSequence_TA.EnterSequence", std::bind([this]() { is_in_menu = true; }));
Expand Down Expand Up @@ -475,9 +475,14 @@ void RocketStats::onInit()

cvarManager->registerCvar("rs_mode", std::to_string(rs_mode), GetLang(LANG_MODE), true, true, 0, true, float(modes.size() - 1), false).addOnValueChanged(std::bind(&RocketStats::RefreshTheme, this, std::placeholders::_1, std::placeholders::_2));
cvarManager->registerCvar("rs_theme", std::to_string(rs_theme), GetLang(LANG_THEME), true, true, 0, false, 99, false).addOnValueChanged([this](std::string old, CVarWrapper now) {
if (!ChangeTheme(now.getIntValue()))
if (is_in_MainMenu && !ChangeTheme(now.getIntValue()))
now.setValue(old);
});
cvarManager->registerCvar("rs_gameTheme", std::to_string(rs_gameTheme), GetLang(LANG_MENU) + GetLang(LANG_THEME), true, true, 0, false, 99, false).addOnValueChanged([this](std::string old, CVarWrapper now) {
if (!is_in_MainMenu && !ChangeTheme(now.getIntValue())) {
now.setValue(old);
}
});

cvarManager->registerCvar("rs_x", std::to_string(rs_x), GetLang(LANG_X), true, true, 0.f, true, 1.f, false).addOnValueChanged(std::bind(&RocketStats::RefreshTheme, this, std::placeholders::_1, std::placeholders::_2));
cvarManager->registerCvar("rs_y", std::to_string(rs_y), GetLang(LANG_Y), true, true, 0.f, true, 1.f, false).addOnValueChanged(std::bind(&RocketStats::RefreshTheme, this, std::placeholders::_1, std::placeholders::_2));
Expand Down
Loading

0 comments on commit 64b5b5f

Please sign in to comment.