enum LAchievement { LA_SUPPORTER = 0, LA_REVIEWER, LA_MONTHLING, LA_CASUAL, LA_ENTHUSIAST, LA_FANATIC, LA_PUZZLENEWBIE3X3, // ... // - , };
typedef bool (*HasAchievementProc)(void); // , typedef LString (*GetNoteProc)(void); // -, , " 99 "
enum AchievementVisibility { L_VIS, L_HID, };
struct sAchievement { int FID; // LAchievement bool FPaidVersion; // ? const char* FName; // , const char* FDescription; // , HasAchievementProc FProc; AchievementVisibility FHidden; const char* FProgressNote; // , "%s solved" GetNoteProc FNoteProc; bool FShowNoteAfterAwarding; // // , . // . // generated at runtime iGUIView* FViewPlate; iGUIView* FViewNote; clCVar* FAwarded; };
static sAchievement Achievements[] = { { LA_SUPPORTER, false, "Supporter", "Purchased Linderdaum Puzzle HD", &Check_Supporter, L_VIS, NULL }, { LA_REVIEWER, false, "Reviewer", "Added a review on Google Play", &Check_Reviewer, L_VIS, NULL }, { LA_MONTHLING, false, "Month's campaign", "Used the game for one month", &Check_Monthling, L_VIS, "%s days", &Get_DaysSinceFirstUse, true }, { LA_CASUAL, false, "Casual", "Spent half an hour in game", &Check_Casual, L_VIS, "%s minutes", &Get_MinutesInGame, false }, { LA_ENTHUSIAST, false, "Enthusiast", "Spent 2 hours in game", &Check_Enthusiast, L_VIS, "%s minutes", &Get_MinutesInGame, false }, { LA_FANATIC, true, "Fanatic", "Spent 10 hours in game", &Check_Fanatic, L_VIS, "%s hours", &Get_HoursInGame, false }, // ... // - , }
bool Check_Monthling() { LDate FirstRun = LDate( FirstRunDate.GetString() ); LDate Today; int Days = Today-FirstRun; return Days >= 30; }
if ( Time < 5.0 ) g_Achievements->Award( LA_BLINKOFANEYE );
class clAchievementsManager: public iObject { public: // // // clAchievementsManager // /// trigger the award for a one-time achievement virtual void Award( LAchievement Achievement ); virtual void AwardName( const LString& AchievementName ); virtual bool IsAwarded( LAchievement Achievement ) const; /// called automatically every 6 seconds or so to check new achievements virtual void ProcessAchievements(); virtual void RecheckAchievements(); // - public: std::deque<LAchievement> FPendingAwards; iGUIView* FAchievementsText; mlNode* FNode_Awarded; };
Env->SendAsyncCapsule( BindCapsule( &clAchievementsManager::ProcessAchievements, this ), 6.0 );
void clAchievementsManager::ProcessAchievements() { // save gamestate // ... RecheckAchievements(); // check achievements once in a while Env->SendAsyncCapsule( BindCapsule( &clAchievementsManager::ProcessAchievements, this ), 6.0 ); // nothing new to award if ( FPendingAwards.empty() ) return; LAchievement A = FPendingAwards.front(); FPendingAwards.pop_front(); // this achievement had been awarded long time ago if ( Achievements[ A ].FAwarded->GetBool() ) return; Achievements[ A ].FAwarded->SetBool( true ); // don't lose achievements in case of crash g_Game->SaveAchievements( g_SaveAchievementsFileName ); // show nice message here Env->Renderer->GetCanvas()->AnnounceObject( Construct<clAchievementAnnouncer>( Env, A, FNode_Awarded ), 0.0, 5.0 ); clPuzzl_AchievementsContainer* C = Env->GUI->FindView<clPuzzl_AchievementsContainer>("AchievementsContainer"); // update UI if ( C ) C->RecreateSubViews(); }
Source: https://habr.com/ru/post/161949/
All Articles