ACHIEVEMENTS: Load achivements descriptions from achievements.dat
This commit is contained in:
parent
a81d534509
commit
629e5c2783
2 changed files with 83 additions and 16 deletions
|
@ -23,8 +23,10 @@
|
|||
|
||||
#include "common/achievements.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/system.h"
|
||||
#include "common/translation.h"
|
||||
#include "common/unzip.h"
|
||||
|
||||
namespace Common {
|
||||
|
||||
|
@ -67,11 +69,11 @@ bool AchievementsManager::setActiveDomain(const AchievementsInfo &info) {
|
|||
_iniFile = new Common::INIFile();
|
||||
_iniFile->loadFromSaveFile(_iniFileName); // missing file is OK
|
||||
|
||||
_descriptions = info.descriptions;
|
||||
loadAchievementsData(platform, info.appId.c_str());
|
||||
|
||||
for (uint32 i = 0; i < info.stats.size(); i++) {
|
||||
if (!(_iniFile->hasKey(info.stats[i].id, "statistics"))) {
|
||||
_iniFile->setKey(info.stats[i].id, "statistics", info.stats[i].start);
|
||||
for (uint32 i = 0; i < _stats.size(); i++) {
|
||||
if (!(_iniFile->hasKey(_stats[i].id, "statistics"))) {
|
||||
_iniFile->setKey(_stats[i].id, "statistics", _stats[i].start);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,6 +84,68 @@ bool AchievementsManager::setActiveDomain(const AchievementsInfo &info) {
|
|||
}
|
||||
|
||||
|
||||
bool AchievementsManager::loadAchievementsData(const char *platform, const char *appId) {
|
||||
Archive *cfgZip = Common::makeZipArchive("achievements.dat");
|
||||
if (!cfgZip) {
|
||||
warning("achievements.dat is not found. Achievements messages are unavailable");
|
||||
return false;
|
||||
}
|
||||
|
||||
String cfgFileName = String::format("%s-%s.ini", platform, appId);
|
||||
SeekableReadStream *stream = cfgZip->createReadStreamForMember(cfgFileName);
|
||||
if (!stream) {
|
||||
delete cfgZip;
|
||||
warning("%s is not found in achievements.dat. Achievements messages are unavailable", cfgFileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
INIFile cfgFile;
|
||||
if (!cfgFile.loadFromStream(*stream)) {
|
||||
delete stream;
|
||||
delete cfgZip;
|
||||
warning("%s is corrupted in achievements.dat. Achievements messages are unavailable", cfgFileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
_descriptions.clear();
|
||||
for (int i = 0; i < 256; i++) {
|
||||
String prefix = String::format("item_%d", i);
|
||||
|
||||
String id, title, comment, hidden;
|
||||
cfgFile.getKey(prefix + "_id", "achievements:en", id);
|
||||
cfgFile.getKey(prefix + "_title", "achievements:en", title);
|
||||
cfgFile.getKey(prefix + "_comment", "achievements:en", comment);
|
||||
cfgFile.getKey(prefix + "_hidden", "achievements:en", hidden);
|
||||
|
||||
if (id.empty()) {
|
||||
break;
|
||||
} else {
|
||||
_descriptions.push_back({id, title, comment, !hidden.empty()});
|
||||
}
|
||||
}
|
||||
|
||||
_stats.clear();
|
||||
for (int i = 0; i < 256; i++) {
|
||||
String prefix = String::format("item_%d", i);
|
||||
|
||||
String id, comment, start;
|
||||
cfgFile.getKey(prefix + "_id", "stats:en", id);
|
||||
cfgFile.getKey(prefix + "_comment", "stats:en", comment);
|
||||
cfgFile.getKey(prefix + "_start", "stats:en", start);
|
||||
|
||||
if (id.empty()) {
|
||||
break;
|
||||
} else {
|
||||
_stats.push_back({id, comment, start});
|
||||
}
|
||||
}
|
||||
|
||||
delete stream;
|
||||
delete cfgZip;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AchievementsManager::unsetActiveDomain() {
|
||||
debug("AchievementsManager::unsetActiveDomain()");
|
||||
|
||||
|
@ -91,6 +155,7 @@ bool AchievementsManager::unsetActiveDomain() {
|
|||
_iniFile = nullptr;
|
||||
|
||||
_descriptions.clear();
|
||||
_stats.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -107,7 +172,7 @@ bool AchievementsManager::setAchievement(const String &id) {
|
|||
|
||||
String displayedMessage = id;
|
||||
for (uint32 i = 0; i < _descriptions.size(); i++) {
|
||||
if (strcmp(_descriptions[i].id, id.c_str()) == 0) {
|
||||
if (_descriptions[i].id == id) {
|
||||
displayedMessage = _descriptions[i].title;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -53,19 +53,19 @@ enum AchievementsPlatform {
|
|||
* Information structure for game-specific statistics.
|
||||
*/
|
||||
struct StatDescription {
|
||||
const char *id; //!< Stat internal ID, such as "ITEMS_THROWN".
|
||||
const char *comment; //!< Optional stat comment, such as "Items Thrown".
|
||||
const char *start; //!< Stat default value, such as "0".
|
||||
String id; //!< Stat internal ID, such as "ITEMS_THROWN".
|
||||
String comment; //!< Optional stat comment, such as "Items Thrown".
|
||||
String start; //!< Stat default value, such as "0".
|
||||
};
|
||||
|
||||
/**
|
||||
* Information structure for game-specific achievements.
|
||||
*/
|
||||
struct AchievementDescription {
|
||||
const char *id; //!< Achievement internal ID, such as "ACHIEVEMENT_TIMING".
|
||||
bool isHidden; //!< Whether the achievement is hidden.
|
||||
const char *title; //!< Achievement displayed text, such as "Marathon Runner".
|
||||
const char *comment; //!< Optional achievement hint or comment, such as "Finish the game in less than 4 hours".
|
||||
String id; //!< Achievement internal ID, such as "ACHIEVEMENT_TIMING".
|
||||
String title; //!< Achievement displayed text, such as "Marathon Runner".
|
||||
String comment; //!< Optional achievement hint or comment, such as "Finish the game in less than 4 hours".
|
||||
bool isHidden; //!< Whether the achievement is hidden.
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -74,8 +74,6 @@ struct AchievementDescription {
|
|||
struct AchievementsInfo {
|
||||
Common::AchievementsPlatform platform; //!< Achievements platform, such as "STEAM_ACHIEVEMENTS".
|
||||
Common::String appId; //!< Achievements application ID of the given platform.
|
||||
Common::Array<StatDescription> stats; //!< Descriptions of all game stats.
|
||||
Common::Array<AchievementDescription> descriptions; //!< Descriptions of all game achievements.
|
||||
|
||||
AchievementsInfo() { platform = Common::UNK_ACHIEVEMENTS; }
|
||||
};
|
||||
|
@ -91,9 +89,10 @@ public:
|
|||
~AchievementsManager();
|
||||
|
||||
/**
|
||||
* Set a platform and application ID as active domain, store messages texts.
|
||||
* Set a game targeted by platform type and application ID as active domain.
|
||||
* Automaticly loads messages texts from achievements.dat.
|
||||
*
|
||||
* @param[in] info Achievements platform, application ID and messages information.
|
||||
* @param[in] info Achievements platform type and application ID.
|
||||
*/
|
||||
bool setActiveDomain(const AchievementsInfo &info);
|
||||
bool unsetActiveDomain(); //!< Unset the current active domain.
|
||||
|
@ -213,11 +212,14 @@ public:
|
|||
/** @} */
|
||||
|
||||
private:
|
||||
bool loadAchievementsData(const char *platform, const char *appId);
|
||||
|
||||
float getStatFloatEx(const String &id, const String §ion) const;
|
||||
bool setStatFloatEx(const String &id, float value, const String §ion) const;
|
||||
|
||||
INIFile *_iniFile;
|
||||
String _iniFileName;
|
||||
Common::Array<StatDescription> _stats;
|
||||
Common::Array<AchievementDescription> _descriptions;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue