NANCY: Implement Second Chance

Implemented Second Chance, which is the original engine's autosave system. This is disabled by default, since it replaces ScummVM's built-in autosaves.
This commit is contained in:
fracturehill 2021-04-13 23:11:33 +03:00
parent 5a7a2d8086
commit 864db52a09
7 changed files with 41 additions and 3 deletions

View File

@ -20,6 +20,8 @@
*
*/
#include "common/config-manager.h"
#include "engines/nancy/nancy.h"
#include "engines/nancy/sound.h"
#include "engines/nancy/resource.h"
@ -210,6 +212,19 @@ void SaveContinueGame::readData(Common::SeekableReadStream &stream) {
stream.skip(1);
}
void SaveContinueGame::execute() {
if (ConfMan.getBool("second_chance")) {
if (_state == kBegin) {
// Slight hack, skip first call to let the graphics render once and provide the correct thumbnail
_state = kRun;
return;
}
g_nancy->saveGameState(g_nancy->getAutosaveSlot(), "Second Chance", true);
}
_isDone = true;
}
void TurnOffMainRendering::readData(Common::SeekableReadStream &stream) {
stream.skip(1);
}

View File

@ -193,6 +193,7 @@ protected:
class SaveContinueGame : public ActionRecord {
public:
virtual void readData(Common::SeekableReadStream &stream) override;
virtual void execute() override;
protected:
virtual Common::String getRecordTypeName() const override { return "SaveContinueGame"; }

View File

@ -42,6 +42,9 @@ NancyOptionsWidget::NancyOptionsWidget(GuiObject *boss, const Common::String &na
_characterSpeechCheckbox = new GUI::CheckboxWidget(widgetsBoss(), "NancyOptionsDialog.CharacterSpeech", _("Character Speech"), _("Enable NPC speech. Only works if speech is enabled in the Audio settings."));
_originalMenusCheckbox = new GUI::CheckboxWidget(widgetsBoss(), "NancyOptionsDialog.OriginalMenus", _("Use original menus"), _("Use the original engine's main, save/load, and setup menus. ScummVM's Global Main Menu can still be accessed through its keymap."));
// I18N: Second Chance is the name of the original engine's autosave system
_secondChanceCheckbox = new GUI::CheckboxWidget(widgetsBoss(), "NancyOptionsDialog.SecondChance", _("Enable Second Chance"), _("Enable the Second Chance feature, which automatically saves at specific scenes. Enabling this disables timed autosaves."));
new GUI::StaticTextWidget(widgetsBoss(), "NancyOptionsDialog.SpeechSettingsLabel", _("Speech Options"));
new GUI::StaticTextWidget(widgetsBoss(), "NancyOptionsDialog.EngineSettingsLabel", _("Engine Options"));
}
@ -50,12 +53,14 @@ void NancyOptionsWidget::load() {
_playerSpeechCheckbox->setState(ConfMan.getBool("player_speech", _domain));
_characterSpeechCheckbox->setState(ConfMan.getBool("character_speech", _domain));
_originalMenusCheckbox->setState(ConfMan.getBool("original_menus", _domain));
_secondChanceCheckbox->setState(ConfMan.getBool("second_chance", _domain));
}
bool NancyOptionsWidget::save() {
ConfMan.setBool("player_speech", _playerSpeechCheckbox->getState(), _domain);
ConfMan.setBool("character_speech", _characterSpeechCheckbox->getState(), _domain);
ConfMan.setBool("original_menus", _originalMenusCheckbox->getState(), _domain);
ConfMan.setBool("second_chance", _secondChanceCheckbox->getState(), _domain);
return true;
}
@ -70,6 +75,7 @@ void NancyOptionsWidget::defineLayout(GUI::ThemeEval &layouts, const Common::Str
.addSpace(16)
.addWidget("EngineSettingsLabel", "OptionsLabel")
.addWidget("OriginalMenus", "Checkbox")
.addWidget("SecondChance", "Checkbox")
.closeLayout()
.closeDialog();
}

View File

@ -43,6 +43,7 @@ private:
GUI::CheckboxWidget *_playerSpeechCheckbox;
GUI::CheckboxWidget *_characterSpeechCheckbox;
GUI::CheckboxWidget *_originalMenusCheckbox;
GUI::CheckboxWidget *_secondChanceCheckbox;
};
class CheatDialog : public GUI::Dialog {

View File

@ -118,6 +118,14 @@ bool NancyEngine::canSaveGameStateCurrently() {
return Action::PlayPrimaryVideoChan0::_activePrimaryVideo == nullptr;
}
bool NancyEngine::canSaveAutosaveCurrently() {
if (ConfMan.getBool("second_chance")) {
return false;
} else {
return Engine::canSaveAutosaveCurrently();
}
}
bool NancyEngine::hasFeature(EngineFeature f) const {
return (f == kSupportsReturnToLauncher) ||
(f == kSupportsLoadingDuringRuntime) ||
@ -293,6 +301,7 @@ void NancyEngine::bootGameEngine() {
ConfMan.registerDefault("player_speech", true);
ConfMan.registerDefault("character_speech", true);
ConfMan.registerDefault("original_menus", false);
ConfMan.registerDefault("second_chance", false);
// Load archive
Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember("data1.cab");

View File

@ -91,6 +91,7 @@ public:
virtual Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override;
virtual bool canLoadGameStateCurrently() override;
virtual bool canSaveGameStateCurrently() override;
virtual bool canSaveAutosaveCurrently() override;
const char *getCopyrightString() const;
uint32 getGameFlags() const;

View File

@ -155,8 +155,13 @@ void MainMenu::stop() {
}
break;
case 4:
// Second Chance, TODO
_state = kRun;
// Second Chance
if (!Scene::hasInstance()) {
NancySceneState.process(); // run once to init the state
}
g_nancy->loadGameState(g_nancy->getAutosaveSlot());
g_nancy->setState(NancyState::kScene);
break;
case 5:
// Game Setup, TODO
@ -164,7 +169,7 @@ void MainMenu::stop() {
break;
case 6:
// Exit Game
g_nancy->quitGame(); // Consider returning to launcher instead?
g_nancy->quitGame();
break;
case 7:
// Help