Add achievements processing logic.

This commit is contained in:
Bartosz Taudul 2024-06-07 22:50:22 +02:00
parent d2e995478e
commit cddab58b0d
No known key found for this signature in database
GPG Key ID: B7FE2008B7575DF3
3 changed files with 178 additions and 27 deletions

View File

@ -121,6 +121,7 @@ static bool s_isElevated = false;
static size_t s_totalMem = tracy::GetPhysicalMemorySize(); static size_t s_totalMem = tracy::GetPhysicalMemorySize();
tracy::Config s_config; tracy::Config s_config;
tracy::AchievementsMgr s_achievements; tracy::AchievementsMgr s_achievements;
static const tracy::data::AchievementItem* s_achievementItem = nullptr;
static float smoothstep( float x ) static float smoothstep( float x )
{ {
@ -574,6 +575,45 @@ static void TextComment( const char* str )
ImGui::PopFont(); ImGui::PopFont();
} }
static void DrawAchievements( tracy::data::AchievementItem** items )
{
while( *items )
{
auto& it = *items++;
if( it->unlockTime > 0 )
{
if( it->doneTime > 0 ) ImGui::PushStyleColor( ImGuiCol_Text, GImGui->Style.Colors[ImGuiCol_TextDisabled] );
bool isSelected = s_achievementItem == it;
if( isSelected )
{
if( !it->hideNew ) it->hideNew = true;
if( !it->hideCompleted && it->doneTime > 0 ) it->hideCompleted = true;
}
if( ImGui::Selectable( it->name, isSelected ) )
{
s_achievementItem = it;
}
if( it->doneTime > 0 ) ImGui::PopStyleColor();
if( !it->hideNew )
{
ImGui::SameLine();
tracy::TextColoredUnformatted( 0xFF4488FF, ICON_FA_CIRCLE_EXCLAMATION );
}
if( !it->hideCompleted && it->doneTime > 0 )
{
ImGui::SameLine();
tracy::TextColoredUnformatted( 0xFF44FF44, ICON_FA_CIRCLE_CHECK );
}
if( it->items )
{
ImGui::Indent();
DrawAchievements( it->items );
ImGui::Unindent();
}
}
}
}
static void DrawContents() static void DrawContents()
{ {
static bool reconnect = false; static bool reconnect = false;
@ -1284,33 +1324,43 @@ static void DrawContents()
static int animStage = 0; static int animStage = 0;
static float animProgress = 0; static float animProgress = 0;
static bool showAchievements = false; static bool showAchievements = false;
static float openTimeLeft = 0;
float aSize = 0; float aSize = 0;
const auto aName = s_achievements.GetNextQueue(); const auto aItem = s_achievements.GetNextQueue();
if( aName )
if( aItem )
{ {
aSize = ImGui::CalcTextSize( aName->c_str() ).x + ImGui::GetStyle().ItemSpacing.x + ImGui::GetStyle().WindowPadding.x * 0.5f; aSize = ImGui::CalcTextSize( aItem->name ).x + ImGui::GetStyle().ItemSpacing.x + ImGui::GetStyle().WindowPadding.x * 0.5f;
if( animStage == 0 ) if( animStage == 0 )
{ {
animStage = 1; animStage = 1;
} }
} }
if( animStage == 1 ) if( animStage > 0 )
{ {
animProgress = std::min( animProgress + ImGui::GetIO().DeltaTime / 0.3f, 1.f );
if( animProgress == 1 ) animStage = 2;
tracy::s_wasActive = true; tracy::s_wasActive = true;
}
else if( animStage == 3 ) if( animStage == 1 )
{
animProgress = std::max( animProgress - ImGui::GetIO().DeltaTime / 0.3f, 0.f );
if( animProgress == 0 )
{ {
s_achievements.PopQueue(); animProgress = std::min( animProgress + ImGui::GetIO().DeltaTime / 0.3f, 1.f );
animStage = 0; if( animProgress == 1 )
{
animStage = 2;
openTimeLeft = 8;
}
tracy::s_wasActive = true;
}
else if( animStage == 3 )
{
animProgress = std::max( animProgress - ImGui::GetIO().DeltaTime / 0.3f, 0.f );
if( animProgress == 0 )
{
s_achievements.PopQueue();
animStage = 0;
}
} }
tracy::s_wasActive = true;
} }
ImGui::SetNextWindowPos( ImVec2( display_w - starSize.x - ImGui::GetStyle().WindowPadding.x * 1.5f - aSize * smoothstep( animProgress ), display_h - starSize.y * 2 - ImGui::GetStyle().WindowPadding.y * 2 ) ); ImGui::SetNextWindowPos( ImVec2( display_w - starSize.x - ImGui::GetStyle().WindowPadding.x * 1.5f - aSize * smoothstep( animProgress ), display_h - starSize.y * 2 - ImGui::GetStyle().WindowPadding.y * 2 ) );
@ -1323,26 +1373,48 @@ static void DrawContents()
if( ( animStage == 0 || animStage == 2 ) && ImGui::IsMouseHoveringRect( cursorScreen - ImVec2( dpiScale * 2, dpiScale * 2 ), cursorScreen + starSize + ImVec2( dpiScale * 4, dpiScale * 4 ) ) ) if( ( animStage == 0 || animStage == 2 ) && ImGui::IsMouseHoveringRect( cursorScreen - ImVec2( dpiScale * 2, dpiScale * 2 ), cursorScreen + starSize + ImVec2( dpiScale * 4, dpiScale * 4 ) ) )
{ {
color = 0xFFFFFFFF; color = 0xFFFFFFFF;
if( ImGui::IsMouseClicked( 0 ) ) showAchievements = !showAchievements; if( ImGui::IsMouseClicked( 0 ) )
{
if( animStage == 0 )
{
showAchievements = !showAchievements;
}
else
{
showAchievements = true;
animStage = 3;
s_achievementItem = aItem;
}
}
} }
ImGui::PushFont( s_bigFont ); ImGui::PushFont( s_bigFont );
tracy::TextColoredUnformatted( color, ICON_FA_STAR ); tracy::TextColoredUnformatted( color, ICON_FA_STAR );
ImGui::PopFont(); ImGui::PopFont();
if( aName ) if( aItem )
{ {
ImGui::SameLine(); ImGui::SameLine();
const auto dismiss = ImGui::GetCursorScreenPos(); const auto dismiss = ImGui::GetCursorScreenPos();
const auto th = ImGui::GetTextLineHeight(); const auto th = ImGui::GetTextLineHeight();
ImGui::SetCursorPosY( cursor.y - th * 0.175f ); ImGui::SetCursorPosY( cursor.y - th * 0.175f );
ImGui::TextUnformatted( aName->c_str() ); ImGui::TextUnformatted( aItem->name );
ImGui::PushFont( s_smallFont ); ImGui::PushFont( s_smallFont );
ImGui::SetCursorPos( cursor + ImVec2( starSize.x + ImGui::GetStyle().ItemSpacing.x, th ) ); ImGui::SetCursorPos( cursor + ImVec2( starSize.x + ImGui::GetStyle().ItemSpacing.x, th ) );
tracy::TextDisabledUnformatted( "Click to dismiss" ); tracy::TextDisabledUnformatted( "Click to open" );
ImGui::PopFont(); ImGui::PopFont();
if( animStage == 2 && ImGui::IsMouseHoveringRect( dismiss - ImVec2( 0, dpiScale * 6 ), dismiss + ImVec2( aSize, th * 1.5f + dpiScale * 4 ) ) && ImGui::IsMouseClicked( 0 ) ) if( animStage == 2 )
{ {
animStage = 3; if( ImGui::IsMouseHoveringRect( dismiss - ImVec2( 0, dpiScale * 6 ), dismiss + ImVec2( aSize, th * 1.5f + dpiScale * 4 ) ) && ImGui::IsMouseClicked( 0 ) )
{
s_achievementItem = aItem;
showAchievements = true;
animStage = 3;
}
if( !aItem->keepOpen )
{
openTimeLeft -= ImGui::GetIO().DeltaTime;
if( openTimeLeft < 0 ) animStage = 3;
}
} }
} }
@ -1353,6 +1425,29 @@ static void DrawContents()
{ {
ImGui::SetNextWindowSize( ImVec2( 600 * dpiScale, 400 * dpiScale ), ImGuiCond_FirstUseEver ); ImGui::SetNextWindowSize( ImVec2( 600 * dpiScale, 400 * dpiScale ), ImGuiCond_FirstUseEver );
ImGui::Begin( "Achievements List", &showAchievements, ImGuiWindowFlags_NoDocking ); ImGui::Begin( "Achievements List", &showAchievements, ImGuiWindowFlags_NoDocking );
ImGui::BeginTabBar( "###categories" );
auto categories = s_achievements.GetCategories();
while( *categories )
{
auto& c = *categories++;
if( c->unlockTime > 0 )
{
if( ImGui::BeginTabItem( c->name ) )
{
ImGui::Columns( 2 );
DrawAchievements( c->items );
ImGui::NextColumn();
if( s_achievementItem )
{
const tracy::data::ctx ctx = { s_bigFont, s_smallFont, s_fixedWidth };
s_achievementItem->description( ctx );
}
ImGui::EndColumns();
ImGui::EndTabItem();
}
}
}
ImGui::EndTabBar();
ImGui::End(); ImGui::End();
} }
} }

