diff --git a/engines/asylum/asylum.cpp b/engines/asylum/asylum.cpp index 31a2dd0d3aa..9d3b0ccaaed 100644 --- a/engines/asylum/asylum.cpp +++ b/engines/asylum/asylum.cpp @@ -22,6 +22,7 @@ #include "backends/keymapper/keymapper.h" +#include "common/achievements.h" #include "common/debug-channels.h" #include "common/rect.h" @@ -144,6 +145,10 @@ Common::Error AsylumEngine::run() { // Setup mixer syncSoundSettings(); + // Set up achievements system + Common::String gameTarget = ConfMan.getActiveDomainName(); + AchMan.setActiveDomain(getMetaEngine()->getAchievementsInfo(gameTarget)); + // Send init event to our default event handler AsylumEvent initEvt(EVENT_ASYLUM_INIT); if (_handler) @@ -156,6 +161,9 @@ Common::Error AsylumEngine::run() { _system->delayMillis(10); _system->updateScreen(); + + if (_scene) + checkAchievements(); } return Common::kNoError; @@ -550,6 +558,75 @@ bool AsylumEngine::isGameFlagNotSet(GameFlag flag) const { return ((1 << (flag % 32)) & _gameFlags[flag / 32]) >> (flag % 32) == 0; } +bool AsylumEngine::areGameFlagsSet(uint from, uint to) const { + while (from <= to) + if (isGameFlagNotSet((GameFlag)from++)) + return false; + + return true; +} + +////////////////////////////////////////////////////////////////////////// +// Steam achievements +////////////////////////////////////////////////////////////////////////// +void AsylumEngine::unlockAchievement(const Common::String &id) { + AchMan.setAchievement(id); +} + +void AsylumEngine::checkAchievements() { + switch (_scene->worldstats()->chapter) { + default: + return; + + case kChapter2: + if (isGameFlagSet(kGameFlag128) && !isGameFlagSet(kGameFlag3189)) { + unlockAchievement("ASYLUM_HIDE_AND_SEEK"); + setGameFlag(kGameFlag3189); + } + break; + + case kChapter3: + if (isGameFlagSet(kGameFlag86) && !isGameFlagSet(kGameFlag3386)) + setGameFlag(kGameFlag3386); + if (isGameFlagSet(kGameFlag87) && !isGameFlagSet(kGameFlag3387)) + setGameFlag(kGameFlag3387); + if (isGameFlagSet(kGameFlag88) && !isGameFlagSet(kGameFlag3388)) + setGameFlag(kGameFlag3388); + + if (areGameFlagsSet(kGameFlag3386, kGameFlag3388) && !isGameFlagSet(kGameFlag3389)) { + unlockAchievement("ASYLUM_DANCE"); + setGameFlag(kGameFlag3389); + } + break; + + case kChapter5: + if (!isGameFlagSet(kGameFlag3351) && areGameFlagsSet(kGameFlag284, kGameFlag289)) { + unlockAchievement("ASYLUM_PASSWORD"); + setGameFlag(kGameFlag3351); + } + break; + + case kChapter6: + if (!isGameFlagSet(kGameFlag3754) && isGameFlagSet(kGameFlagSolveHiveMachine) && !isGameFlagSet(kGameFlag3755)) { + unlockAchievement("ASYLUM_MELODY"); + setGameFlag(kGameFlag3755); + } + break; + + case kChapter8: + if (!isGameFlagSet(kGameFlag3842) && areGameFlagsSet(kGameFlag3810, kGameFlag3823)) { + unlockAchievement("ASYLUM_SOCIAL"); + setGameFlag(kGameFlag3842); + } + + if (!isGameFlagSet(kGameFlag3843) && isGameFlagSet(kGameFlag899)) { + unlockAchievement("ASYLUM_SORT"); + setGameFlag(kGameFlag3843); + } + break; + } +} + ////////////////////////////////////////////////////////////////////////// // Misc ////////////////////////////////////////////////////////////////////////// diff --git a/engines/asylum/asylum.h b/engines/asylum/asylum.h index 8e227855aec..f36aa3b622e 100644 --- a/engines/asylum/asylum.h +++ b/engines/asylum/asylum.h @@ -162,6 +162,7 @@ public: void toggleGameFlag(GameFlag flag); bool isGameFlagSet(GameFlag flag) const; bool isGameFlagNotSet(GameFlag flag) const; + bool areGameFlagsSet(uint from, uint to) const; void resetFlags(); // Misc @@ -170,6 +171,10 @@ public: bool rectContains(const int16 (*rectPtr)[4], const Common::Point &p) const; + // Steam achievements + void unlockAchievement(const Common::String &id); + void checkAchievements(); + /** * Switch message handler. * diff --git a/engines/asylum/metaengine.cpp b/engines/asylum/metaengine.cpp index aa63ea57c23..8e97c00c6ce 100644 --- a/engines/asylum/metaengine.cpp +++ b/engines/asylum/metaengine.cpp @@ -26,6 +26,7 @@ #include "backends/keymapper/action.h" #include "backends/keymapper/keymap.h" +#include "common/achievements.h" #include "common/translation.h" #include "asylum/asylum.h" @@ -44,6 +45,7 @@ public: bool hasFeature(MetaEngineFeature f) const override; Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const override; Common::KeymapArray initKeymaps(const char *target) const override; + const Common::AchievementDescriptionList *getAchievementDescriptionList() const override; }; bool AsylumMetaEngine::hasFeature(MetaEngineFeature f) const { @@ -98,6 +100,16 @@ Common::KeymapArray AsylumMetaEngine::initKeymaps(const char *target) const { return Keymap::arrayOf(engineKeyMap); } +const Common::AchievementDescriptionList *AsylumMetaEngine::getAchievementDescriptionList() const { + static const Common::AchievementDescriptionList achievementDescriptionList[] = { + {"asylum", Common::STEAM_ACHIEVEMENTS, "284050"}, + + ACHIEVEMENT_DESC_TABLE_END_MARKER + }; + + return achievementDescriptionList; +} + #if PLUGIN_ENABLED_DYNAMIC(ASYLUM) REGISTER_PLUGIN_DYNAMIC(ASYLUM, PLUGIN_TYPE_ENGINE, AsylumMetaEngine); #else diff --git a/engines/asylum/resources/script.cpp b/engines/asylum/resources/script.cpp index bda990b321f..62e54e18050 100644 --- a/engines/asylum/resources/script.cpp +++ b/engines/asylum/resources/script.cpp @@ -947,6 +947,8 @@ IMPLEMENT_OPCODE(ChangeScene) getSound()->stopAll(); getSound()->stopMusic(); + _vm->unlockAchievement(Common::String::format("ASYLUM_LEVEL_%d", getWorld()->chapter)); + // Switch the scene _vm->switchScene((ResourcePackId)(cmd->param1 + 4)); @@ -1328,6 +1330,9 @@ IMPLEMENT_OPCODE(PlaySpeech) return; if (cmd->param4 != 2) { + if (cmd->param1 == 153 && getWorld()->chapter == kChapter2) + _vm->unlockAchievement("ASYLUM_FIND_CHILDREN"); + cmd->param5 = (int32)getSpeech()->playPlayer((ResourceId)cmd->param1); if (cmd->param2) { @@ -1893,6 +1898,10 @@ END_OPCODE ////////////////////////////////////////////////////////////////////////// // Opcode 0x62 IMPLEMENT_OPCODE(ShowMenu) + if (!_vm->isGameFlagSet(kGameFlag3931)) { + _vm->unlockAchievement("ASYLUM_LEVEL_13"); + _vm->setGameFlag(kGameFlag3931); + } _vm->menu()->show(); END_OPCODE diff --git a/engines/asylum/shared.h b/engines/asylum/shared.h index 69afd04e37b..9c26d6ae712 100644 --- a/engines/asylum/shared.h +++ b/engines/asylum/shared.h @@ -34,8 +34,12 @@ enum GameFlag { kGameFlag4 = 4, kGameFlag12 = 12, kGameFlag52 = 52, + kGameFlag86 = 86, + kGameFlag87 = 87, + kGameFlag88 = 88, kGameFlag114 = 114, kGameFlag115 = 115, + kGameFlag128 = 128, kGameFlag169 = 169, kGameFlagScriptProcessing = 183, kGameFlag186 = 186, @@ -81,6 +85,8 @@ enum GameFlag { kGameFlag281 = 281, kGameFlag282 = 282, kGameFlag283 = 283, + kGameFlag284 = 284, + kGameFlag289 = 289, kGameFlag319 = 319, kGameFlag320 = 320, kGameFlag321 = 321, @@ -227,6 +233,7 @@ enum GameFlag { kGameFlag880 = 880, kGameFlag881 = 881, kGameFlag897 = 897, + kGameFlag899 = 899, kGameFlagFinishGame = 901, kGameFlag925 = 925, kGameFlag937 = 937, @@ -254,7 +261,20 @@ enum GameFlag { kGameFlag1122 = 1122, kGameFlag1131 = 1131, kGameFlag1137 = 1137, - kGameFlag1144 = 1144 + kGameFlag1144 = 1144, + kGameFlag3189 = 3189, + kGameFlag3351 = 3351, + kGameFlag3386 = 3386, + kGameFlag3387 = 3387, + kGameFlag3388 = 3388, + kGameFlag3389 = 3389, + kGameFlag3754 = 3754, + kGameFlag3755 = 3755, + kGameFlag3810 = 3810, + kGameFlag3823 = 3823, + kGameFlag3842 = 3842, + kGameFlag3843 = 3843, + kGameFlag3931 = 3931 }; enum ChapterIndex {