├── source ├── pch.cpp ├── fonts │ └── Panton-LightCaps.otf ├── packages.config ├── packages │ └── nlohmann.json.3.9.1 │ │ ├── nlohmann.json.3.9.1.nupkg │ │ └── build │ │ └── native │ │ └── nlohmann.json.targets ├── RankViewer.vcxproj.user ├── imgui │ ├── imgui_timeline.h │ ├── imgui_additions.cpp │ ├── imgui_additions.h │ ├── imgui_searchablecombo.h │ ├── imgui_impl_dx11.h │ ├── imgui_impl_win32.h │ ├── imgui_rangeslider.h │ ├── imgui_timeline.cpp │ ├── imconfig.h │ ├── imgui_searchablecombo.cpp │ ├── imgui_impl_win32.cpp │ └── imstb_rectpack.h ├── pch.h ├── PlaylistData.h ├── RankEnums.h ├── cpp.hint ├── customPaths.props ├── RankViewerSolution.sln ├── RankViewer.h ├── RankViewer.vcxproj.filters ├── RankViewer.vcxproj ├── PlaylistData.cpp └── RankViewer.cpp ├── data ├── RankViewer │ ├── RankIcons │ │ ├── 0.png │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ ├── 7.png │ │ ├── 8.png │ │ ├── 9.png │ │ ├── 10.png │ │ ├── 11.png │ │ ├── 12.png │ │ ├── 13.png │ │ ├── 14.png │ │ ├── 15.png │ │ ├── 16.png │ │ ├── 17.png │ │ ├── 18.png │ │ ├── 19.png │ │ ├── 20.png │ │ ├── 21.png │ │ └── 22.png │ └── RankNumbers │ │ ├── 30.json │ │ ├── 27.json │ │ ├── 29.json │ │ ├── 10.json │ │ ├── 28.json │ │ ├── 11.json │ │ ├── 13.json │ │ └── 34.json └── fonts │ └── Panton-LightCaps.otf ├── plugins └── settings │ └── rankviewer.set ├── README.md └── .gitignore /source/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/0.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/1.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/2.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/3.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/4.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/5.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/6.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/7.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/8.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/9.png -------------------------------------------------------------------------------- /data/fonts/Panton-LightCaps.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/fonts/Panton-LightCaps.otf -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/10.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/11.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/12.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/13.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/14.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/15.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/16.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/17.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/18.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/19.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/20.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/21.png -------------------------------------------------------------------------------- /data/RankViewer/RankIcons/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/data/RankViewer/RankIcons/22.png -------------------------------------------------------------------------------- /plugins/settings/rankviewer.set: -------------------------------------------------------------------------------- 1 | RankViewer plugin 2 | 1|Enable Plugin|rankviewer_enabled 3 | 8| 4 | 9|Made by BeardedOranges -------------------------------------------------------------------------------- /source/fonts/Panton-LightCaps.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/source/fonts/Panton-LightCaps.otf -------------------------------------------------------------------------------- /source/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /source/packages/nlohmann.json.3.9.1/nlohmann.json.3.9.1.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeardedOranges/RankViewer/HEAD/source/packages/nlohmann.json.3.9.1/nlohmann.json.3.9.1.nupkg -------------------------------------------------------------------------------- /source/RankViewer.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | false 5 | 6 | -------------------------------------------------------------------------------- /source/imgui/imgui_timeline.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | namespace ImGui { 3 | 4 | bool BeginTimeline(const char* str_id, float max_time); 5 | bool TimelineEvent(const char* str_id, float times[2]); 6 | void EndTimeline(float current_time = -1); 7 | 8 | } 9 | 10 | -------------------------------------------------------------------------------- /source/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN 4 | #define _CRT_SECURE_NO_WARNINGS 5 | #include "bakkesmod/plugin/bakkesmodplugin.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "imgui/imgui.h" -------------------------------------------------------------------------------- /source/packages/nlohmann.json.3.9.1/build/native/nlohmann.json.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | $(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories) 6 | 7 | 8 | -------------------------------------------------------------------------------- /source/PlaylistData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "RankEnums.h" 4 | /* 5 | struct DivisionData 6 | { 7 | int lower; 8 | int higher; 9 | }; 10 | 11 | struct TierData 12 | { 13 | std::vector divisions; 14 | }; 15 | 16 | struct PlaylistData 17 | { 18 | std::vector tiers; 19 | };*/ 20 | 21 | struct FName2 22 | { 23 | int32_t Index; 24 | int32_t Instance; 25 | }; 26 | 27 | struct RankInfo { std::string name; }; 28 | 29 | //extern std::map playlistMMRDatabase; 30 | extern std::map RankInfoDB; -------------------------------------------------------------------------------- /source/RankEnums.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | 5 | 6 | enum Rank 7 | { 8 | SupersonicLegend = 22, 9 | GrandChamp3 = 21, 10 | GrandChamp2 = 20, 11 | GrandChamp1 = 19, 12 | Champ3 = 18, 13 | Champ2 = 17, 14 | Champ1 = 16, 15 | Diamond3 = 15, 16 | Diamond2 = 14, 17 | Diamond1 = 13, 18 | Platinum3 = 12, 19 | Platinum2 = 11, 20 | Platinum1 = 10, 21 | Gold3 = 9, 22 | Gold2 = 8, 23 | Gold1 = 7, 24 | Silver3 = 6, 25 | Silver2 = 5, 26 | Silver1 = 4, 27 | Bronze3 = 3, 28 | Bronze2 = 2, 29 | Bronze1 = 1, 30 | Unranked = 0, 31 | }; 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /source/imgui/imgui_additions.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "imgui_additions.h" 3 | 4 | namespace ImGui { 5 | bool Combo(const char* label, int* currIndex, std::vector& values) 6 | { 7 | if (values.empty()) { return false; } 8 | return Combo(label, currIndex, vector_getter, 9 | static_cast(&values), values.size()); 10 | } 11 | 12 | bool ListBox(const char* label, int* currIndex, std::vector& values) 13 | { 14 | if (values.empty()) { return false; } 15 | return ListBox(label, currIndex, vector_getter, 16 | static_cast(&values), values.size()); 17 | } 18 | } -------------------------------------------------------------------------------- /source/imgui/imgui_additions.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "imgui.h" 5 | #include "imgui_internal.h" 6 | 7 | namespace ImGui 8 | { 9 | static auto vector_getter = [](void* vec, int idx, const char** out_text) 10 | { 11 | auto& vector = *static_cast*>(vec); 12 | if (idx < 0 || idx >= static_cast(vector.size())) { return false; } 13 | *out_text = vector.at(idx).c_str(); 14 | return true; 15 | }; 16 | bool Combo(const char* label, int* currIndex, std::vector& values); 17 | bool ListBox(const char* label, int* currIndex, std::vector& values); 18 | } -------------------------------------------------------------------------------- /source/imgui/imgui_searchablecombo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "imgui.h" 3 | 4 | #include // isprint 5 | #include // vector<> 6 | #include // string 7 | #include // transform 8 | 9 | namespace ImGui 10 | { 11 | IMGUI_API bool BeginSearchableCombo(const char* label, const char* preview_value, char* input, int input_size, const char* input_preview_value, ImGuiComboFlags flags = 0); 12 | IMGUI_API void EndSearchableCombo(); 13 | IMGUI_API bool SearchableCombo(const char* label, int* current_item, std::vector items, const char* default_preview_text, const char* input_preview_value, int popup_max_height_in_items = -1); 14 | } // namespace ImGui -------------------------------------------------------------------------------- /source/cpp.hint: -------------------------------------------------------------------------------- 1 | // Hint files help the Visual Studio IDE interpret Visual C++ identifiers 2 | // such as names of functions and macros. 3 | // For more information see https://go.microsoft.com/fwlink/?linkid=865984 4 | #define BAKKESMOD_PLUGIN(classType, pluginName, pluginVersion, pluginType) static std::shared_ptr singleton; extern "C" { BAKKESMOD_PLUGIN_EXPORT uintptr_t getPlugin() { if(!singleton) { singleton = std::shared_ptr(new classType()); } return reinterpret_cast(&singleton); } BAKKESMOD_PLUGIN_EXPORT void deleteMe() { if(singleton) singleton = nullptr; } BAKKESMOD_PLUGIN_EXPORT BakkesMod::Plugin::PluginInfo exports = { BAKKESMOD_STANDARD_PLUGIN_STUFF, #classType, pluginName, pluginVersion, pluginType, getPlugin, deleteMe }; } 5 | -------------------------------------------------------------------------------- /source/customPaths.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | C:\Program Files (x86)\Steam\steamapps\common\rocketleague\Binaries\Win64\bakkesmod 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | C:\Users\m4rti\Miniconda3\python.exe "$(BAKKESMOD)\bakkesmodsdk\bakkes_patchplugin.py" "$(TargetPath)" 15 | 16 | 17 | 18 | 19 | $(BAKKESMOD) 20 | 21 | 22 | -------------------------------------------------------------------------------- /source/imgui/imgui_impl_dx11.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Renderer for DirectX11 2 | // This needs to be used along with a Platform Binding (e.g. Win32) 3 | 4 | // Implemented features: 5 | // [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID! 6 | // [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. 7 | 8 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 9 | // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. 10 | // https://github.com/ocornut/imgui 11 | 12 | #pragma once 13 | 14 | struct ID3D11Device; 15 | struct ID3D11DeviceContext; 16 | 17 | IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context); 18 | IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown(); 19 | IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame(); 20 | IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data); 21 | 22 | // Use if you want to reset your rendering device without losing ImGui state. 23 | IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects(); 24 | IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects(); -------------------------------------------------------------------------------- /source/RankViewerSolution.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29613.14 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RankViewer", "RankViewer.vcxproj", "{5D298F96-8F97-4E41-8CDC-605F0665FAF6}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {5D298F96-8F97-4E41-8CDC-605F0665FAF6}.Debug|x64.ActiveCfg = Debug|x64 17 | {5D298F96-8F97-4E41-8CDC-605F0665FAF6}.Debug|x64.Build.0 = Debug|x64 18 | {5D298F96-8F97-4E41-8CDC-605F0665FAF6}.Debug|x86.ActiveCfg = Debug|x64 19 | {5D298F96-8F97-4E41-8CDC-605F0665FAF6}.Release|x64.ActiveCfg = Release|x64 20 | {5D298F96-8F97-4E41-8CDC-605F0665FAF6}.Release|x64.Build.0 = Release|x64 21 | {5D298F96-8F97-4E41-8CDC-605F0665FAF6}.Release|x86.ActiveCfg = Release|x64 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | GlobalSection(ExtensibilityGlobals) = postSolution 27 | SolutionGuid = {C6B13D88-8816-41E2-A74B-EDACABF03E2A} 28 | EndGlobalSection 29 | EndGlobal 30 | -------------------------------------------------------------------------------- /source/imgui/imgui_impl_win32.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Platform Binding for Windows (standard windows API for 32 and 64 bits applications) 2 | // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) 3 | 4 | // Implemented features: 5 | // [X] Platform: Clipboard support (for Win32 this is actually part of core imgui) 6 | // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. 7 | // [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE). 8 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. 9 | 10 | #pragma once 11 | 12 | IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd); 13 | IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown(); 14 | IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame(); 15 | 16 | // Configuration: Disable gamepad support or linking with xinput.lib 17 | #define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD 18 | #define IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT 19 | 20 | // Handler for Win32 messages, update mouse/keyboard data. 21 | // You may or not need this for your implementation, but it can serve as reference for handling inputs. 22 | // Intentionally commented out to avoid dragging dependencies on types. You can COPY this line into your .cpp code instead. 23 | #if 0 24 | IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 25 | #endif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RankViewer 2 | RankViewer plugin for BakkesMod (https://bakkesplugins.com/plugins/view/91) 3 | 4 | ### About 5 | This plugin allows you to see the MMR that you need for the division above and below your rank! The slider on the side will show you how close you are to ranking up! No longer will you sit there and wonder when you will rank up! All Rocket League players not only want this, but need this plugin in their lives. 6 | 7 | ### Usage 8 | Make sure that the plugin is enabled. Press F2 to open up the bakkes mod settings. Navigate to the settings tab, and click the check box for enabled under "RankViewer". After a match is over, the MMR text will display next to your rank. When you go back to the main menu it will disappear. 9 | 10 | ### Important 11 | How you rank up in Rocket League is not exactly known. The MMR's given are just estimates from [Rocket Tracker](https://rocketleague.tracker.network/rocket-league/distribution?playlist=13). This means that sometimes it will be wrong, this plugin is just to have an idea of where the next division is. 12 | 13 | ### Update Log 14 | - v1.0 - Initial Release 15 | - v1.1 - Added support for displays that are not 1080p. The font size now resizes itself based on your display! I also fixed the banner image on this plugin page to have the ranks in order correctly XD. 16 | - v1.2 - Fixed a bug where it will stay on screen if you leave the match right after it ends. Cleaned up some code (thanks Brank and CinderBlock). Placement matches now display as they should. 17 | - v2.0 - Huge graphical overhaul to make it look like it belongs in the game. Fixed many bugs. Friends list hides the RankViewer graphics. Updated MMR for new seasons and tournaments. Sorry that the update took so long, but I hope it was worth the wait 18 | -------------------------------------------------------------------------------- /source/RankViewer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma comment( lib, "pluginsdk.lib" ) 3 | #include "bakkesmod/plugin/bakkesmodplugin.h" 4 | #include "bakkesmod/plugin/pluginwindow.h" 5 | #include "imgui/imgui.h" 6 | 7 | using namespace std; 8 | 9 | class RankViewer : public BakkesMod::Plugin::BakkesModPlugin, public BakkesMod::Plugin::PluginWindow 10 | { 11 | private: 12 | // Steam/Epic id 13 | UniqueIDWrapper uniqueID; 14 | 15 | bool drawCanvas, isEnabled; 16 | 17 | void CheckMMR(int retryCount); 18 | bool gotNewMMR; 19 | 20 | // Friends Menu 21 | bool isFriendOpen = false; 22 | struct FName2 23 | { 24 | int32_t Index; 25 | int32_t Instance; 26 | }; 27 | FName2 friendsOpen, friendsClose; 28 | 29 | int userPlaylist, userDiv, userTier, upperTier, lowerTier, upperDiv, lowerDiv, nextLower, beforeUpper, yPos; 30 | float userMMR = 0; 31 | 32 | // Div numbers are stored in these 33 | string nameCurrent, nameNext, nameBefore; 34 | string nextDiff, beforeDiff; 35 | 36 | // Colors for the rank viewer graphics 37 | ImColor lightBlue = ImVec4(0.862745098f, 0.968627451f, 1.0f, 1.0f); 38 | ImColor darkBlue = ImVec4(0.0117647059f, 0.3803921569f, 0.5647058824f, 1.0f); 39 | ImColor white = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); 40 | 41 | // Images n fonts 42 | std::shared_ptr beforeRank, currentRank, nextRank; 43 | ImFont* fontBig; 44 | 45 | // Imgui stuff 46 | virtual void onLoad(); 47 | virtual void onUnload(); 48 | bool isWindowOpen_ = false; 49 | bool isMinimized_ = false; 50 | std::string menuTitle_ = "RankViewer"; 51 | Vector2 screenSize; 52 | //float safeZone; 53 | //float uiScale; 54 | void Render() override; 55 | void RenderImGui(); 56 | std::string GetMenuName() override; 57 | std::string GetMenuTitle() override; 58 | void SetImGuiContext(uintptr_t ctx) override; 59 | bool ShouldBlockInput() override; 60 | bool IsActiveOverlay() override; 61 | void OnOpen() override; 62 | void OnClose() override; 63 | 64 | // Converts into mmr 65 | int unranker(int mode, int rank, int div, bool upperLimit); 66 | 67 | // Rocket League Events 68 | void StatsScreen(std::string eventName); 69 | void loadMenu(std::string eventName); 70 | void friendScreen(ActorWrapper caller, void* params, const std::string& functionName); 71 | 72 | int rankedPlaylists[8] = { 10, // Ones 73 | 11, // Twos 74 | 13, // Threes 75 | 27, // Hoops 76 | 28, // Rumble 77 | 29, // Dropshot 78 | 30, // Snowday 79 | 34 // Psynoix Tournaments 80 | }; 81 | }; -------------------------------------------------------------------------------- /source/imgui/imgui_rangeslider.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "imgui.h" 3 | namespace ImGui 4 | { 5 | IMGUI_API bool RangeSliderScalar(const char* label, ImGuiDataType data_type, void* p_data1, void* p_data2, const void* p_min, const void* p_max, const char* format = NULL, float power = 1.0f); 6 | IMGUI_API bool RangeSliderScalarN(const char* label, ImGuiDataType data_type, void* p_data1, void* p_data2, int components, const void* p_min, const void* p_max, const char* format = NULL, float power = 1.0f); 7 | IMGUI_API bool RangeSliderFloat(const char* label, float* v1, float* v2, float v_min, float v_max, const char* format = "(%.3f, %.3f)", float power = 1.0f); // adjust format to decorate the value with a prefix or a suffix for in-slider labels or unit display. Use power!=1.0 for power curve sliders 8 | IMGUI_API bool RangeSliderFloat2(const char* label, float v1[2], float v2[2], float v_min, float v_max, const char* format = "(%.3f, %.3f)", float power = 1.0f); 9 | IMGUI_API bool RangeSliderFloat3(const char* label, float v1[3], float v2[3], float v_min, float v_max, const char* format = "(%.3f, %.3f)", float power = 1.0f); 10 | IMGUI_API bool RangeSliderFloat4(const char* label, float v1[4], float v2[4], float v_min, float v_max, const char* format = "(%.3f, %.3f)", float power = 1.0f); 11 | IMGUI_API bool RangeSliderAngle(const char* label, float* v_rad1, float* v_rad2, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f, const char* format = "(%d, %d) deg"); 12 | IMGUI_API bool RangeSliderInt(const char* label, int* v1, int* v2, int v_min, int v_max, const char* format = "(%d, %d)"); 13 | IMGUI_API bool RangeSliderInt2(const char* label, int v1[2], int v2[2], int v_min, int v_max, const char* format = "(%d, %d)"); 14 | IMGUI_API bool RangeSliderInt3(const char* label, int v1[3], int v2[3], int v_min, int v_max, const char* format = "(%d, %d)"); 15 | IMGUI_API bool RangeSliderInt4(const char* label, int v1[4], int v2[4], int v_min, int v_max, const char* format = "(%d, %d)"); 16 | IMGUI_API bool RangeVSliderScalar(const char* label, const ImVec2& size, ImGuiDataType data_type, void* p_data1, void* p_data2, const void* p_min, const void* p_max, const char* format = NULL, float power = 1.0f); 17 | IMGUI_API bool RangeVSliderFloat(const char* label, const ImVec2& size, float* v1, float* v2, float v_min, float v_max, const char* format = "(%.3f, %.3f)", float power = 1.0f); 18 | IMGUI_API bool RangeVSliderInt(const char* label, const ImVec2& size, int* v1, int* v2, int v_min, int v_max, const char* format = "(%d, %d)"); 19 | 20 | } // namespace ImGui -------------------------------------------------------------------------------- /source/RankViewer.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {cd98297b-5bab-4b49-a2c3-abaf65bac333} 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | imgui 29 | 30 | 31 | imgui 32 | 33 | 34 | imgui 35 | 36 | 37 | imgui 38 | 39 | 40 | imgui 41 | 42 | 43 | imgui 44 | 45 | 46 | imgui 47 | 48 | 49 | imgui 50 | 51 | 52 | imgui 53 | 54 | 55 | imgui 56 | 57 | 58 | imgui 59 | 60 | 61 | imgui 62 | 63 | 64 | imgui 65 | 66 | 67 | 68 | 69 | Source Files 70 | 71 | 72 | Source Files 73 | 74 | 75 | imgui 76 | 77 | 78 | imgui 79 | 80 | 81 | imgui 82 | 83 | 84 | imgui 85 | 86 | 87 | imgui 88 | 89 | 90 | imgui 91 | 92 | 93 | imgui 94 | 95 | 96 | imgui 97 | 98 | 99 | imgui 100 | 101 | 102 | imgui 103 | 104 | 105 | imgui 106 | 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /source/imgui/imgui_timeline.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "imgui_timeline.h" 3 | // cpp 4 | #include "imgui.h" 5 | #include "imgui_internal.h" 6 | // https://github.com/ocornut/imgui/issues/76 7 | 8 | namespace ImGui { 9 | 10 | static float s_max_timeline_value; 11 | 12 | 13 | bool BeginTimeline(const char* str_id, float max_time) 14 | { 15 | s_max_timeline_value = max_time; 16 | return BeginChild(str_id); 17 | } 18 | 19 | 20 | static const float TIMELINE_RADIUS = 6; 21 | 22 | 23 | bool TimelineEvent(const char* str_id, float values[2]) 24 | { 25 | ImGuiWindow* win = GetCurrentWindow(); 26 | const ImU32 inactive_color = ColorConvertFloat4ToU32(GImGui->Style.Colors[ImGuiCol_Button]); 27 | const ImU32 active_color = ColorConvertFloat4ToU32(GImGui->Style.Colors[ImGuiCol_ButtonHovered]); 28 | const ImU32 line_color = ColorConvertFloat4ToU32(GImGui->Style.Colors[ImGuiCol_SeparatorActive]); 29 | bool changed = false; 30 | ImVec2 cursor_pos = win->DC.CursorPos; 31 | 32 | // @r-lyeh { 33 | Button(str_id, ImVec2(120, 0)); // @todo: enable/disable track channel here 34 | SameLine(); 35 | cursor_pos += ImVec2(0, GetTextLineHeightWithSpacing() / 3); 36 | // } 37 | 38 | for (int i = 0; i < 2; ++i) 39 | { 40 | ImVec2 pos = cursor_pos; 41 | pos.x += win->Size.x * values[i] / s_max_timeline_value + TIMELINE_RADIUS; 42 | pos.y += TIMELINE_RADIUS; 43 | 44 | SetCursorScreenPos(pos - ImVec2(TIMELINE_RADIUS, TIMELINE_RADIUS)); 45 | PushID(i); 46 | InvisibleButton(str_id, ImVec2(2 * TIMELINE_RADIUS, 2 * TIMELINE_RADIUS)); 47 | if (IsItemActive() || IsItemHovered()) 48 | { 49 | ImGui::SetTooltip("%f", values[i]); 50 | ImVec2 a(pos.x, GetWindowContentRegionMin().y + win->Pos.y + win->Scroll.y); 51 | ImVec2 b(pos.x, GetWindowContentRegionMax().y + win->Pos.y + win->Scroll.y); 52 | win->DrawList->AddLine(a, b, line_color); 53 | } 54 | if (IsItemActive() && IsMouseDragging(0)) 55 | { 56 | values[i] += GetIO().MouseDelta.x / win->Size.x * s_max_timeline_value; 57 | changed = true; 58 | } 59 | PopID(); 60 | win->DrawList->AddCircleFilled( 61 | pos, TIMELINE_RADIUS, IsItemActive() || IsItemHovered() ? active_color : inactive_color); 62 | } 63 | 64 | ImVec2 start = cursor_pos; 65 | start.x += win->Size.x * values[0] / s_max_timeline_value + 2 * TIMELINE_RADIUS; 66 | start.y += TIMELINE_RADIUS * 0.5f; 67 | ImVec2 end = start + ImVec2(win->Size.x * (values[1] - values[0]) / s_max_timeline_value - 2 * TIMELINE_RADIUS, 68 | TIMELINE_RADIUS); 69 | 70 | PushID(-1); 71 | SetCursorScreenPos(start); 72 | InvisibleButton(str_id, end - start); 73 | if (IsItemActive() && IsMouseDragging(0)) 74 | { 75 | values[0] += GetIO().MouseDelta.x / win->Size.x * s_max_timeline_value; 76 | values[1] += GetIO().MouseDelta.x / win->Size.x * s_max_timeline_value; 77 | changed = true; 78 | } 79 | PopID(); 80 | 81 | SetCursorScreenPos(cursor_pos + ImVec2(0, GetTextLineHeightWithSpacing())); 82 | 83 | win->DrawList->AddRectFilled(start, end, IsItemActive() || IsItemHovered() ? active_color : inactive_color); 84 | 85 | if (values[0] > values[1]) 86 | { 87 | float tmp = values[0]; 88 | values[0] = values[1]; 89 | values[1] = tmp; 90 | } 91 | if (values[1] > s_max_timeline_value) values[1] = s_max_timeline_value; 92 | if (values[0] < 0) values[0] = 0; 93 | return changed; 94 | } 95 | 96 | 97 | void EndTimeline(float t) 98 | { 99 | ImGuiWindow* win = GetCurrentWindow(); 100 | 101 | // @r-lyeh { 102 | if (t >= 0) { 103 | if (t > s_max_timeline_value) t = s_max_timeline_value; t /= s_max_timeline_value; 104 | const ImU32 line_color = ColorConvertFloat4ToU32(GImGui->Style.Colors[ImGuiCol_SeparatorActive]); 105 | ImVec2 a(win->Pos.x + GetWindowContentRegionMin().x + t * GetWindowContentRegionWidth(), GetWindowContentRegionMin().y + win->Pos.y + win->Scroll.y); 106 | ImVec2 b(win->Pos.x + GetWindowContentRegionMin().x + t * GetWindowContentRegionWidth(), GetWindowContentRegionMax().y + win->Pos.y + win->Scroll.y); 107 | win->DrawList->AddLine(a, b, line_color); 108 | } 109 | // } 110 | 111 | ImU32 color = ColorConvertFloat4ToU32(GImGui->Style.Colors[ImGuiCol_Button]); 112 | ImU32 line_color = ColorConvertFloat4ToU32(GImGui->Style.Colors[ImGuiCol_Border]); 113 | ImU32 text_color = ColorConvertFloat4ToU32(GImGui->Style.Colors[ImGuiCol_Text]); 114 | float rounding = GImGui->Style.ScrollbarRounding; 115 | ImVec2 start(GetWindowContentRegionMin().x + win->Pos.x, 116 | GetWindowContentRegionMax().y - GetTextLineHeightWithSpacing() + win->Pos.y + win->Scroll.y); 117 | ImVec2 end = GetWindowContentRegionMax() + win->Pos + ImVec2(0, win->Scroll.y); 118 | 119 | win->DrawList->AddRectFilled(start, end, color, rounding); 120 | 121 | const int LINE_COUNT = 5; 122 | const ImVec2 text_offset(0, GetTextLineHeightWithSpacing()); 123 | for (int i = 0; i <= LINE_COUNT; ++i) 124 | { 125 | ImVec2 a = GetWindowContentRegionMin() + win->Pos; // @r-lyeh: - ImVec2(TIMELINE_RADIUS, 0); 126 | a.x += i * (GetWindowContentRegionWidth() - 1) / LINE_COUNT; // @r-lyeh: -1 127 | ImVec2 b = a; 128 | b.y = start.y; 129 | win->DrawList->AddLine(a, b, line_color); 130 | char tmp[256]; 131 | ImFormatString(tmp, sizeof(tmp), "%.2f", i * s_max_timeline_value / LINE_COUNT); 132 | win->DrawList->AddText(b, text_color, tmp); 133 | } 134 | 135 | EndChild(); 136 | } 137 | 138 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # Benchmark Results 46 | BenchmarkDotNet.Artifacts/ 47 | 48 | # .NET Core 49 | project.lock.json 50 | project.fragment.lock.json 51 | artifacts/ 52 | **/Properties/launchSettings.json 53 | 54 | *_i.c 55 | *_p.c 56 | *_i.h 57 | *.ilk 58 | *.meta 59 | *.obj 60 | *.pch 61 | *.pdb 62 | *.pgc 63 | *.pgd 64 | *.rsp 65 | *.sbr 66 | *.tlb 67 | *.tli 68 | *.tlh 69 | *.tmp 70 | *.tmp_proj 71 | *.log 72 | *.vspscc 73 | *.vssscc 74 | .builds 75 | *.pidb 76 | *.svclog 77 | *.scc 78 | 79 | # Chutzpah Test files 80 | _Chutzpah* 81 | 82 | # Visual C++ cache files 83 | ipch/ 84 | *.aps 85 | *.ncb 86 | *.opendb 87 | *.opensdf 88 | *.sdf 89 | *.cachefile 90 | *.VC.db 91 | *.VC.VC.opendb 92 | 93 | # Visual Studio profiler 94 | *.psess 95 | *.vsp 96 | *.vspx 97 | *.sap 98 | 99 | # Visual Studio Trace Files 100 | *.e2e 101 | 102 | # TFS 2012 Local Workspace 103 | $tf/ 104 | 105 | # Guidance Automation Toolkit 106 | *.gpState 107 | 108 | # ReSharper is a .NET coding add-in 109 | _ReSharper*/ 110 | *.[Rr]e[Ss]harper 111 | *.DotSettings.user 112 | 113 | # JustCode is a .NET coding add-in 114 | .JustCode 115 | 116 | # TeamCity is a build add-in 117 | _TeamCity* 118 | 119 | # DotCover is a Code Coverage Tool 120 | *.dotCover 121 | 122 | # AxoCover is a Code Coverage Tool 123 | .axoCover/* 124 | !.axoCover/settings.json 125 | 126 | # Visual Studio code coverage results 127 | *.coverage 128 | *.coveragexml 129 | 130 | # NCrunch 131 | _NCrunch_* 132 | .*crunch*.local.xml 133 | nCrunchTemp_* 134 | 135 | # MightyMoose 136 | *.mm.* 137 | AutoTest.Net/ 138 | 139 | # Web workbench (sass) 140 | .sass-cache/ 141 | 142 | # Installshield output folder 143 | [Ee]xpress/ 144 | 145 | # DocProject is a documentation generator add-in 146 | DocProject/buildhelp/ 147 | DocProject/Help/*.HxT 148 | DocProject/Help/*.HxC 149 | DocProject/Help/*.hhc 150 | DocProject/Help/*.hhk 151 | DocProject/Help/*.hhp 152 | DocProject/Help/Html2 153 | DocProject/Help/html 154 | 155 | # Click-Once directory 156 | publish/ 157 | 158 | # Publish Web Output 159 | *.[Pp]ublish.xml 160 | *.azurePubxml 161 | # Note: Comment the next line if you want to checkin your web deploy settings, 162 | # but database connection strings (with potential passwords) will be unencrypted 163 | *.pubxml 164 | *.publishproj 165 | 166 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 167 | # checkin your Azure Web App publish settings, but sensitive information contained 168 | # in these scripts will be unencrypted 169 | PublishScripts/ 170 | 171 | # NuGet Packages 172 | *.nupkg 173 | # The packages folder can be ignored because of Package Restore 174 | **/[Pp]ackages/* 175 | # except build/, which is used as an MSBuild target. 176 | !**/[Pp]ackages/build/ 177 | # Uncomment if necessary however generally it will be regenerated when needed 178 | #!**/[Pp]ackages/repositories.config 179 | # NuGet v3's project.json files produces more ignorable files 180 | *.nuget.props 181 | *.nuget.targets 182 | 183 | # Microsoft Azure Build Output 184 | csx/ 185 | *.build.csdef 186 | 187 | # Microsoft Azure Emulator 188 | ecf/ 189 | rcf/ 190 | 191 | # Windows Store app package directories and files 192 | AppPackages/ 193 | BundleArtifacts/ 194 | Package.StoreAssociation.xml 195 | _pkginfo.txt 196 | *.appx 197 | 198 | # Visual Studio cache files 199 | # files ending in .cache can be ignored 200 | *.[Cc]ache 201 | # but keep track of directories ending in .cache 202 | !*.[Cc]ache/ 203 | 204 | # Others 205 | ClientBin/ 206 | ~$* 207 | *~ 208 | *.dbmdl 209 | *.dbproj.schemaview 210 | *.jfm 211 | *.pfx 212 | *.publishsettings 213 | orleans.codegen.cs 214 | 215 | # Since there are multiple workflows, uncomment next line to ignore bower_components 216 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 217 | #bower_components/ 218 | 219 | # RIA/Silverlight projects 220 | Generated_Code/ 221 | 222 | # Backup & report files from converting an old project file 223 | # to a newer Visual Studio version. Backup files are not needed, 224 | # because we have git ;-) 225 | _UpgradeReport_Files/ 226 | Backup*/ 227 | UpgradeLog*.XML 228 | UpgradeLog*.htm 229 | 230 | # SQL Server files 231 | *.mdf 232 | *.ldf 233 | *.ndf 234 | 235 | # Business Intelligence projects 236 | *.rdl.data 237 | *.bim.layout 238 | *.bim_*.settings 239 | 240 | # Microsoft Fakes 241 | FakesAssemblies/ 242 | 243 | # GhostDoc plugin setting file 244 | *.GhostDoc.xml 245 | 246 | # Node.js Tools for Visual Studio 247 | .ntvs_analysis.dat 248 | node_modules/ 249 | 250 | # Typescript v1 declaration files 251 | typings/ 252 | 253 | # Visual Studio 6 build log 254 | *.plg 255 | 256 | # Visual Studio 6 workspace options file 257 | *.opt 258 | 259 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 260 | *.vbw 261 | 262 | # Visual Studio LightSwitch build output 263 | **/*.HTMLClient/GeneratedArtifacts 264 | **/*.DesktopClient/GeneratedArtifacts 265 | **/*.DesktopClient/ModelManifest.xml 266 | **/*.Server/GeneratedArtifacts 267 | **/*.Server/ModelManifest.xml 268 | _Pvt_Extensions 269 | 270 | # Paket dependency manager 271 | .paket/paket.exe 272 | paket-files/ 273 | 274 | # FAKE - F# Make 275 | .fake/ 276 | 277 | # JetBrains Rider 278 | .idea/ 279 | *.sln.iml 280 | 281 | # CodeRush 282 | .cr/ 283 | 284 | # Python Tools for Visual Studio (PTVS) 285 | __pycache__/ 286 | *.pyc 287 | 288 | # Cake - Uncomment if you are using it 289 | # tools/** 290 | # !tools/packages.config 291 | 292 | # Tabs Studio 293 | *.tss 294 | 295 | # Telerik's JustMock configuration file 296 | *.jmconfig 297 | 298 | # BizTalk build output 299 | *.btp.cs 300 | *.btm.cs 301 | *.odx.cs 302 | *.xsd.cs 303 | 304 | # OpenCover UI analysis results 305 | OpenCover/ -------------------------------------------------------------------------------- /data/RankViewer/RankNumbers/30.json: -------------------------------------------------------------------------------- 1 | {"data":{"tiers":["Unranked","Bronze I","Bronze II","Bronze III","Silver I","Silver II","Silver III","Gold I","Gold II","Gold III","Platinum I","Platinum II","Platinum III","Diamond I","Diamond II","Diamond III","Champion I","Champion II","Champion III","Grand Champion I","Grand Champion II","Grand Champion III","Supersonic Legend"],"divisions":["Division I","Division II","Division III","Division IV"],"playlists":[{"key":0,"value":"Un-Ranked"},{"key":10,"value":"Ranked Duel 1v1"},{"key":11,"value":"Ranked Doubles 2v2"},{"key":13,"value":"Ranked Standard 3v3"},{"key":27,"value":"Hoops"},{"key":28,"value":"Rumble"},{"key":29,"value":"Dropshot"},{"key":30,"value":"Snowday"},{"key":34,"value":"Tournament Matches"}],"data":[{"id":0,"tier":0,"playlist":30,"players":0,"division":0,"minMMR":393,"maxMMR":913},{"id":1,"tier":1,"playlist":30,"players":0,"division":0,"minMMR":0,"maxMMR":91},{"id":2,"tier":1,"playlist":30,"players":0,"division":1,"minMMR":135,"maxMMR":157},{"id":3,"tier":1,"playlist":30,"players":0,"division":2,"minMMR":163,"maxMMR":184},{"id":4,"tier":1,"playlist":30,"players":0,"division":3,"minMMR":187,"maxMMR":199},{"id":5,"tier":2,"playlist":30,"players":0,"division":0,"minMMR":211,"maxMMR":218},{"id":6,"tier":2,"playlist":30,"players":0,"division":1,"minMMR":220,"maxMMR":237},{"id":7,"tier":2,"playlist":30,"players":0,"division":2,"minMMR":239,"maxMMR":255},{"id":8,"tier":2,"playlist":30,"players":0,"division":3,"minMMR":257,"maxMMR":274},{"id":9,"tier":3,"playlist":30,"players":0,"division":0,"minMMR":267,"maxMMR":278},{"id":10,"tier":3,"playlist":30,"players":0,"division":1,"minMMR":279,"maxMMR":297},{"id":11,"tier":3,"playlist":30,"players":0,"division":2,"minMMR":298,"maxMMR":315},{"id":12,"tier":3,"playlist":30,"players":0,"division":3,"minMMR":317,"maxMMR":333},{"id":13,"tier":4,"playlist":30,"players":0,"division":0,"minMMR":321,"maxMMR":333},{"id":14,"tier":4,"playlist":30,"players":0,"division":1,"minMMR":335,"maxMMR":347},{"id":15,"tier":4,"playlist":30,"players":0,"division":2,"minMMR":348,"maxMMR":360},{"id":16,"tier":4,"playlist":30,"players":0,"division":3,"minMMR":362,"maxMMR":373},{"id":17,"tier":5,"playlist":30,"players":0,"division":0,"minMMR":374,"maxMMR":378},{"id":18,"tier":5,"playlist":30,"players":0,"division":1,"minMMR":379,"maxMMR":397},{"id":19,"tier":5,"playlist":30,"players":0,"division":2,"minMMR":398,"maxMMR":416},{"id":20,"tier":5,"playlist":30,"players":0,"division":3,"minMMR":417,"maxMMR":431},{"id":21,"tier":6,"playlist":30,"players":0,"division":0,"minMMR":422,"maxMMR":433},{"id":22,"tier":6,"playlist":30,"players":0,"division":1,"minMMR":435,"maxMMR":447},{"id":23,"tier":6,"playlist":30,"players":0,"division":2,"minMMR":448,"maxMMR":461},{"id":24,"tier":6,"playlist":30,"players":0,"division":3,"minMMR":462,"maxMMR":474},{"id":25,"tier":7,"playlist":30,"players":0,"division":0,"minMMR":469,"maxMMR":478},{"id":26,"tier":7,"playlist":30,"players":0,"division":1,"minMMR":479,"maxMMR":497},{"id":27,"tier":7,"playlist":30,"players":0,"division":2,"minMMR":498,"maxMMR":516},{"id":28,"tier":7,"playlist":30,"players":0,"division":3,"minMMR":517,"maxMMR":531},{"id":29,"tier":8,"playlist":30,"players":0,"division":0,"minMMR":524,"maxMMR":533},{"id":30,"tier":8,"playlist":30,"players":0,"division":1,"minMMR":535,"maxMMR":547},{"id":31,"tier":8,"playlist":30,"players":0,"division":2,"minMMR":548,"maxMMR":561},{"id":32,"tier":8,"playlist":30,"players":0,"division":3,"minMMR":562,"maxMMR":574},{"id":33,"tier":9,"playlist":30,"players":0,"division":0,"minMMR":573,"maxMMR":578},{"id":34,"tier":9,"playlist":30,"players":0,"division":1,"minMMR":579,"maxMMR":597},{"id":35,"tier":9,"playlist":30,"players":0,"division":2,"minMMR":598,"maxMMR":616},{"id":36,"tier":9,"playlist":30,"players":0,"division":3,"minMMR":617,"maxMMR":626},{"id":37,"tier":10,"playlist":30,"players":0,"division":0,"minMMR":623,"maxMMR":633},{"id":38,"tier":10,"playlist":30,"players":0,"division":1,"minMMR":635,"maxMMR":647},{"id":39,"tier":10,"playlist":30,"players":0,"division":2,"minMMR":648,"maxMMR":661},{"id":40,"tier":10,"playlist":30,"players":0,"division":3,"minMMR":662,"maxMMR":674},{"id":41,"tier":11,"playlist":30,"players":0,"division":0,"minMMR":670,"maxMMR":678},{"id":42,"tier":11,"playlist":30,"players":0,"division":1,"minMMR":679,"maxMMR":697},{"id":43,"tier":11,"playlist":30,"players":0,"division":2,"minMMR":698,"maxMMR":716},{"id":44,"tier":11,"playlist":30,"players":0,"division":3,"minMMR":717,"maxMMR":723},{"id":45,"tier":12,"playlist":30,"players":0,"division":0,"minMMR":723,"maxMMR":733},{"id":46,"tier":12,"playlist":30,"players":0,"division":1,"minMMR":734,"maxMMR":747},{"id":47,"tier":12,"playlist":30,"players":0,"division":2,"minMMR":748,"maxMMR":761},{"id":48,"tier":12,"playlist":30,"players":0,"division":3,"minMMR":762,"maxMMR":772},{"id":49,"tier":13,"playlist":30,"players":0,"division":0,"minMMR":774,"maxMMR":778},{"id":50,"tier":13,"playlist":30,"players":0,"division":1,"minMMR":779,"maxMMR":797},{"id":51,"tier":13,"playlist":30,"players":0,"division":2,"minMMR":798,"maxMMR":816},{"id":52,"tier":13,"playlist":30,"players":0,"division":3,"minMMR":817,"maxMMR":825},{"id":53,"tier":14,"playlist":30,"players":0,"division":0,"minMMR":825,"maxMMR":833},{"id":54,"tier":14,"playlist":30,"players":0,"division":1,"minMMR":834,"maxMMR":847},{"id":55,"tier":14,"playlist":30,"players":0,"division":2,"minMMR":848,"maxMMR":861},{"id":56,"tier":14,"playlist":30,"players":0,"division":3,"minMMR":862,"maxMMR":872},{"id":57,"tier":15,"playlist":30,"players":0,"division":0,"minMMR":869,"maxMMR":878},{"id":58,"tier":15,"playlist":30,"players":0,"division":1,"minMMR":879,"maxMMR":897},{"id":59,"tier":15,"playlist":30,"players":0,"division":2,"minMMR":898,"maxMMR":916},{"id":60,"tier":15,"playlist":30,"players":0,"division":3,"minMMR":917,"maxMMR":924},{"id":61,"tier":16,"playlist":30,"players":0,"division":0,"minMMR":924,"maxMMR":933},{"id":62,"tier":16,"playlist":30,"players":0,"division":1,"minMMR":935,"maxMMR":947},{"id":63,"tier":16,"playlist":30,"players":0,"division":2,"minMMR":948,"maxMMR":961},{"id":64,"tier":16,"playlist":30,"players":0,"division":3,"minMMR":962,"maxMMR":971},{"id":65,"tier":17,"playlist":30,"players":0,"division":0,"minMMR":967,"maxMMR":978},{"id":66,"tier":17,"playlist":30,"players":0,"division":1,"minMMR":979,"maxMMR":997},{"id":67,"tier":17,"playlist":30,"players":0,"division":2,"minMMR":998,"maxMMR":1015},{"id":68,"tier":17,"playlist":30,"players":0,"division":3,"minMMR":1017,"maxMMR":1025},{"id":69,"tier":18,"playlist":30,"players":0,"division":0,"minMMR":1026,"maxMMR":1038},{"id":70,"tier":18,"playlist":30,"players":0,"division":1,"minMMR":1039,"maxMMR":1057},{"id":71,"tier":18,"playlist":30,"players":0,"division":2,"minMMR":1058,"maxMMR":1074},{"id":72,"tier":18,"playlist":30,"players":0,"division":3,"minMMR":1077,"maxMMR":1086},{"id":73,"tier":19,"playlist":30,"players":0,"division":0,"minMMR":1086,"maxMMR":1098},{"id":74,"tier":19,"playlist":30,"players":0,"division":1,"minMMR":1099,"maxMMR":1117},{"id":75,"tier":19,"playlist":30,"players":0,"division":2,"minMMR":1118,"maxMMR":1135},{"id":76,"tier":19,"playlist":30,"players":0,"division":3,"minMMR":1137,"maxMMR":1150},{"id":77,"tier":20,"playlist":30,"players":0,"division":0,"minMMR":1143,"maxMMR":1158},{"id":78,"tier":20,"playlist":30,"players":0,"division":1,"minMMR":1160,"maxMMR":1168},{"id":79,"tier":20,"playlist":30,"players":0,"division":2,"minMMR":1178,"maxMMR":1195},{"id":80,"tier":20,"playlist":30,"players":0,"division":3,"minMMR":1197,"maxMMR":1210},{"id":81,"tier":21,"playlist":30,"players":0,"division":0,"minMMR":1205,"maxMMR":1218},{"id":82,"tier":21,"playlist":30,"players":0,"division":1,"minMMR":1219,"maxMMR":1236},{"id":83,"tier":21,"playlist":30,"players":0,"division":2,"minMMR":1239,"maxMMR":1254},{"id":84,"tier":21,"playlist":30,"players":0,"division":3,"minMMR":1257,"maxMMR":1268},{"id":85,"tier":22,"playlist":30,"players":0,"division":0,"minMMR":1261,"maxMMR":1402}]}} -------------------------------------------------------------------------------- /data/RankViewer/RankNumbers/27.json: -------------------------------------------------------------------------------- 1 | {"data":{"tiers":["Unranked","Bronze I","Bronze II","Bronze III","Silver I","Silver II","Silver III","Gold I","Gold II","Gold III","Platinum I","Platinum II","Platinum III","Diamond I","Diamond II","Diamond III","Champion I","Champion II","Champion III","Grand Champion I","Grand Champion II","Grand Champion III","Supersonic Legend"],"divisions":["Division I","Division II","Division III","Division IV"],"playlists":[{"key":0,"value":"Un-Ranked"},{"key":10,"value":"Ranked Duel 1v1"},{"key":11,"value":"Ranked Doubles 2v2"},{"key":13,"value":"Ranked Standard 3v3"},{"key":27,"value":"Hoops"},{"key":28,"value":"Rumble"},{"key":29,"value":"Dropshot"},{"key":30,"value":"Snowday"},{"key":34,"value":"Tournament Matches"}],"data":[{"id":0,"tier":0,"playlist":27,"players":0,"division":0,"minMMR":468,"maxMMR":1160},{"id":1,"tier":1,"playlist":27,"players":0,"division":0,"minMMR":0,"maxMMR":114},{"id":2,"tier":1,"playlist":27,"players":0,"division":1,"minMMR":141,"maxMMR":156},{"id":3,"tier":1,"playlist":27,"players":0,"division":2,"minMMR":162,"maxMMR":186},{"id":4,"tier":1,"playlist":27,"players":0,"division":3,"minMMR":194,"maxMMR":200},{"id":5,"tier":2,"playlist":27,"players":0,"division":0,"minMMR":205,"maxMMR":216},{"id":6,"tier":2,"playlist":27,"players":0,"division":1,"minMMR":226,"maxMMR":233},{"id":7,"tier":2,"playlist":27,"players":0,"division":2,"minMMR":241,"maxMMR":254},{"id":8,"tier":2,"playlist":27,"players":0,"division":3,"minMMR":257,"maxMMR":270},{"id":9,"tier":3,"playlist":27,"players":0,"division":0,"minMMR":263,"maxMMR":278},{"id":10,"tier":3,"playlist":27,"players":0,"division":1,"minMMR":280,"maxMMR":297},{"id":11,"tier":3,"playlist":27,"players":0,"division":2,"minMMR":302,"maxMMR":316},{"id":12,"tier":3,"playlist":27,"players":0,"division":3,"minMMR":317,"maxMMR":334},{"id":13,"tier":4,"playlist":27,"players":0,"division":0,"minMMR":325,"maxMMR":333},{"id":14,"tier":4,"playlist":27,"players":0,"division":1,"minMMR":335,"maxMMR":347},{"id":15,"tier":4,"playlist":27,"players":0,"division":2,"minMMR":348,"maxMMR":360},{"id":16,"tier":4,"playlist":27,"players":0,"division":3,"minMMR":362,"maxMMR":374},{"id":17,"tier":5,"playlist":27,"players":0,"division":0,"minMMR":365,"maxMMR":378},{"id":18,"tier":5,"playlist":27,"players":0,"division":1,"minMMR":379,"maxMMR":397},{"id":19,"tier":5,"playlist":27,"players":0,"division":2,"minMMR":398,"maxMMR":416},{"id":20,"tier":5,"playlist":27,"players":0,"division":3,"minMMR":417,"maxMMR":433},{"id":21,"tier":6,"playlist":27,"players":0,"division":0,"minMMR":423,"maxMMR":433},{"id":22,"tier":6,"playlist":27,"players":0,"division":1,"minMMR":435,"maxMMR":447},{"id":23,"tier":6,"playlist":27,"players":0,"division":2,"minMMR":448,"maxMMR":461},{"id":24,"tier":6,"playlist":27,"players":0,"division":3,"minMMR":463,"maxMMR":474},{"id":25,"tier":7,"playlist":27,"players":0,"division":0,"minMMR":465,"maxMMR":478},{"id":26,"tier":7,"playlist":27,"players":0,"division":1,"minMMR":479,"maxMMR":497},{"id":27,"tier":7,"playlist":27,"players":0,"division":2,"minMMR":498,"maxMMR":516},{"id":28,"tier":7,"playlist":27,"players":0,"division":3,"minMMR":517,"maxMMR":522},{"id":29,"tier":8,"playlist":27,"players":0,"division":0,"minMMR":521,"maxMMR":533},{"id":30,"tier":8,"playlist":27,"players":0,"division":1,"minMMR":534,"maxMMR":547},{"id":31,"tier":8,"playlist":27,"players":0,"division":2,"minMMR":548,"maxMMR":561},{"id":32,"tier":8,"playlist":27,"players":0,"division":3,"minMMR":562,"maxMMR":574},{"id":33,"tier":9,"playlist":27,"players":0,"division":0,"minMMR":574,"maxMMR":578},{"id":34,"tier":9,"playlist":27,"players":0,"division":1,"minMMR":579,"maxMMR":597},{"id":35,"tier":9,"playlist":27,"players":0,"division":2,"minMMR":598,"maxMMR":616},{"id":36,"tier":9,"playlist":27,"players":0,"division":3,"minMMR":617,"maxMMR":622},{"id":37,"tier":10,"playlist":27,"players":0,"division":0,"minMMR":623,"maxMMR":633},{"id":38,"tier":10,"playlist":27,"players":0,"division":1,"minMMR":634,"maxMMR":647},{"id":39,"tier":10,"playlist":27,"players":0,"division":2,"minMMR":648,"maxMMR":661},{"id":40,"tier":10,"playlist":27,"players":0,"division":3,"minMMR":662,"maxMMR":672},{"id":41,"tier":11,"playlist":27,"players":0,"division":0,"minMMR":671,"maxMMR":678},{"id":42,"tier":11,"playlist":27,"players":0,"division":1,"minMMR":679,"maxMMR":697},{"id":43,"tier":11,"playlist":27,"players":0,"division":2,"minMMR":698,"maxMMR":716},{"id":44,"tier":11,"playlist":27,"players":0,"division":3,"minMMR":717,"maxMMR":722},{"id":45,"tier":12,"playlist":27,"players":0,"division":0,"minMMR":723,"maxMMR":733},{"id":46,"tier":12,"playlist":27,"players":0,"division":1,"minMMR":734,"maxMMR":747},{"id":47,"tier":12,"playlist":27,"players":0,"division":2,"minMMR":748,"maxMMR":761},{"id":48,"tier":12,"playlist":27,"players":0,"division":3,"minMMR":762,"maxMMR":769},{"id":49,"tier":13,"playlist":27,"players":0,"division":0,"minMMR":774,"maxMMR":778},{"id":50,"tier":13,"playlist":27,"players":0,"division":1,"minMMR":779,"maxMMR":797},{"id":51,"tier":13,"playlist":27,"players":0,"division":2,"minMMR":798,"maxMMR":816},{"id":52,"tier":13,"playlist":27,"players":0,"division":3,"minMMR":817,"maxMMR":823},{"id":53,"tier":14,"playlist":27,"players":0,"division":0,"minMMR":824,"maxMMR":833},{"id":54,"tier":14,"playlist":27,"players":0,"division":1,"minMMR":834,"maxMMR":847},{"id":55,"tier":14,"playlist":27,"players":0,"division":2,"minMMR":848,"maxMMR":861},{"id":56,"tier":14,"playlist":27,"players":0,"division":3,"minMMR":862,"maxMMR":869},{"id":57,"tier":15,"playlist":27,"players":0,"division":0,"minMMR":867,"maxMMR":878},{"id":58,"tier":15,"playlist":27,"players":0,"division":1,"minMMR":879,"maxMMR":897},{"id":59,"tier":15,"playlist":27,"players":0,"division":2,"minMMR":898,"maxMMR":916},{"id":60,"tier":15,"playlist":27,"players":0,"division":3,"minMMR":917,"maxMMR":922},{"id":61,"tier":16,"playlist":27,"players":0,"division":0,"minMMR":924,"maxMMR":933},{"id":62,"tier":16,"playlist":27,"players":0,"division":1,"minMMR":935,"maxMMR":947},{"id":63,"tier":16,"playlist":27,"players":0,"division":2,"minMMR":948,"maxMMR":961},{"id":64,"tier":16,"playlist":27,"players":0,"division":3,"minMMR":962,"maxMMR":971},{"id":65,"tier":17,"playlist":27,"players":0,"division":0,"minMMR":969,"maxMMR":978},{"id":66,"tier":17,"playlist":27,"players":0,"division":1,"minMMR":979,"maxMMR":997},{"id":67,"tier":17,"playlist":27,"players":0,"division":2,"minMMR":998,"maxMMR":1016},{"id":68,"tier":17,"playlist":27,"players":0,"division":3,"minMMR":1017,"maxMMR":1023},{"id":69,"tier":18,"playlist":27,"players":0,"division":0,"minMMR":1027,"maxMMR":1038},{"id":70,"tier":18,"playlist":27,"players":0,"division":1,"minMMR":1039,"maxMMR":1057},{"id":71,"tier":18,"playlist":27,"players":0,"division":2,"minMMR":1058,"maxMMR":1076},{"id":72,"tier":18,"playlist":27,"players":0,"division":3,"minMMR":1077,"maxMMR":1083},{"id":73,"tier":19,"playlist":27,"players":0,"division":0,"minMMR":1095,"maxMMR":1098},{"id":74,"tier":19,"playlist":27,"players":0,"division":1,"minMMR":1099,"maxMMR":1117},{"id":75,"tier":19,"playlist":27,"players":0,"division":2,"minMMR":1118,"maxMMR":1134},{"id":76,"tier":19,"playlist":27,"players":0,"division":3,"minMMR":1137,"maxMMR":1152},{"id":77,"tier":20,"playlist":27,"players":0,"division":0,"minMMR":1146,"maxMMR":1158},{"id":78,"tier":20,"playlist":27,"players":0,"division":1,"minMMR":1160,"maxMMR":1175},{"id":79,"tier":20,"playlist":27,"players":0,"division":2,"minMMR":1178,"maxMMR":1195},{"id":80,"tier":20,"playlist":27,"players":0,"division":3,"minMMR":1197,"maxMMR":1204},{"id":81,"tier":21,"playlist":27,"players":0,"division":0,"minMMR":1205,"maxMMR":1218},{"id":82,"tier":21,"playlist":27,"players":0,"division":1,"minMMR":1219,"maxMMR":1232},{"id":83,"tier":21,"playlist":27,"players":0,"division":2,"minMMR":1238,"maxMMR":1255},{"id":84,"tier":21,"playlist":27,"players":0,"division":3,"minMMR":1257,"maxMMR":1265},{"id":85,"tier":22,"playlist":27,"players":0,"division":0,"minMMR":1262,"maxMMR":1345}]}} -------------------------------------------------------------------------------- /data/RankViewer/RankNumbers/29.json: -------------------------------------------------------------------------------- 1 | {"data":{"tiers":["Unranked","Bronze I","Bronze II","Bronze III","Silver I","Silver II","Silver III","Gold I","Gold II","Gold III","Platinum I","Platinum II","Platinum III","Diamond I","Diamond II","Diamond III","Champion I","Champion II","Champion III","Grand Champion I","Grand Champion II","Grand Champion III","Supersonic Legend"],"divisions":["Division I","Division II","Division III","Division IV"],"playlists":[{"key":0,"value":"Un-Ranked"},{"key":10,"value":"Ranked Duel 1v1"},{"key":11,"value":"Ranked Doubles 2v2"},{"key":13,"value":"Ranked Standard 3v3"},{"key":27,"value":"Hoops"},{"key":28,"value":"Rumble"},{"key":29,"value":"Dropshot"},{"key":30,"value":"Snowday"},{"key":34,"value":"Tournament Matches"}],"data":[{"id":0,"tier":0,"playlist":29,"players":0,"division":0,"minMMR":397,"maxMMR":825},{"id":1,"tier":1,"playlist":29,"players":0,"division":0,"minMMR":0,"maxMMR":125},{"id":2,"tier":1,"playlist":29,"players":0,"division":1,"minMMR":130,"maxMMR":156},{"id":3,"tier":1,"playlist":29,"players":0,"division":2,"minMMR":158,"maxMMR":185},{"id":4,"tier":1,"playlist":29,"players":0,"division":3,"minMMR":187,"maxMMR":212},{"id":5,"tier":2,"playlist":29,"players":0,"division":0,"minMMR":205,"maxMMR":218},{"id":6,"tier":2,"playlist":29,"players":0,"division":1,"minMMR":220,"maxMMR":236},{"id":7,"tier":2,"playlist":29,"players":0,"division":2,"minMMR":239,"maxMMR":255},{"id":8,"tier":2,"playlist":29,"players":0,"division":3,"minMMR":257,"maxMMR":274},{"id":9,"tier":3,"playlist":29,"players":0,"division":0,"minMMR":265,"maxMMR":278},{"id":10,"tier":3,"playlist":29,"players":0,"division":1,"minMMR":279,"maxMMR":297},{"id":11,"tier":3,"playlist":29,"players":0,"division":2,"minMMR":298,"maxMMR":316},{"id":12,"tier":3,"playlist":29,"players":0,"division":3,"minMMR":317,"maxMMR":334},{"id":13,"tier":4,"playlist":29,"players":0,"division":0,"minMMR":323,"maxMMR":333},{"id":14,"tier":4,"playlist":29,"players":0,"division":1,"minMMR":334,"maxMMR":347},{"id":15,"tier":4,"playlist":29,"players":0,"division":2,"minMMR":348,"maxMMR":361},{"id":16,"tier":4,"playlist":29,"players":0,"division":3,"minMMR":362,"maxMMR":374},{"id":17,"tier":5,"playlist":29,"players":0,"division":0,"minMMR":371,"maxMMR":378},{"id":18,"tier":5,"playlist":29,"players":0,"division":1,"minMMR":379,"maxMMR":397},{"id":19,"tier":5,"playlist":29,"players":0,"division":2,"minMMR":398,"maxMMR":416},{"id":20,"tier":5,"playlist":29,"players":0,"division":3,"minMMR":417,"maxMMR":423},{"id":21,"tier":6,"playlist":29,"players":0,"division":0,"minMMR":422,"maxMMR":433},{"id":22,"tier":6,"playlist":29,"players":0,"division":1,"minMMR":434,"maxMMR":447},{"id":23,"tier":6,"playlist":29,"players":0,"division":2,"minMMR":448,"maxMMR":461},{"id":24,"tier":6,"playlist":29,"players":0,"division":3,"minMMR":462,"maxMMR":474},{"id":25,"tier":7,"playlist":29,"players":0,"division":0,"minMMR":470,"maxMMR":478},{"id":26,"tier":7,"playlist":29,"players":0,"division":1,"minMMR":479,"maxMMR":497},{"id":27,"tier":7,"playlist":29,"players":0,"division":2,"minMMR":498,"maxMMR":516},{"id":28,"tier":7,"playlist":29,"players":0,"division":3,"minMMR":517,"maxMMR":523},{"id":29,"tier":8,"playlist":29,"players":0,"division":0,"minMMR":523,"maxMMR":533},{"id":30,"tier":8,"playlist":29,"players":0,"division":1,"minMMR":534,"maxMMR":547},{"id":31,"tier":8,"playlist":29,"players":0,"division":2,"minMMR":548,"maxMMR":561},{"id":32,"tier":8,"playlist":29,"players":0,"division":3,"minMMR":562,"maxMMR":573},{"id":33,"tier":9,"playlist":29,"players":0,"division":0,"minMMR":569,"maxMMR":578},{"id":34,"tier":9,"playlist":29,"players":0,"division":1,"minMMR":579,"maxMMR":597},{"id":35,"tier":9,"playlist":29,"players":0,"division":2,"minMMR":598,"maxMMR":616},{"id":36,"tier":9,"playlist":29,"players":0,"division":3,"minMMR":617,"maxMMR":622},{"id":37,"tier":10,"playlist":29,"players":0,"division":0,"minMMR":624,"maxMMR":633},{"id":38,"tier":10,"playlist":29,"players":0,"division":1,"minMMR":634,"maxMMR":647},{"id":39,"tier":10,"playlist":29,"players":0,"division":2,"minMMR":648,"maxMMR":661},{"id":40,"tier":10,"playlist":29,"players":0,"division":3,"minMMR":662,"maxMMR":673},{"id":41,"tier":11,"playlist":29,"players":0,"division":0,"minMMR":672,"maxMMR":678},{"id":42,"tier":11,"playlist":29,"players":0,"division":1,"minMMR":679,"maxMMR":697},{"id":43,"tier":11,"playlist":29,"players":0,"division":2,"minMMR":698,"maxMMR":716},{"id":44,"tier":11,"playlist":29,"players":0,"division":3,"minMMR":717,"maxMMR":722},{"id":45,"tier":12,"playlist":29,"players":0,"division":0,"minMMR":724,"maxMMR":733},{"id":46,"tier":12,"playlist":29,"players":0,"division":1,"minMMR":734,"maxMMR":747},{"id":47,"tier":12,"playlist":29,"players":0,"division":2,"minMMR":748,"maxMMR":761},{"id":48,"tier":12,"playlist":29,"players":0,"division":3,"minMMR":762,"maxMMR":770},{"id":49,"tier":13,"playlist":29,"players":0,"division":0,"minMMR":773,"maxMMR":778},{"id":50,"tier":13,"playlist":29,"players":0,"division":1,"minMMR":779,"maxMMR":797},{"id":51,"tier":13,"playlist":29,"players":0,"division":2,"minMMR":798,"maxMMR":816},{"id":52,"tier":13,"playlist":29,"players":0,"division":3,"minMMR":817,"maxMMR":826},{"id":53,"tier":14,"playlist":29,"players":0,"division":0,"minMMR":824,"maxMMR":833},{"id":54,"tier":14,"playlist":29,"players":0,"division":1,"minMMR":834,"maxMMR":847},{"id":55,"tier":14,"playlist":29,"players":0,"division":2,"minMMR":848,"maxMMR":861},{"id":56,"tier":14,"playlist":29,"players":0,"division":3,"minMMR":862,"maxMMR":867},{"id":57,"tier":15,"playlist":29,"players":0,"division":0,"minMMR":868,"maxMMR":878},{"id":58,"tier":15,"playlist":29,"players":0,"division":1,"minMMR":879,"maxMMR":897},{"id":59,"tier":15,"playlist":29,"players":0,"division":2,"minMMR":898,"maxMMR":916},{"id":60,"tier":15,"playlist":29,"players":0,"division":3,"minMMR":917,"maxMMR":924},{"id":61,"tier":16,"playlist":29,"players":0,"division":0,"minMMR":925,"maxMMR":933},{"id":62,"tier":16,"playlist":29,"players":0,"division":1,"minMMR":935,"maxMMR":947},{"id":63,"tier":16,"playlist":29,"players":0,"division":2,"minMMR":948,"maxMMR":961},{"id":64,"tier":16,"playlist":29,"players":0,"division":3,"minMMR":962,"maxMMR":971},{"id":65,"tier":17,"playlist":29,"players":0,"division":0,"minMMR":971,"maxMMR":978},{"id":66,"tier":17,"playlist":29,"players":0,"division":1,"minMMR":979,"maxMMR":997},{"id":67,"tier":17,"playlist":29,"players":0,"division":2,"minMMR":998,"maxMMR":1016},{"id":68,"tier":17,"playlist":29,"players":0,"division":3,"minMMR":1017,"maxMMR":1030},{"id":69,"tier":18,"playlist":29,"players":0,"division":0,"minMMR":1026,"maxMMR":1038},{"id":70,"tier":18,"playlist":29,"players":0,"division":1,"minMMR":1039,"maxMMR":1057},{"id":71,"tier":18,"playlist":29,"players":0,"division":2,"minMMR":1058,"maxMMR":1075},{"id":72,"tier":18,"playlist":29,"players":0,"division":3,"minMMR":1077,"maxMMR":1091},{"id":73,"tier":19,"playlist":29,"players":0,"division":0,"minMMR":1088,"maxMMR":1098},{"id":74,"tier":19,"playlist":29,"players":0,"division":1,"minMMR":1099,"maxMMR":1110},{"id":75,"tier":19,"playlist":29,"players":0,"division":2,"minMMR":1118,"maxMMR":1136},{"id":76,"tier":19,"playlist":29,"players":0,"division":3,"minMMR":1137,"maxMMR":1154},{"id":77,"tier":20,"playlist":29,"players":0,"division":0,"minMMR":1144,"maxMMR":1158},{"id":78,"tier":20,"playlist":29,"players":0,"division":1,"minMMR":1160,"maxMMR":1177},{"id":79,"tier":20,"playlist":29,"players":0,"division":2,"minMMR":1179,"maxMMR":1194},{"id":80,"tier":20,"playlist":29,"players":0,"division":3,"minMMR":1197,"maxMMR":1213},{"id":81,"tier":21,"playlist":29,"players":0,"division":0,"minMMR":1212,"maxMMR":1218},{"id":82,"tier":21,"playlist":29,"players":0,"division":1,"minMMR":1220,"maxMMR":1236},{"id":83,"tier":21,"playlist":29,"players":0,"division":2,"minMMR":1238,"maxMMR":1254},{"id":84,"tier":21,"playlist":29,"players":0,"division":3,"minMMR":1257,"maxMMR":1269},{"id":85,"tier":22,"playlist":29,"players":0,"division":0,"minMMR":1268,"maxMMR":1289}]}} -------------------------------------------------------------------------------- /data/RankViewer/RankNumbers/10.json: -------------------------------------------------------------------------------- 1 | {"data":{"tiers":["Unranked","Bronze I","Bronze II","Bronze III","Silver I","Silver II","Silver III","Gold I","Gold II","Gold III","Platinum I","Platinum II","Platinum III","Diamond I","Diamond II","Diamond III","Champion I","Champion II","Champion III","Grand Champion I","Grand Champion II","Grand Champion III","Supersonic Legend"],"divisions":["Division I","Division II","Division III","Division IV"],"playlists":[{"key":0,"value":"Un-Ranked"},{"key":10,"value":"Ranked Duel 1v1"},{"key":11,"value":"Ranked Doubles 2v2"},{"key":13,"value":"Ranked Standard 3v3"},{"key":27,"value":"Hoops"},{"key":28,"value":"Rumble"},{"key":29,"value":"Dropshot"},{"key":30,"value":"Snowday"},{"key":34,"value":"Tournament Matches"}],"data":[{"id":0,"tier":0,"playlist":10,"players":0,"division":0,"minMMR":483,"maxMMR":1137},{"id":1,"tier":1,"playlist":10,"players":0,"division":0,"minMMR":0,"maxMMR":114},{"id":2,"tier":1,"playlist":10,"players":0,"division":1,"minMMR":115,"maxMMR":127},{"id":3,"tier":1,"playlist":10,"players":0,"division":2,"minMMR":128,"maxMMR":140},{"id":4,"tier":1,"playlist":10,"players":0,"division":3,"minMMR":144,"maxMMR":154},{"id":5,"tier":2,"playlist":10,"players":0,"division":0,"minMMR":149,"maxMMR":158},{"id":6,"tier":2,"playlist":10,"players":0,"division":1,"minMMR":160,"maxMMR":177},{"id":7,"tier":2,"playlist":10,"players":0,"division":2,"minMMR":178,"maxMMR":196},{"id":8,"tier":2,"playlist":10,"players":0,"division":3,"minMMR":197,"maxMMR":210},{"id":9,"tier":3,"playlist":10,"players":0,"division":0,"minMMR":207,"maxMMR":218},{"id":10,"tier":3,"playlist":10,"players":0,"division":1,"minMMR":219,"maxMMR":237},{"id":11,"tier":3,"playlist":10,"players":0,"division":2,"minMMR":238,"maxMMR":256},{"id":12,"tier":3,"playlist":10,"players":0,"division":3,"minMMR":257,"maxMMR":268},{"id":13,"tier":4,"playlist":10,"players":0,"division":0,"minMMR":269,"maxMMR":278},{"id":14,"tier":4,"playlist":10,"players":0,"division":1,"minMMR":279,"maxMMR":297},{"id":15,"tier":4,"playlist":10,"players":0,"division":2,"minMMR":298,"maxMMR":316},{"id":16,"tier":4,"playlist":10,"players":0,"division":3,"minMMR":317,"maxMMR":320},{"id":17,"tier":5,"playlist":10,"players":0,"division":0,"minMMR":333,"maxMMR":338},{"id":18,"tier":5,"playlist":10,"players":0,"division":1,"minMMR":339,"maxMMR":357},{"id":19,"tier":5,"playlist":10,"players":0,"division":2,"minMMR":358,"maxMMR":376},{"id":20,"tier":5,"playlist":10,"players":0,"division":3,"minMMR":377,"maxMMR":383},{"id":21,"tier":6,"playlist":10,"players":0,"division":0,"minMMR":393,"maxMMR":398},{"id":22,"tier":6,"playlist":10,"players":0,"division":1,"minMMR":399,"maxMMR":417},{"id":23,"tier":6,"playlist":10,"players":0,"division":2,"minMMR":418,"maxMMR":436},{"id":24,"tier":6,"playlist":10,"players":0,"division":3,"minMMR":437,"maxMMR":445},{"id":25,"tier":7,"playlist":10,"players":0,"division":0,"minMMR":453,"maxMMR":458},{"id":26,"tier":7,"playlist":10,"players":0,"division":1,"minMMR":459,"maxMMR":477},{"id":27,"tier":7,"playlist":10,"players":0,"division":2,"minMMR":478,"maxMMR":496},{"id":28,"tier":7,"playlist":10,"players":0,"division":3,"minMMR":497,"maxMMR":505},{"id":29,"tier":8,"playlist":10,"players":0,"division":0,"minMMR":507,"maxMMR":518},{"id":30,"tier":8,"playlist":10,"players":0,"division":1,"minMMR":519,"maxMMR":537},{"id":31,"tier":8,"playlist":10,"players":0,"division":2,"minMMR":538,"maxMMR":556},{"id":32,"tier":8,"playlist":10,"players":0,"division":3,"minMMR":557,"maxMMR":565},{"id":33,"tier":9,"playlist":10,"players":0,"division":0,"minMMR":567,"maxMMR":578},{"id":34,"tier":9,"playlist":10,"players":0,"division":1,"minMMR":579,"maxMMR":597},{"id":35,"tier":9,"playlist":10,"players":0,"division":2,"minMMR":598,"maxMMR":616},{"id":36,"tier":9,"playlist":10,"players":0,"division":3,"minMMR":617,"maxMMR":626},{"id":37,"tier":10,"playlist":10,"players":0,"division":0,"minMMR":627,"maxMMR":638},{"id":38,"tier":10,"playlist":10,"players":0,"division":1,"minMMR":639,"maxMMR":657},{"id":39,"tier":10,"playlist":10,"players":0,"division":2,"minMMR":658,"maxMMR":676},{"id":40,"tier":10,"playlist":10,"players":0,"division":3,"minMMR":677,"maxMMR":686},{"id":41,"tier":11,"playlist":10,"players":0,"division":0,"minMMR":686,"maxMMR":698},{"id":42,"tier":11,"playlist":10,"players":0,"division":1,"minMMR":699,"maxMMR":717},{"id":43,"tier":11,"playlist":10,"players":0,"division":2,"minMMR":718,"maxMMR":736},{"id":44,"tier":11,"playlist":10,"players":0,"division":3,"minMMR":737,"maxMMR":746},{"id":45,"tier":12,"playlist":10,"players":0,"division":0,"minMMR":746,"maxMMR":758},{"id":46,"tier":12,"playlist":10,"players":0,"division":1,"minMMR":759,"maxMMR":777},{"id":47,"tier":12,"playlist":10,"players":0,"division":2,"minMMR":778,"maxMMR":796},{"id":48,"tier":12,"playlist":10,"players":0,"division":3,"minMMR":797,"maxMMR":806},{"id":49,"tier":13,"playlist":10,"players":0,"division":0,"minMMR":807,"maxMMR":818},{"id":50,"tier":13,"playlist":10,"players":0,"division":1,"minMMR":819,"maxMMR":837},{"id":51,"tier":13,"playlist":10,"players":0,"division":2,"minMMR":838,"maxMMR":856},{"id":52,"tier":13,"playlist":10,"players":0,"division":3,"minMMR":857,"maxMMR":866},{"id":53,"tier":14,"playlist":10,"players":0,"division":0,"minMMR":866,"maxMMR":878},{"id":54,"tier":14,"playlist":10,"players":0,"division":1,"minMMR":879,"maxMMR":897},{"id":55,"tier":14,"playlist":10,"players":0,"division":2,"minMMR":898,"maxMMR":916},{"id":56,"tier":14,"playlist":10,"players":0,"division":3,"minMMR":917,"maxMMR":926},{"id":57,"tier":15,"playlist":10,"players":0,"division":0,"minMMR":926,"maxMMR":938},{"id":58,"tier":15,"playlist":10,"players":0,"division":1,"minMMR":939,"maxMMR":957},{"id":59,"tier":15,"playlist":10,"players":0,"division":2,"minMMR":958,"maxMMR":976},{"id":60,"tier":15,"playlist":10,"players":0,"division":3,"minMMR":977,"maxMMR":986},{"id":61,"tier":16,"playlist":10,"players":0,"division":0,"minMMR":987,"maxMMR":998},{"id":62,"tier":16,"playlist":10,"players":0,"division":1,"minMMR":999,"maxMMR":1017},{"id":63,"tier":16,"playlist":10,"players":0,"division":2,"minMMR":1018,"maxMMR":1036},{"id":64,"tier":16,"playlist":10,"players":0,"division":3,"minMMR":1037,"maxMMR":1045},{"id":65,"tier":17,"playlist":10,"players":0,"division":0,"minMMR":1046,"maxMMR":1058},{"id":66,"tier":17,"playlist":10,"players":0,"division":1,"minMMR":1059,"maxMMR":1077},{"id":67,"tier":17,"playlist":10,"players":0,"division":2,"minMMR":1078,"maxMMR":1096},{"id":68,"tier":17,"playlist":10,"players":0,"division":3,"minMMR":1097,"maxMMR":1106},{"id":69,"tier":18,"playlist":10,"players":0,"division":0,"minMMR":1106,"maxMMR":1118},{"id":70,"tier":18,"playlist":10,"players":0,"division":1,"minMMR":1120,"maxMMR":1135},{"id":71,"tier":18,"playlist":10,"players":0,"division":2,"minMMR":1138,"maxMMR":1155},{"id":72,"tier":18,"playlist":10,"players":0,"division":3,"minMMR":1157,"maxMMR":1165},{"id":73,"tier":19,"playlist":10,"players":0,"division":0,"minMMR":1173,"maxMMR":1178},{"id":74,"tier":19,"playlist":10,"players":0,"division":1,"minMMR":1180,"maxMMR":1193},{"id":75,"tier":19,"playlist":10,"players":0,"division":2,"minMMR":1200,"maxMMR":1215},{"id":76,"tier":19,"playlist":10,"players":0,"division":3,"minMMR":1217,"maxMMR":1226},{"id":77,"tier":20,"playlist":10,"players":0,"division":0,"minMMR":1227,"maxMMR":1238},{"id":78,"tier":20,"playlist":10,"players":0,"division":1,"minMMR":1240,"maxMMR":1247},{"id":79,"tier":20,"playlist":10,"players":0,"division":2,"minMMR":1258,"maxMMR":1275},{"id":80,"tier":20,"playlist":10,"players":0,"division":3,"minMMR":1277,"maxMMR":1286},{"id":81,"tier":21,"playlist":10,"players":0,"division":0,"minMMR":1286,"maxMMR":1298},{"id":82,"tier":21,"playlist":10,"players":0,"division":1,"minMMR":1300,"maxMMR":1308},{"id":83,"tier":21,"playlist":10,"players":0,"division":2,"minMMR":1318,"maxMMR":1335},{"id":84,"tier":21,"playlist":10,"players":0,"division":3,"minMMR":1337,"maxMMR":1346},{"id":85,"tier":22,"playlist":10,"players":0,"division":0,"minMMR":1342,"maxMMR":1489}]}} -------------------------------------------------------------------------------- /data/RankViewer/RankNumbers/28.json: -------------------------------------------------------------------------------- 1 | {"data":{"tiers":["Unranked","Bronze I","Bronze II","Bronze III","Silver I","Silver II","Silver III","Gold I","Gold II","Gold III","Platinum I","Platinum II","Platinum III","Diamond I","Diamond II","Diamond III","Champion I","Champion II","Champion III","Grand Champion I","Grand Champion II","Grand Champion III","Supersonic Legend"],"divisions":["Division I","Division II","Division III","Division IV"],"playlists":[{"key":0,"value":"Un-Ranked"},{"key":10,"value":"Ranked Duel 1v1"},{"key":11,"value":"Ranked Doubles 2v2"},{"key":13,"value":"Ranked Standard 3v3"},{"key":27,"value":"Hoops"},{"key":28,"value":"Rumble"},{"key":29,"value":"Dropshot"},{"key":30,"value":"Snowday"},{"key":34,"value":"Tournament Matches"}],"data":[{"id":0,"tier":0,"playlist":28,"players":0,"division":0,"minMMR":477,"maxMMR":1170},{"id":1,"tier":1,"playlist":28,"players":0,"division":0,"minMMR":0,"maxMMR":97},{"id":2,"tier":1,"playlist":28,"players":0,"division":1,"minMMR":114,"maxMMR":124},{"id":3,"tier":1,"playlist":28,"players":0,"division":2,"minMMR":139,"maxMMR":139},{"id":4,"tier":1,"playlist":28,"players":0,"division":3,"minMMR":140,"maxMMR":147},{"id":5,"tier":2,"playlist":28,"players":0,"division":0,"minMMR":148,"maxMMR":156},{"id":6,"tier":2,"playlist":28,"players":0,"division":1,"minMMR":163,"maxMMR":177},{"id":7,"tier":2,"playlist":28,"players":0,"division":2,"minMMR":180,"maxMMR":195},{"id":8,"tier":2,"playlist":28,"players":0,"division":3,"minMMR":197,"maxMMR":214},{"id":9,"tier":3,"playlist":28,"players":0,"division":0,"minMMR":210,"maxMMR":218},{"id":10,"tier":3,"playlist":28,"players":0,"division":1,"minMMR":220,"maxMMR":237},{"id":11,"tier":3,"playlist":28,"players":0,"division":2,"minMMR":240,"maxMMR":255},{"id":12,"tier":3,"playlist":28,"players":0,"division":3,"minMMR":257,"maxMMR":262},{"id":13,"tier":4,"playlist":28,"players":0,"division":0,"minMMR":274,"maxMMR":278},{"id":14,"tier":4,"playlist":28,"players":0,"division":1,"minMMR":280,"maxMMR":297},{"id":15,"tier":4,"playlist":28,"players":0,"division":2,"minMMR":299,"maxMMR":316},{"id":16,"tier":4,"playlist":28,"players":0,"division":3,"minMMR":317,"maxMMR":330},{"id":17,"tier":5,"playlist":28,"players":0,"division":0,"minMMR":328,"maxMMR":338},{"id":18,"tier":5,"playlist":28,"players":0,"division":1,"minMMR":339,"maxMMR":357},{"id":19,"tier":5,"playlist":28,"players":0,"division":2,"minMMR":358,"maxMMR":376},{"id":20,"tier":5,"playlist":28,"players":0,"division":3,"minMMR":377,"maxMMR":392},{"id":21,"tier":6,"playlist":28,"players":0,"division":0,"minMMR":386,"maxMMR":398},{"id":22,"tier":6,"playlist":28,"players":0,"division":1,"minMMR":399,"maxMMR":417},{"id":23,"tier":6,"playlist":28,"players":0,"division":2,"minMMR":418,"maxMMR":436},{"id":24,"tier":6,"playlist":28,"players":0,"division":3,"minMMR":437,"maxMMR":443},{"id":25,"tier":7,"playlist":28,"players":0,"division":0,"minMMR":450,"maxMMR":458},{"id":26,"tier":7,"playlist":28,"players":0,"division":1,"minMMR":459,"maxMMR":477},{"id":27,"tier":7,"playlist":28,"players":0,"division":2,"minMMR":478,"maxMMR":496},{"id":28,"tier":7,"playlist":28,"players":0,"division":3,"minMMR":497,"maxMMR":502},{"id":29,"tier":8,"playlist":28,"players":0,"division":0,"minMMR":510,"maxMMR":518},{"id":30,"tier":8,"playlist":28,"players":0,"division":1,"minMMR":519,"maxMMR":537},{"id":31,"tier":8,"playlist":28,"players":0,"division":2,"minMMR":538,"maxMMR":556},{"id":32,"tier":8,"playlist":28,"players":0,"division":3,"minMMR":557,"maxMMR":563},{"id":33,"tier":9,"playlist":28,"players":0,"division":0,"minMMR":569,"maxMMR":578},{"id":34,"tier":9,"playlist":28,"players":0,"division":1,"minMMR":579,"maxMMR":597},{"id":35,"tier":9,"playlist":28,"players":0,"division":2,"minMMR":598,"maxMMR":616},{"id":36,"tier":9,"playlist":28,"players":0,"division":3,"minMMR":617,"maxMMR":623},{"id":37,"tier":10,"playlist":28,"players":0,"division":0,"minMMR":633,"maxMMR":638},{"id":38,"tier":10,"playlist":28,"players":0,"division":1,"minMMR":639,"maxMMR":657},{"id":39,"tier":10,"playlist":28,"players":0,"division":2,"minMMR":658,"maxMMR":676},{"id":40,"tier":10,"playlist":28,"players":0,"division":3,"minMMR":677,"maxMMR":683},{"id":41,"tier":11,"playlist":28,"players":0,"division":0,"minMMR":689,"maxMMR":698},{"id":42,"tier":11,"playlist":28,"players":0,"division":1,"minMMR":699,"maxMMR":717},{"id":43,"tier":11,"playlist":28,"players":0,"division":2,"minMMR":718,"maxMMR":736},{"id":44,"tier":11,"playlist":28,"players":0,"division":3,"minMMR":737,"maxMMR":743},{"id":45,"tier":12,"playlist":28,"players":0,"division":0,"minMMR":752,"maxMMR":758},{"id":46,"tier":12,"playlist":28,"players":0,"division":1,"minMMR":759,"maxMMR":777},{"id":47,"tier":12,"playlist":28,"players":0,"division":2,"minMMR":778,"maxMMR":796},{"id":48,"tier":12,"playlist":28,"players":0,"division":3,"minMMR":797,"maxMMR":803},{"id":49,"tier":13,"playlist":28,"players":0,"division":0,"minMMR":811,"maxMMR":818},{"id":50,"tier":13,"playlist":28,"players":0,"division":1,"minMMR":819,"maxMMR":837},{"id":51,"tier":13,"playlist":28,"players":0,"division":2,"minMMR":838,"maxMMR":856},{"id":52,"tier":13,"playlist":28,"players":0,"division":3,"minMMR":857,"maxMMR":863},{"id":53,"tier":14,"playlist":28,"players":0,"division":0,"minMMR":872,"maxMMR":878},{"id":54,"tier":14,"playlist":28,"players":0,"division":1,"minMMR":879,"maxMMR":897},{"id":55,"tier":14,"playlist":28,"players":0,"division":2,"minMMR":898,"maxMMR":916},{"id":56,"tier":14,"playlist":28,"players":0,"division":3,"minMMR":917,"maxMMR":923},{"id":57,"tier":15,"playlist":28,"players":0,"division":0,"minMMR":932,"maxMMR":938},{"id":58,"tier":15,"playlist":28,"players":0,"division":1,"minMMR":939,"maxMMR":957},{"id":59,"tier":15,"playlist":28,"players":0,"division":2,"minMMR":958,"maxMMR":976},{"id":60,"tier":15,"playlist":28,"players":0,"division":3,"minMMR":977,"maxMMR":983},{"id":61,"tier":16,"playlist":28,"players":0,"division":0,"minMMR":992,"maxMMR":998},{"id":62,"tier":16,"playlist":28,"players":0,"division":1,"minMMR":999,"maxMMR":1017},{"id":63,"tier":16,"playlist":28,"players":0,"division":2,"minMMR":1018,"maxMMR":1036},{"id":64,"tier":16,"playlist":28,"players":0,"division":3,"minMMR":1037,"maxMMR":1044},{"id":65,"tier":17,"playlist":28,"players":0,"division":0,"minMMR":1049,"maxMMR":1058},{"id":66,"tier":17,"playlist":28,"players":0,"division":1,"minMMR":1059,"maxMMR":1077},{"id":67,"tier":17,"playlist":28,"players":0,"division":2,"minMMR":1078,"maxMMR":1096},{"id":68,"tier":17,"playlist":28,"players":0,"division":3,"minMMR":1097,"maxMMR":1105},{"id":69,"tier":18,"playlist":28,"players":0,"division":0,"minMMR":1113,"maxMMR":1123},{"id":70,"tier":18,"playlist":28,"players":0,"division":1,"minMMR":1125,"maxMMR":1147},{"id":71,"tier":18,"playlist":28,"players":0,"division":2,"minMMR":1148,"maxMMR":1170},{"id":72,"tier":18,"playlist":28,"players":0,"division":3,"minMMR":1172,"maxMMR":1181},{"id":73,"tier":19,"playlist":28,"players":0,"division":0,"minMMR":1195,"maxMMR":1203},{"id":74,"tier":19,"playlist":28,"players":0,"division":1,"minMMR":1204,"maxMMR":1226},{"id":75,"tier":19,"playlist":28,"players":0,"division":2,"minMMR":1229,"maxMMR":1246},{"id":76,"tier":19,"playlist":28,"players":0,"division":3,"minMMR":1252,"maxMMR":1261},{"id":77,"tier":20,"playlist":28,"players":0,"division":0,"minMMR":1271,"maxMMR":1283},{"id":78,"tier":20,"playlist":28,"players":0,"division":1,"minMMR":1285,"maxMMR":1302},{"id":79,"tier":20,"playlist":28,"players":0,"division":2,"minMMR":1308,"maxMMR":1330},{"id":80,"tier":20,"playlist":28,"players":0,"division":3,"minMMR":1332,"maxMMR":1344},{"id":81,"tier":21,"playlist":28,"players":0,"division":0,"minMMR":1348,"maxMMR":1367},{"id":82,"tier":21,"playlist":28,"players":0,"division":1,"minMMR":1371,"maxMMR":1388},{"id":83,"tier":21,"playlist":28,"players":0,"division":2,"minMMR":1398,"maxMMR":1418},{"id":84,"tier":21,"playlist":28,"players":0,"division":3,"minMMR":1427,"maxMMR":1441},{"id":85,"tier":22,"playlist":28,"players":0,"division":0,"minMMR":1449,"maxMMR":1528}]}} -------------------------------------------------------------------------------- /data/RankViewer/RankNumbers/11.json: -------------------------------------------------------------------------------- 1 | {"data":{"tiers":["Unranked","Bronze I","Bronze II","Bronze III","Silver I","Silver II","Silver III","Gold I","Gold II","Gold III","Platinum I","Platinum II","Platinum III","Diamond I","Diamond II","Diamond III","Champion I","Champion II","Champion III","Grand Champion I","Grand Champion II","Grand Champion III","Supersonic Legend"],"divisions":["Division I","Division II","Division III","Division IV"],"playlists":[{"key":0,"value":"Un-Ranked"},{"key":10,"value":"Ranked Duel 1v1"},{"key":11,"value":"Ranked Doubles 2v2"},{"key":13,"value":"Ranked Standard 3v3"},{"key":27,"value":"Hoops"},{"key":28,"value":"Rumble"},{"key":29,"value":"Dropshot"},{"key":30,"value":"Snowday"},{"key":34,"value":"Tournament Matches"}],"data":[{"id":0,"tier":0,"playlist":11,"players":0,"division":0,"minMMR":464,"maxMMR":1540},{"id":1,"tier":1,"playlist":11,"players":0,"division":0,"minMMR":0,"maxMMR":118},{"id":2,"tier":1,"playlist":11,"players":0,"division":1,"minMMR":126,"maxMMR":137},{"id":3,"tier":1,"playlist":11,"players":0,"division":2,"minMMR":140,"maxMMR":156},{"id":4,"tier":1,"playlist":11,"players":0,"division":3,"minMMR":157,"maxMMR":174},{"id":5,"tier":2,"playlist":11,"players":0,"division":0,"minMMR":164,"maxMMR":178},{"id":6,"tier":2,"playlist":11,"players":0,"division":1,"minMMR":181,"maxMMR":197},{"id":7,"tier":2,"playlist":11,"players":0,"division":2,"minMMR":198,"maxMMR":216},{"id":8,"tier":2,"playlist":11,"players":0,"division":3,"minMMR":217,"maxMMR":221},{"id":9,"tier":3,"playlist":11,"players":0,"division":0,"minMMR":226,"maxMMR":238},{"id":10,"tier":3,"playlist":11,"players":0,"division":1,"minMMR":239,"maxMMR":257},{"id":11,"tier":3,"playlist":11,"players":0,"division":2,"minMMR":258,"maxMMR":276},{"id":12,"tier":3,"playlist":11,"players":0,"division":3,"minMMR":277,"maxMMR":280},{"id":13,"tier":4,"playlist":11,"players":0,"division":0,"minMMR":288,"maxMMR":298},{"id":14,"tier":4,"playlist":11,"players":0,"division":1,"minMMR":299,"maxMMR":317},{"id":15,"tier":4,"playlist":11,"players":0,"division":2,"minMMR":318,"maxMMR":336},{"id":16,"tier":4,"playlist":11,"players":0,"division":3,"minMMR":337,"maxMMR":341},{"id":17,"tier":5,"playlist":11,"players":0,"division":0,"minMMR":351,"maxMMR":358},{"id":18,"tier":5,"playlist":11,"players":0,"division":1,"minMMR":359,"maxMMR":377},{"id":19,"tier":5,"playlist":11,"players":0,"division":2,"minMMR":378,"maxMMR":396},{"id":20,"tier":5,"playlist":11,"players":0,"division":3,"minMMR":397,"maxMMR":403},{"id":21,"tier":6,"playlist":11,"players":0,"division":0,"minMMR":410,"maxMMR":418},{"id":22,"tier":6,"playlist":11,"players":0,"division":1,"minMMR":419,"maxMMR":437},{"id":23,"tier":6,"playlist":11,"players":0,"division":2,"minMMR":438,"maxMMR":456},{"id":24,"tier":6,"playlist":11,"players":0,"division":3,"minMMR":457,"maxMMR":462},{"id":25,"tier":7,"playlist":11,"players":0,"division":0,"minMMR":469,"maxMMR":478},{"id":26,"tier":7,"playlist":11,"players":0,"division":1,"minMMR":479,"maxMMR":497},{"id":27,"tier":7,"playlist":11,"players":0,"division":2,"minMMR":498,"maxMMR":516},{"id":28,"tier":7,"playlist":11,"players":0,"division":3,"minMMR":517,"maxMMR":523},{"id":29,"tier":8,"playlist":11,"players":0,"division":0,"minMMR":530,"maxMMR":538},{"id":30,"tier":8,"playlist":11,"players":0,"division":1,"minMMR":539,"maxMMR":557},{"id":31,"tier":8,"playlist":11,"players":0,"division":2,"minMMR":558,"maxMMR":576},{"id":32,"tier":8,"playlist":11,"players":0,"division":3,"minMMR":577,"maxMMR":585},{"id":33,"tier":9,"playlist":11,"players":0,"division":0,"minMMR":590,"maxMMR":598},{"id":34,"tier":9,"playlist":11,"players":0,"division":1,"minMMR":599,"maxMMR":617},{"id":35,"tier":9,"playlist":11,"players":0,"division":2,"minMMR":618,"maxMMR":636},{"id":36,"tier":9,"playlist":11,"players":0,"division":3,"minMMR":637,"maxMMR":644},{"id":37,"tier":10,"playlist":11,"players":0,"division":0,"minMMR":650,"maxMMR":658},{"id":38,"tier":10,"playlist":11,"players":0,"division":1,"minMMR":659,"maxMMR":677},{"id":39,"tier":10,"playlist":11,"players":0,"division":2,"minMMR":678,"maxMMR":696},{"id":40,"tier":10,"playlist":11,"players":0,"division":3,"minMMR":697,"maxMMR":704},{"id":41,"tier":11,"playlist":11,"players":0,"division":0,"minMMR":709,"maxMMR":718},{"id":42,"tier":11,"playlist":11,"players":0,"division":1,"minMMR":719,"maxMMR":737},{"id":43,"tier":11,"playlist":11,"players":0,"division":2,"minMMR":738,"maxMMR":756},{"id":44,"tier":11,"playlist":11,"players":0,"division":3,"minMMR":757,"maxMMR":765},{"id":45,"tier":12,"playlist":11,"players":0,"division":0,"minMMR":770,"maxMMR":778},{"id":46,"tier":12,"playlist":11,"players":0,"division":1,"minMMR":779,"maxMMR":797},{"id":47,"tier":12,"playlist":11,"players":0,"division":2,"minMMR":798,"maxMMR":816},{"id":48,"tier":12,"playlist":11,"players":0,"division":3,"minMMR":817,"maxMMR":825},{"id":49,"tier":13,"playlist":11,"players":0,"division":0,"minMMR":835,"maxMMR":843},{"id":50,"tier":13,"playlist":11,"players":0,"division":1,"minMMR":844,"maxMMR":867},{"id":51,"tier":13,"playlist":11,"players":0,"division":2,"minMMR":868,"maxMMR":891},{"id":52,"tier":13,"playlist":11,"players":0,"division":3,"minMMR":892,"maxMMR":900},{"id":53,"tier":14,"playlist":11,"players":0,"division":0,"minMMR":915,"maxMMR":923},{"id":54,"tier":14,"playlist":11,"players":0,"division":1,"minMMR":924,"maxMMR":947},{"id":55,"tier":14,"playlist":11,"players":0,"division":2,"minMMR":948,"maxMMR":971},{"id":56,"tier":14,"playlist":11,"players":0,"division":3,"minMMR":972,"maxMMR":980},{"id":57,"tier":15,"playlist":11,"players":0,"division":0,"minMMR":994,"maxMMR":1003},{"id":58,"tier":15,"playlist":11,"players":0,"division":1,"minMMR":1004,"maxMMR":1027},{"id":59,"tier":15,"playlist":11,"players":0,"division":2,"minMMR":1028,"maxMMR":1051},{"id":60,"tier":15,"playlist":11,"players":0,"division":3,"minMMR":1052,"maxMMR":1060},{"id":61,"tier":16,"playlist":11,"players":0,"division":0,"minMMR":1075,"maxMMR":1093},{"id":62,"tier":16,"playlist":11,"players":0,"division":1,"minMMR":1095,"maxMMR":1126},{"id":63,"tier":16,"playlist":11,"players":0,"division":2,"minMMR":1128,"maxMMR":1158},{"id":64,"tier":16,"playlist":11,"players":0,"division":3,"minMMR":1162,"maxMMR":1179},{"id":65,"tier":17,"playlist":11,"players":0,"division":0,"minMMR":1195,"maxMMR":1213},{"id":66,"tier":17,"playlist":11,"players":0,"division":1,"minMMR":1215,"maxMMR":1246},{"id":67,"tier":17,"playlist":11,"players":0,"division":2,"minMMR":1248,"maxMMR":1276},{"id":68,"tier":17,"playlist":11,"players":0,"division":3,"minMMR":1282,"maxMMR":1299},{"id":69,"tier":18,"playlist":11,"players":0,"division":0,"minMMR":1314,"maxMMR":1333},{"id":70,"tier":18,"playlist":11,"players":0,"division":1,"minMMR":1335,"maxMMR":1365},{"id":71,"tier":18,"playlist":11,"players":0,"division":2,"minMMR":1368,"maxMMR":1397},{"id":72,"tier":18,"playlist":11,"players":0,"division":3,"minMMR":1402,"maxMMR":1419},{"id":73,"tier":19,"playlist":11,"players":0,"division":0,"minMMR":1435,"maxMMR":1456},{"id":74,"tier":19,"playlist":11,"players":0,"division":1,"minMMR":1462,"maxMMR":1495},{"id":75,"tier":19,"playlist":11,"players":0,"division":2,"minMMR":1498,"maxMMR":1526},{"id":76,"tier":19,"playlist":11,"players":0,"division":3,"minMMR":1537,"maxMMR":1559},{"id":77,"tier":20,"playlist":11,"players":0,"division":0,"minMMR":1574,"maxMMR":1597},{"id":78,"tier":20,"playlist":11,"players":0,"division":1,"minMMR":1600,"maxMMR":1625},{"id":79,"tier":20,"playlist":11,"players":0,"division":2,"minMMR":1638,"maxMMR":1665},{"id":80,"tier":20,"playlist":11,"players":0,"division":3,"minMMR":1677,"maxMMR":1703},{"id":81,"tier":21,"playlist":11,"players":0,"division":0,"minMMR":1715,"maxMMR":1737},{"id":82,"tier":21,"playlist":11,"players":0,"division":1,"minMMR":1745,"maxMMR":1776},{"id":83,"tier":21,"playlist":11,"players":0,"division":2,"minMMR":1788,"maxMMR":1825},{"id":84,"tier":21,"playlist":11,"players":0,"division":3,"minMMR":1832,"maxMMR":1859},{"id":85,"tier":22,"playlist":11,"players":0,"division":0,"minMMR":1862,"maxMMR":2072}]}} -------------------------------------------------------------------------------- /data/RankViewer/RankNumbers/13.json: -------------------------------------------------------------------------------- 1 | {"data":{"tiers":["Unranked","Bronze I","Bronze II","Bronze III","Silver I","Silver II","Silver III","Gold I","Gold II","Gold III","Platinum I","Platinum II","Platinum III","Diamond I","Diamond II","Diamond III","Champion I","Champion II","Champion III","Grand Champion I","Grand Champion II","Grand Champion III","Supersonic Legend"],"divisions":["Division I","Division II","Division III","Division IV"],"playlists":[{"key":0,"value":"Un-Ranked"},{"key":10,"value":"Ranked Duel 1v1"},{"key":11,"value":"Ranked Doubles 2v2"},{"key":13,"value":"Ranked Standard 3v3"},{"key":27,"value":"Hoops"},{"key":28,"value":"Rumble"},{"key":29,"value":"Dropshot"},{"key":30,"value":"Snowday"},{"key":34,"value":"Tournament Matches"}],"data":[{"id":0,"tier":0,"playlist":13,"players":0,"division":0,"minMMR":406,"maxMMR":1660},{"id":1,"tier":1,"playlist":13,"players":0,"division":0,"minMMR":0,"maxMMR":118},{"id":2,"tier":1,"playlist":13,"players":0,"division":1,"minMMR":126,"maxMMR":137},{"id":3,"tier":1,"playlist":13,"players":0,"division":2,"minMMR":140,"maxMMR":156},{"id":4,"tier":1,"playlist":13,"players":0,"division":3,"minMMR":157,"maxMMR":168},{"id":5,"tier":2,"playlist":13,"players":0,"division":0,"minMMR":164,"maxMMR":178},{"id":6,"tier":2,"playlist":13,"players":0,"division":1,"minMMR":181,"maxMMR":197},{"id":7,"tier":2,"playlist":13,"players":0,"division":2,"minMMR":198,"maxMMR":216},{"id":8,"tier":2,"playlist":13,"players":0,"division":3,"minMMR":217,"maxMMR":229},{"id":9,"tier":3,"playlist":13,"players":0,"division":0,"minMMR":225,"maxMMR":238},{"id":10,"tier":3,"playlist":13,"players":0,"division":1,"minMMR":239,"maxMMR":257},{"id":11,"tier":3,"playlist":13,"players":0,"division":2,"minMMR":258,"maxMMR":276},{"id":12,"tier":3,"playlist":13,"players":0,"division":3,"minMMR":277,"maxMMR":284},{"id":13,"tier":4,"playlist":13,"players":0,"division":0,"minMMR":287,"maxMMR":298},{"id":14,"tier":4,"playlist":13,"players":0,"division":1,"minMMR":299,"maxMMR":317},{"id":15,"tier":4,"playlist":13,"players":0,"division":2,"minMMR":318,"maxMMR":336},{"id":16,"tier":4,"playlist":13,"players":0,"division":3,"minMMR":337,"maxMMR":342},{"id":17,"tier":5,"playlist":13,"players":0,"division":0,"minMMR":351,"maxMMR":358},{"id":18,"tier":5,"playlist":13,"players":0,"division":1,"minMMR":359,"maxMMR":377},{"id":19,"tier":5,"playlist":13,"players":0,"division":2,"minMMR":378,"maxMMR":396},{"id":20,"tier":5,"playlist":13,"players":0,"division":3,"minMMR":397,"maxMMR":403},{"id":21,"tier":6,"playlist":13,"players":0,"division":0,"minMMR":409,"maxMMR":418},{"id":22,"tier":6,"playlist":13,"players":0,"division":1,"minMMR":419,"maxMMR":437},{"id":23,"tier":6,"playlist":13,"players":0,"division":2,"minMMR":438,"maxMMR":456},{"id":24,"tier":6,"playlist":13,"players":0,"division":3,"minMMR":457,"maxMMR":465},{"id":25,"tier":7,"playlist":13,"players":0,"division":0,"minMMR":470,"maxMMR":478},{"id":26,"tier":7,"playlist":13,"players":0,"division":1,"minMMR":479,"maxMMR":497},{"id":27,"tier":7,"playlist":13,"players":0,"division":2,"minMMR":498,"maxMMR":516},{"id":28,"tier":7,"playlist":13,"players":0,"division":3,"minMMR":517,"maxMMR":524},{"id":29,"tier":8,"playlist":13,"players":0,"division":0,"minMMR":531,"maxMMR":538},{"id":30,"tier":8,"playlist":13,"players":0,"division":1,"minMMR":539,"maxMMR":557},{"id":31,"tier":8,"playlist":13,"players":0,"division":2,"minMMR":558,"maxMMR":576},{"id":32,"tier":8,"playlist":13,"players":0,"division":3,"minMMR":577,"maxMMR":584},{"id":33,"tier":9,"playlist":13,"players":0,"division":0,"minMMR":590,"maxMMR":598},{"id":34,"tier":9,"playlist":13,"players":0,"division":1,"minMMR":599,"maxMMR":617},{"id":35,"tier":9,"playlist":13,"players":0,"division":2,"minMMR":618,"maxMMR":636},{"id":36,"tier":9,"playlist":13,"players":0,"division":3,"minMMR":637,"maxMMR":645},{"id":37,"tier":10,"playlist":13,"players":0,"division":0,"minMMR":650,"maxMMR":658},{"id":38,"tier":10,"playlist":13,"players":0,"division":1,"minMMR":659,"maxMMR":677},{"id":39,"tier":10,"playlist":13,"players":0,"division":2,"minMMR":678,"maxMMR":696},{"id":40,"tier":10,"playlist":13,"players":0,"division":3,"minMMR":697,"maxMMR":705},{"id":41,"tier":11,"playlist":13,"players":0,"division":0,"minMMR":710,"maxMMR":718},{"id":42,"tier":11,"playlist":13,"players":0,"division":1,"minMMR":719,"maxMMR":737},{"id":43,"tier":11,"playlist":13,"players":0,"division":2,"minMMR":738,"maxMMR":756},{"id":44,"tier":11,"playlist":13,"players":0,"division":3,"minMMR":757,"maxMMR":765},{"id":45,"tier":12,"playlist":13,"players":0,"division":0,"minMMR":769,"maxMMR":778},{"id":46,"tier":12,"playlist":13,"players":0,"division":1,"minMMR":779,"maxMMR":797},{"id":47,"tier":12,"playlist":13,"players":0,"division":2,"minMMR":798,"maxMMR":816},{"id":48,"tier":12,"playlist":13,"players":0,"division":3,"minMMR":817,"maxMMR":825},{"id":49,"tier":13,"playlist":13,"players":0,"division":0,"minMMR":835,"maxMMR":843},{"id":50,"tier":13,"playlist":13,"players":0,"division":1,"minMMR":844,"maxMMR":867},{"id":51,"tier":13,"playlist":13,"players":0,"division":2,"minMMR":868,"maxMMR":891},{"id":52,"tier":13,"playlist":13,"players":0,"division":3,"minMMR":892,"maxMMR":900},{"id":53,"tier":14,"playlist":13,"players":0,"division":0,"minMMR":913,"maxMMR":923},{"id":54,"tier":14,"playlist":13,"players":0,"division":1,"minMMR":924,"maxMMR":947},{"id":55,"tier":14,"playlist":13,"players":0,"division":2,"minMMR":948,"maxMMR":971},{"id":56,"tier":14,"playlist":13,"players":0,"division":3,"minMMR":972,"maxMMR":980},{"id":57,"tier":15,"playlist":13,"players":0,"division":0,"minMMR":993,"maxMMR":1003},{"id":58,"tier":15,"playlist":13,"players":0,"division":1,"minMMR":1004,"maxMMR":1027},{"id":59,"tier":15,"playlist":13,"players":0,"division":2,"minMMR":1028,"maxMMR":1051},{"id":60,"tier":15,"playlist":13,"players":0,"division":3,"minMMR":1052,"maxMMR":1060},{"id":61,"tier":16,"playlist":13,"players":0,"division":0,"minMMR":1075,"maxMMR":1093},{"id":62,"tier":16,"playlist":13,"players":0,"division":1,"minMMR":1095,"maxMMR":1115},{"id":63,"tier":16,"playlist":13,"players":0,"division":2,"minMMR":1128,"maxMMR":1145},{"id":64,"tier":16,"playlist":13,"players":0,"division":3,"minMMR":1162,"maxMMR":1180},{"id":65,"tier":17,"playlist":13,"players":0,"division":0,"minMMR":1195,"maxMMR":1213},{"id":66,"tier":17,"playlist":13,"players":0,"division":1,"minMMR":1215,"maxMMR":1247},{"id":67,"tier":17,"playlist":13,"players":0,"division":2,"minMMR":1248,"maxMMR":1276},{"id":68,"tier":17,"playlist":13,"players":0,"division":3,"minMMR":1282,"maxMMR":1300},{"id":69,"tier":18,"playlist":13,"players":0,"division":0,"minMMR":1315,"maxMMR":1333},{"id":70,"tier":18,"playlist":13,"players":0,"division":1,"minMMR":1335,"maxMMR":1365},{"id":71,"tier":18,"playlist":13,"players":0,"division":2,"minMMR":1368,"maxMMR":1395},{"id":72,"tier":18,"playlist":13,"players":0,"division":3,"minMMR":1402,"maxMMR":1419},{"id":73,"tier":19,"playlist":13,"players":0,"division":0,"minMMR":1435,"maxMMR":1456},{"id":74,"tier":19,"playlist":13,"players":0,"division":1,"minMMR":1461,"maxMMR":1487},{"id":75,"tier":19,"playlist":13,"players":0,"division":2,"minMMR":1498,"maxMMR":1535},{"id":76,"tier":19,"playlist":13,"players":0,"division":3,"minMMR":1537,"maxMMR":1559},{"id":77,"tier":20,"playlist":13,"players":0,"division":0,"minMMR":1575,"maxMMR":1598},{"id":78,"tier":20,"playlist":13,"players":0,"division":1,"minMMR":1600,"maxMMR":1637},{"id":79,"tier":20,"playlist":13,"players":0,"division":2,"minMMR":1638,"maxMMR":1665},{"id":80,"tier":20,"playlist":13,"players":0,"division":3,"minMMR":1677,"maxMMR":1700},{"id":81,"tier":21,"playlist":13,"players":0,"division":0,"minMMR":1712,"maxMMR":1742},{"id":82,"tier":21,"playlist":13,"players":0,"division":1,"minMMR":1744,"maxMMR":1773},{"id":83,"tier":21,"playlist":13,"players":0,"division":2,"minMMR":1788,"maxMMR":1811},{"id":84,"tier":21,"playlist":13,"players":0,"division":3,"minMMR":1832,"maxMMR":1860},{"id":85,"tier":22,"playlist":13,"players":0,"division":0,"minMMR":1864,"maxMMR":2000}]}} -------------------------------------------------------------------------------- /source/RankViewer.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | 16.0 15 | {5D298F96-8F97-4E41-8CDC-605F0665FAF6} 16 | RankViewer 17 | 10.0 18 | 19 | 20 | 21 | DynamicLibrary 22 | true 23 | v142 24 | Unicode 25 | 26 | 27 | DynamicLibrary 28 | false 29 | v142 30 | true 31 | Unicode 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | true 49 | 50 | 51 | false 52 | 53 | 54 | 55 | Level3 56 | true 57 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 58 | true 59 | MultiThreadedDebug 60 | $(ProjectDir);$(BAKKESMOD)\bakkesmodsdk\include;%(AdditionalIncludeDirectories) 61 | Create 62 | pch.h 63 | 64 | 65 | Console 66 | true 67 | $(BAKKESMOD)\bakkesmodsdk\lib;%(AdditionalLibraryDirectories) 68 | 69 | 70 | 71 | 72 | Level3 73 | true 74 | true 75 | true 76 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 77 | true 78 | MultiThreaded 79 | $(ProjectDir);$(APPDATA)\bakkesmod\bakkesmod\bakkesmodsdk\include;%(AdditionalIncludeDirectories) 80 | Create 81 | pch.h 82 | stdcpp17 83 | 84 | 85 | Console 86 | true 87 | true 88 | true 89 | $(APPDATA)\bakkesmod\bakkesmod\bakkesmodsdk\lib;%(AdditionalLibraryDirectories) 90 | 91 | 92 | "$(APPDATA)\bakkesmod\bakkesmod\bakkesmodsdk\bakkesmod-patch.exe" "$(TargetPath)" 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /source/imgui/imconfig.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // COMPILE-TIME OPTIONS FOR DEAR IMGUI 3 | // Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure. 4 | // You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions. 5 | //----------------------------------------------------------------------------- 6 | // A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/branch with your modifications to imconfig.h) 7 | // B) or add configuration directives in your own file and compile with #define IMGUI_USER_CONFIG "myfilename.h" 8 | // If you do so you need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include 9 | // the imgui*.cpp files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures. 10 | // Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts. 11 | // Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using. 12 | //----------------------------------------------------------------------------- 13 | 14 | #pragma once 15 | 16 | //---- Define assertion handler. Defaults to calling assert(). 17 | // If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement. 18 | //#define IM_ASSERT(_EXPR) MyAssert(_EXPR) 19 | //#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts 20 | 21 | //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows 22 | // Using dear imgui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility. 23 | //#define IMGUI_API __declspec( dllexport ) 24 | //#define IMGUI_API __declspec( dllimport ) 25 | 26 | //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names. 27 | //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS 28 | 29 | //---- Disable all of Dear ImGui or don't implement standard windows. 30 | // It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp. 31 | //#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty. 32 | //#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended. 33 | //#define IMGUI_DISABLE_METRICS_WINDOW // Disable debug/metrics window: ShowMetricsWindow() will be empty. 34 | 35 | //---- Don't implement some functions to reduce linkage requirements. 36 | //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. 37 | //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow. 38 | //#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime). 39 | //#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default). 40 | //#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf) 41 | //#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself. 42 | //#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function. 43 | //#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions(). 44 | 45 | //---- Include imgui_user.h at the end of imgui.h as a convenience 46 | //#define IMGUI_INCLUDE_IMGUI_USER_H 47 | 48 | //---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another) 49 | //#define IMGUI_USE_BGRA_PACKED_COLOR 50 | 51 | //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version 52 | // By default the embedded implementations are declared static and not available outside of imgui cpp files. 53 | //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" 54 | //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" 55 | //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION 56 | //#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION 57 | 58 | //---- Unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined, use the much faster STB sprintf library implementation of vsnprintf instead of the one from the default C library. 59 | // Note that stb_sprintf.h is meant to be provided by the user and available in the include path at compile time. Also, the compatibility checks of the arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf. 60 | // #define IMGUI_USE_STB_SPRINTF 61 | 62 | //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4. 63 | // This will be inlined as part of ImVec2 and ImVec4 class declarations. 64 | /* 65 | #define IM_VEC2_CLASS_EXTRA \ 66 | ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \ 67 | operator MyVec2() const { return MyVec2(x,y); } 68 | 69 | #define IM_VEC4_CLASS_EXTRA \ 70 | ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \ 71 | operator MyVec4() const { return MyVec4(x,y,z,w); } 72 | */ 73 | 74 | //---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices. 75 | // Your renderer back-end will need to support it (most example renderer back-ends support both 16/32-bit indices). 76 | // Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer. 77 | // Read about ImGuiBackendFlags_RendererHasVtxOffset for details. 78 | //#define ImDrawIdx unsigned int 79 | 80 | //---- Override ImDrawCallback signature (will need to modify renderer back-ends accordingly) 81 | //struct ImDrawList; 82 | //struct ImDrawCmd; 83 | //typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data); 84 | //#define ImDrawCallback MyImDrawCallback 85 | 86 | //---- Debug Tools: Macro to break in Debugger 87 | // (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.) 88 | //#define IM_DEBUG_BREAK IM_ASSERT(0) 89 | //#define IM_DEBUG_BREAK __debugbreak() 90 | 91 | //---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(), 92 | // (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.) 93 | // This adds a small runtime cost which is why it is not enabled by default. 94 | //#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX 95 | 96 | //---- Debug Tools: Enable slower asserts 97 | //#define IMGUI_DEBUG_PARANOID 98 | 99 | //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files. 100 | /* 101 | namespace ImGui 102 | { 103 | void MyFunction(const char* name, const MyMatrix44& v); 104 | } 105 | */ 106 | 107 | #define IMGUI_DEFINE_MATH_OPERATORS -------------------------------------------------------------------------------- /source/imgui/imgui_searchablecombo.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "imgui_searchablecombo.h" 3 | #include "imgui_internal.h" 4 | 5 | static float CalcMaxPopupHeightFromItemCount(int items_count) 6 | { 7 | ImGuiContext& g = *GImGui; 8 | if (items_count <= 0) 9 | return FLT_MAX; 10 | return (g.FontSize + g.Style.ItemSpacing.y) * items_count - g.Style.ItemSpacing.y + (g.Style.WindowPadding.y * 2); 11 | } 12 | 13 | /* Modified version of BeginCombo from imgui.cpp at line 9172, 14 | * to include a input field to be able to filter the combo values. */ 15 | bool ImGui::BeginSearchableCombo(const char* label, const char* preview_value, char* input, int input_size, const char* input_preview_value, ImGuiComboFlags flags) 16 | { 17 | // Always consume the SetNextWindowSizeConstraint() call in our early return paths 18 | ImGuiContext& g = *GImGui; 19 | bool has_window_size_constraint = (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint) != 0; 20 | g.NextWindowData.Flags &= ~ImGuiNextWindowDataFlags_HasSizeConstraint; 21 | 22 | ImGuiWindow* window = GetCurrentWindow(); 23 | if (window->SkipItems) 24 | return false; 25 | 26 | IM_ASSERT((flags & (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)) != (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)); // Can't use both flags together 27 | 28 | const ImGuiStyle& style = g.Style; 29 | const ImGuiID id = window->GetID(label); 30 | 31 | const float arrow_size = (flags & ImGuiComboFlags_NoArrowButton) ? 0.0f : GetFrameHeight(); 32 | const ImVec2 label_size = CalcTextSize(label, NULL, true); 33 | const float expected_w = CalcItemWidth(); 34 | const float w = (flags & ImGuiComboFlags_NoPreview) ? arrow_size : expected_w; 35 | const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f)); 36 | const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); 37 | 38 | bool hovered, held; 39 | bool pressed = ButtonBehavior(frame_bb, id, &hovered, &held); 40 | bool popup_open = IsPopupOpen(id); 41 | 42 | const ImU32 frame_col = GetColorU32(hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg); 43 | const float value_x2 = ImMax(frame_bb.Min.x, frame_bb.Max.x - arrow_size); 44 | 45 | if (popup_open || (pressed || g.NavActivateId == id)) 46 | { 47 | ImGuiID activeId = g.ActiveId; 48 | if (popup_open) 49 | g.ActiveId = id; 50 | else 51 | g.NavInputId = id; 52 | InputTextEx(label, input_preview_value, input, input_size, frame_bb.Max - frame_bb.Min, ImGuiInputTextFlags_NoUndoRedo); 53 | g.ActiveId = activeId; 54 | if (!(flags & ImGuiComboFlags_NoArrowButton)) 55 | { 56 | ImU32 bg_col = GetColorU32((popup_open || hovered) ? ImGuiCol_ButtonHovered : ImGuiCol_Button); 57 | ImU32 text_col = GetColorU32(ImGuiCol_Text); 58 | window->DrawList->AddRectFilled(ImVec2(value_x2, frame_bb.Min.y), frame_bb.Max, bg_col, style.FrameRounding, (w <= arrow_size) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Right); 59 | if (value_x2 + arrow_size - style.FramePadding.x <= frame_bb.Max.x) 60 | RenderArrow(window->DrawList, ImVec2(value_x2 + style.FramePadding.y, frame_bb.Min.y + style.FramePadding.y), text_col, ImGuiDir_Down, 1.0f); 61 | } 62 | } 63 | else 64 | { 65 | ItemSize(total_bb, style.FramePadding.y); 66 | if (!ItemAdd(total_bb, id, &frame_bb)) 67 | return false; 68 | } 69 | 70 | if ((pressed || g.NavActivateId == id) && !popup_open) 71 | { 72 | if (window->DC.NavLayerCurrent == 0) 73 | window->NavLastIds[0] = id; 74 | OpenPopupEx(id); 75 | popup_open = true; 76 | } 77 | 78 | if (!popup_open) 79 | { 80 | RenderNavHighlight(frame_bb, id); 81 | if (!(flags & ImGuiComboFlags_NoPreview)) 82 | window->DrawList->AddRectFilled(frame_bb.Min, ImVec2(value_x2, frame_bb.Max.y), frame_col, style.FrameRounding, (flags & ImGuiComboFlags_NoArrowButton) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Left); 83 | if (!(flags & ImGuiComboFlags_NoArrowButton)) 84 | { 85 | ImU32 bg_col = GetColorU32((popup_open || hovered) ? ImGuiCol_ButtonHovered : ImGuiCol_Button); 86 | ImU32 text_col = GetColorU32(ImGuiCol_Text); 87 | window->DrawList->AddRectFilled(ImVec2(value_x2, frame_bb.Min.y), frame_bb.Max, bg_col, style.FrameRounding, (w <= arrow_size) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Right); 88 | if (value_x2 + arrow_size - style.FramePadding.x <= frame_bb.Max.x) 89 | RenderArrow(window->DrawList, ImVec2(value_x2 + style.FramePadding.y, frame_bb.Min.y + style.FramePadding.y), text_col, ImGuiDir_Down, 1.0f); 90 | } 91 | RenderFrameBorder(frame_bb.Min, frame_bb.Max, style.FrameRounding); 92 | 93 | if (preview_value != NULL && !(flags & ImGuiComboFlags_NoPreview)) 94 | RenderTextClipped(frame_bb.Min + style.FramePadding, ImVec2(value_x2, frame_bb.Max.y), preview_value, NULL, NULL, ImVec2(0.0f, 0.0f)); 95 | if (label_size.x > 0) 96 | RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); 97 | 98 | return false; 99 | } 100 | 101 | if (has_window_size_constraint) 102 | { 103 | g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasSizeConstraint; 104 | g.NextWindowData.SizeConstraintRect.Min.x = ImMax(g.NextWindowData.SizeConstraintRect.Min.x, w); 105 | } 106 | else 107 | { 108 | if ((flags & ImGuiComboFlags_HeightMask_) == 0) 109 | flags |= ImGuiComboFlags_HeightRegular; 110 | IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiComboFlags_HeightMask_)); // Only one 111 | int popup_max_height_in_items = -1; 112 | if (flags & ImGuiComboFlags_HeightRegular) popup_max_height_in_items = 8; 113 | else if (flags & ImGuiComboFlags_HeightSmall) popup_max_height_in_items = 4; 114 | else if (flags & ImGuiComboFlags_HeightLarge) popup_max_height_in_items = 20; 115 | SetNextWindowSizeConstraints(ImVec2(w, 0.0f), ImVec2(FLT_MAX, CalcMaxPopupHeightFromItemCount(popup_max_height_in_items))); 116 | } 117 | 118 | char name[16]; 119 | ImFormatString(name, IM_ARRAYSIZE(name), "##Combo_%02d", g.BeginPopupStack.Size); // Recycle windows based on depth 120 | 121 | // Peak into expected window size so we can position it 122 | if (ImGuiWindow* popup_window = FindWindowByName(name)) 123 | if (popup_window->WasActive) 124 | { 125 | ImVec2 size_expected = CalcWindowExpectedSize(popup_window); 126 | if (flags & ImGuiComboFlags_PopupAlignLeft) 127 | popup_window->AutoPosLastDirection = ImGuiDir_Left; 128 | ImRect r_outer = GetWindowAllowedExtentRect(popup_window); 129 | ImVec2 pos = FindBestWindowPosForPopupEx(frame_bb.GetBL(), size_expected, &popup_window->AutoPosLastDirection, r_outer, frame_bb, ImGuiPopupPositionPolicy_ComboBox); 130 | SetNextWindowPos(pos); 131 | } 132 | 133 | // We don't use BeginPopupEx() solely because we have a custom name string, which we could make an argument to BeginPopupEx() 134 | ImGuiWindowFlags window_flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_Popup | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoMove; 135 | 136 | // Horizontally align ourselves with the framed text 137 | PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(style.FramePadding.x, style.WindowPadding.y)); 138 | bool ret = Begin(name, NULL, window_flags); 139 | PopStyleVar(); 140 | if (!ret) 141 | { 142 | EndPopup(); 143 | IM_ASSERT(0); // This should never happen as we tested for IsPopupOpen() above 144 | return false; 145 | } 146 | 147 | return true; 148 | } 149 | 150 | 151 | // Just so you can end your BeginSearchableCombo with EndSearchableCombo. 152 | void ImGui::EndSearchableCombo() 153 | { 154 | EndCombo(); 155 | } 156 | 157 | 158 | /* Modified version of Combo from imgui.cpp at line 9343, 159 | * to include a input field to be able to filter the combo values. */ 160 | bool ImGui::SearchableCombo(const char* label, int* current_item, std::vector items, const char* default_preview_text, const char* input_preview_value, int popup_max_height_in_items) 161 | { 162 | ImGuiContext& g = *GImGui; 163 | 164 | const char* preview_text = NULL; 165 | if (*current_item >= (int)items.size()) 166 | *current_item = 0; 167 | if (*current_item >= 0 && *current_item < (int)items.size()) 168 | preview_text = items[*current_item].c_str(); 169 | else 170 | preview_text = default_preview_text; 171 | 172 | // The old Combo() API exposed "popup_max_height_in_items". The new more general BeginCombo() API doesn't have/need it, but we emulate it here. 173 | if (popup_max_height_in_items != -1 && !(g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint)) 174 | SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, CalcMaxPopupHeightFromItemCount(popup_max_height_in_items))); 175 | 176 | const int input_size = 64; 177 | char input_buffer[input_size] = ""; 178 | if (!BeginSearchableCombo(label, preview_text, input_buffer, input_size, input_preview_value, ImGuiComboFlags_None)) 179 | return false; 180 | 181 | // Display items 182 | // FIXME-OPT: Use clipper (but we need to disable it on the appearing frame to make sure our call to SetItemDefaultFocus() is processed) 183 | int matched_items = 0; 184 | bool value_changed = false; 185 | for (int i = 0; i < (int)items.size(); i++) 186 | { 187 | char buffer[input_size] = ""; 188 | ImStrncpy(buffer, input_buffer, input_size); 189 | std::string input(buffer); 190 | std::string item = items[i]; 191 | 192 | std::transform(item.begin(), item.end(), item.begin(), 193 | [](unsigned char c) { return (unsigned char)std::tolower(c); }); 194 | std::transform(input.begin(), input.end(), input.begin(), 195 | [](unsigned char c) { return (unsigned char)std::tolower(c); }); 196 | 197 | if (item.find(input, 0) == std::string::npos) 198 | continue; 199 | 200 | matched_items++; 201 | PushID((void*)(intptr_t)i); 202 | const bool item_selected = (i == *current_item); 203 | const char* item_text = items[i].c_str(); 204 | if (Selectable(item_text, item_selected)) 205 | { 206 | value_changed = true; 207 | *current_item = i; 208 | } 209 | if (item_selected) 210 | SetItemDefaultFocus(); 211 | PopID(); 212 | } 213 | if (matched_items == 0) 214 | ImGui::Selectable("No maps found", false, ImGuiSelectableFlags_Disabled); 215 | 216 | EndSearchableCombo(); 217 | 218 | return value_changed; 219 | } -------------------------------------------------------------------------------- /source/PlaylistData.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "PlaylistData.h" 3 | 4 | 5 | 6 | 7 | // [Rank descending (Grand Champ, Champ 3, Champ 2, etc)][Divisions descending (IV, III, II, I)][MMR Range ascending (lower limit, upper limit)] 8 | /* 9 | PlaylistData Ones = 10 | { {{ 11 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // SupersonicLegend 12 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp3 13 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp2 14 | {{ {1223, 1325}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp1 15 | {{ {1212, 1225}, {1188, 1206}, {1164, 1183}, {1155, 1163} }}, // Champ3 16 | {{ {1132, 1142}, {1108, 1123}, {1085, 1107}, {1074, 1083} }}, // Champ2 17 | {{ {1052, 1060}, {1028, 1048}, {1005, 1025}, {995, 1003} }}, // Champ1 18 | {{ {977, 985}, {958, 976}, {939, 957}, {929, 938} }}, // Diamond3 19 | {{ {917, 925}, {898, 916}, {879, 897}, {872, 878} }}, // Diamond2 20 | {{ {857, 865}, {838, 856}, {819, 837}, {814, 818} }}, // Diamond1 21 | {{ {797, 805}, {778, 796}, {759, 777}, {747, 758} }}, // Platinum3 22 | {{ {737, 745}, {718, 736}, {699, 717}, {692, 698} }}, // Platinum2 23 | {{ {677, 684}, {658, 676}, {639, 657}, {633, 638} }}, // Platinum1 24 | {{ {617, 624}, {598, 616}, {579, 597}, {571, 578} }}, // Gold3 25 | {{ {557, 564}, {538, 556}, {519, 537}, {513, 518} }}, // Gold2 26 | {{ {497, 505}, {478, 496}, {459, 477}, {453, 458} }}, // Gold1 27 | {{ {437, 445}, {418, 436}, {399, 417}, {392, 398} }}, // Silver3 28 | {{ {377, 384}, {358, 376}, {339, 357}, {332, 338} }}, // Silver2 29 | {{ {317, 322}, {298, 316}, {279, 297}, {273, 278} }}, // Silver1 30 | {{ {257, 265}, {238, 256}, {219, 237}, {212, 218} }}, // Bronze3 31 | {{ {197, 200}, {178, 196}, {159, 177}, {148, 158} }}, // Bronze2 32 | {{ {142, 153}, {128, 140}, {114, 127}, {0, 113} }}, // Bronze1 33 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }} // Unranked 34 | }} }; 35 | 36 | PlaylistData Twos = 37 | { {{ 38 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // SupersonicLegend 39 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp3 40 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp2 41 | {{ {1500, 1708}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp1 42 | {{ {1482, 1500}, {1448, 1466}, {1415, 1436}, {1395, 1413} }}, // Champ3 43 | {{ {1367, 1380}, {1338, 1365}, {1312, 1337}, {1295, 1308} }}, // Champ2 44 | {{ {1267, 1280}, {1238, 1265}, {1210, 1237}, {1195, 1208} }}, // Champ1 45 | {{ {1167, 1180}, {1138, 1165}, {1110, 1137}, {1094, 1108} }}, // Diamond3 46 | {{ {1072, 1080}, {1048, 1071}, {1024, 1047}, {1013, 1023} }}, // Diamond2 47 | {{ {992, 1000}, {968, 991}, {944, 967}, {933, 943} }}, // Diamond1 48 | {{ {912, 920}, {888, 911}, {864, 887}, {852, 863} }}, // Platinum3 49 | {{ {832, 840}, {808, 831}, {784, 807}, {773, 783} }}, // Platinum2 50 | {{ {752, 760}, {728, 751}, {704, 727}, {693, 703} }}, // Platinum1 51 | {{ {672, 680}, {648, 671}, {624, 647}, {612, 623} }}, // Gold3 52 | {{ {597, 605}, {578, 596}, {559, 577}, {549, 558} }}, // Gold2 53 | {{ {537, 545}, {518, 536}, {499, 517}, {489, 498} }}, // Gold1 54 | {{ {477, 485}, {458, 476}, {439, 457}, {429, 438} }}, // Silver3 55 | {{ {417, 424}, {398, 416}, {379, 397}, {368, 378} }}, // Silver2 56 | {{ {357, 365}, {338, 356}, {319, 337}, {310, 318} }}, // Silver1 57 | {{ {297, 305}, {278, 296}, {259, 277}, {250, 258} }}, // Bronze3 58 | {{ {237, 242}, {218, 236}, {199, 217}, {190, 198} }}, // Bronze2 59 | {{ {172, 180}, {148, 171}, {125, 147}, {0, 123} }}, // Bronze1 60 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }} // Unranked 61 | }} }; 62 | 63 | PlaylistData Threes = 64 | { {{ 65 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // SupersonicLegend 66 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp3 67 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp2 68 | {{ {1501, 1710}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp1 69 | {{ {1482, 1500}, {1448, 1466}, {1415, 1434}, {1395, 1413} }}, // Champ3 70 | {{ {1367, 1380}, {1338, 1365}, {1310, 1337}, {1295, 1308} }}, // Champ2 71 | {{ {1267, 1280}, {1238, 1265}, {1210, 1237}, {1195, 1208} }}, // Champ1 72 | {{ {1167, 1180}, {1138, 1165}, {1110, 1137}, {1095, 1108} }}, // Diamond3 73 | {{ {1072, 1080}, {1048, 1071}, {1024, 1047}, {1013, 1023} }}, // Diamond2 74 | {{ {992, 1000}, {968, 991}, {944, 967}, {934, 943} }}, // Diamond1 75 | {{ {912, 920}, {888, 911}, {864, 887}, {852, 863} }}, // Platinum3 76 | {{ {832, 840}, {808, 831}, {784, 807}, {772, 783} }}, // Platinum2 77 | {{ {752, 761}, {728, 751}, {704, 727}, {695, 703} }}, // Platinum1 78 | {{ {672, 681}, {648, 671}, {624, 647}, {613, 623} }}, // Gold3 79 | {{ {597, 605}, {578, 596}, {559, 577}, {548, 558} }}, // Gold2 80 | {{ {537, 545}, {518, 536}, {499, 517}, {490, 498} }}, // Gold1 81 | {{ {477, 484}, {458, 476}, {439, 457}, {430, 438} }}, // Silver3 82 | {{ {417, 425}, {398, 416}, {379, 397}, {370, 378} }}, // Silver2 83 | {{ {357, 365}, {338, 356}, {319, 337}, {310, 318} }}, // Silver1 84 | {{ {297, 302}, {278, 296}, {259, 277}, {250, 258} }}, // Bronze3 85 | {{ {237, 243}, {218, 236}, {199, 217}, {189, 198} }}, // Bronze2 86 | {{ {172, 180}, {155, 170}, {125, 147}, {0, 123} }}, // Bronze1 87 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }} // Unranked 88 | }} }; 89 | 90 | PlaylistData Hoops = 91 | { {{ 92 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // SupersonicLegend 93 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp3 94 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp2 95 | {{ {1242, 1322}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp1 96 | {{ {1232, 1242}, {1208, 1225}, {1185, 1207}, {1167, 1183} }}, // Champ3 97 | {{ {1152, 1160}, {1128, 1150}, {1105, 1127}, {1089, 1103} }}, // Champ2 98 | {{ {1072, 1081}, {1048, 1071}, {1024, 1047}, {1015, 1023} }}, // Champ1 99 | {{ {992, 1000}, {968, 991}, {944, 967}, {930, 943} }}, // Diamond3 100 | {{ {917, 923}, {898, 916}, {879, 897}, {868, 878} }}, // Diamond2 101 | {{ {857, 862}, {838, 856}, {819, 837}, {813, 818} }}, // Diamond1 102 | {{ {797, 803}, {778, 796}, {759, 777}, {747, 758} }}, // Platinum3 103 | {{ {737, 743}, {718, 736}, {699,717}, {689, 698} }}, // Platinum2 104 | {{ {677, 681}, {658, 676}, {639, 657}, {633, 638} }}, // Platinum1 105 | {{ {617, 622}, {598, 616}, {579, 597}, {572, 578} }}, // Gold3 106 | {{ {557, 563}, {538, 556}, {519, 537}, {510, 518} }}, // Gold2 107 | {{ {497, 504}, {478, 496}, {459, 477}, {451, 458} }}, // Gold1 108 | {{ {437, 447}, {418, 436}, {399, 417}, {383, 398} }}, // Silver3 109 | {{ {377, 380}, {358, 376}, {339, 357}, {321, 338} }}, // Silver2 110 | {{ {317, 327}, {301, 316}, {281, 297}, {266, 277} }}, // Silver1 111 | {{ {258, 274}, {238, 256}, {219, 228}, {211, 213} }}, // Bronze3 112 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // Bronze2 113 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // Bronze1 114 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }} // Unranked 115 | }} }; 116 | 117 | PlaylistData Rumble = 118 | { {{ 119 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // SupersonicLegend 120 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp3 121 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp2 122 | {{ {1241, 1330}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp1 123 | {{ {1232, 1242}, {1208, 1227}, {1185, 1207}, {1170, 1183} }}, // Champ3 124 | {{ {1152, 1160}, {1128, 1150}, {1105, 1127}, {1093, 1103} }}, // Champ2 125 | {{ {1072, 1080}, {1048, 1071}, {1024, 1047}, {1015, 1023} }}, // Champ1 126 | {{ {992, 1000}, {968, 991}, {944, 967}, {933, 943} }}, // Diamond3 127 | {{ {917, 923}, {898, 916}, {879, 897}, {870, 878} }}, // Diamond2 128 | {{ {857, 864}, {838, 856}, {819, 837}, {809, 818} }}, // Diamond1 129 | {{ {797, 803}, {778, 796}, {759, 777}, {748, 758} }}, // Platinum3 130 | {{ {737, 744}, {718, 736}, {699,717}, {691, 698} }}, // Platinum2 131 | {{ {677, 685}, {658, 676}, {639, 657}, {630, 638} }}, // Platinum1 132 | {{ {617, 623}, {598, 616}, {579, 597}, {571, 578} }}, // Gold3 133 | {{ {557, 560}, {538, 556}, {519, 537}, {511, 518} }}, // Gold2 134 | {{ {497, 504}, {478, 496}, {459, 477}, {449, 458} }}, // Gold1 135 | {{ {437, 441}, {418, 436}, {399, 417}, {388, 398} }}, // Silver3 136 | {{ {377, 385}, {358, 376}, {340, 357}, {328, 338} }}, // Silver2 137 | {{ {317, 325}, {298, 315}, {280, 297}, {266, 278} }}, // Silver1 138 | {{ {257, 267}, {238, 255}, {225, 237}, {206, 218} }}, // Bronze3 139 | {{ {197, 200}, {178, 196}, {164, 177}, {153, 157} }}, // Bronze2 140 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // Bronze1 141 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }} // Unranked 142 | }} }; 143 | 144 | PlaylistData Dropshot = 145 | { {{ 146 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // SupersonicLegendd 147 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp3 148 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp2 149 | {{ {1244, 1298}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp1 150 | {{ {1232, 1250}, {1208, 1230}, {1185, 1204}, {1166, 1183} }}, // Champ3 151 | {{ {1152, 1162}, {1128, 1149}, {1105, 1124}, {1094, 1103} }}, // Champ2 152 | {{ {1072, 1080}, {1048, 1070}, {1024, 1047}, {1015, 1023} }}, // Champ1 153 | {{ {992, 1002}, {968, 991}, {944, 967}, {935, 943} }}, // Diamond3 154 | {{ {917, 925}, {898, 916}, {879, 897}, {873, 878} }}, // Diamond2 155 | {{ {857, 862}, {838, 856}, {819, 837}, {811, 818} }}, // Diamond1 156 | {{ {797, 805}, {778, 796}, {759, 777}, {749, 758} }}, // Platinum3 157 | {{ {737, 742}, {718, 736}, {699,717}, {692, 698} }}, // Platinum2 158 | {{ {677, 682}, {658, 676}, {639, 657}, {630, 638} }}, // Platinum1 159 | {{ {617, 621}, {598, 616}, {579, 597}, {573, 578} }}, // Gold3 160 | {{ {557, 562}, {538, 556}, {519, 537}, {512, 518} }}, // Gold2 161 | {{ {497, 502}, {478, 496}, {459, 477}, {454, 458} }}, // Gold1 162 | {{ {437, 443}, {418, 436}, {399, 417}, {385, 398} }}, // Silver3 163 | {{ {377, 388}, {358, 376}, {339, 357}, {323, 338} }}, // Silver2 164 | {{ {317, 329}, {299, 316}, {279, 297}, {268, 278} }}, // Silver1 165 | {{ {257, 272}, {238, 255}, {220, 237}, {203, 218} }}, // Bronze3 166 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // Bronze2 167 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // Bronze1 168 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }} // Unranked 169 | }} }; 170 | 171 | PlaylistData Snowday = 172 | { {{ 173 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // SupersonicLegend 174 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp3 175 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp2 176 | {{ {1241, 1312}, {-1, -1}, {-1, -1}, {-1, -1} }}, // GrandChamp1 177 | {{ {1232, 1240}, {1208, 1227}, {1185, 1205}, {1165, 1183} }}, // Champ3 178 | {{ {1152, 1163}, {1128, 1150}, {1105, 1127}, {1091, 1103} }}, // Champ2 179 | {{ {1072, 1080}, {1048, 1071}, {1024, 1047}, {1015, 1023} }}, // Champ1 180 | {{ {992, 1000}, {968, 991}, {944, 967}, {935, 943} }}, // Diamond3 181 | {{ {917, 926}, {898, 916}, {879, 897}, {869, 878} }}, // Diamond2 182 | {{ {857, 863}, {838, 856}, {819, 837}, {811, 818} }}, // Diamond1 183 | {{ {797, 805}, {778, 796}, {759, 777}, {747, 758} }}, // Platinum3 184 | {{ {737, 743}, {718, 736}, {699,717}, {688, 698} }}, // Platinum2 185 | {{ {677, 685}, {658, 676}, {639, 657}, {634, 638} }}, // Platinum1 186 | {{ {617, 622}, {598, 616}, {579, 597}, {566, 578} }}, // Gold3 187 | {{ {557, 573}, {538, 556}, {519, 537}, {505, 518} }}, // Gold2 188 | {{ {497, 508}, {478, 496}, {459, 477}, {446, 458} }}, // Gold1 189 | {{ {437, 447}, {418, 436}, {400, 417}, {384, 398} }}, // Silver3 190 | {{ {377, 388}, {358, 375}, {341, 357}, {327, 338} }}, // Silver2 191 | {{ {317, 332}, {301, 314}, {282, 297}, {266, 277} }}, // Silver1 192 | {{ {257, 263}, {238, 251}, {219, 235}, {211, 217} }}, // Bronze3 193 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // Bronze2 194 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }}, // Bronze1 195 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }} // Unranked 196 | }} }; 197 | 198 | PlaylistData Tournament = 199 | { {{ 200 | {{ {1901, 2166}, {-1, -1}, {-1, -1}, {-1, -1} }}, 201 | {{ {1882, 1902}, {1848, 1878}, {1814, 1847}, {1781, 1813} }}, 202 | {{ {1762, 1780}, {1728, 1760}, {1695, 1727}, {1661, 1693} }}, 203 | {{ {1642, 1660}, {1608, 1641}, {1574, 1607}, {1507, 1574} }}, 204 | {{ {1522, 1540}, {1488, 1521}, {1454, 1487}, {1420, 1453} }}, 205 | {{ {1406, 1420}, {1378, 1406}, {1349, 1377}, {1320, 1348} }}, 206 | {{ {1306, 1320}, {1278, 1306}, {1249, 1277}, {1220, 1248} }}, 207 | {{ {1206, 1220}, {1178, 1206}, {1149, 1177}, {1120, 1148} }}, 208 | {{ {1106, 1120}, {1078, 1106}, {1049, 1077}, {1020, 1048} }}, 209 | {{ {1007, 1020}, {978, 1006}, {950, 977}, {921, 948} }}, 210 | {{ {912, 920}, {888, 910}, {865, 887}, {841, 863} }}, 211 | {{ {832, 840}, {808, 831}, {784, 807}, {761, 783} }}, 212 | {{ {752, 760}, {728, 751}, {704, 727}, {681, 703} }}, 213 | {{ {672, 680}, {648, 671}, {624, 647}, {613, 623} }}, 214 | {{ {596, 600}, {576, 596}, {557, 577}, {541, 558} }}, 215 | {{ {536, 540}, {517, 536}, {498, 517}, {481, 498} }}, 216 | {{ {476, 480}, {457, 476}, {438, 457}, {421, 438} }}, 217 | {{ {416, 420}, {397, 416}, {378, 397}, {361, 378} }}, 218 | {{ {356, 360}, {338, 356}, {319, 337}, {301, 317} }}, 219 | {{ {296, 300}, {278, 296}, {259, 277}, {243, 256} }}, 220 | {{ {237, 240}, {218, 236}, {200, 216}, {181, 198} }}, 221 | {{ {172, 180}, {149, 170}, {126, 147}, {0, 123} }}, 222 | {{ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }} 223 | }} }; 224 | 225 | std::map playlistMMRDatabase = { 226 | {Playlists::ONES, Ones}, 227 | {Playlists::TWOS, Twos}, 228 | {Playlists::THREES, Threes}, 229 | {Playlists::HOOPS, Hoops}, 230 | {Playlists::RUMBLE, Rumble}, 231 | {Playlists::DROPSHOT, Dropshot}, 232 | {Playlists::SNOWDAY, Snowday}, 233 | }; 234 | */ 235 | 236 | std::map RankInfoDB 237 | { 238 | {Rank::Unranked, {"Unranked"}}, 239 | {Rank::Bronze1, {"Bronze 1"}}, 240 | {Rank::Bronze2, {"Bronze 2"}}, 241 | {Rank::Bronze3, {"Bronze 3"}}, 242 | {Rank::Silver1, {"Silver 1"}}, 243 | {Rank::Silver2, {"Silver 2"}}, 244 | {Rank::Silver3, {"Silver 3"}}, 245 | {Rank::Gold1, {"Gold 1"}}, 246 | {Rank::Gold2, {"Gold 2"}}, 247 | {Rank::Gold3, {"Gold 3"}}, 248 | {Rank::Platinum1, {"Platinum 1"}}, 249 | {Rank::Platinum2, {"Platinum 2"}}, 250 | {Rank::Platinum3, {"Platinum 3"}}, 251 | {Rank::Diamond1, {"Diamond 1"}}, 252 | {Rank::Diamond2, {"Diamond 2"}}, 253 | {Rank::Diamond3, {"Diamond 3"}}, 254 | {Rank::Champ1, {"Champion 1"}}, 255 | {Rank::Champ2, {"Champion 2"}}, 256 | {Rank::Champ3, {"Champion 3"}}, 257 | {Rank::GrandChamp1, {"Grand Champion 1"}}, 258 | {Rank::GrandChamp2, {"Grand Champion 2"}}, 259 | {Rank::GrandChamp3, {"Grand Champion 3"}}, 260 | {Rank::SupersonicLegend, {"Supersonic Legend"}} 261 | }; -------------------------------------------------------------------------------- /source/imgui/imgui_impl_win32.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | // dear imgui: Platform Binding for Windows (standard windows API for 32 and 64 bits applications) 3 | // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) 4 | 5 | // Implemented features: 6 | // [X] Platform: Clipboard support (for Win32 this is actually part of core imgui) 7 | // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. 8 | // [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE). 9 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. 10 | 11 | #include "imgui.h" 12 | #include "imgui_impl_win32.h" 13 | #ifndef WIN32_LEAN_AND_MEAN 14 | #define WIN32_LEAN_AND_MEAN 15 | #endif 16 | #include 17 | #include 18 | 19 | // Using XInput library for gamepad (with recent Windows SDK this may leads to executables which won't run on Windows 7) 20 | #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD 21 | #include 22 | #else 23 | #define IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT 24 | #endif 25 | #if defined(_MSC_VER) && !defined(IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT) 26 | #pragma comment(lib, "xinput") 27 | //#pragma comment(lib, "Xinput9_1_0") 28 | #endif 29 | 30 | // CHANGELOG 31 | // (minor and older changes stripped away, please see git history for details) 32 | // 2020-01-14: Inputs: Added support for #define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD/IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT. 33 | // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. 34 | // 2019-05-11: Inputs: Don't filter value from WM_CHAR before calling AddInputCharacter(). 35 | // 2019-01-17: Misc: Using GetForegroundWindow()+IsChild() instead of GetActiveWindow() to be compatible with windows created in a different thread or parent. 36 | // 2019-01-17: Inputs: Added support for mouse buttons 4 and 5 via WM_XBUTTON* messages. 37 | // 2019-01-15: Inputs: Added support for XInput gamepads (if ImGuiConfigFlags_NavEnableGamepad is set by user application). 38 | // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. 39 | // 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor. 40 | // 2018-06-10: Inputs: Fixed handling of mouse wheel messages to support fine position messages (typically sent by track-pads). 41 | // 2018-06-08: Misc: Extracted imgui_impl_win32.cpp/.h away from the old combined DX9/DX10/DX11/DX12 examples. 42 | // 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors and ImGuiBackendFlags_HasSetMousePos flags + honor ImGuiConfigFlags_NoMouseCursorChange flag. 43 | // 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). 44 | // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. 45 | // 2018-02-06: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set). 46 | // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. 47 | // 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. 48 | // 2018-01-08: Inputs: Added mapping for ImGuiKey_Insert. 49 | // 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag. 50 | // 2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the VK_MENU key can be read. 51 | // 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging. 52 | // 2016-11-12: Inputs: Only call Win32 ::SetCursor(NULL) when io.MouseDrawCursor is set. 53 | 54 | // Win32 Data 55 | static HWND g_hWnd = NULL; 56 | static INT64 g_Time = 0; 57 | static INT64 g_TicksPerSecond = 0; 58 | static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT; 59 | static bool g_HasGamepad = false; 60 | static bool g_WantUpdateHasGamepad = true; 61 | 62 | // Functions 63 | bool ImGui_ImplWin32_Init(void* hwnd) 64 | { 65 | if (!::QueryPerformanceFrequency((LARGE_INTEGER*)&g_TicksPerSecond)) 66 | return false; 67 | if (!::QueryPerformanceCounter((LARGE_INTEGER*)&g_Time)) 68 | return false; 69 | 70 | // Setup back-end capabilities flags 71 | g_hWnd = (HWND)hwnd; 72 | ImGuiIO& io = ImGui::GetIO(); 73 | io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) 74 | io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) 75 | io.BackendPlatformName = "imgui_impl_win32"; 76 | io.ImeWindowHandle = hwnd; 77 | 78 | // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime. 79 | io.KeyMap[ImGuiKey_Tab] = VK_TAB; 80 | io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT; 81 | io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT; 82 | io.KeyMap[ImGuiKey_UpArrow] = VK_UP; 83 | io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN; 84 | io.KeyMap[ImGuiKey_PageUp] = VK_PRIOR; 85 | io.KeyMap[ImGuiKey_PageDown] = VK_NEXT; 86 | io.KeyMap[ImGuiKey_Home] = VK_HOME; 87 | io.KeyMap[ImGuiKey_End] = VK_END; 88 | io.KeyMap[ImGuiKey_Insert] = VK_INSERT; 89 | io.KeyMap[ImGuiKey_Delete] = VK_DELETE; 90 | io.KeyMap[ImGuiKey_Backspace] = VK_BACK; 91 | io.KeyMap[ImGuiKey_Space] = VK_SPACE; 92 | io.KeyMap[ImGuiKey_Enter] = VK_RETURN; 93 | io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE; 94 | io.KeyMap[ImGuiKey_KeyPadEnter] = VK_RETURN; 95 | io.KeyMap[ImGuiKey_A] = 'A'; 96 | io.KeyMap[ImGuiKey_C] = 'C'; 97 | io.KeyMap[ImGuiKey_V] = 'V'; 98 | io.KeyMap[ImGuiKey_X] = 'X'; 99 | io.KeyMap[ImGuiKey_Y] = 'Y'; 100 | io.KeyMap[ImGuiKey_Z] = 'Z'; 101 | 102 | return true; 103 | } 104 | 105 | void ImGui_ImplWin32_Shutdown() 106 | { 107 | g_hWnd = (HWND)0; 108 | } 109 | 110 | static bool ImGui_ImplWin32_UpdateMouseCursor() 111 | { 112 | ImGuiIO& io = ImGui::GetIO(); 113 | if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) 114 | return false; 115 | 116 | ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); 117 | if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor) 118 | { 119 | // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor 120 | ::SetCursor(NULL); 121 | } 122 | else 123 | { 124 | // Show OS mouse cursor 125 | LPTSTR win32_cursor = IDC_ARROW; 126 | switch (imgui_cursor) 127 | { 128 | case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break; 129 | case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break; 130 | case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break; 131 | case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break; 132 | case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break; 133 | case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break; 134 | case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break; 135 | case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break; 136 | case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break; 137 | } 138 | ::SetCursor(::LoadCursor(NULL, win32_cursor)); 139 | } 140 | return true; 141 | } 142 | 143 | static void ImGui_ImplWin32_UpdateMousePos() 144 | { 145 | ImGuiIO& io = ImGui::GetIO(); 146 | 147 | // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) 148 | if (io.WantSetMousePos) 149 | { 150 | POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y }; 151 | ::ClientToScreen(g_hWnd, &pos); 152 | ::SetCursorPos(pos.x, pos.y); 153 | } 154 | 155 | // Set mouse position 156 | io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); 157 | POINT pos; 158 | if (HWND active_window = ::GetForegroundWindow()) 159 | if (active_window == g_hWnd || ::IsChild(active_window, g_hWnd)) 160 | if (::GetCursorPos(&pos) && ::ScreenToClient(g_hWnd, &pos)) 161 | io.MousePos = ImVec2((float)pos.x, (float)pos.y); 162 | } 163 | 164 | // Gamepad navigation mapping 165 | static void ImGui_ImplWin32_UpdateGamepads() 166 | { 167 | #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD 168 | ImGuiIO& io = ImGui::GetIO(); 169 | memset(io.NavInputs, 0, sizeof(io.NavInputs)); 170 | if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) 171 | return; 172 | 173 | // Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow. 174 | // Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE. 175 | if (g_WantUpdateHasGamepad) 176 | { 177 | XINPUT_CAPABILITIES caps; 178 | g_HasGamepad = (XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS); 179 | g_WantUpdateHasGamepad = false; 180 | } 181 | 182 | XINPUT_STATE xinput_state; 183 | io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; 184 | if (g_HasGamepad && XInputGetState(0, &xinput_state) == ERROR_SUCCESS) 185 | { 186 | const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad; 187 | io.BackendFlags |= ImGuiBackendFlags_HasGamepad; 188 | 189 | #define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; } 190 | #define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; } 191 | MAP_BUTTON(ImGuiNavInput_Activate, XINPUT_GAMEPAD_A); // Cross / A 192 | MAP_BUTTON(ImGuiNavInput_Cancel, XINPUT_GAMEPAD_B); // Circle / B 193 | MAP_BUTTON(ImGuiNavInput_Menu, XINPUT_GAMEPAD_X); // Square / X 194 | MAP_BUTTON(ImGuiNavInput_Input, XINPUT_GAMEPAD_Y); // Triangle / Y 195 | MAP_BUTTON(ImGuiNavInput_DpadLeft, XINPUT_GAMEPAD_DPAD_LEFT); // D-Pad Left 196 | MAP_BUTTON(ImGuiNavInput_DpadRight, XINPUT_GAMEPAD_DPAD_RIGHT); // D-Pad Right 197 | MAP_BUTTON(ImGuiNavInput_DpadUp, XINPUT_GAMEPAD_DPAD_UP); // D-Pad Up 198 | MAP_BUTTON(ImGuiNavInput_DpadDown, XINPUT_GAMEPAD_DPAD_DOWN); // D-Pad Down 199 | MAP_BUTTON(ImGuiNavInput_FocusPrev, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB 200 | MAP_BUTTON(ImGuiNavInput_FocusNext, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB 201 | MAP_BUTTON(ImGuiNavInput_TweakSlow, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB 202 | MAP_BUTTON(ImGuiNavInput_TweakFast, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB 203 | MAP_ANALOG(ImGuiNavInput_LStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768); 204 | MAP_ANALOG(ImGuiNavInput_LStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); 205 | MAP_ANALOG(ImGuiNavInput_LStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); 206 | MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32767); 207 | #undef MAP_BUTTON 208 | #undef MAP_ANALOG 209 | } 210 | #endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD 211 | } 212 | 213 | void ImGui_ImplWin32_NewFrame() 214 | { 215 | ImGuiIO& io = ImGui::GetIO(); 216 | IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame()."); 217 | 218 | // Setup display size (every frame to accommodate for window resizing) 219 | RECT rect; 220 | ::GetClientRect(g_hWnd, &rect); 221 | io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); 222 | 223 | // Setup time step 224 | INT64 current_time; 225 | ::QueryPerformanceCounter((LARGE_INTEGER*)¤t_time); 226 | io.DeltaTime = (float)(current_time - g_Time) / g_TicksPerSecond; 227 | g_Time = current_time; 228 | 229 | // Read keyboard modifiers inputs 230 | io.KeyCtrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; 231 | io.KeyShift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; 232 | io.KeyAlt = (::GetKeyState(VK_MENU) & 0x8000) != 0; 233 | io.KeySuper = false; 234 | // io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below. 235 | 236 | // Update OS mouse position 237 | ImGui_ImplWin32_UpdateMousePos(); 238 | 239 | // Update OS mouse cursor with the cursor requested by imgui 240 | ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); 241 | if (g_LastMouseCursor != mouse_cursor) 242 | { 243 | g_LastMouseCursor = mouse_cursor; 244 | ImGui_ImplWin32_UpdateMouseCursor(); 245 | } 246 | 247 | // Update game controllers (if enabled and available) 248 | ImGui_ImplWin32_UpdateGamepads(); 249 | } 250 | 251 | // Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions. 252 | #ifndef WM_MOUSEHWHEEL 253 | #define WM_MOUSEHWHEEL 0x020E 254 | #endif 255 | #ifndef DBT_DEVNODES_CHANGED 256 | #define DBT_DEVNODES_CHANGED 0x0007 257 | #endif 258 | 259 | // Process Win32 mouse/keyboard inputs. 260 | // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. 261 | // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. 262 | // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. 263 | // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. 264 | // PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds. 265 | // PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag. 266 | IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 267 | { 268 | if (ImGui::GetCurrentContext() == NULL) 269 | return 0; 270 | 271 | ImGuiIO& io = ImGui::GetIO(); 272 | switch (msg) 273 | { 274 | case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: 275 | case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: 276 | case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: 277 | case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: 278 | { 279 | int button = 0; 280 | if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; } 281 | if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; } 282 | if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; } 283 | if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; } 284 | if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL) 285 | ::SetCapture(hwnd); 286 | io.MouseDown[button] = true; 287 | return 0; 288 | } 289 | case WM_LBUTTONUP: 290 | case WM_RBUTTONUP: 291 | case WM_MBUTTONUP: 292 | case WM_XBUTTONUP: 293 | { 294 | int button = 0; 295 | if (msg == WM_LBUTTONUP) { button = 0; } 296 | if (msg == WM_RBUTTONUP) { button = 1; } 297 | if (msg == WM_MBUTTONUP) { button = 2; } 298 | if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; } 299 | io.MouseDown[button] = false; 300 | if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd) 301 | ::ReleaseCapture(); 302 | return 0; 303 | } 304 | case WM_MOUSEWHEEL: 305 | io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; 306 | return 0; 307 | case WM_MOUSEHWHEEL: 308 | io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; 309 | return 0; 310 | case WM_KEYDOWN: 311 | case WM_SYSKEYDOWN: 312 | if (wParam < 256) 313 | io.KeysDown[wParam] = 1; 314 | return 0; 315 | case WM_KEYUP: 316 | case WM_SYSKEYUP: 317 | if (wParam < 256) 318 | io.KeysDown[wParam] = 0; 319 | return 0; 320 | case WM_CHAR: 321 | // You can also use ToAscii()+GetKeyboardState() to retrieve characters. 322 | io.AddInputCharacter((unsigned int)wParam); 323 | return 0; 324 | case WM_SETCURSOR: 325 | if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor()) 326 | return 1; 327 | return 0; 328 | case WM_DEVICECHANGE: 329 | if ((UINT)wParam == DBT_DEVNODES_CHANGED) 330 | g_WantUpdateHasGamepad = true; 331 | return 0; 332 | } 333 | return 0; 334 | } 335 | -------------------------------------------------------------------------------- /data/RankViewer/RankNumbers/34.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "tiers": [ "Unranked", "Bronze I", "Bronze II", "Bronze III", "Silver I", "Silver II", "Silver III", "Gold I", "Gold II", "Gold III", "Platinum I", "Platinum II", "Platinum III", "Diamond I", "Diamond II", "Diamond III", "Champion I", "Champion II", "Champion III", "Grand Champion I", "Grand Champion II", "Grand Champion III", "Supersonic Legend" ], 4 | "divisions": [ "Division I", "Division II", "Division III", "Division IV" ], 5 | "playlists": [ 6 | { 7 | "key": 0, 8 | "value": "Un-Ranked" 9 | }, 10 | { 11 | "key": 10, 12 | "value": "Ranked Duel 1v1" 13 | }, 14 | { 15 | "key": 11, 16 | "value": "Ranked Doubles 2v2" 17 | }, 18 | { 19 | "key": 13, 20 | "value": "Ranked Standard 3v3" 21 | }, 22 | { 23 | "key": 27, 24 | "value": "Hoops" 25 | }, 26 | { 27 | "key": 28, 28 | "value": "Rumble" 29 | }, 30 | { 31 | "key": 29, 32 | "value": "Dropshot" 33 | }, 34 | { 35 | "key": 30, 36 | "value": "Snowday" 37 | }, 38 | { 39 | "key": 34, 40 | "value": "Tournament Matches" 41 | } 42 | ], 43 | "data": [ 44 | { 45 | "id": 0, 46 | "tier": 0, 47 | "playlist": 34, 48 | "players": 0, 49 | "division": 0, 50 | "minMMR": 0, 51 | "maxMMR": 118 52 | }, 53 | { 54 | "id": 1, 55 | "tier": 1, 56 | "playlist": 34, 57 | "players": 0, 58 | "division": 0, 59 | "minMMR": 0, 60 | "maxMMR": 118 61 | }, 62 | { 63 | "id": 2, 64 | "tier": 1, 65 | "playlist": 34, 66 | "players": 0, 67 | "division": 1, 68 | "minMMR": 120, 69 | "maxMMR": 135 70 | }, 71 | { 72 | "id": 3, 73 | "tier": 1, 74 | "playlist": 34, 75 | "players": 0, 76 | "division": 2, 77 | "minMMR": 138, 78 | "maxMMR": 156 79 | }, 80 | { 81 | "id": 4, 82 | "tier": 1, 83 | "playlist": 34, 84 | "players": 0, 85 | "division": 3, 86 | "minMMR": 157, 87 | "maxMMR": 160 88 | }, 89 | { 90 | "id": 5, 91 | "tier": 2, 92 | "playlist": 34, 93 | "players": 0, 94 | "division": 0, 95 | "minMMR": 161, 96 | "maxMMR": 177 97 | }, 98 | { 99 | "id": 6, 100 | "tier": 2, 101 | "playlist": 34, 102 | "players": 0, 103 | "division": 1, 104 | "minMMR": 179, 105 | "maxMMR": 197 106 | }, 107 | { 108 | "id": 7, 109 | "tier": 2, 110 | "playlist": 34, 111 | "players": 0, 112 | "division": 2, 113 | "minMMR": 198, 114 | "maxMMR": 216 115 | }, 116 | { 117 | "id": 8, 118 | "tier": 2, 119 | "playlist": 34, 120 | "players": 0, 121 | "division": 3, 122 | "minMMR": 217, 123 | "maxMMR": 220 124 | }, 125 | { 126 | "id": 9, 127 | "tier": 3, 128 | "playlist": 34, 129 | "players": 0, 130 | "division": 0, 131 | "minMMR": 221, 132 | "maxMMR": 238 133 | }, 134 | { 135 | "id": 10, 136 | "tier": 3, 137 | "playlist": 34, 138 | "players": 0, 139 | "division": 1, 140 | "minMMR": 238, 141 | "maxMMR": 257 142 | }, 143 | { 144 | "id": 11, 145 | "tier": 3, 146 | "playlist": 34, 147 | "players": 0, 148 | "division": 2, 149 | "minMMR": 258, 150 | "maxMMR": 276 151 | }, 152 | { 153 | "id": 12, 154 | "tier": 3, 155 | "playlist": 34, 156 | "players": 0, 157 | "division": 3, 158 | "minMMR": 276, 159 | "maxMMR": 280 160 | }, 161 | { 162 | "id": 13, 163 | "tier": 4, 164 | "playlist": 34, 165 | "players": 0, 166 | "division": 0, 167 | "minMMR": 280, 168 | "maxMMR": 298 169 | }, 170 | { 171 | "id": 14, 172 | "tier": 4, 173 | "playlist": 34, 174 | "players": 0, 175 | "division": 1, 176 | "minMMR": 298, 177 | "maxMMR": 317 178 | }, 179 | { 180 | "id": 15, 181 | "tier": 4, 182 | "playlist": 34, 183 | "players": 0, 184 | "division": 2, 185 | "minMMR": 317, 186 | "maxMMR": 336 187 | }, 188 | { 189 | "id": 16, 190 | "tier": 4, 191 | "playlist": 34, 192 | "players": 0, 193 | "division": 3, 194 | "minMMR": 336, 195 | "maxMMR": 340 196 | }, 197 | { 198 | "id": 17, 199 | "tier": 5, 200 | "playlist": 34, 201 | "players": 0, 202 | "division": 0, 203 | "minMMR": 340, 204 | "maxMMR": 358 205 | }, 206 | { 207 | "id": 18, 208 | "tier": 5, 209 | "playlist": 34, 210 | "players": 0, 211 | "division": 1, 212 | "minMMR": 357, 213 | "maxMMR": 377 214 | }, 215 | { 216 | "id": 19, 217 | "tier": 5, 218 | "playlist": 34, 219 | "players": 0, 220 | "division": 2, 221 | "minMMR": 377, 222 | "maxMMR": 396 223 | }, 224 | { 225 | "id": 20, 226 | "tier": 5, 227 | "playlist": 34, 228 | "players": 0, 229 | "division": 3, 230 | "minMMR": 396, 231 | "maxMMR": 400 232 | }, 233 | { 234 | "id": 21, 235 | "tier": 6, 236 | "playlist": 34, 237 | "players": 0, 238 | "division": 0, 239 | "minMMR": 400, 240 | "maxMMR": 418 241 | }, 242 | { 243 | "id": 22, 244 | "tier": 6, 245 | "playlist": 34, 246 | "players": 0, 247 | "division": 1, 248 | "minMMR": 417, 249 | "maxMMR": 437 250 | }, 251 | { 252 | "id": 23, 253 | "tier": 6, 254 | "playlist": 34, 255 | "players": 0, 256 | "division": 2, 257 | "minMMR": 436, 258 | "maxMMR": 456 259 | }, 260 | { 261 | "id": 24, 262 | "tier": 6, 263 | "playlist": 34, 264 | "players": 0, 265 | "division": 3, 266 | "minMMR": 456, 267 | "maxMMR": 462 268 | }, 269 | { 270 | "id": 25, 271 | "tier": 7, 272 | "playlist": 34, 273 | "players": 0, 274 | "division": 0, 275 | "minMMR": 460, 276 | "maxMMR": 478 277 | }, 278 | { 279 | "id": 26, 280 | "tier": 7, 281 | "playlist": 34, 282 | "players": 0, 283 | "division": 1, 284 | "minMMR": 477, 285 | "maxMMR": 497 286 | }, 287 | { 288 | "id": 27, 289 | "tier": 7, 290 | "playlist": 34, 291 | "players": 0, 292 | "division": 2, 293 | "minMMR": 497, 294 | "maxMMR": 516 295 | }, 296 | { 297 | "id": 28, 298 | "tier": 7, 299 | "playlist": 34, 300 | "players": 0, 301 | "division": 3, 302 | "minMMR": 516, 303 | "maxMMR": 524 304 | }, 305 | { 306 | "id": 29, 307 | "tier": 8, 308 | "playlist": 34, 309 | "players": 0, 310 | "division": 0, 311 | "minMMR": 520, 312 | "maxMMR": 538 313 | }, 314 | { 315 | "id": 30, 316 | "tier": 8, 317 | "playlist": 34, 318 | "players": 0, 319 | "division": 1, 320 | "minMMR": 537, 321 | "maxMMR": 557 322 | }, 323 | { 324 | "id": 31, 325 | "tier": 8, 326 | "playlist": 34, 327 | "players": 0, 328 | "division": 2, 329 | "minMMR": 556, 330 | "maxMMR": 576 331 | }, 332 | { 333 | "id": 32, 334 | "tier": 8, 335 | "playlist": 34, 336 | "players": 0, 337 | "division": 3, 338 | "minMMR": 576, 339 | "maxMMR": 585 340 | }, 341 | { 342 | "id": 33, 343 | "tier": 9, 344 | "playlist": 34, 345 | "players": 0, 346 | "division": 0, 347 | "minMMR": 580, 348 | "maxMMR": 598 349 | }, 350 | { 351 | "id": 34, 352 | "tier": 9, 353 | "playlist": 34, 354 | "players": 0, 355 | "division": 1, 356 | "minMMR": 597, 357 | "maxMMR": 617 358 | }, 359 | { 360 | "id": 35, 361 | "tier": 9, 362 | "playlist": 34, 363 | "players": 0, 364 | "division": 2, 365 | "minMMR": 616, 366 | "maxMMR": 636 367 | }, 368 | { 369 | "id": 36, 370 | "tier": 9, 371 | "playlist": 34, 372 | "players": 0, 373 | "division": 3, 374 | "minMMR": 636, 375 | "maxMMR": 654 376 | }, 377 | { 378 | "id": 37, 379 | "tier": 10, 380 | "playlist": 34, 381 | "players": 0, 382 | "division": 0, 383 | "minMMR": 640, 384 | "maxMMR": 658 385 | }, 386 | { 387 | "id": 38, 388 | "tier": 10, 389 | "playlist": 34, 390 | "players": 0, 391 | "division": 1, 392 | "minMMR": 657, 393 | "maxMMR": 677 394 | }, 395 | { 396 | "id": 39, 397 | "tier": 10, 398 | "playlist": 34, 399 | "players": 0, 400 | "division": 2, 401 | "minMMR": 676, 402 | "maxMMR": 696 403 | }, 404 | { 405 | "id": 40, 406 | "tier": 10, 407 | "playlist": 34, 408 | "players": 0, 409 | "division": 3, 410 | "minMMR": 696, 411 | "maxMMR": 714 412 | }, 413 | { 414 | "id": 41, 415 | "tier": 11, 416 | "playlist": 34, 417 | "players": 0, 418 | "division": 0, 419 | "minMMR": 700, 420 | "maxMMR": 718 421 | }, 422 | { 423 | "id": 42, 424 | "tier": 11, 425 | "playlist": 34, 426 | "players": 0, 427 | "division": 1, 428 | "minMMR": 717, 429 | "maxMMR": 737 430 | }, 431 | { 432 | "id": 43, 433 | "tier": 11, 434 | "playlist": 34, 435 | "players": 0, 436 | "division": 2, 437 | "minMMR": 736, 438 | "maxMMR": 756 439 | }, 440 | { 441 | "id": 44, 442 | "tier": 11, 443 | "playlist": 34, 444 | "players": 0, 445 | "division": 3, 446 | "minMMR": 756, 447 | "maxMMR": 774 448 | }, 449 | { 450 | "id": 45, 451 | "tier": 12, 452 | "playlist": 34, 453 | "players": 0, 454 | "division": 0, 455 | "minMMR": 760, 456 | "maxMMR": 778 457 | }, 458 | { 459 | "id": 46, 460 | "tier": 12, 461 | "playlist": 34, 462 | "players": 0, 463 | "division": 1, 464 | "minMMR": 776, 465 | "maxMMR": 797 466 | }, 467 | { 468 | "id": 47, 469 | "tier": 12, 470 | "playlist": 34, 471 | "players": 0, 472 | "division": 2, 473 | "minMMR": 796, 474 | "maxMMR": 816 475 | }, 476 | { 477 | "id": 48, 478 | "tier": 12, 479 | "playlist": 34, 480 | "players": 0, 481 | "division": 3, 482 | "minMMR": 816, 483 | "maxMMR": 835 484 | }, 485 | { 486 | "id": 49, 487 | "tier": 13, 488 | "playlist": 34, 489 | "players": 0, 490 | "division": 0, 491 | "minMMR": 820, 492 | "maxMMR": 844 493 | }, 494 | { 495 | "id": 50, 496 | "tier": 13, 497 | "playlist": 34, 498 | "players": 0, 499 | "division": 1, 500 | "minMMR": 844, 501 | "maxMMR": 867 502 | }, 503 | { 504 | "id": 51, 505 | "tier": 13, 506 | "playlist": 34, 507 | "players": 0, 508 | "division": 2, 509 | "minMMR": 868, 510 | "maxMMR": 891 511 | }, 512 | { 513 | "id": 52, 514 | "tier": 13, 515 | "playlist": 34, 516 | "players": 0, 517 | "division": 3, 518 | "minMMR": 891, 519 | "maxMMR": 914 520 | }, 521 | { 522 | "id": 53, 523 | "tier": 14, 524 | "playlist": 34, 525 | "players": 0, 526 | "division": 0, 527 | "minMMR": 900, 528 | "maxMMR": 924 529 | }, 530 | { 531 | "id": 54, 532 | "tier": 14, 533 | "playlist": 34, 534 | "players": 0, 535 | "division": 1, 536 | "minMMR": 924, 537 | "maxMMR": 947 538 | }, 539 | { 540 | "id": 55, 541 | "tier": 14, 542 | "playlist": 34, 543 | "players": 0, 544 | "division": 2, 545 | "minMMR": 948, 546 | "maxMMR": 971 547 | }, 548 | { 549 | "id": 56, 550 | "tier": 14, 551 | "playlist": 34, 552 | "players": 0, 553 | "division": 3, 554 | "minMMR": 971, 555 | "maxMMR": 994 556 | }, 557 | { 558 | "id": 57, 559 | "tier": 15, 560 | "playlist": 34, 561 | "players": 0, 562 | "division": 0, 563 | "minMMR": 980, 564 | "maxMMR": 1004 565 | }, 566 | { 567 | "id": 58, 568 | "tier": 15, 569 | "playlist": 34, 570 | "players": 0, 571 | "division": 1, 572 | "minMMR": 1004, 573 | "maxMMR": 1027 574 | }, 575 | { 576 | "id": 59, 577 | "tier": 15, 578 | "playlist": 34, 579 | "players": 0, 580 | "division": 2, 581 | "minMMR": 1028, 582 | "maxMMR": 1051 583 | }, 584 | { 585 | "id": 60, 586 | "tier": 15, 587 | "playlist": 34, 588 | "players": 0, 589 | "division": 3, 590 | "minMMR": 1051, 591 | "maxMMR": 1074 592 | }, 593 | { 594 | "id": 61, 595 | "tier": 16, 596 | "playlist": 34, 597 | "players": 0, 598 | "division": 0, 599 | "minMMR": 1060, 600 | "maxMMR": 1093 601 | }, 602 | { 603 | "id": 62, 604 | "tier": 16, 605 | "playlist": 34, 606 | "players": 0, 607 | "division": 1, 608 | "minMMR": 1094, 609 | "maxMMR": 1127 610 | }, 611 | { 612 | "id": 63, 613 | "tier": 16, 614 | "playlist": 34, 615 | "players": 0, 616 | "division": 2, 617 | "minMMR": 1128, 618 | "maxMMR": 1161 619 | }, 620 | { 621 | "id": 64, 622 | "tier": 16, 623 | "playlist": 34, 624 | "players": 0, 625 | "division": 3, 626 | "minMMR": 1161, 627 | "maxMMR": 1187 628 | }, 629 | { 630 | "id": 65, 631 | "tier": 17, 632 | "playlist": 34, 633 | "players": 0, 634 | "division": 0, 635 | "minMMR": 1180, 636 | "maxMMR": 1214 637 | }, 638 | { 639 | "id": 66, 640 | "tier": 17, 641 | "playlist": 34, 642 | "players": 0, 643 | "division": 1, 644 | "minMMR": 1214, 645 | "maxMMR": 1247 646 | }, 647 | { 648 | "id": 67, 649 | "tier": 17, 650 | "playlist": 34, 651 | "players": 0, 652 | "division": 2, 653 | "minMMR": 1248, 654 | "maxMMR": 1281 655 | }, 656 | { 657 | "id": 68, 658 | "tier": 17, 659 | "playlist": 34, 660 | "players": 0, 661 | "division": 3, 662 | "minMMR": 1281, 663 | "maxMMR": 1300 664 | }, 665 | { 666 | "id": 69, 667 | "tier": 18, 668 | "playlist": 34, 669 | "players": 0, 670 | "division": 0, 671 | "minMMR": 1300, 672 | "maxMMR": 1333 673 | }, 674 | { 675 | "id": 70, 676 | "tier": 18, 677 | "playlist": 34, 678 | "players": 0, 679 | "division": 1, 680 | "minMMR": 1334, 681 | "maxMMR": 1367 682 | }, 683 | { 684 | "id": 71, 685 | "tier": 18, 686 | "playlist": 34, 687 | "players": 0, 688 | "division": 2, 689 | "minMMR": 1368, 690 | "maxMMR": 1401 691 | }, 692 | { 693 | "id": 72, 694 | "tier": 18, 695 | "playlist": 34, 696 | "players": 0, 697 | "division": 3, 698 | "minMMR": 1401, 699 | "maxMMR": 1420 700 | }, 701 | { 702 | "id": 73, 703 | "tier": 19, 704 | "playlist": 34, 705 | "players": 0, 706 | "division": 0, 707 | "minMMR": 1420, 708 | "maxMMR": 1458 709 | }, 710 | { 711 | "id": 74, 712 | "tier": 19, 713 | "playlist": 34, 714 | "players": 0, 715 | "division": 1, 716 | "minMMR": 1459, 717 | "maxMMR": 1497 718 | }, 719 | { 720 | "id": 75, 721 | "tier": 19, 722 | "playlist": 34, 723 | "players": 0, 724 | "division": 2, 725 | "minMMR": 1498, 726 | "maxMMR": 1536 727 | }, 728 | { 729 | "id": 76, 730 | "tier": 19, 731 | "playlist": 34, 732 | "players": 0, 733 | "division": 3, 734 | "minMMR": 1537, 735 | "maxMMR": 1560 736 | }, 737 | { 738 | "id": 77, 739 | "tier": 20, 740 | "playlist": 34, 741 | "players": 0, 742 | "division": 0, 743 | "minMMR": 1560, 744 | "maxMMR": 1598 745 | }, 746 | { 747 | "id": 78, 748 | "tier": 20, 749 | "playlist": 34, 750 | "players": 0, 751 | "division": 1, 752 | "minMMR": 1599, 753 | "maxMMR": 1637 754 | }, 755 | { 756 | "id": 79, 757 | "tier": 20, 758 | "playlist": 34, 759 | "players": 0, 760 | "division": 2, 761 | "minMMR": 1638, 762 | "maxMMR": 1676 763 | }, 764 | { 765 | "id": 80, 766 | "tier": 20, 767 | "playlist": 34, 768 | "players": 0, 769 | "division": 3, 770 | "minMMR": 1677, 771 | "maxMMR": 1700 772 | }, 773 | { 774 | "id": 81, 775 | "tier": 21, 776 | "playlist": 34, 777 | "players": 0, 778 | "division": 0, 779 | "minMMR": 1701, 780 | "maxMMR": 1743 781 | }, 782 | { 783 | "id": 82, 784 | "tier": 21, 785 | "playlist": 34, 786 | "players": 0, 787 | "division": 1, 788 | "minMMR": 1744, 789 | "maxMMR": 1787 790 | }, 791 | { 792 | "id": 83, 793 | "tier": 21, 794 | "playlist": 34, 795 | "players": 0, 796 | "division": 2, 797 | "minMMR": 1788, 798 | "maxMMR": 1829 799 | }, 800 | { 801 | "id": 84, 802 | "tier": 21, 803 | "playlist": 34, 804 | "players": 0, 805 | "division": 3, 806 | "minMMR": 1832, 807 | "maxMMR": 1860 808 | }, 809 | { 810 | "id": 85, 811 | "tier": 22, 812 | "playlist": 34, 813 | "players": 0, 814 | "division": 0, 815 | "minMMR": 1861, 816 | "maxMMR": 2033 817 | } 818 | ] 819 | } 820 | } -------------------------------------------------------------------------------- /source/imgui/imstb_rectpack.h: -------------------------------------------------------------------------------- 1 | // [DEAR IMGUI] 2 | // This is a slightly modified version of stb_rect_pack.h 1.00. 3 | // Those changes would need to be pushed into nothings/stb: 4 | // - Added STBRP__CDECL 5 | // Grep for [DEAR IMGUI] to find the changes. 6 | 7 | // stb_rect_pack.h - v1.00 - public domain - rectangle packing 8 | // Sean Barrett 2014 9 | // 10 | // Useful for e.g. packing rectangular textures into an atlas. 11 | // Does not do rotation. 12 | // 13 | // Not necessarily the awesomest packing method, but better than 14 | // the totally naive one in stb_truetype (which is primarily what 15 | // this is meant to replace). 16 | // 17 | // Has only had a few tests run, may have issues. 18 | // 19 | // More docs to come. 20 | // 21 | // No memory allocations; uses qsort() and assert() from stdlib. 22 | // Can override those by defining STBRP_SORT and STBRP_ASSERT. 23 | // 24 | // This library currently uses the Skyline Bottom-Left algorithm. 25 | // 26 | // Please note: better rectangle packers are welcome! Please 27 | // implement them to the same API, but with a different init 28 | // function. 29 | // 30 | // Credits 31 | // 32 | // Library 33 | // Sean Barrett 34 | // Minor features 35 | // Martins Mozeiko 36 | // github:IntellectualKitty 37 | // 38 | // Bugfixes / warning fixes 39 | // Jeremy Jaussaud 40 | // Fabian Giesen 41 | // 42 | // Version history: 43 | // 44 | // 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles 45 | // 0.99 (2019-02-07) warning fixes 46 | // 0.11 (2017-03-03) return packing success/fail result 47 | // 0.10 (2016-10-25) remove cast-away-const to avoid warnings 48 | // 0.09 (2016-08-27) fix compiler warnings 49 | // 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0) 50 | // 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0) 51 | // 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort 52 | // 0.05: added STBRP_ASSERT to allow replacing assert 53 | // 0.04: fixed minor bug in STBRP_LARGE_RECTS support 54 | // 0.01: initial release 55 | // 56 | // LICENSE 57 | // 58 | // See end of file for license information. 59 | 60 | ////////////////////////////////////////////////////////////////////////////// 61 | // 62 | // INCLUDE SECTION 63 | // 64 | 65 | #ifndef STB_INCLUDE_STB_RECT_PACK_H 66 | #define STB_INCLUDE_STB_RECT_PACK_H 67 | 68 | #define STB_RECT_PACK_VERSION 1 69 | 70 | #ifdef STBRP_STATIC 71 | #define STBRP_DEF static 72 | #else 73 | #define STBRP_DEF extern 74 | #endif 75 | 76 | #ifdef __cplusplus 77 | extern "C" { 78 | #endif 79 | 80 | typedef struct stbrp_context stbrp_context; 81 | typedef struct stbrp_node stbrp_node; 82 | typedef struct stbrp_rect stbrp_rect; 83 | 84 | #ifdef STBRP_LARGE_RECTS 85 | typedef int stbrp_coord; 86 | #else 87 | typedef unsigned short stbrp_coord; 88 | #endif 89 | 90 | STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects); 91 | // Assign packed locations to rectangles. The rectangles are of type 92 | // 'stbrp_rect' defined below, stored in the array 'rects', and there 93 | // are 'num_rects' many of them. 94 | // 95 | // Rectangles which are successfully packed have the 'was_packed' flag 96 | // set to a non-zero value and 'x' and 'y' store the minimum location 97 | // on each axis (i.e. bottom-left in cartesian coordinates, top-left 98 | // if you imagine y increasing downwards). Rectangles which do not fit 99 | // have the 'was_packed' flag set to 0. 100 | // 101 | // You should not try to access the 'rects' array from another thread 102 | // while this function is running, as the function temporarily reorders 103 | // the array while it executes. 104 | // 105 | // To pack into another rectangle, you need to call stbrp_init_target 106 | // again. To continue packing into the same rectangle, you can call 107 | // this function again. Calling this multiple times with multiple rect 108 | // arrays will probably produce worse packing results than calling it 109 | // a single time with the full rectangle array, but the option is 110 | // available. 111 | // 112 | // The function returns 1 if all of the rectangles were successfully 113 | // packed and 0 otherwise. 114 | 115 | struct stbrp_rect 116 | { 117 | // reserved for your use: 118 | int id; 119 | 120 | // input: 121 | stbrp_coord w, h; 122 | 123 | // output: 124 | stbrp_coord x, y; 125 | int was_packed; // non-zero if valid packing 126 | 127 | }; // 16 bytes, nominally 128 | 129 | 130 | STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes); 131 | // Initialize a rectangle packer to: 132 | // pack a rectangle that is 'width' by 'height' in dimensions 133 | // using temporary storage provided by the array 'nodes', which is 'num_nodes' long 134 | // 135 | // You must call this function every time you start packing into a new target. 136 | // 137 | // There is no "shutdown" function. The 'nodes' memory must stay valid for 138 | // the following stbrp_pack_rects() call (or calls), but can be freed after 139 | // the call (or calls) finish. 140 | // 141 | // Note: to guarantee best results, either: 142 | // 1. make sure 'num_nodes' >= 'width' 143 | // or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1' 144 | // 145 | // If you don't do either of the above things, widths will be quantized to multiples 146 | // of small integers to guarantee the algorithm doesn't run out of temporary storage. 147 | // 148 | // If you do #2, then the non-quantized algorithm will be used, but the algorithm 149 | // may run out of temporary storage and be unable to pack some rectangles. 150 | 151 | STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem); 152 | // Optionally call this function after init but before doing any packing to 153 | // change the handling of the out-of-temp-memory scenario, described above. 154 | // If you call init again, this will be reset to the default (false). 155 | 156 | 157 | STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic); 158 | // Optionally select which packing heuristic the library should use. Different 159 | // heuristics will produce better/worse results for different data sets. 160 | // If you call init again, this will be reset to the default. 161 | 162 | enum 163 | { 164 | STBRP_HEURISTIC_Skyline_default=0, 165 | STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default, 166 | STBRP_HEURISTIC_Skyline_BF_sortHeight 167 | }; 168 | 169 | 170 | ////////////////////////////////////////////////////////////////////////////// 171 | // 172 | // the details of the following structures don't matter to you, but they must 173 | // be visible so you can handle the memory allocations for them 174 | 175 | struct stbrp_node 176 | { 177 | stbrp_coord x,y; 178 | stbrp_node *next; 179 | }; 180 | 181 | struct stbrp_context 182 | { 183 | int width; 184 | int height; 185 | int align; 186 | int init_mode; 187 | int heuristic; 188 | int num_nodes; 189 | stbrp_node *active_head; 190 | stbrp_node *free_head; 191 | stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' 192 | }; 193 | 194 | #ifdef __cplusplus 195 | } 196 | #endif 197 | 198 | #endif 199 | 200 | ////////////////////////////////////////////////////////////////////////////// 201 | // 202 | // IMPLEMENTATION SECTION 203 | // 204 | 205 | #ifdef STB_RECT_PACK_IMPLEMENTATION 206 | #ifndef STBRP_SORT 207 | #include 208 | #define STBRP_SORT qsort 209 | #endif 210 | 211 | #ifndef STBRP_ASSERT 212 | #include 213 | #define STBRP_ASSERT assert 214 | #endif 215 | 216 | // [DEAR IMGUI] Added STBRP__CDECL 217 | #ifdef _MSC_VER 218 | #define STBRP__NOTUSED(v) (void)(v) 219 | #define STBRP__CDECL __cdecl 220 | #else 221 | #define STBRP__NOTUSED(v) (void)sizeof(v) 222 | #define STBRP__CDECL 223 | #endif 224 | 225 | enum 226 | { 227 | STBRP__INIT_skyline = 1 228 | }; 229 | 230 | STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic) 231 | { 232 | switch (context->init_mode) { 233 | case STBRP__INIT_skyline: 234 | STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight); 235 | context->heuristic = heuristic; 236 | break; 237 | default: 238 | STBRP_ASSERT(0); 239 | } 240 | } 241 | 242 | STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem) 243 | { 244 | if (allow_out_of_mem) 245 | // if it's ok to run out of memory, then don't bother aligning them; 246 | // this gives better packing, but may fail due to OOM (even though 247 | // the rectangles easily fit). @TODO a smarter approach would be to only 248 | // quantize once we've hit OOM, then we could get rid of this parameter. 249 | context->align = 1; 250 | else { 251 | // if it's not ok to run out of memory, then quantize the widths 252 | // so that num_nodes is always enough nodes. 253 | // 254 | // I.e. num_nodes * align >= width 255 | // align >= width / num_nodes 256 | // align = ceil(width/num_nodes) 257 | 258 | context->align = (context->width + context->num_nodes-1) / context->num_nodes; 259 | } 260 | } 261 | 262 | STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes) 263 | { 264 | int i; 265 | #ifndef STBRP_LARGE_RECTS 266 | STBRP_ASSERT(width <= 0xffff && height <= 0xffff); 267 | #endif 268 | 269 | for (i=0; i < num_nodes-1; ++i) 270 | nodes[i].next = &nodes[i+1]; 271 | nodes[i].next = NULL; 272 | context->init_mode = STBRP__INIT_skyline; 273 | context->heuristic = STBRP_HEURISTIC_Skyline_default; 274 | context->free_head = &nodes[0]; 275 | context->active_head = &context->extra[0]; 276 | context->width = width; 277 | context->height = height; 278 | context->num_nodes = num_nodes; 279 | stbrp_setup_allow_out_of_mem(context, 0); 280 | 281 | // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) 282 | context->extra[0].x = 0; 283 | context->extra[0].y = 0; 284 | context->extra[0].next = &context->extra[1]; 285 | context->extra[1].x = (stbrp_coord) width; 286 | #ifdef STBRP_LARGE_RECTS 287 | context->extra[1].y = (1<<30); 288 | #else 289 | context->extra[1].y = 65535; 290 | #endif 291 | context->extra[1].next = NULL; 292 | } 293 | 294 | // find minimum y position if it starts at x1 295 | static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste) 296 | { 297 | stbrp_node *node = first; 298 | int x1 = x0 + width; 299 | int min_y, visited_width, waste_area; 300 | 301 | STBRP__NOTUSED(c); 302 | 303 | STBRP_ASSERT(first->x <= x0); 304 | 305 | #if 0 306 | // skip in case we're past the node 307 | while (node->next->x <= x0) 308 | ++node; 309 | #else 310 | STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency 311 | #endif 312 | 313 | STBRP_ASSERT(node->x <= x0); 314 | 315 | min_y = 0; 316 | waste_area = 0; 317 | visited_width = 0; 318 | while (node->x < x1) { 319 | if (node->y > min_y) { 320 | // raise min_y higher. 321 | // we've accounted for all waste up to min_y, 322 | // but we'll now add more waste for everything we've visted 323 | waste_area += visited_width * (node->y - min_y); 324 | min_y = node->y; 325 | // the first time through, visited_width might be reduced 326 | if (node->x < x0) 327 | visited_width += node->next->x - x0; 328 | else 329 | visited_width += node->next->x - node->x; 330 | } else { 331 | // add waste area 332 | int under_width = node->next->x - node->x; 333 | if (under_width + visited_width > width) 334 | under_width = width - visited_width; 335 | waste_area += under_width * (min_y - node->y); 336 | visited_width += under_width; 337 | } 338 | node = node->next; 339 | } 340 | 341 | *pwaste = waste_area; 342 | return min_y; 343 | } 344 | 345 | typedef struct 346 | { 347 | int x,y; 348 | stbrp_node **prev_link; 349 | } stbrp__findresult; 350 | 351 | static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height) 352 | { 353 | int best_waste = (1<<30), best_x, best_y = (1 << 30); 354 | stbrp__findresult fr; 355 | stbrp_node **prev, *node, *tail, **best = NULL; 356 | 357 | // align to multiple of c->align 358 | width = (width + c->align - 1); 359 | width -= width % c->align; 360 | STBRP_ASSERT(width % c->align == 0); 361 | 362 | // if it can't possibly fit, bail immediately 363 | if (width > c->width || height > c->height) { 364 | fr.prev_link = NULL; 365 | fr.x = fr.y = 0; 366 | return fr; 367 | } 368 | 369 | node = c->active_head; 370 | prev = &c->active_head; 371 | while (node->x + width <= c->width) { 372 | int y,waste; 373 | y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste); 374 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL 375 | // bottom left 376 | if (y < best_y) { 377 | best_y = y; 378 | best = prev; 379 | } 380 | } else { 381 | // best-fit 382 | if (y + height <= c->height) { 383 | // can only use it if it first vertically 384 | if (y < best_y || (y == best_y && waste < best_waste)) { 385 | best_y = y; 386 | best_waste = waste; 387 | best = prev; 388 | } 389 | } 390 | } 391 | prev = &node->next; 392 | node = node->next; 393 | } 394 | 395 | best_x = (best == NULL) ? 0 : (*best)->x; 396 | 397 | // if doing best-fit (BF), we also have to try aligning right edge to each node position 398 | // 399 | // e.g, if fitting 400 | // 401 | // ____________________ 402 | // |____________________| 403 | // 404 | // into 405 | // 406 | // | | 407 | // | ____________| 408 | // |____________| 409 | // 410 | // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned 411 | // 412 | // This makes BF take about 2x the time 413 | 414 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) { 415 | tail = c->active_head; 416 | node = c->active_head; 417 | prev = &c->active_head; 418 | // find first node that's admissible 419 | while (tail->x < width) 420 | tail = tail->next; 421 | while (tail) { 422 | int xpos = tail->x - width; 423 | int y,waste; 424 | STBRP_ASSERT(xpos >= 0); 425 | // find the left position that matches this 426 | while (node->next->x <= xpos) { 427 | prev = &node->next; 428 | node = node->next; 429 | } 430 | STBRP_ASSERT(node->next->x > xpos && node->x <= xpos); 431 | y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste); 432 | if (y + height <= c->height) { 433 | if (y <= best_y) { 434 | if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) { 435 | best_x = xpos; 436 | STBRP_ASSERT(y <= best_y); 437 | best_y = y; 438 | best_waste = waste; 439 | best = prev; 440 | } 441 | } 442 | } 443 | tail = tail->next; 444 | } 445 | } 446 | 447 | fr.prev_link = best; 448 | fr.x = best_x; 449 | fr.y = best_y; 450 | return fr; 451 | } 452 | 453 | static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height) 454 | { 455 | // find best position according to heuristic 456 | stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height); 457 | stbrp_node *node, *cur; 458 | 459 | // bail if: 460 | // 1. it failed 461 | // 2. the best node doesn't fit (we don't always check this) 462 | // 3. we're out of memory 463 | if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) { 464 | res.prev_link = NULL; 465 | return res; 466 | } 467 | 468 | // on success, create new node 469 | node = context->free_head; 470 | node->x = (stbrp_coord) res.x; 471 | node->y = (stbrp_coord) (res.y + height); 472 | 473 | context->free_head = node->next; 474 | 475 | // insert the new node into the right starting point, and 476 | // let 'cur' point to the remaining nodes needing to be 477 | // stiched back in 478 | 479 | cur = *res.prev_link; 480 | if (cur->x < res.x) { 481 | // preserve the existing one, so start testing with the next one 482 | stbrp_node *next = cur->next; 483 | cur->next = node; 484 | cur = next; 485 | } else { 486 | *res.prev_link = node; 487 | } 488 | 489 | // from here, traverse cur and free the nodes, until we get to one 490 | // that shouldn't be freed 491 | while (cur->next && cur->next->x <= res.x + width) { 492 | stbrp_node *next = cur->next; 493 | // move the current node to the free list 494 | cur->next = context->free_head; 495 | context->free_head = cur; 496 | cur = next; 497 | } 498 | 499 | // stitch the list back in 500 | node->next = cur; 501 | 502 | if (cur->x < res.x + width) 503 | cur->x = (stbrp_coord) (res.x + width); 504 | 505 | #ifdef _DEBUG 506 | cur = context->active_head; 507 | while (cur->x < context->width) { 508 | STBRP_ASSERT(cur->x < cur->next->x); 509 | cur = cur->next; 510 | } 511 | STBRP_ASSERT(cur->next == NULL); 512 | 513 | { 514 | int count=0; 515 | cur = context->active_head; 516 | while (cur) { 517 | cur = cur->next; 518 | ++count; 519 | } 520 | cur = context->free_head; 521 | while (cur) { 522 | cur = cur->next; 523 | ++count; 524 | } 525 | STBRP_ASSERT(count == context->num_nodes+2); 526 | } 527 | #endif 528 | 529 | return res; 530 | } 531 | 532 | // [DEAR IMGUI] Added STBRP__CDECL 533 | static int STBRP__CDECL rect_height_compare(const void *a, const void *b) 534 | { 535 | const stbrp_rect *p = (const stbrp_rect *) a; 536 | const stbrp_rect *q = (const stbrp_rect *) b; 537 | if (p->h > q->h) 538 | return -1; 539 | if (p->h < q->h) 540 | return 1; 541 | return (p->w > q->w) ? -1 : (p->w < q->w); 542 | } 543 | 544 | // [DEAR IMGUI] Added STBRP__CDECL 545 | static int STBRP__CDECL rect_original_order(const void *a, const void *b) 546 | { 547 | const stbrp_rect *p = (const stbrp_rect *) a; 548 | const stbrp_rect *q = (const stbrp_rect *) b; 549 | return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); 550 | } 551 | 552 | #ifdef STBRP_LARGE_RECTS 553 | #define STBRP__MAXVAL 0xffffffff 554 | #else 555 | #define STBRP__MAXVAL 0xffff 556 | #endif 557 | 558 | STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects) 559 | { 560 | int i, all_rects_packed = 1; 561 | 562 | // we use the 'was_packed' field internally to allow sorting/unsorting 563 | for (i=0; i < num_rects; ++i) { 564 | rects[i].was_packed = i; 565 | } 566 | 567 | // sort according to heuristic 568 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare); 569 | 570 | for (i=0; i < num_rects; ++i) { 571 | if (rects[i].w == 0 || rects[i].h == 0) { 572 | rects[i].x = rects[i].y = 0; // empty rect needs no space 573 | } else { 574 | stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h); 575 | if (fr.prev_link) { 576 | rects[i].x = (stbrp_coord) fr.x; 577 | rects[i].y = (stbrp_coord) fr.y; 578 | } else { 579 | rects[i].x = rects[i].y = STBRP__MAXVAL; 580 | } 581 | } 582 | } 583 | 584 | // unsort 585 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order); 586 | 587 | // set was_packed flags and all_rects_packed status 588 | for (i=0; i < num_rects; ++i) { 589 | rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL); 590 | if (!rects[i].was_packed) 591 | all_rects_packed = 0; 592 | } 593 | 594 | // return the all_rects_packed status 595 | return all_rects_packed; 596 | } 597 | #endif 598 | 599 | /* 600 | ------------------------------------------------------------------------------ 601 | This software is available under 2 licenses -- choose whichever you prefer. 602 | ------------------------------------------------------------------------------ 603 | ALTERNATIVE A - MIT License 604 | Copyright (c) 2017 Sean Barrett 605 | Permission is hereby granted, free of charge, to any person obtaining a copy of 606 | this software and associated documentation files (the "Software"), to deal in 607 | the Software without restriction, including without limitation the rights to 608 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 609 | of the Software, and to permit persons to whom the Software is furnished to do 610 | so, subject to the following conditions: 611 | The above copyright notice and this permission notice shall be included in all 612 | copies or substantial portions of the Software. 613 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 614 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 615 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 616 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 617 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 618 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 619 | SOFTWARE. 620 | ------------------------------------------------------------------------------ 621 | ALTERNATIVE B - Public Domain (www.unlicense.org) 622 | This is free and unencumbered software released into the public domain. 623 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 624 | software, either in source code form or as a compiled binary, for any purpose, 625 | commercial or non-commercial, and by any means. 626 | In jurisdictions that recognize copyright laws, the author or authors of this 627 | software dedicate any and all copyright interest in the software to the public 628 | domain. We make this dedication for the benefit of the public at large and to 629 | the detriment of our heirs and successors. We intend this dedication to be an 630 | overt act of relinquishment in perpetuity of all present and future rights to 631 | this software under copyright law. 632 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 633 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 634 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 635 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 636 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 637 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 638 | ------------------------------------------------------------------------------ 639 | */ 640 | -------------------------------------------------------------------------------- /source/RankViewer.cpp: -------------------------------------------------------------------------------- 1 | // Credits: Bakkes: MMR rounding, being a cool guy. CinderBlock: overall big help <3. mega: ] his SessionStats plugin was a really helpful reference. Others: savior, Martinn, Simple_AOB, HalfwayDead. 2 | // New Credits: Martin for the clean-up, thanks so much! I know it was a mess before, I suck at coding :D 3 | // New New Credits: I don't even know anymore so many people have helped, love this community everyone is so helpful <3 4 | 5 | #include "pch.h" 6 | #include "RankViewer.h" 7 | #include "bakkesmod/wrappers/MMRWrapper.h" 8 | #include "bakkesmod/wrappers/GuiManagerWrapper.h" 9 | #include "utils/parser.h" 10 | #include 11 | 12 | using json = nlohmann::json; 13 | 14 | BAKKESMOD_PLUGIN(RankViewer, "Rank Viewer", "2.1.1", 0) 15 | 16 | 17 | // Converts information into mmr. Format is directly from game (mode is 11-30, rank is 0-22, div is 0-3). Upper limit is to get the upper part of the range, setting it to false gets the lower part of the mmr range. 18 | int RankViewer::unranker(int mode, int rank, int div, bool upperLimit) { 19 | 20 | string fileName = std::to_string(mode) + ".json"; 21 | 22 | // Gets the correct json from the folder 23 | const auto rankJSON = gameWrapper->GetDataFolder() / "RankViewer" / "RankNumbers" / fileName; 24 | 25 | string limit; 26 | 27 | if (upperLimit == true) { 28 | limit = "maxMMR"; 29 | } 30 | else { 31 | limit = "minMMR"; 32 | } 33 | 34 | // Stores the json 35 | std::ifstream file(rankJSON); 36 | json j = json::parse(file); 37 | 38 | 39 | // Gets the correct mmr number 40 | return j["data"]["data"][((rank - 1) * 4) + (div + 1)][limit]; 41 | 42 | /* 43 | // This was an old attempt to fix the jsons. They currently have an issue where if there is missing spots in the database, it crashes. So for the few spots I have to manually add numbers to the json which is a pain 44 | // Below here also crashed the game, but leaving it here in case I want another attempt at fixing it 45 | int mmrNum = -1; 46 | 47 | for (int id = 0; id <= j["data"]["data"].size(); id++) { 48 | if (j["data"]["data"][id]["tier"] == rank && j["data"]["data"][id]["division"] == div) { 49 | mmrNum = j["data"]["data"][id][limit]; 50 | } 51 | } 52 | 53 | return mmrNum; // return here 54 | */ 55 | } 56 | 57 | 58 | // Converts rank and div into the usable string that displays on the screen 59 | string GetDivName(int rank, int div) { 60 | if (rank < 0 || rank > 22) { 61 | return "ERROR"; 62 | } 63 | else if (rank == 0 || rank == 22) { 64 | string rankName = " "; 65 | return rankName; 66 | } 67 | else { 68 | string divNumbers[] = { "I", "II", "III", "IV" }; 69 | string rankName = "DIV " + divNumbers[div]; 70 | 71 | return rankName; 72 | } 73 | 74 | 75 | /* 76 | if (rank < 0 || rank > 22) { 77 | return "ERROR"; 78 | } 79 | else { 80 | Rank realRank = (Rank)(rank); 81 | std::string rankName = RankInfoDB[realRank].name; 82 | string divNumbers[] = { "I", "II", "III", "IV" }; 83 | 84 | // Screw you brank for not helping me - Lol ok martinn idk the story behind this XD 85 | if (rank != Rank::Unranked && rank != Rank::SupersonicLegend) 86 | rankName += " Div " + divNumbers[div]; 87 | 88 | return rankName; 89 | }*/ 90 | } 91 | 92 | 93 | // Called when loaded in 94 | void RankViewer::onLoad() 95 | { 96 | // I didn't write this part, no idea how it works. It's for grabbing the mmr from the game 97 | gameWrapper->SetTimeout([this](GameWrapper* gameWrapper) { 98 | cvarManager->executeCommand("togglemenu " + GetMenuName()); 99 | }, 1); 100 | 101 | // Setting for if the plugin is enabled 102 | cvarManager->registerCvar("rankviewer_enabled", "1", "Enable or Disable the Rank Viewer Plugin", true, true, 0, true, 1, true); 103 | 104 | // Called when game ends 105 | gameWrapper->HookEvent("Function TAGame.GameEvent_Soccar_TA.OnMatchWinnerSet", bind(&RankViewer::StatsScreen, this, std::placeholders::_1)); 106 | 107 | // Called when you leave the stats screen 108 | gameWrapper->HookEvent("Function TAGame.GameEvent_Soccar_TA.Destroyed", bind(&RankViewer::loadMenu, this, std::placeholders::_1)); 109 | 110 | // Called when you open the friend tab 111 | gameWrapper->HookEventWithCaller("Function TAGame.GFxData_MenuStack_TA.ButtonTriggered", bind(&RankViewer::friendScreen, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); 112 | friendsOpen.Index = gameWrapper->GetFNameIndexByString("friendsButton"); 113 | friendsClose.Index = gameWrapper->GetFNameIndexByString("closeButton"); 114 | 115 | // Puts in the unranked icon as a placeholder for the three images in case something goes wrong later on 116 | auto testPath = gameWrapper->GetDataFolder() / "RankViewer" / "RankIcons" / "0.png"; 117 | currentRank = std::make_shared(testPath, false, true); 118 | 119 | testPath = gameWrapper->GetDataFolder() / "RankViewer" / "RankIcons" / "0.png"; 120 | nextRank = std::make_shared(testPath, false, true); 121 | 122 | testPath = gameWrapper->GetDataFolder() / "RankViewer" / "RankIcons" / "0.png"; 123 | beforeRank = std::make_shared(testPath, false, true); 124 | 125 | // Screen resolution 126 | screenSize = gameWrapper->GetScreenSize(); 127 | //safeZone = gameWrapper->GetSafeZoneRatio(); 128 | //uiScale = gameWrapper->GetUIScale(); 129 | } 130 | 131 | 132 | // Called when unloading 133 | void RankViewer::onUnload() 134 | { 135 | gameWrapper->UnhookEvent("Function TAGame.GameEvent_Soccar_TA.OnMatchWinnerSet"); 136 | gameWrapper->UnhookEvent("Function TAGame.GameEvent_Soccar_TA.Destroyed"); 137 | gameWrapper->UnhookEvent("Function TAGame.GFxData_MenuStack_TA.ButtonTriggered"); 138 | gameWrapper->UnregisterDrawables(); 139 | } 140 | 141 | // Gets mmr and rank information for displaying 142 | void RankViewer::CheckMMR(int retryCount) 143 | { 144 | isEnabled = cvarManager->getCvar("rankviewer_enabled").getBoolValue(); 145 | if (!isEnabled) { 146 | return; 147 | } 148 | 149 | // The updateMMR section is all from mega's plugin: SessionStats. Please view it here, its great :) https://bakkesplugins.com/plugins/view/39 150 | 151 | ServerWrapper sw = gameWrapper->GetOnlineGame(); 152 | 153 | if (sw.IsNull() || !sw.IsOnlineMultiplayer() || gameWrapper->IsInReplay()) 154 | return; 155 | 156 | if (retryCount > 20 || retryCount < 0) 157 | return; 158 | 159 | if (userPlaylist != 0) { 160 | gameWrapper->SetTimeout([retryCount, this](GameWrapper* gameWrapper) { 161 | gotNewMMR = false; 162 | while (!gotNewMMR) { 163 | if (1 || (gameWrapper->GetMMRWrapper().IsSynced(uniqueID, userPlaylist) && !gameWrapper->GetMMRWrapper().IsSyncing(uniqueID))) { 164 | 165 | // Makes sure it is one of the ranked gamemodes to prevent crashes 166 | if (!(find(begin(rankedPlaylists), end(rankedPlaylists), userPlaylist) != end(rankedPlaylists))) { 167 | return; 168 | } 169 | 170 | // Getting the mmr 171 | userMMR = gameWrapper->GetMMRWrapper().GetPlayerMMR(uniqueID, userPlaylist); 172 | gotNewMMR = true; 173 | 174 | MMRWrapper mw = gameWrapper->GetMMRWrapper(); 175 | 176 | // The SkillRank has information about the players rank 177 | SkillRank userRank = mw.GetPlayerRank(uniqueID, userPlaylist); 178 | 179 | // Getting the player rank information into separate variables 180 | userDiv = userRank.Division; 181 | userTier = userRank.Tier; 182 | 183 | // Converts the tier and div into the division with the roman numeral (I, II, III, IV) 184 | nameCurrent = GetDivName(userTier, userDiv); 185 | 186 | // Gets and loads the rank icon for your current rank from the RankViewer folder 187 | string fileName; 188 | fileName = std::to_string(userTier) + ".png"; 189 | const auto currentPath = gameWrapper->GetDataFolder() / "RankViewer" / "RankIcons" / fileName; 190 | currentRank = std::make_shared(currentPath, false, true); 191 | 192 | // This all checks for different scenarios where it won't be the default method of displaying 193 | if (userTier <= 0) { // --- When still in placement matches -- 194 | // For placement shows from bronze 1 and supersonic legend 195 | lowerTier = 1; 196 | upperTier = 22; 197 | 198 | nextLower = unranker(userPlaylist, upperTier, 0, true); // div has to be I (0) since ssl doesn't have divisions 199 | nameNext = GetDivName(22, 0); 200 | 201 | beforeUpper = unranker(userPlaylist, lowerTier, 0, false); 202 | nameBefore = GetDivName(0, 0); // This inputs the unranked name since it just won't show the division number 203 | } 204 | else if (userTier == 1 && userDiv == 0) { 205 | // For bronze 1 div 1. It just shows the bronze 1 div 1 lower limit on the bottom and bronze 1 div 2 on top 206 | upperTier = userTier; 207 | lowerTier = userTier; 208 | upperDiv = userDiv + 1; 209 | lowerDiv = 0; 210 | 211 | // Finds the mmr for that div and tier 212 | nextLower = unranker(userPlaylist, upperTier, upperDiv, false); 213 | nameNext = GetDivName(upperTier, upperDiv); 214 | 215 | beforeUpper = unranker(userPlaylist, lowerTier, lowerDiv, false); 216 | nameBefore = GetDivName(lowerTier, lowerDiv); 217 | } 218 | else if (userTier == 22) { 219 | // For ssl. Shows the ssl upper limit on top and gc 3 div 4 on bottom 220 | upperTier = userTier; 221 | lowerTier = userTier - 1; 222 | upperDiv = userDiv; 223 | lowerDiv = 3; 224 | 225 | // Finds the mmr for that div and tier 226 | nextLower = unranker(userPlaylist, upperTier, upperDiv, true); 227 | nameNext = GetDivName(upperTier, upperDiv); 228 | 229 | beforeUpper = unranker(userPlaylist, lowerTier, lowerDiv, true); 230 | nameBefore = GetDivName(lowerTier, lowerDiv); 231 | } 232 | else { 233 | // Finds out what div is above and below you 234 | if (userDiv == 0) { 235 | upperTier = userTier; 236 | lowerTier = userTier - 1; 237 | upperDiv = userDiv + 1; 238 | lowerDiv = 3; 239 | 240 | } 241 | else if (userDiv == 3) { 242 | upperTier = userTier + 1; 243 | lowerTier = userTier; 244 | upperDiv = 0; 245 | lowerDiv = userDiv - 1; 246 | } 247 | else { 248 | upperTier = userTier; 249 | lowerTier = userTier; 250 | upperDiv = userDiv + 1; 251 | lowerDiv = userDiv - 1; 252 | } 253 | 254 | // Finds the mmr for that div and tier 255 | nextLower = unranker(userPlaylist, upperTier, upperDiv, false); 256 | nameNext = GetDivName(upperTier, upperDiv); 257 | 258 | beforeUpper = unranker(userPlaylist, lowerTier, lowerDiv, true); 259 | nameBefore = GetDivName(lowerTier, lowerDiv); 260 | } 261 | 262 | // Gets correct rank icons from folder for before and after ranks 263 | fileName = std::to_string(lowerTier) + ".png"; 264 | const auto beforePath = gameWrapper->GetDataFolder() / "RankViewer" / "RankIcons" / fileName; 265 | beforeRank = std::make_shared(beforePath, false, true); 266 | 267 | fileName = std::to_string(upperTier) + ".png"; 268 | const auto nextPath = gameWrapper->GetDataFolder() / "RankViewer" / "RankIcons" / fileName; 269 | nextRank = std::make_shared(nextPath, false, true); 270 | 271 | // Lets rank viewer display 272 | drawCanvas = true; 273 | } 274 | // Failsafe 275 | if (!gotNewMMR && retryCount > 0) { 276 | gameWrapper->SetTimeout([retryCount, this](GameWrapper* gameWrapper) { 277 | this->CheckMMR(retryCount - 1); 278 | }, 0.5f); 279 | } 280 | else { 281 | return; 282 | } 283 | } 284 | }, 3); 285 | } 286 | } 287 | 288 | 289 | // Decides if it should render or not 290 | void RankViewer::Render() 291 | { 292 | // Only displays if the user has the plugin enableded 293 | isEnabled = cvarManager->getCvar("rankviewer_enabled").getBoolValue(); 294 | if (!isEnabled) { 295 | return; 296 | } 297 | 298 | if (isFriendOpen) { 299 | return; 300 | } 301 | 302 | // Makes sure you are in the game 303 | bool inGame = gameWrapper->IsInOnlineGame(); 304 | if (!inGame) { 305 | drawCanvas = false; 306 | return; 307 | } 308 | 309 | if (drawCanvas) { 310 | RankViewer::RenderImGui(); 311 | } 312 | } 313 | 314 | 315 | // The actual rendering of imgui 316 | void RankViewer::RenderImGui() 317 | { 318 | // Percentages for converting to a non-1080p screen 319 | float xPercent = ((float)screenSize.X / 1920); 320 | float yPercent = ((float)screenSize.Y / 1080); 321 | float upperBound = (290); 322 | float lowerBound = (835); 323 | 324 | // The imgui window allows the quads to show on the screen 325 | ImVec2 windowPos = ImVec2((1660 * xPercent), 0); 326 | ImGui::SetNextWindowPos(windowPos, ImGuiCond_Always); 327 | ImGui::SetNextWindowSize(ImVec2(screenSize.X - (1660 * xPercent) + (10 * xPercent), screenSize.Y + (10 * yPercent))); 328 | 329 | auto gui = gameWrapper->GetGUIManager(); 330 | fontBig = gui.GetFont("PantonBig"); 331 | 332 | // Early out if the window is collapsed, as an optimization. 333 | if (!ImGui::Begin(menuTitle_.c_str(), &isWindowOpen_, ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar)) 334 | { 335 | ImGui::End(); 336 | return; 337 | } 338 | 339 | ImDrawList* drawList = ImGui::GetWindowDrawList(); 340 | 341 | // Sidebar 342 | ImVec2 centerPoint = ImVec2(1920, 950); 343 | drawList->AddQuadFilled(ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y)), 344 | ImVec2(xPercent * (centerPoint.x - 45), yPercent * (centerPoint.y)), 345 | ImVec2(xPercent * (centerPoint.x - 45), yPercent * (centerPoint.y - 820)), 346 | ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y - 820)), 347 | IM_COL32_BLACK); 348 | 349 | // --- Lower Box --- 350 | // Displays the box 351 | centerPoint = ImVec2(1875, 950); 352 | drawList->AddQuadFilled(ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y)), 353 | ImVec2(xPercent * (centerPoint.x - 180), yPercent * (centerPoint.y)), 354 | ImVec2(xPercent * (centerPoint.x - 205), yPercent * (centerPoint.y - 45)), 355 | ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y - 45)), 356 | IM_COL32_BLACK); 357 | drawList->AddTriangleFilled(ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y - 45)), 358 | ImVec2(xPercent * (centerPoint.x - 35), yPercent * (centerPoint.y - 45)), 359 | ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y - 80)), 360 | IM_COL32_BLACK); 361 | // Displays fonts 362 | if (fontBig) { 363 | float defaultFontSize = 35 * xPercent; 364 | ImGui::PushFont(fontBig); 365 | drawList->AddText(fontBig, defaultFontSize, ImVec2(xPercent * (centerPoint.x - 155), yPercent * (centerPoint.y - 40)), ImU32(white), to_string(beforeUpper).c_str()); 366 | ImGui::PopFont(); 367 | 368 | defaultFontSize = 25 * xPercent; 369 | ImGui::PushFont(fontBig); 370 | drawList->AddText(fontBig, defaultFontSize, ImVec2(xPercent * (centerPoint.x - 85), yPercent * (centerPoint.y - 32)), ImU32(white), "MMR"); 371 | ImGui::PopFont(); 372 | 373 | defaultFontSize = 20 * xPercent; 374 | ImGui::PushFont(fontBig); 375 | drawList->AddText(fontBig, defaultFontSize, ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y - 75)), ImU32(white), nameBefore.c_str()); 376 | ImGui::PopFont(); 377 | } 378 | // Displays rank image 379 | if (beforeRank->IsLoadedForImGui()) { 380 | if (auto beforeRankTex = beforeRank->GetImGuiTex()) { 381 | auto beforeRankRect = beforeRank->GetSizeF(); 382 | ImGui::SetCursorPos(ImVec2(((xPercent * (centerPoint.x - 10)) - windowPos.x), yPercent * (centerPoint.y - 50))); 383 | ImGui::Image(beforeRankTex, ImVec2(beforeRankRect.X * 0.19f * xPercent, beforeRankRect.Y * 0.19f * yPercent)); 384 | } 385 | } 386 | 387 | // Upper Box 388 | // Displays the box 389 | centerPoint = ImVec2(1875, 175); 390 | drawList->AddQuadFilled(ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y)), 391 | ImVec2(xPercent * (centerPoint.x - 180), yPercent * (centerPoint.y)), 392 | ImVec2(xPercent * (centerPoint.x - 205), yPercent * (centerPoint.y - 45)), 393 | ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y - 45)), 394 | IM_COL32_BLACK); 395 | drawList->AddTriangleFilled(ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y)), 396 | ImVec2(xPercent * (centerPoint.x - 35), yPercent * (centerPoint.y)), 397 | ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y + 35)), 398 | IM_COL32_BLACK); 399 | // Displays fonts 400 | if (fontBig) { 401 | float defaultFontSize = 35 * xPercent; 402 | ImGui::PushFont(fontBig); 403 | drawList->AddText(fontBig, defaultFontSize, ImVec2(xPercent * (centerPoint.x - 155), yPercent * (centerPoint.y - 40)), ImU32(white), to_string(nextLower).c_str()); 404 | ImGui::PopFont(); 405 | 406 | defaultFontSize = 25 * xPercent; 407 | ImGui::PushFont(fontBig); 408 | drawList->AddText(fontBig, defaultFontSize, ImVec2(xPercent * (centerPoint.x - 85), yPercent * (centerPoint.y - 32)), ImU32(white), "MMR"); 409 | ImGui::PopFont(); 410 | 411 | defaultFontSize = 20 * xPercent; 412 | ImGui::PushFont(fontBig); 413 | drawList->AddText(fontBig, defaultFontSize, ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y - 40)), ImU32(white), nameNext.c_str()); 414 | ImGui::PopFont(); 415 | } 416 | // Displays rank image 417 | if (nextRank->IsLoadedForImGui()) { 418 | if (auto nextRankTex = nextRank->GetImGuiTex()) { 419 | auto nextRankRect = nextRank->GetSizeF(); 420 | ImGui::SetCursorPos(ImVec2(((xPercent * (centerPoint.x - 10)) - windowPos.x), yPercent * (centerPoint.y - 25))); 421 | ImGui::Image(nextRankTex, ImVec2(nextRankRect.X * 0.19f * xPercent, nextRankRect.Y * 0.19f * yPercent)); 422 | } 423 | } 424 | 425 | // Determines where the middle box should be (y position) based on upper and lower bounds 426 | yPos = (int)(upperBound + (((nextLower - userMMR) / (nextLower - beforeUpper)) * (lowerBound - upperBound))); 427 | if (yPos < upperBound) { 428 | yPos = upperBound; 429 | } 430 | else if (yPos > lowerBound) { 431 | yPos = lowerBound; 432 | } 433 | 434 | 435 | // Middle Box 436 | // Displays the box 437 | centerPoint = ImVec2(1875, yPos); 438 | drawList->AddQuadFilled(ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y)), 439 | ImVec2(xPercent * (centerPoint.x - 180), yPercent * (centerPoint.y)), 440 | ImVec2(xPercent * (centerPoint.x - 205), yPercent * (centerPoint.y - 45)), 441 | ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y - 45)), 442 | lightBlue); 443 | drawList->AddQuadFilled(ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y + 35)), 444 | ImVec2(xPercent * (centerPoint.x + 45), yPercent * (centerPoint.y + 35)), 445 | ImVec2(xPercent * (centerPoint.x + 45), yPercent * (centerPoint.y - 79)), 446 | ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y - 79)), 447 | lightBlue); 448 | drawList->AddTriangleFilled(ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y)), 449 | ImVec2(xPercent * (centerPoint.x - 35), yPercent * (centerPoint.y)), 450 | ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y + 35)), 451 | lightBlue); 452 | drawList->AddTriangleFilled(ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y - 45)), 453 | ImVec2(xPercent * (centerPoint.x - 35), yPercent * (centerPoint.y - 45)), 454 | ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y - 80)), 455 | lightBlue); 456 | // Displays fonts 457 | if (fontBig) { 458 | float defaultFontSize = 35 * xPercent; 459 | ImGui::PushFont(fontBig); 460 | drawList->AddText(fontBig, defaultFontSize, ImVec2(xPercent * (centerPoint.x - 155), yPercent * (centerPoint.y - 40)), ImU32(darkBlue), to_string((int)(round(userMMR))).c_str()); 461 | ImGui::PopFont(); 462 | 463 | defaultFontSize = 25 * xPercent; 464 | ImGui::PushFont(fontBig); 465 | drawList->AddText(fontBig, defaultFontSize, ImVec2(xPercent * (centerPoint.x - 85), yPercent * (centerPoint.y - 32)), ImU32(darkBlue), "MMR"); 466 | ImGui::PopFont(); 467 | 468 | defaultFontSize = 20 * xPercent; 469 | ImGui::PushFont(fontBig); 470 | drawList->AddText(fontBig, defaultFontSize, ImVec2(xPercent * (centerPoint.x), yPercent * (centerPoint.y - 65)), ImU32(darkBlue), nameCurrent.c_str()); 471 | ImGui::PopFont(); 472 | } 473 | // Displays rank image 474 | if (currentRank->IsLoadedForImGui()) { 475 | if (auto currentRankTex = currentRank->GetImGuiTex()) { 476 | auto currentRankRect = currentRank->GetSizeF(); 477 | ImGui::SetCursorPos(ImVec2(((xPercent * (centerPoint.x - 10)) - windowPos.x), yPercent * (centerPoint.y - 40))); 478 | ImGui::Image(currentRankTex, ImVec2(currentRankRect.X * 0.19f * xPercent, currentRankRect.Y * 0.19f * yPercent)); 479 | } 480 | } 481 | 482 | ImGui::End(); 483 | 484 | if (!isWindowOpen_) 485 | { 486 | cvarManager->executeCommand("togglemenu " + GetMenuName()); 487 | } 488 | } 489 | 490 | 491 | // Name of the menu that is used to toggle the window. 492 | std::string RankViewer::GetMenuName() 493 | { 494 | return "RankViewer"; 495 | } 496 | 497 | 498 | // Title to give the menu 499 | std::string RankViewer::GetMenuTitle() 500 | { 501 | return menuTitle_; 502 | } 503 | 504 | 505 | // Don't call this yourself, BM will call this function with a pointer to the current ImGui context 506 | void RankViewer::SetImGuiContext(uintptr_t ctx) 507 | { 508 | ImGui::SetCurrentContext(reinterpret_cast(ctx)); 509 | 510 | auto gui = gameWrapper->GetGUIManager(); 511 | 512 | gui.LoadFont("PantonBig", "Panton-LightCaps.otf", 32); 513 | } 514 | 515 | 516 | // Should events such as mouse clicks/key inputs be blocked so they won't reach the game 517 | bool RankViewer::ShouldBlockInput() 518 | { 519 | return ImGui::GetIO().WantCaptureMouse || ImGui::GetIO().WantCaptureKeyboard; 520 | } 521 | 522 | 523 | // Return true if window should be interactive 524 | bool RankViewer::IsActiveOverlay() 525 | { 526 | return false; 527 | } 528 | 529 | 530 | // Called when window is opened 531 | void RankViewer::OnOpen() 532 | { 533 | isWindowOpen_ = true; 534 | } 535 | 536 | 537 | // Called when window is closed 538 | void RankViewer::OnClose() 539 | { 540 | isWindowOpen_ = false; 541 | } 542 | 543 | 544 | // Called when the game ends 545 | void RankViewer::StatsScreen(std::string eventName) 546 | { 547 | isEnabled = cvarManager->getCvar("rankviewer_enabled").getBoolValue(); 548 | if (!isEnabled) { 549 | return; 550 | } 551 | 552 | // Getting the playlist and steam/epic id 553 | MMRWrapper mw = gameWrapper->GetMMRWrapper(); 554 | 555 | uniqueID = gameWrapper->GetUniqueID(); 556 | userPlaylist = mw.GetCurrentPlaylist(); 557 | 558 | // Gets the screen size in case it changed from the last time 559 | screenSize = gameWrapper->GetScreenSize(); 560 | //safeZone = gameWrapper->GetSafeZoneRatio(); 561 | //uiScale = gameWrapper->GetUIScale(); 562 | 563 | // The friend menu automatically closes when the game finishes 564 | isFriendOpen = false; 565 | 566 | // Getting the mmr, and after that all of the rank information needed 567 | if (mw.IsRanked(userPlaylist)) { 568 | // Makes sure the mmr updates 569 | CheckMMR(5); 570 | } 571 | } 572 | 573 | 574 | // Called when you go back to the main menu 575 | void RankViewer::loadMenu(std::string eventName) 576 | { 577 | // Removes canvas if you quit the stats screen 578 | drawCanvas = false; 579 | isFriendOpen = false; 580 | 581 | } 582 | 583 | 584 | // Called when you open or close the friend tab 585 | // Brank love you <3 this all him 586 | void RankViewer::friendScreen(ActorWrapper caller, void* params, const std::string& functionName) 587 | { 588 | // Temporarily disabling this feature until i get it working better 589 | 590 | /* 591 | if (params) 592 | { 593 | FName2* menuName = reinterpret_cast(params); 594 | 595 | if (menuName->Index == friendsOpen.Index) { 596 | if (isFriendOpen) { 597 | isFriendOpen = false; 598 | } 599 | else { 600 | isFriendOpen = true; 601 | } 602 | 603 | //cvarManager->log(to_string(isFriendOpen)); 604 | } 605 | else if (menuName->Index == friendsClose.Index) { 606 | isFriendOpen = false; 607 | //cvarManager->log(to_string(isFriendOpen)); 608 | } 609 | } 610 | */ 611 | 612 | } 613 | 614 | 615 | --------------------------------------------------------------------------------