View File

@ -1,21 +1,50 @@
#include <assert.h> #include <assert.h>
#include <time.h>
#include "TracyAchievements.hpp" #include "TracyAchievements.hpp"
namespace tracy namespace tracy
{ {
namespace data { extern AchievementCategory* AchievementCategories[]; }
AchievementsMgr::AchievementsMgr() AchievementsMgr::AchievementsMgr()
{ {
m_queue.emplace_back( "Discover achievements!" ); auto cat = data::AchievementCategories;
m_queue.emplace_back( "Achievements are fun!" ); while( *cat )
m_queue.emplace_back( "The new beginnings are always the best!" ); {
FillMap( (*cat)->items, *cat );
cat++;
}
} }
const std::string* AchievementsMgr::GetNextQueue() void AchievementsMgr::Achieve( const char* id )
{
auto it = m_map.find( id );
assert( it != m_map.end() );
if( it->second.item->doneTime > 0 ) return;
const auto t = uint64_t( time( nullptr ) );
it->second.item->doneTime = uint64_t( t );
m_queue.push_back( it->second.item );
auto c = it->second.item->items;
if( c )
{
while( *c ) (*c++)->unlockTime = t;
}
}
data::AchievementCategory** AchievementsMgr::GetCategories() const
{
return data::AchievementCategories;
}
data::AchievementItem* AchievementsMgr::GetNextQueue()
{ {
if( m_queue.empty() ) return nullptr; if( m_queue.empty() ) return nullptr;
return &m_queue.front(); return m_queue.front();
} }
void AchievementsMgr::PopQueue() void AchievementsMgr::PopQueue()
@ -29,4 +58,14 @@ bool AchievementsMgr::NeedsUpdates() const
return false; return false;
} }
void AchievementsMgr::FillMap( data::AchievementItem** items, data::AchievementCategory* category )
{
while( *items )
{
m_map.emplace( (*items)->id, AchievementPair { *items, category } );
if( (*items)->items) FillMap( (*items)->items, category );
items++;
}
}
} }

View File

@ -5,6 +5,11 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "imgui.h"
#include "TracyCharUtil.hpp"
#include "tracy_robin_hood.h"
namespace tracy namespace tracy
{ {
@ -43,16 +48,28 @@ struct AchievementCategory
class AchievementsMgr class AchievementsMgr
{ {
struct AchievementPair
{
data::AchievementItem* item;
data::AchievementCategory* category;
};
public: public:
AchievementsMgr(); AchievementsMgr();
const std::string* GetNextQueue(); void Achieve( const char* id );
data::AchievementCategory** GetCategories() const;
data::AchievementItem* GetNextQueue();
void PopQueue(); void PopQueue();
bool NeedsUpdates() const; bool NeedsUpdates() const;
private: private:
std::vector<std::string> m_queue; void FillMap( data::AchievementItem** items, data::AchievementCategory* category );
std::vector<data::AchievementItem*> m_queue;
tracy::unordered_flat_map<const char*, AchievementPair, charutil::Hasher, charutil::Comparator> m_map;
}; };
} }