[Scummvm-git-logs] scummvm master -> 8a378fb89b03229f11154685838de209681ffd2f

fracturehill noreply at scummvm.org
Fri Mar 3 15:39:52 UTC 2023


This automated email contains information about 7 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
5fb49e2fe8 NANCY: Implement HotMultiframeMultisceneChange action record type
bfff477734 NANCY: Add support for secondary movie in The Vampire Diaries
a367dfe519 DEVTOOLS: Update create-nancy
5908e0b2d4 NANCY: Add facilities to load nancy.dat
2c9443ecf9 NANCY: Load conditional dialogue and hints from nancy.dat
900e4666c0 NANCY: Upgrade debug console
8a378fb89b NANCY: Remove cheat dialogs


Commit: 5fb49e2fe87ad18cc6b9073dbcc231e1a15d4b3f
    https://github.com/scummvm/scummvm/commit/5fb49e2fe87ad18cc6b9073dbcc231e1a15d4b3f
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-03T17:35:56+02:00

Commit Message:
NANCY: Implement HotMultiframeMultisceneChange action record type

Implemented the HotMultiframeMultisceneChange action record,
which chooses between two different scene transitions depending on
some condition.

Changed paths:
    engines/nancy/action/recordtypes.cpp
    engines/nancy/action/recordtypes.h


diff --git a/engines/nancy/action/recordtypes.cpp b/engines/nancy/action/recordtypes.cpp
index 0fc8df7ce18..5379bebdca8 100644
--- a/engines/nancy/action/recordtypes.cpp
+++ b/engines/nancy/action/recordtypes.cpp
@@ -106,9 +106,66 @@ void Hot1FrSceneChange::execute() {
 }
 
 void HotMultiframeMultisceneChange::readData(Common::SeekableReadStream &stream) {
-	stream.seek(0x14, SEEK_CUR);
-	uint size = stream.readUint16LE() * 0x12;
-	stream.skip(size);
+	_onTrue.readData(stream);
+	_onFalse.readData(stream);
+	_condType = (ConditionType)stream.readByte();
+	_conditionID = stream.readUint16LE();
+	_conditionPayload = stream.readByte();
+	uint numHotspots = stream.readUint16LE();
+	
+	_hotspots.resize(numHotspots);
+	
+	for (uint i = 0; i < numHotspots; ++i) {
+		_hotspots[i].readData(stream);
+	}
+}
+
+void HotMultiframeMultisceneChange::execute() {
+	switch (_state) {
+	case kBegin:
+		// set something to 1
+		_state = kRun;
+		// fall through
+	case kRun:
+		_hasHotspot = false;
+
+		for (HotspotDescription &desc : _hotspots) {
+			if (desc.frameID == NancySceneState.getSceneInfo().frameID) {
+				_hotspot = desc.coords;
+				_hasHotspot = true;
+			}
+		}
+
+		break;
+	case kActionTrigger: {
+		bool conditionMet = false;
+		switch (_condType) {
+		case kEventFlag:
+			if (NancySceneState.getEventFlag(_conditionID, (NancyFlag)_conditionPayload)) {
+				conditionMet = true;
+			}
+			break;
+		case kItem:
+			if (NancySceneState.hasItem(_conditionID) == _conditionPayload) {
+				conditionMet = true;
+			}
+			break;
+		case kItemHeld:
+			if (NancySceneState.getHeldItem() == _conditionPayload) {
+				conditionMet = true;
+			}
+			break;
+		}
+
+		if (conditionMet) {
+			NancySceneState.changeScene(_onTrue);
+		} else {
+			NancySceneState.changeScene(_onFalse);
+		}
+
+		break;
+	}
+	}
 }
 
 void PaletteThisScene::readData(Common::SeekableReadStream &stream) {
diff --git a/engines/nancy/action/recordtypes.h b/engines/nancy/action/recordtypes.h
index ee99e028ca0..0e0cf611e53 100644
--- a/engines/nancy/action/recordtypes.h
+++ b/engines/nancy/action/recordtypes.h
@@ -79,7 +79,17 @@ protected:
 
 class HotMultiframeMultisceneChange : public Unimplemented {
 public:
+	enum ConditionType { kEventFlag = 1, kItem = 2, kItemHeld = 3 };
+
 	void readData(Common::SeekableReadStream &stream) override;
+	void execute() override;
+
+	SceneChangeDescription _onTrue;
+	SceneChangeDescription _onFalse;
+	ConditionType _condType;
+	uint16 _conditionID;
+	byte _conditionPayload;
+	Common::Array<HotspotDescription> _hotspots;
 
 protected:
 	Common::String getRecordTypeName() const override { return "HotMultiframeMultisceneChange"; }


Commit: bfff477734d8ce911bdc72b2ca4de884cd80c8f6
    https://github.com/scummvm/scummvm/commit/bfff477734d8ce911bdc72b2ca4de884cd80c8f6
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-03T17:35:56+02:00

Commit Message:
NANCY: Add support for secondary movie in The Vampire Diaries

Made changes to PlaySecondaryMovie to support The Vampire Diaries'
slightly different data format.

Changed paths:
    engines/nancy/action/secondarymovie.cpp
    engines/nancy/action/secondarymovie.h


diff --git a/engines/nancy/action/secondarymovie.cpp b/engines/nancy/action/secondarymovie.cpp
index bbc59ca0dda..14d89b67aeb 100644
--- a/engines/nancy/action/secondarymovie.cpp
+++ b/engines/nancy/action/secondarymovie.cpp
@@ -28,6 +28,8 @@
 
 #include "engines/nancy/state/scene.h"
 
+#include "common/serializer.h"
+
 namespace Nancy {
 namespace Action {
 
@@ -40,29 +42,44 @@ PlaySecondaryMovie::~PlaySecondaryMovie() {
 }
 
 void PlaySecondaryMovie::readData(Common::SeekableReadStream &stream) {
-	readFilename(stream, _videoName);
+	Common::Serializer ser(&stream, nullptr);
+	ser.setVersion(g_nancy->getGameType());
 
-	stream.skip(0x12);
-	_unknown = stream.readUint16LE();
-	_hideMouse = (NancyFlag)stream.readUint16LE();
-	_isReverse = (NancyFlag)stream.readUint16LE();
-	_firstFrame = (NancyFlag)stream.readUint16LE();
-	_lastFrame = (NancyFlag)stream.readUint16LE();
-
-	for (uint i = 0; i < 15; ++i) {
-		_frameFlags[i].frameID = stream.readSint16LE();
-		_frameFlags[i].flagDesc.label = stream.readSint16LE();
-		_frameFlags[i].flagDesc.flag = (NancyFlag)stream.readUint16LE();
+	readFilename(stream, _videoName);
+	readFilename(stream, _paletteName);
+	ser.skip(10, kGameTypeVampire, kGameTypeVampire); // skip _bitmapOverlayName for now
+
+	ser.skip(0x2); // videoPlaySource
+
+	ser.syncAsUint16LE(_isTransparent, kGameTypeVampire, kGameTypeVampire);
+	ser.skip(4, kGameTypeVampire, kGameTypeVampire); // paletteStart, paletteSize
+	ser.skip(2, kGameTypeVampire, kGameTypeVampire); // hasBitmapOverlaySurface
+	ser.skip(2, kGameTypeVampire, kGameTypeVampire); // unknown, probably related to playing a sfx
+
+	ser.syncAsUint16LE(_unknown);
+	ser.syncAsUint16LE(_hideMouse);
+	ser.syncAsUint16LE(_isReverse);
+	ser.syncAsUint16LE(_firstFrame);
+	ser.syncAsUint16LE(_lastFrame);
+
+	if (ser.getVersion() >= kGameTypeNancy1) {
+		_frameFlags.resize(15);
+		for (uint i = 0; i < 15; ++i) {
+			ser.syncAsSint16LE(_frameFlags[i].frameID);
+			ser.syncAsSint16LE(_frameFlags[i].flagDesc.label);
+			ser.syncAsUint16LE(_frameFlags[i].flagDesc.flag);
+		}
 	}
 
 	_triggerFlags.readData(stream);
 	_sound.read(stream, SoundDescription::kNormal);
 	_sceneChange.readData(stream);
+	ser.skip(3, kGameTypeVampire, kGameTypeVampire); // unknown 3 sceneChange bytes
 
-	uint16 numVideoDescs = stream.readUint16LE();
-	_videoDescs.reserve(numVideoDescs);
+	uint16 numVideoDescs;
+	ser.syncAsUint16LE(numVideoDescs);
+	_videoDescs.resize(numVideoDescs);
 	for (uint i = 0; i < numVideoDescs; ++i) {
-		_videoDescs.push_back(SecondaryVideoDescription());
 		_videoDescs[i].readData(stream);
 	}
 }
@@ -76,6 +93,15 @@ void PlaySecondaryMovie::init() {
 		error("Couldn't load video file %s", _videoName.c_str());
 	}
 	_drawSurface.create(_decoder.getWidth(), _decoder.getHeight(), g_nancy->_graphicsManager->getInputPixelFormat());
+	if (_paletteName.size()) {
+		GraphicsManager::loadSurfacePalette(_fullFrame, _paletteName);
+	}
+
+	if (_isTransparent) {
+		setTransparent(true);
+		_fullFrame.setTransparentColor(_drawSurface.getTransparentColor());
+	}
+
 	_screenPosition = _drawSurface.getBounds();
 
 	RenderObject::init();
@@ -106,7 +132,9 @@ void PlaySecondaryMovie::updateGraphics() {
 			}
 		}
 
-		_drawSurface.blitFrom(*_decoder.decodeNextFrame(), _videoDescs[descID].srcRect, Common::Point());
+		GraphicsManager::copyToManaged(*_decoder.decodeNextFrame(), _fullFrame, _paletteName.size() > 0);
+		_drawSurface.create(_fullFrame, _fullFrame.getBounds());
+		moveTo(_videoDescs[descID].destRect);
 		_needsRedraw = true;
 
 		for (auto f : _frameFlags) {
diff --git a/engines/nancy/action/secondarymovie.h b/engines/nancy/action/secondarymovie.h
index eaefb2d0888..62991e6e537 100644
--- a/engines/nancy/action/secondarymovie.h
+++ b/engines/nancy/action/secondarymovie.h
@@ -49,13 +49,16 @@ public:
 	void execute() override;
 
 	Common::String _videoName; // 0x00
+	Common::String _paletteName;
+	//Common::String _bitmapOverlayName
+	NancyFlag _isTransparent = kFalse;
 
 	uint16 _unknown = 0; // 0x1C
 	NancyFlag _hideMouse = NancyFlag::kFalse; // 0x1E
-	NancyFlag _isReverse = NancyFlag::kFalse; // 0x20
-	uint16 _firstFrame = 0; // 0x22
-	uint16 _lastFrame = 0; // 0x24
-	FlagAtFrame _frameFlags[15]; // 0x26
+	NancyFlag _isReverse = NancyFlag::kFalse; // 0x20, 2E
+	uint16 _firstFrame = 0; // 0x22, 30
+	uint16 _lastFrame = 0; // 0x24, 32
+	Common::Array<FlagAtFrame> _frameFlags; // 0x26
 	MultiEventFlagDescription _triggerFlags; // 0x80
 
 	SoundDescription _sound; // 0xA8
@@ -68,6 +71,7 @@ protected:
 	bool isViewportRelative() const override { return true; }
 
 	AVFDecoder _decoder;
+	Graphics::ManagedSurface _fullFrame;
 	int _curViewportFrame = -1;
 	bool _isFinished = false;
 };


Commit: a367dfe5192735d5e89dceef9ea855be9b8361c4
    https://github.com/scummvm/scummvm/commit/a367dfe5192735d5e89dceef9ea855be9b8361c4
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-03T17:35:57+02:00

Commit Message:
DEVTOOLS: Update create-nancy

Updated the format for nancy.dat to make multilanguage arrays
much easier to read.

Changed paths:
    devtools/create_nancy/file.cpp
    devtools/create_nancy/types.h
    dists/engine-data/nancy.dat


diff --git a/devtools/create_nancy/file.cpp b/devtools/create_nancy/file.cpp
index 7b5a8f06a1a..c027b6099db 100644
--- a/devtools/create_nancy/file.cpp
+++ b/devtools/create_nancy/file.cpp
@@ -220,11 +220,10 @@ void writeToFile(File &file, const Hint &obj) {
 }
 
 void writeMultilangArray(File &file, const Common::Array<Common::Array<const char *>> &array) {
-    file.writeUint16(array.size());
     Common::Array<uint32> offsets;
     uint32 offsetsOffset = file.pos();
 
-    file.skip(array.size() * 4);
+    file.skip(array.size() * 4 + 4 + 2);
 
     for (uint i = 0; i < array.size(); ++i) {
         offsets.push_back(file.pos());
@@ -234,6 +233,8 @@ void writeMultilangArray(File &file, const Common::Array<Common::Array<const cha
     uint end = file.pos();
     file.seek(offsetsOffset);
 
+    file.writeUint16(array.size());
+    file.writeUint32(end);
     for (uint i = 0; i < array.size(); ++i) {
         file.writeUint32(offsets[i]);
     }
diff --git a/devtools/create_nancy/types.h b/devtools/create_nancy/types.h
index cf5c6677d1d..f6191ef4250 100644
--- a/devtools/create_nancy/types.h
+++ b/devtools/create_nancy/types.h
@@ -61,7 +61,7 @@ struct ConditionalDialogue {
 };
 
 struct GoodbyeSceneChange {
-	Common::Array<int16> sceneIDs;
+	Common::Array<uint16> sceneIDs;
 	Common::Array<EventFlagDescription> flagConditions;
 	EventFlagDescription flagToSet;
 };
diff --git a/dists/engine-data/nancy.dat b/dists/engine-data/nancy.dat
index 59684a3f665..1d238387232 100644
Binary files a/dists/engine-data/nancy.dat and b/dists/engine-data/nancy.dat differ


Commit: 5908e0b2d433b400e658c374614b9584a09587ca
    https://github.com/scummvm/scummvm/commit/5908e0b2d433b400e658c374614b9584a09587ca
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-03T17:35:57+02:00

Commit Message:
NANCY: Add facilities to load nancy.dat

Added functions for loading the data inside nancy.dat. Removed
constants.h and .cpp.

Changed paths:
  R engines/nancy/constants.cpp
  R engines/nancy/constants.h
    engines/nancy/commontypes.cpp
    engines/nancy/commontypes.h
    engines/nancy/cursor.cpp
    engines/nancy/module.mk
    engines/nancy/nancy.cpp
    engines/nancy/nancy.h
    engines/nancy/state/logo.cpp
    engines/nancy/state/scene.cpp
    engines/nancy/ui/inventorybox.cpp


diff --git a/engines/nancy/commontypes.cpp b/engines/nancy/commontypes.cpp
index 387c9ca0612..f7d490ca348 100644
--- a/engines/nancy/commontypes.cpp
+++ b/engines/nancy/commontypes.cpp
@@ -101,4 +101,201 @@ void SoundDescription::read(Common::SeekableReadStream &stream, Type type) {
 	stream.skip(2);
 }
 
+void ConditionalDialogue::readData(Common::SeekableReadStream &stream) {
+	textID = stream.readByte();
+	sceneID = stream.readUint16LE();
+	soundID = stream.readString();
+
+	uint16 num = stream.readUint16LE();
+	flagConditions.resize(num);
+	for (uint16 i = 0; i < num; ++i) {
+		flagConditions[i].label = stream.readSint16LE();
+		flagConditions[i].flag = (NancyFlag)stream.readByte();
+	}
+
+	num = stream.readUint16LE();
+	inventoryConditions.resize(num);
+	for (uint16 i = 0; i < num; ++i) {
+		inventoryConditions[i].label = stream.readSint16LE();
+		inventoryConditions[i].flag = (NancyFlag)stream.readByte();
+	}
+}
+
+void GoodbyeSceneChange::readData(Common::SeekableReadStream &stream) {
+	uint16 num = stream.readUint16LE();
+	sceneIDs.resize(num);
+	for (uint16 i = 0; i < num; ++i) {
+		sceneIDs[i] = stream.readSint16LE();
+	}
+
+	num = stream.readUint16LE();
+	flagConditions.resize(num);
+	for (uint16 i = 0; i < num; ++i) {
+		flagConditions[i].label = stream.readSint16LE();
+		flagConditions[i].flag = (NancyFlag)stream.readByte();
+	}
+
+	flagToSet.label = stream.readSint16LE();
+	flagToSet.flag = (NancyFlag)stream.readByte();
+}
+
+void Goodbye::readData(Common::SeekableReadStream &stream) {
+	soundID = stream.readString();
+
+	uint16 num = stream.readUint16LE();
+	sceneChanges.resize(num);
+	for (uint16 i = 0; i < num; ++i) {
+		sceneChanges[i].readData(stream);
+	}
+}
+
+void Hint::readData(Common::SeekableReadStream &stream) {
+	textID = stream.readByte();
+	hintWeight = stream.readSint16LE();
+	sceneChange.readData(stream);
+	soundIDs[0] = stream.readString();
+	soundIDs[1] = stream.readString();
+	soundIDs[2] = stream.readString();
+	
+	uint16 num = stream.readUint16LE();
+	flagConditions.resize(num);
+	for (uint16 i = 0; i < num; ++i) {
+		flagConditions[i].label = stream.readSint16LE();
+		flagConditions[i].flag = (NancyFlag)stream.readByte();
+	}
+
+	num = stream.readUint16LE();
+	inventoryConditions.resize(num);
+	for (uint16 i = 0; i < num; ++i) {
+		inventoryConditions[i].label = stream.readSint16LE();
+		inventoryConditions[i].flag = (NancyFlag)stream.readByte();
+	}
+}
+
+void StaticData::readData(Common::SeekableReadStream &stream, Common::Language language) {
+	numItems = stream.readUint16LE();
+	numEventFlags = stream.readUint16LE();
+
+	uint16 num = stream.readUint16LE();
+	mapAccessSceneIDs.resize(num);
+	for (uint16 i = 0; i < num; ++i) {
+		mapAccessSceneIDs[i] = stream.readUint16LE();
+	}
+
+	num = stream.readUint16LE();
+	genericEventFlags.resize(num);
+	for (uint16 i = 0; i < num; ++i) {
+		genericEventFlags[i] = stream.readUint16LE();
+	}
+
+	numNonItemCursors = stream.readUint16LE();
+	numCurtainAnimationFrames = stream.readUint16LE();
+	logoEndAfter = stream.readUint32LE();
+
+	// Check for language
+	num = stream.readUint16LE();
+	int languageID = -1;
+	for (uint16 i = 0; i < num; ++i) {
+		if (stream.readByte() == language) {
+			languageID = i;
+		}
+	}
+
+	if (languageID == -1) {
+		error("Language not present in nancy.dat");
+	}
+
+	// Read the strings logic
+	num = stream.readUint16LE();
+	conditionalDialogue.resize(num);
+	for (uint16 i = 0; i < num; ++i) {
+		uint16 num2 = stream.readUint16LE();
+		conditionalDialogue[i].resize(num2);
+		for (uint j = 0; j < num2; ++j) {
+			conditionalDialogue[i][j].readData(stream);
+		}
+	}
+
+	num = stream.readUint16LE();
+	goodbyes.resize(num);
+	for (uint16 i = 0; i < num; ++i) {
+		goodbyes[i].readData(stream);
+	}
+
+	num = stream.readUint16LE();
+	hints.resize(num);
+	for (uint16 i = 0; i < num; ++i) {
+		uint16 num2 = stream.readUint16LE();
+		hints[i].resize(num2);
+		for (uint j = 0; j < num2; ++j) {
+			hints[i][j].readData(stream);
+		}
+	}
+
+	// Read the in-game strings, making sure to pick the correct language
+	num = stream.readUint16LE();
+	if (num > 0) {
+		uint32 endOffset = stream.readUint32LE();
+		stream.skip(languageID * 4);
+		stream.seek(stream.readUint32LE());
+		num = stream.readUint16LE();
+		conditionalDialogueTexts.resize(num);
+		for (uint16 i = 0; i < num; ++i) {
+			conditionalDialogueTexts[i] = stream.readString();
+		}
+
+		stream.seek(endOffset);
+	}
+
+	num = stream.readUint16LE();
+	if (num > 0) {
+		uint32 endOffset = stream.readUint32LE();
+		stream.skip(languageID * 4);
+		stream.seek(stream.readUint32LE());
+		num = stream.readUint16LE();
+		goodbyeTexts.resize(num);
+		for (uint16 i = 0; i < num; ++i) {
+			goodbyeTexts[i] = stream.readString();
+		}
+
+		stream.seek(endOffset);
+	}
+
+	num = stream.readUint16LE();
+	if (num > 0) {
+		uint32 endOffset = stream.readUint32LE();
+		stream.skip(languageID * 4);
+		stream.seek(stream.readUint32LE());
+		num = stream.readUint16LE();
+		hintTexts.resize(num);
+		for (uint16 i = 0; i < num; ++i) {
+			hintTexts[i] = stream.readString();
+		}
+
+		stream.seek(endOffset);
+	}
+
+	num = stream.readUint16LE();
+	for (int i = 0; i < num; ++i) {
+		if (i == languageID) {
+			ringingText = stream.readString();
+		} else {
+			stream.readString();
+		}
+	}
+
+	// Read debug strings
+	num = stream.readUint16LE();
+	itemNames.resize(num);
+	for (uint16 i = 0; i < num; ++i) {
+		itemNames[i] = stream.readString();
+	}
+
+	num = stream.readUint16LE();
+	eventFlagNames.resize(num);
+	for (uint16 i = 0; i < num; ++i) {
+		eventFlagNames[i] = stream.readString();
+	}
+}
+
 } // End of namespace Nancy
diff --git a/engines/nancy/commontypes.h b/engines/nancy/commontypes.h
index 2bdd4bcd814..8453307b625 100644
--- a/engines/nancy/commontypes.h
+++ b/engines/nancy/commontypes.h
@@ -23,6 +23,8 @@
 #define NANCY_COMMONYPES_H
 
 #include "common/rect.h"
+#include "common/array.h"
+#include "common/str.h"
 
 namespace Common {
 class SeekableReadStream;
@@ -122,6 +124,72 @@ struct SoundDescription {
 	void read(Common::SeekableReadStream &stream, Type type);
 };
 
+// Structs inside nancy.dat, which contains all the data that was
+// originally stored inside the executable
+
+struct ConditionalDialogue {
+    byte textID;
+    uint16 sceneID;
+    Common::String soundID;
+	Common::Array<EventFlagDescription> flagConditions;
+	Common::Array<EventFlagDescription> inventoryConditions;
+
+	void readData(Common::SeekableReadStream &stream);
+};
+
+struct GoodbyeSceneChange {
+	Common::Array<uint16> sceneIDs;
+	Common::Array<EventFlagDescription> flagConditions;
+	EventFlagDescription flagToSet;
+
+	void readData(Common::SeekableReadStream &stream);
+};
+
+struct Goodbye {
+	Common::String soundID;
+	Common::Array<GoodbyeSceneChange> sceneChanges;
+
+	void readData(Common::SeekableReadStream &stream);
+};
+
+struct Hint {
+    byte textID;
+    int16 hintWeight;
+    SceneChangeDescription sceneChange;
+    Common::String soundIDs[3];
+    Common::Array<EventFlagDescription> flagConditions;
+	Common::Array<EventFlagDescription> inventoryConditions;
+
+	void readData(Common::SeekableReadStream &stream);
+};
+
+struct StaticData {
+	// Default values are for nancy1, provided for debugging purposes
+	uint16 numItems = 11;
+	uint16 numEventFlags = 168;
+	Common::Array<uint16> mapAccessSceneIDs;
+	Common::Array<uint16> genericEventFlags;
+	uint16 numNonItemCursors = 12;
+	uint16 numCurtainAnimationFrames = 7;
+	uint32 logoEndAfter = 7000;
+
+	// In-game strings and related logic
+	Common::Array<Common::Array<ConditionalDialogue>> conditionalDialogue;
+	Common::Array<Goodbye> goodbyes;
+	Common::Array<Common::Array<Hint>> hints;
+
+	Common::Array<Common::String> conditionalDialogueTexts;
+	Common::Array<Common::String> goodbyeTexts;
+	Common::Array<Common::String> hintTexts;
+	Common::String ringingText;
+
+	// Debug strings
+	Common::Array<Common::String> itemNames;
+	Common::Array<Common::String> eventFlagNames;
+
+	void readData(Common::SeekableReadStream &stream, Common::Language language);
+};
+
 } // End of namespace Nancy
 
 #endif // NANCY_COMMONYPES_H
diff --git a/engines/nancy/constants.cpp b/engines/nancy/constants.cpp
deleted file mode 100644
index 6db75949194..00000000000
--- a/engines/nancy/constants.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "engines/nancy/constants.h"
-
-namespace Nancy {
-
-const GameConstants gameConstants[] {
-	// The Vampire Diaries
-	{
-		24,
-		120,
-		{ 0, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 125, 219, 220, -1 },
-		{ 110, 111, 112, 113, 114, -1 },
-		8,
-		10,
-		167000
-	},
-
-	// Nancy Drew: Secrets Can Kill
-	{
-		11,
-		168,
-		{ 9, 10, 11, 666, 888, 1200, 1250, 1666, -1 },
-		{	44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
-			63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
-			75, 76, 77, 78, 79, 80, 81, 82, 83, 84, -1 },
-		12,
-		7,
-		7000
-	},
-
-	// Nancy Drew: Stay Tuned For Danger
-	{
-		18,
-		240,
-		{ -1 }, // No dedicated Map state
-		{	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
-			11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
-			21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1 },
-		12, // TODO
-		7, // TODO
-		7000 // TODO
-	}
-};
-
-} // End of namespace Nancy
diff --git a/engines/nancy/constants.h b/engines/nancy/constants.h
deleted file mode 100644
index e8fb08560fe..00000000000
--- a/engines/nancy/constants.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef NANCY_CONSTANTS_H
-#define NANCY_CONSTANTS_H
-
-#include "common/scummsys.h"
-
-namespace Nancy {
-
-// A struct containing various data that was hardcoded in the original engine but changed between titles
-struct GameConstants {
-	uint numItems;
-	uint numEventFlags;
-	int mapAccessSceneIDs[18];
-	int eventFlagsToClearOnSceneChange[32];
-	uint numNonItemCursors;
-	uint numCurtainAnimationFrames;
-	uint logoEndAfter;
-};
-
-extern const GameConstants gameConstants[];
-
-} // End of namespace Nancy
-
-#endif // NANCY_CONSTANTS_H
diff --git a/engines/nancy/cursor.cpp b/engines/nancy/cursor.cpp
index 1f5e113d585..69fe7800a6e 100644
--- a/engines/nancy/cursor.cpp
+++ b/engines/nancy/cursor.cpp
@@ -26,18 +26,17 @@
 #include "engines/nancy/graphics.h"
 #include "engines/nancy/resource.h"
 #include "engines/nancy/util.h"
-#include "engines/nancy/constants.h"
 
 namespace Nancy {
 
 void CursorManager::init() {
 	Common::SeekableReadStream *chunk = g_nancy->getBootChunkStream("INV");
-	chunk->seek(0xD6 + g_nancy->getConstants().numCurtainAnimationFrames * 0x20 + 0x1C);
+	chunk->seek(0xD6 + g_nancy->getStaticData().numCurtainAnimationFrames * 0x20 + 0x1C);
 	Common::String inventoryCursorsImageName = chunk->readString();
 
 	chunk = g_nancy->getBootChunkStream("CURS");
 	chunk->seek(0);
-	uint numCursors = g_nancy->getConstants().numNonItemCursors + g_nancy->getConstants().numItems * 4;
+	uint numCursors = g_nancy->getStaticData().numNonItemCursors + g_nancy->getStaticData().numItems * 4;
 	_cursors.reserve(numCursors);
 	for (uint i = 0; i < numCursors; ++i) {
 		_cursors.push_back(Cursor());
@@ -95,7 +94,7 @@ void CursorManager::setCursor(CursorType type, int16 itemID) {
 			itemID = 0;
 		} else {
 			// Item held
-			itemsOffset = g_nancy->getConstants().numNonItemCursors;
+			itemsOffset = g_nancy->getStaticData().numNonItemCursors;
 			hasItem = true;
 		}
 
diff --git a/engines/nancy/module.mk b/engines/nancy/module.mk
index 128025c9e2f..18870ea1530 100644
--- a/engines/nancy/module.mk
+++ b/engines/nancy/module.mk
@@ -30,7 +30,6 @@ MODULE_OBJS = \
   state/scene.o \
   commontypes.o \
   console.o \
-  constants.o \
   cursor.o \
   decompress.o \
   dialogs.o \
diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index 66524deb26a..1bcf5874c21 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -35,7 +35,6 @@
 #include "engines/nancy/graphics.h"
 #include "engines/nancy/dialogs.h"
 #include "engines/nancy/console.h"
-#include "engines/nancy/constants.h"
 #include "engines/nancy/util.h"
 
 #include "engines/nancy/action/primaryvideo.h"
@@ -51,7 +50,13 @@ namespace Nancy {
 
 NancyEngine *g_nancy;
 
-NancyEngine::NancyEngine(OSystem *syst, const NancyGameDescription *gd) : Engine(syst), _gameDescription(gd), _system(syst) {
+NancyEngine::NancyEngine(OSystem *syst, const NancyGameDescription *gd) :
+		Engine(syst),
+		_gameDescription(gd),
+		_system(syst),
+		_datFileMajorVersion(0),
+		_datFileMinorVersion(1) {
+
 	g_nancy = this;
 
 	_randomSource = new Common::RandomSource("Nancy");
@@ -151,8 +156,8 @@ Common::Platform NancyEngine::getPlatform() const {
 	return _gameDescription->desc.platform;
 }
 
-const GameConstants &NancyEngine::getConstants() const {
-	return gameConstants[getGameType() - 1];
+const StaticData &NancyEngine::getStaticData() const {
+	return _staticData;
 }
 
 void NancyEngine::setState(NancyState::NancyState state, NancyState::NancyState overridePrevious) {
@@ -318,6 +323,9 @@ void NancyEngine::bootGameEngine() {
 	_resource = new ResourceManager();
 	_resource->initialize();
 
+	// Read nancy.dat
+	readDatFile();
+
 	// Setup mixer
 	syncSoundSettings();
 
@@ -338,9 +346,7 @@ void NancyEngine::bootGameEngine() {
 		"MAP", "CD", "TBOX", "CURS", "VIEW", "MSND",
 		"BUOK", "BUDE", "BULS", "GLOB", "SLID",
 		"SET", "CURT", "CANT", "TH1", "TH2",
-		"QUOT", "TMOD",
-		// Used in nancy2
-		"CLOK", "SPEC"
+		"QUOT", "TMOD", "CLOK", "SPEC"
 	};
 
 	for (auto const &n : names) {
@@ -488,6 +494,36 @@ void NancyEngine::readBootSummary(const IFF &boot) {
 	}
 }
 
+void NancyEngine::readDatFile() {
+	Common::SeekableReadStream *datFile = SearchMan.createReadStreamForMember("nancy.dat");
+	if (!datFile) {
+		error("Unable to find nancy.dat");
+	}
+
+	if (datFile->readUint32BE() != MKTAG('N', 'N', 'C', 'Y')) {
+		error("nancy.dat is invalid");
+	}
+
+	byte major = datFile->readByte();
+	byte minor = datFile->readByte();
+	if (major != _datFileMajorVersion || minor != _datFileMinorVersion) {	
+		error("Incorrect nancy.dat version. Expected '%d.%d', found %d.%d",
+			_datFileMajorVersion, _datFileMinorVersion, major, minor);
+	}
+
+	uint16 numGames = datFile->readUint16LE();
+	if (getGameType() > numGames) {
+		warning("Data for game type %d is not in nancy.dat", numGames);
+		return;
+	}
+
+	// Seek to offset containing current game
+	datFile->skip((getGameType() - 1) * 4);
+	datFile->seek(datFile->readUint32LE());
+
+	_staticData.readData(*datFile, _gameDescription->desc.language);
+}
+
 Common::Error NancyEngine::synchronize(Common::Serializer &ser) {
 	Common::SeekableReadStream *bsum = getBootChunkStream("BSUM");
 	bsum->seek(0);
diff --git a/engines/nancy/nancy.h b/engines/nancy/nancy.h
index ef4cd8067e8..19099cf2994 100644
--- a/engines/nancy/nancy.h
+++ b/engines/nancy/nancy.h
@@ -64,7 +64,6 @@ class GraphicsManager;
 class CursorManager;
 class CheatDialog;
 class NancyConsole;
-struct GameConstants;
 
 namespace State {
 class State;
@@ -93,7 +92,7 @@ public:
 	GameType getGameType() const;
 	Common::Platform getPlatform() const;
 
-	const GameConstants &getConstants() const;
+	const StaticData &getStaticData() const;
 
 	void setState(NancyState::NancyState state, NancyState::NancyState overridePrevious = NancyState::kNone);
 	NancyState::NancyState getState() { return _gameFlow.curState; }
@@ -150,6 +149,7 @@ private:
 	void readChunkList(const IFF &boot, Common::Serializer &ser, const Common::String &prefix);
 
 	void readBootSummary(const IFF &boot);
+	void readDatFile();
 
 	Common::Error synchronize(Common::Serializer &serializer);
 
@@ -157,6 +157,10 @@ private:
 
 	bool _cheatTypeIsEventFlag;
 
+	StaticData _staticData;
+	const byte _datFileMajorVersion;
+	const byte _datFileMinorVersion;
+
 	GameFlow _gameFlow;
 	OSystem *_system;
 
diff --git a/engines/nancy/state/logo.cpp b/engines/nancy/state/logo.cpp
index 4bd43889f79..0b4c74a0cda 100644
--- a/engines/nancy/state/logo.cpp
+++ b/engines/nancy/state/logo.cpp
@@ -24,7 +24,6 @@
 #include "engines/nancy/nancy.h"
 #include "engines/nancy/sound.h"
 #include "engines/nancy/input.h"
-#include "engines/nancy/constants.h"
 
 #include "engines/nancy/state/logo.h"
 
@@ -73,7 +72,7 @@ void Logo::startSound() {
 }
 
 void Logo::run() {
-	if ((g_nancy->getTotalPlayTime() - _startTicks >= g_nancy->getConstants().logoEndAfter) ||
+	if ((g_nancy->getTotalPlayTime() - _startTicks >= g_nancy->getStaticData().logoEndAfter) ||
 		(g_nancy->_input->getInput().input & NancyInput::kLeftMouseButtonDown)) {
 		_state = kStop;
 	}
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index d6d2910af8e..69a3c717638 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -29,7 +29,6 @@
 #include "engines/nancy/graphics.h"
 #include "engines/nancy/cursor.h"
 #include "engines/nancy/util.h"
-#include "engines/nancy/constants.h"
 
 #include "engines/nancy/state/scene.h"
 
@@ -235,7 +234,7 @@ void Scene::setHeldItem(int16 id)  {
 }
 
 void Scene::setEventFlag(int16 label, NancyFlag flag) {
-	if (label > -1 && (uint)label < g_nancy->getConstants().numEventFlags) {
+	if (label > -1 && (uint)label < g_nancy->getStaticData().numEventFlags) {
 		_flags.eventFlags[label] = flag;
 	}
 }
@@ -245,7 +244,7 @@ void Scene::setEventFlag(EventFlagDescription eventFlag) {
 }
 
 bool Scene::getEventFlag(int16 label, NancyFlag flag) const {
-	if (label > -1 && (uint)label < g_nancy->getConstants().numEventFlags) {
+	if (label > -1 && (uint)label < g_nancy->getStaticData().numEventFlags) {
 		return _flags.eventFlags[label] == flag;
 	} else {
 		return false;
@@ -345,7 +344,7 @@ void Scene::synchronize(Common::Serializer &ser) {
 	// TODO hardcoded inventory size
 	auto &order = getInventoryBox()._order;
 	uint prevSize = getInventoryBox()._order.size();
-	getInventoryBox()._order.resize(g_nancy->getConstants().numItems);
+	getInventoryBox()._order.resize(g_nancy->getStaticData().numItems);
 
 	if (ser.isSaving()) {
 		for (uint i = prevSize; i < order.size(); ++i) {
@@ -353,7 +352,7 @@ void Scene::synchronize(Common::Serializer &ser) {
 		}
 	}
 
-	ser.syncArray(order.data(), g_nancy->getConstants().numItems, Common::Serializer::Sint16LE);
+	ser.syncArray(order.data(), g_nancy->getStaticData().numItems, Common::Serializer::Sint16LE);
 
 	while (order.size() && order.back() == -1) {
 		order.pop_back();
@@ -365,7 +364,7 @@ void Scene::synchronize(Common::Serializer &ser) {
 	}
 
 	// TODO hardcoded inventory size
-	ser.syncArray(_flags.items.data(), g_nancy->getConstants().numItems, Common::Serializer::Byte);
+	ser.syncArray(_flags.items.data(), g_nancy->getStaticData().numItems, Common::Serializer::Byte);
 	ser.syncAsSint16LE(_flags.heldItem);
 	g_nancy->_cursorManager->setCursorItemID(_flags.heldItem);
 
@@ -380,7 +379,7 @@ void Scene::synchronize(Common::Serializer &ser) {
 	g_nancy->setTotalPlayTime((uint32)_timers.lastTotalTime);
 
 	// TODO hardcoded number of event flags
-	ser.syncArray(_flags.eventFlags.data(), g_nancy->getConstants().numEventFlags, Common::Serializer::Byte);
+	ser.syncArray(_flags.eventFlags.data(), g_nancy->getStaticData().numEventFlags, Common::Serializer::Byte);
 
 	ser.syncArray<uint16>(_flags.sceneHitCount, (uint16)2001, Common::Serializer::Uint16LE);
 
@@ -414,14 +413,14 @@ void Scene::synchronize(Common::Serializer &ser) {
 }
 
 void Scene::init() {
-	_flags.eventFlags = Common::Array<NancyFlag>(g_nancy->getConstants().numEventFlags, kFalse);
+	_flags.eventFlags = Common::Array<NancyFlag>(g_nancy->getStaticData().numEventFlags, kFalse);
 
 	// Does this ever get used?
 	for (uint i = 0; i < 2001; ++i) {
 		_flags.sceneHitCount[i] = 0;
 	}
 
-	_flags.items = Common::Array<NancyFlag>(g_nancy->getConstants().numItems, kFalse);
+	_flags.items = Common::Array<NancyFlag>(g_nancy->getStaticData().numItems, kFalse);
 
 	_timers.lastTotalTime = 0;
 	_timers.playerTime = g_nancy->_startTimeHours * 3600000;
@@ -619,12 +618,8 @@ void Scene::run() {
 	}
 
 	// Handle invisible map button
-	for (uint i = 0; i < ARRAYSIZE(g_nancy->getConstants().mapAccessSceneIDs); ++i) {
-		if (g_nancy->getConstants().mapAccessSceneIDs[i] == -1) {
-			break;
-		}
-
-		if ((int)_sceneState.currentScene.sceneID == g_nancy->getConstants().mapAccessSceneIDs[i]) {
+	for (uint16 id : g_nancy->getStaticData().mapAccessSceneIDs) {
+		if ((int)_sceneState.currentScene.sceneID == id) {
 			if (_mapHotspot.contains(input.mousePos)) {
 				g_nancy->_cursorManager->setCursorType(CursorManager::kHotspotArrow);
 
@@ -632,6 +627,8 @@ void Scene::run() {
 					requestStateChange(NancyState::kMap);
 				}
 			}
+
+			break;
 		}
 	}
 
@@ -682,13 +679,9 @@ void Scene::initStaticData() {
 }
 
 void Scene::clearSceneData() {
-	// only clear select flags
-	for (uint i = 0; i < ARRAYSIZE(g_nancy->getConstants().eventFlagsToClearOnSceneChange); ++i) {
-		if (g_nancy->getConstants().eventFlagsToClearOnSceneChange[i] == -1) {
-			break;
-		}
-
-		_flags.eventFlags[g_nancy->getConstants().eventFlagsToClearOnSceneChange[i]] = kFalse;
+	// Clear generic flags only
+	for (uint16 id : g_nancy->getStaticData().genericEventFlags) {
+		_flags.eventFlags[id] = kFalse;
 	}
 
 	clearLogicConditions();
diff --git a/engines/nancy/ui/inventorybox.cpp b/engines/nancy/ui/inventorybox.cpp
index f88ac99730d..2546ac4cf60 100644
--- a/engines/nancy/ui/inventorybox.cpp
+++ b/engines/nancy/ui/inventorybox.cpp
@@ -26,7 +26,6 @@
 #include "engines/nancy/sound.h"
 #include "engines/nancy/input.h"
 #include "engines/nancy/util.h"
-#include "engines/nancy/constants.h"
 
 #include "engines/nancy/ui/inventorybox.h"
 
@@ -64,7 +63,7 @@ void InventoryBox::init() {
 
 	stream.seek(0xD6, SEEK_SET);
 
-	uint numFrames = g_nancy->getConstants().numCurtainAnimationFrames;
+	uint numFrames = g_nancy->getStaticData().numCurtainAnimationFrames;
 	_curtainsSrc.resize(numFrames * 2);
 	for (uint i = 0; i < numFrames * 2; ++i) {
 		readRect(stream, _curtainsSrc[i]);
@@ -83,8 +82,8 @@ void InventoryBox::init() {
 	char itemName[20];
 	uint itemNameLength = g_nancy->getGameType() == kGameTypeVampire ? 15 : 20;
 
-	_itemDescriptions.reserve(g_nancy->getConstants().numItems);
-	for (uint i = 0; i < g_nancy->getConstants().numItems; ++i) {
+	_itemDescriptions.reserve(g_nancy->getStaticData().numItems);
+	for (uint i = 0; i < g_nancy->getStaticData().numItems; ++i) {
 		stream.read(itemName, itemNameLength);
 		itemName[itemNameLength - 1] = '\0';
 		_itemDescriptions.push_back(ItemDescription());
@@ -96,7 +95,7 @@ void InventoryBox::init() {
 
 	g_nancy->_resource->loadImage(inventoryBoxIconsImageName, _iconsSurface);
 
-	_fullInventorySurface.create(_screenPosition.width(), _screenPosition.height() * ((g_nancy->getConstants().numItems / 4) + 1), g_nancy->_graphicsManager->getScreenPixelFormat());
+	_fullInventorySurface.create(_screenPosition.width(), _screenPosition.height() * ((g_nancy->getStaticData().numItems / 4) + 1), g_nancy->_graphicsManager->getScreenPixelFormat());
 	Common::Rect sourceRect = _screenPosition;
 	sourceRect.moveTo(0, 0);
 	_drawSurface.create(_fullInventorySurface, sourceRect);
@@ -249,7 +248,7 @@ void InventoryBox::Curtains::init() {
 void InventoryBox::Curtains::updateGraphics() {
 	Time time = g_nancy->getTotalPlayTime();
 	if (_areOpen) {
-		if (_curFrame < g_nancy->getConstants().numCurtainAnimationFrames && time > _nextFrameTime) {
+		if (_curFrame < g_nancy->getStaticData().numCurtainAnimationFrames && time > _nextFrameTime) {
 			setAnimationFrame(++_curFrame);
 			_nextFrameTime = time + _parent->_curtainsFrameTime;
 
@@ -270,7 +269,7 @@ void InventoryBox::Curtains::updateGraphics() {
 		}
 	}
 
-	if (_curFrame == 0 || _curFrame == g_nancy->getConstants().numCurtainAnimationFrames) {
+	if (_curFrame == 0 || _curFrame == g_nancy->getStaticData().numCurtainAnimationFrames) {
 		_soundTriggered = false;
 	}
 }
@@ -280,7 +279,7 @@ void InventoryBox::Curtains::setAnimationFrame(uint frame) {
 	Common::Rect srcRect;
 	Common::Point destPoint;
 
-	if (frame > g_nancy->getConstants().numCurtainAnimationFrames - 1) {
+	if (frame > (uint)(g_nancy->getStaticData().numCurtainAnimationFrames - 1)) {
 		setVisible(false);
 		return;
 	} else {


Commit: 2c9443ecf921a548031d5031286082c1e8ddaee7
    https://github.com/scummvm/scummvm/commit/2c9443ecf921a548031d5031286082c1e8ddaee7
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-03T17:35:58+02:00

Commit Message:
NANCY: Load conditional dialogue and hints from nancy.dat

Added facilities to load conditional dialogue and hints from
nancy.dat. Removed unnecessary files. Bumped save game version
up by one.

Changed paths:
  R engines/nancy/action/responses.cpp
  R engines/nancy/dialogueresponses.cpp
  R engines/nancy/dialogueresponses.h
    engines/nancy/action/primaryvideo.cpp
    engines/nancy/action/primaryvideo.h
    engines/nancy/action/recordtypes.cpp
    engines/nancy/action/recordtypes.h
    engines/nancy/nancy.h
    engines/nancy/state/scene.cpp
    engines/nancy/state/scene.h


diff --git a/engines/nancy/action/primaryvideo.cpp b/engines/nancy/action/primaryvideo.cpp
index 89dbfbe28d1..7ab861e7c8a 100644
--- a/engines/nancy/action/primaryvideo.cpp
+++ b/engines/nancy/action/primaryvideo.cpp
@@ -31,7 +31,6 @@
 #include "engines/nancy/graphics.h"
 
 #include "engines/nancy/action/primaryvideo.h"
-#include "engines/nancy/action/responses.cpp"
 
 #include "engines/nancy/state/scene.h"
 
@@ -281,7 +280,7 @@ void PlayPrimaryVideoChan0::execute() {
 
 			// Add responses when conditions have been satisfied
 			if (_conditionalResponseCharacterID != 10) {
-				addConditionalResponses();
+				addConditionalDialogue();
 			}
 
 			if (_goodbyeResponseCharacterID != 10) {
@@ -374,15 +373,54 @@ void PlayPrimaryVideoChan0::handleInput(NancyInput &input) {
 	}
 }
 
-void PlayPrimaryVideoChan0::addConditionalResponses() {
-	for (const auto &res : nancy1ConditionalResponses) {
-		if (res.characterID == _conditionalResponseCharacterID) {
+void PlayPrimaryVideoChan0::addConditionalDialogue() {
+	for (const auto &res : g_nancy->getStaticData().conditionalDialogue[_conditionalResponseCharacterID]) {
+		bool isSatisfied = true;
+
+		for (const auto &cond : res.flagConditions) {
+			if (!NancySceneState.getEventFlag(cond.label, cond.flag)) {
+				isSatisfied = false;
+				break;
+			}
+		}
+
+		for (const auto &cond : res.inventoryConditions) {
+			if (NancySceneState.hasItem(cond.label) != cond.flag) {
+				isSatisfied = false;
+				break;
+			}
+		}
+
+		if (isSatisfied) {
+			_responses.push_back(ResponseStruct());
+			ResponseStruct &newResponse = _responses.back();
+			newResponse.soundName = res.soundID;
+			newResponse.text = g_nancy->getStaticData().conditionalDialogueTexts[res.textID];
+			newResponse.sceneChange.sceneID = res.sceneID;
+			newResponse.sceneChange.doNotStartSound = true;
+		}
+	}
+}
+
+void PlayPrimaryVideoChan0::addGoodbye() {
+	auto &res = g_nancy->getStaticData().goodbyes[_goodbyeResponseCharacterID];
+	_responses.push_back(ResponseStruct());
+	ResponseStruct &newResponse = _responses.back();
+	newResponse.soundName = res.soundID;
+	newResponse.text = g_nancy->getStaticData().goodbyeTexts[_goodbyeResponseCharacterID];
+	
+	// Evaluate conditions to pick from the collection of replies
+	uint sceneChangeID;
+	for (uint i = 0; i < res.sceneChanges.size(); ++i) {
+		const GoodbyeSceneChange &sc = res.sceneChanges[i];
+		if (sc.flagConditions.size() == 0) {
+			// No conditions, default choice
+			sceneChangeID = i;
+			break;
+		} else {
 			bool isSatisfied = true;
-			for (const auto & cond : res.conditions) {
-				if (cond.label == -1) {
-					break;
-				}
 
+			for (const auto &cond : sc.flagConditions) {
 				if (!NancySceneState.getEventFlag(cond.label, cond.flag)) {
 					isSatisfied = false;
 					break;
@@ -390,49 +428,21 @@ void PlayPrimaryVideoChan0::addConditionalResponses() {
 			}
 
 			if (isSatisfied) {
-				Common::File file;
-				char snd[9];
-
-				file.open("game.exe");
-				file.seek(nancy1ResponseBaseFileOffset + res.fileOffset);
-				file.read(snd, 8);
-				snd[8] = '\0';
-
-				_responses.push_back(ResponseStruct());
-				ResponseStruct &newResponse = _responses.back();
-				newResponse.soundName = snd;
-				newResponse.text = file.readString();
-				newResponse.sceneChange.sceneID = res.sceneID;
-				newResponse.sceneChange.doNotStartSound = true;
-
-				file.close();
+				sceneChangeID = i;
+				break;
 			}
 		}
 	}
-}
 
-void PlayPrimaryVideoChan0::addGoodbye() {
-	for (const auto &res : nancy1Goodbyes) {
-		if (res.characterID == _goodbyeResponseCharacterID) {
-			Common::File file;
-			char snd[9];
+	const GoodbyeSceneChange &sceneChange = res.sceneChanges[sceneChangeID];
+	
+	// The reply from the character is picked randomly
+	newResponse.sceneChange.sceneID = sceneChange.sceneIDs[g_nancy->_randomSource->getRandomNumber(sceneChange.sceneIDs.size() - 1)];
 
-			file.open("game.exe");
-			file.seek(nancy1ResponseBaseFileOffset + res.fileOffset);
-			file.read(snd, 8);
-			snd[8] = '\0';
+	// Set an event flag if applicable
+	NancySceneState.setEventFlag(sceneChange.flagToSet);
 
-			_responses.push_back(ResponseStruct());
-			ResponseStruct &newResponse = _responses.back();
-			newResponse.soundName = snd;
-			newResponse.text = file.readString();
-			// response is picked randomly
-			newResponse.sceneChange.sceneID = res.sceneIDs[g_nancy->_randomSource->getRandomNumber(3)];
-			newResponse.sceneChange.doNotStartSound = true;
-
-			file.close();
-		}
-	}
+	newResponse.sceneChange.doNotStartSound = true;
 }
 
 } // End of namespace Action
diff --git a/engines/nancy/action/primaryvideo.h b/engines/nancy/action/primaryvideo.h
index 03aca322a0f..99602ab015d 100644
--- a/engines/nancy/action/primaryvideo.h
+++ b/engines/nancy/action/primaryvideo.h
@@ -81,7 +81,7 @@ public:
 	void handleInput(NancyInput &input) override;
 
 	// Functions for handling the built-in dialogue responses found in the executable
-	void addConditionalResponses();
+	void addConditionalDialogue();
 	void addGoodbye();
 
 	Common::String _videoName;
diff --git a/engines/nancy/action/recordtypes.cpp b/engines/nancy/action/recordtypes.cpp
index 5379bebdca8..99e69469921 100644
--- a/engines/nancy/action/recordtypes.cpp
+++ b/engines/nancy/action/recordtypes.cpp
@@ -27,7 +27,6 @@
 #include "engines/nancy/util.h"
 
 #include "engines/nancy/action/recordtypes.h"
-#include "engines/nancy/action/responses.cpp"
 
 #include "engines/nancy/state/scene.h"
 
@@ -672,14 +671,11 @@ void HintSystem::readData(Common::SeekableReadStream &stream) {
 void HintSystem::execute() {
 	switch (_state) {
 	case kBegin:
-		if (NancySceneState.getHintsRemaining() > 0) {
-			selectHint();
-		} else {
-			getHint(0, NancySceneState.getDifficulty());
-		}
+		selectHint();
+		_genericSound.name = selectedHint->soundIDs[NancySceneState.getDifficulty()];
 
 		NancySceneState.getTextbox().clear();
-		NancySceneState.getTextbox().addTextLine(_text);
+		NancySceneState.getTextbox().addTextLine(g_nancy->getStaticData().hintTexts[selectedHint->textID + NancySceneState.getDifficulty()]);
 
 		g_nancy->_sound->loadSound(_genericSound);
 		g_nancy->_sound->playSound(_genericSound);
@@ -695,10 +691,10 @@ void HintSystem::execute() {
 
 		// fall through
 	case kActionTrigger:
-		NancySceneState.useHint(_hintID, _hintWeight);
+		NancySceneState.useHint(_characterID, _hintID);
 		NancySceneState.getTextbox().clear();
 
-		NancySceneState.changeScene(_sceneChange);
+		NancySceneState.changeScene(selectedHint->sceneChange);
 
 		_isDone = true;
 		break;
@@ -706,10 +702,13 @@ void HintSystem::execute() {
 }
 
 void HintSystem::selectHint() {
-	for (const auto &hint : nancy1Hints) {
-		if (hint.characterID != _characterID) {
-			continue;
-		}
+	if (NancySceneState.getHintsRemaining() == 0) {
+		selectedHint = &g_nancy->getStaticData().hints[_characterID][0];
+	}
+
+	// Start from 1 since the first hint is always the "I give up" option
+	for (uint i = 1; i < g_nancy->getStaticData().hints[_characterID].size(); ++i) {
+		const auto &hint = g_nancy->getStaticData().hints[_characterID][i];
 
 		bool satisfied = true;
 
@@ -724,7 +723,7 @@ void HintSystem::selectHint() {
 			}
 		}
 
-		for (const auto &inv : hint.inventoryCondition) {
+		for (const auto &inv : hint.inventoryConditions) {
 			if (inv.label == -1) {
 				break;
 			}
@@ -736,44 +735,11 @@ void HintSystem::selectHint() {
 		}
 
 		if (satisfied) {
-			getHint(hint.hintID, NancySceneState.getDifficulty());
+			selectedHint = &hint;
 			break;
 		}
 	}
 }
 
-void HintSystem::getHint(uint hint, uint difficulty) {
-	uint fileOffset = 0;
-	if (_characterID < 3) {
-		fileOffset = nancy1HintOffsets[_characterID];
-	}
-
-	fileOffset += 0x288 * hint;
-
-	Common::File file;
-	file.open("game.exe");
-	file.seek(fileOffset);
-
-	_hintID = file.readSint16LE();
-	_hintWeight = file.readSint16LE();
-
-	file.seek(difficulty * 10, SEEK_CUR);
-
-	readFilename(file, _genericSound.name);
-
-	file.seek(-(difficulty * 10) - 10, SEEK_CUR);
-	file.seek(30 + difficulty * 200, SEEK_CUR);
-
-	char textBuf[200];
-	file.read(textBuf, 200);
-	textBuf[199] = '\0';
-	_text = textBuf;
-
-	file.seek(-(difficulty * 200) - 200, SEEK_CUR);
-	file.seek(600, SEEK_CUR);
-
-	_sceneChange.readData(file);
-}
-
 } // End of namespace Action
 } // End of namespace Nancy
diff --git a/engines/nancy/action/recordtypes.h b/engines/nancy/action/recordtypes.h
index 0e0cf611e53..6eeef3c0694 100644
--- a/engines/nancy/action/recordtypes.h
+++ b/engines/nancy/action/recordtypes.h
@@ -508,13 +508,10 @@ public:
 	byte _characterID; // 0x00
 	SoundDescription _genericSound; // 0x01
 
-	Common::String _text;
-	SceneChangeDescription _sceneChange;
-	uint16 _hintID;
-	int16 _hintWeight;
+	const Hint *selectedHint;
+	int16 _hintID;
 
 	void selectHint();
-	void getHint(uint hint, uint difficulty);
 
 protected:
 	Common::String getRecordTypeName() const override { return "HintSystem"; }
diff --git a/engines/nancy/action/responses.cpp b/engines/nancy/action/responses.cpp
deleted file mode 100644
index 5be91e8d6d1..00000000000
--- a/engines/nancy/action/responses.cpp
+++ /dev/null
@@ -1,956 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "engines/nancy/commontypes.h"
-
-namespace Nancy {
-namespace Action {
-
-// For whatever reason the games don't use the conditional dialogue code
-// inside primary video, and instead have a bunch of functions that manually
-// check hardcoded event flag IDs and extract strings embedded inside the exe.
-// These tables contain the extracted data and offsets for the string data, but if
-// there happen to be many versions of the same game it might be a better idea to just
-// directly copy the dialogue strings in here.
-
-struct ConditionalResponseDesc {
-	byte characterID; // 0: Daryl, 1: Connie, 2: Hal, 3: Hulk
-	uint fileOffset;
-	uint16 sceneID;
-	EventFlagDescription conditions[7];
-};
-
-struct GoodbyeDesc {
-	byte characterID;
-	uint fileOffset;
-	uint16 sceneIDs[4];
-};
-
-struct HintDesc {
-	byte characterID; // 0: Ned, 1: Bess, 2: George
-	byte hintID;
-	EventFlagDescription flagConditions[4];
-	EventFlagDescription inventoryCondition[2];
-};
-
-static const uint nancy1ResponseBaseFileOffset = 0xB1FE0; // TODO there could be more than one version of the exe
-static const uint nancy1HintOffsets[] = { 0xABB88, 0xAD760, 0xAF338 }; // Ned, Bess, George
-
-#define EMPTY_DESC { -1, kFalse }
-
-static const GoodbyeDesc nancy1Goodbyes[] = {
-	// Daryl
-	{
-		0,
-		0x11B0,
-		{ 0xC94, 0xC95, 0xC96, 0xC97}
-	},
-
-	// Connie
-	{
-		1,
-		0x11D8,
-		{ 0xFC, 0x9D8, 0x9D9, 0x9DB }
-	},
-
-	// Hal
-	{
-		2,
-		0x11FC,
-		{ 0x1C3, 0x1C4, 0x1C5, 0x1C6}
-	},
-
-	// Hulk
-	{
-		3,
-		0x1228,
-		{ 0xCE2, 0xCE0, 0xCE2, 0xCE0 } // only two responses
-	}
-};
-
-static const ConditionalResponseDesc nancy1ConditionalResponses[] = {
-	// Daryl
-	{
-		0,
-		0x840,
-		0x7C,
-		{
-			{ 0x1D, kTrue },
-			{ 0x39, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		0x804,
-		0x7F,
-		{
-			{ 0x13, kTrue },
-			{ 0x37, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		0x7BC,
-		0x81,
-		{
-			{ 0xB, kTrue },
-			{ 0x38, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		0x750,
-		0x83,
-		{
-			{ 0, kTrue },
-			{ 1, kFalse },
-			{ 0x6B, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		0x6F4,
-		0x84,
-		{
-			{ 0x64, kTrue },
-			{ 0x1E, kFalse },
-			{ 0x14, kFalse },
-			{ 0xC, kFalse },
-			{ 0x6C, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		0x5EC,
-		0x86,
-		{
-			{ 0x6D, kFalse },
-			{ 0x6, kTrue },
-			{ 0x8, kTrue },
-			{ 0x5E, kTrue },
-			{ 0x17, kTrue },
-			{ 0x24, kTrue },
-			{ 0x9, kTrue }
-		}
-	},
-
-	{
-		0,
-		0x554,
-		0x8B,
-		{
-			{ 0x6E, kFalse },
-			{ 0x24, kTrue },
-			{ 0x9, kTrue },
-			{ 0x5E, kFalse },
-			{ 0x8, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		0x4F0,
-		0x8D,
-		{
-			{ 0x6F, kFalse },
-			{ 0x5E, kTrue },
-			{ 0x24, kTrue },
-			{ 0x9, kTrue },
-			{ 0x8, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		0x458,
-		0x8F,
-		{
-			{ 0x70, kFalse },
-			{ 0x24, kTrue },
-			{ 0x9, kTrue },
-			{ 0x6, kTrue },
-			{ 0x8, kTrue },
-			{ 0x5E, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		0x3BC,
-		0x90,
-		{
-			{ 0x71, kFalse },
-			{ 0x5E, kTrue },
-			{ 0x24, kFalse },
-			{ 0x8, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		0x320,
-		0x91,
-		{
-			{ 0x72, kFalse },
-			{ 0x5E, kTrue },
-			{ 0x8, kTrue },
-			{ 0x6, kTrue },
-			{ 0x24, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		0x2AC,
-		0x92,
-		{
-			{ 0x73, kFalse },
-			{ 0x8, kTrue },
-			{ 0x6, kTrue },
-			{ 0x5E, kFalse },
-			{ 0x24, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		0x1F0,
-		0x96,
-		{
-			{ 0x74, kFalse },
-			{ 0x1D, kTrue },
-			{ 0x13, kTrue },
-			{ 0xB, kTrue },
-			{ 0x5E, kFalse },
-			{ 0x24, kFalse },
-			{ 0x8, kFalse }
-		}
-	},
-
-	{
-		0,
-		0x190,
-		0x97,
-		{
-			{ 0x27, kFalse },
-			{ 0x5, kTrue },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		0xF0,
-		0x9C,
-		{
-			{ 0x28, kTrue },
-			{ 0x75, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		0x94,
-		0x93,
-		{
-			{ 0xC, kFalse },
-			{ 0x6, kTrue },
-			{ 0x76, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		0x58,
-		0x94,
-		{
-			{ 0x14, kFalse },
-			{ 0x4, kTrue },
-			{ 0x77, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		0,
-		0x95,
-		{
-			{ 0x1E, kFalse },
-			{ 0x63, kTrue },
-			{ 0x78, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	// Connie
-	{
-		1,
-		0xBE4,
-		0xE9,
-		{
-			{ 0x1D, kTrue },
-			{ 0x18, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		1,
-		0xB8C,
-		0xEA,
-		{
-			{ 0x1F, kTrue },
-			{ 0x19, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		1,
-		0xB54,
-		0xEB,
-		{
-			{ 0xB, kTrue },
-			{ 0x1A, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		1,
-		0xB14,
-		0xEC,
-		{
-			{ 0x26, kTrue },
-			{ 0x1C, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		1,
-		0xABC,
-		0xED,
-		{
-			{ 0, kTrue },
-			{ 1, kFalse },
-			{ 0x79, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		1,
-		0xA00,
-		0xEE,
-		{
-			{ 2, kTrue },
-			{ 3, kTrue },
-			{ 0x17, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		1,
-		0x6F4,
-		0xEF,
-		{
-			{ 0x64, kTrue },
-			{ 0x16, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		1,
-		0x968,
-		0xF0,
-		{
-			{ 0x5, kTrue },
-			{ 0x14, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		1,
-		0x8C8,
-		0xF5,
-		{
-			{ 0x28, kTrue },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		1,
-		0x884,
-		0xE7,
-		{
-			{ 0xD, kTrue },
-			{ 0x5E, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	// Hal
-	{
-		2,
-		0xED0,
-		0x1B3,
-		{
-			{ 0x1D, kTrue },
-			{ 0x11, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		2,
-		0x804,
-		0x1B5,
-		{
-			{ 0x13, kTrue },
-			{ 0xE, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		2,
-		0xE74,
-		0x1B6,
-		{
-			{ 0x1B, kTrue },
-			{ 0xF, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		2,
-		0xE2C,
-		0x1B7,
-		{
-			{ 0x26, kTrue },
-			{ 0x10, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		2,
-		0xDD4,
-		0x1B9,
-		{
-			{ 0, kTrue },
-			{ 1, kFalse },
-			{ 0x68, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		2,
-		0xD48,
-		0x1BA,
-		{
-			{ 0, kTrue },
-			{ 1, kFalse },
-			{ 0x20, kTrue },
-			{ 0x69, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		2,
-		0x6F4,
-		0x1BB,
-		{
-			{ 0x6A, kFalse },
-			{ 0x64, kTrue },
-			{ 0x5, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		2,
-		0xCC8,
-		0x1BC,
-		{
-			{ 0x8, kTrue },
-			{ 0x6, kTrue },
-			{ 0xC, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		2,
-		0xC2C,
-		0x1BE,
-		{
-			{ 0x28, kTrue },
-			EMPTY_DESC
-		}
-	},
-
-	// Hulk
-	{
-		3,
-		0x1164,
-		0x14D,
-		{
-			{ 0x13, kTrue },
-			{ 0x3A, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		3,
-		0xB54,
-		0x150,
-		{
-			{ 0xB, kTrue },
-			{ 0x25, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		3,
-		0x10D8,
-		0x153,
-		{
-			{ 0x12, kTrue },
-			{ 0x21, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-
-		3,
-		0xE2C,
-		0x154,
-		{
-			{ 0x26, kTrue },
-			{ 0x22, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		3,
-		0x108C,
-		0x155,
-		{
-			{ 0, kTrue },
-			{ 1, kFalse },
-			{ 0x66, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		3,
-		0x6F4,
-		0x156,
-		{
-			{ 0x67, kFalse },
-			{ 0x64, kTrue },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		3,
-		0x1028,
-		0x157,
-		{
-			{ 0x63, kTrue },
-			{ 0x24, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		3,
-		0xFB0,
-		0x158,
-		{
-			{ 0x5, kTrue },
-			{ 0x1E, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		3,
-		0xF10,
-		0x159,
-		{
-			{ 0x28, kTrue },
-			EMPTY_DESC
-		}
-	}
-};
-
-static const HintDesc nancy1Hints[] {
-	// Ned
-	{
-		0,
-		1,
-		{
-			{ 0, kFalse },
-			EMPTY_DESC
-		},
-		{
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		2,
-		{
-			{ 0, kTrue },
-			{ 1, kFalse },
-			EMPTY_DESC
-		},
-		{
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		3,
-		{
-			{ 1, kFalse },
-			EMPTY_DESC
-		},
-		{
-			{ 3, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		4,
-		{
-			{ 0x55, kFalse },
-			EMPTY_DESC
-		},
-		{
-			{ 3, kTrue },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		5,
-		{
-			{ 0x55, kTrue },
-			{ 0x56, kFalse },
-			EMPTY_DESC
-		},
-		{
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		6,
-		{
-			{ 0x57, kFalse },
-			{ 0x56, kTrue },
-			EMPTY_DESC
-		},
-		{
-			EMPTY_DESC
-		}
-	},
-
-	{
-		0,
-		8,
-		{
-			{ 0xA, kTrue },
-			{ 0x3B, kTrue },
-			EMPTY_DESC
-		},
-		{
-			{ 7, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	// Bess
-	{
-		1,
-		1,
-		{
-			{ 0x57, kFalse },
-			EMPTY_DESC
-		},
-		{
-			EMPTY_DESC
-		}
-	},
-
-	{
-		1,
-		2,
-		{
-			{ 0x57, kTrue },
-			{ 0x3C, kFalse },
-			EMPTY_DESC
-		},
-		{
-			EMPTY_DESC
-		}
-	},
-
-	{
-		1,
-		3,
-		{
-			{ 0x5A, kFalse },
-			{ 0x3C, kTrue },
-			{ 0x56, kFalse },
-			EMPTY_DESC
-		},
-		{
-			EMPTY_DESC
-		}
-	},
-
-	{
-		1,
-		4,
-		{
-			{ 0x5A, kTrue },
-			{ 0x56, kFalse },
-			EMPTY_DESC
-		},
-		{
-			EMPTY_DESC
-		}
-	},
-
-	{
-		1,
-		6,
-		{
-			{ 0x5A, kFalse },
-			{ 0x3C, kTrue },
-			{ 0x56, kTrue },
-			EMPTY_DESC
-		},
-		{
-			EMPTY_DESC
-		}
-	},
-
-	{
-		1,
-		7,
-		{
-			{ 0x59, kTrue },
-			{ 0xA, kFalse },
-			EMPTY_DESC
-		},
-		{
-			{ 0, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		1,
-		8,
-		{
-			{ 0xA, kTrue },
-			{ 0x3B, kTrue },
-			EMPTY_DESC
-		},
-		{
-			{ 0, kTrue },
-			{ 7, kFalse }
-		}
-	},
-
-	{
-		1,
-		9,
-		{
-			{ 0x59, kFalse },
-			{ 0xA, kTrue },
-			{ 0x3B, kTrue },
-			EMPTY_DESC
-		},
-		{
-			{ 7, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	// George
-	{
-		2,
-		0xA,
-		{
-			{ 0x4A, kTrue },
-			EMPTY_DESC
-		},
-		{
-			EMPTY_DESC
-		}
-	},
-
-	{
-		2,
-		1,
-		{
-			{ 0x5B, kFalse },
-			EMPTY_DESC
-		},
-		{
-			EMPTY_DESC
-		}
-	},
-
-	{
-		2,
-		2,
-		{
-			{ 0x5B, kTrue },
-			EMPTY_DESC
-		},
-		{
-			{ 9, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		2,
-		3,
-		{
-			{ 0x5B, kTrue },
-			{ 0x5C, kFalse },
-			{ 0x5D, kFalse },
-			EMPTY_DESC
-		},
-		{
-			{ 9, kTrue },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		2,
-		4,
-		{
-			{ 0x5B, kTrue },
-			{ 0x5C, kTrue },
-			{ 0x5D, kFalse },
-			EMPTY_DESC
-		},
-		{
-			{ 9, kFalse },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		2,
-		5,
-		{
-			{ 0x5B, kTrue },
-			{ 0x5C, kTrue },
-			{ 0x5D, kTrue },
-			{ 0x3B, kFalse }
-		},
-		{
-			{ 9, kTrue },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		2,
-		6,
-		{
-			{ 0xA, kFalse },
-			{ 0x3B, kTrue },
-			EMPTY_DESC
-		},
-		{
-			{ 9, kTrue },
-			EMPTY_DESC
-		}
-	},
-
-	{
-		2,
-		7,
-		{
-			{ 0x3B, kTrue },
-			{ 0xA, kTrue },
-			EMPTY_DESC
-		},
-		{
-			{ 7, kFalse },
-			EMPTY_DESC
-		}
-	}
-};
-
-} // End of namespace Action
-} // End of namespace Nancy
diff --git a/engines/nancy/dialogueresponses.cpp b/engines/nancy/dialogueresponses.cpp
deleted file mode 100644
index 981f33de723..00000000000
--- a/engines/nancy/dialogueresponses.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "engines/nancy/nancy.h"
-#include "engines/nancy/dialogueresponses.h"
-
-#include "engines/nancy/state/scene.h"
-
-namespace Nancy {
-
-struct ResponseInFile {
-	uint address;
-	uint scene;
-};
-
-static const ResponseInFile nancy1ResponsesDaryl[] = {
-	{ 0xB2820, 0x7C },
-	{ 0xB27E4, 0x7F },
-	{ 0xB279C, 0x81 },
-	{ 0xB2730, 0x83 },
-	{ 0xB26D4, 0x84 },
-	{ 0xB25CC, 0x86 },
-	{ 0xB2534, 0x8B },
-	{ 0xB24D0, 0x8D },
-	{ 0xB2438, 0x8F },
-	{ 0xB239C, 0x90 },
-	{ 0xB2300, 0x91 },
-	{ 0xB228C, 0x92 },
-	{ 0xB21D0, 0x96 },
-	{ 0xB2170, 0x97 },
-	{ 0xB20D0, 0x9C },
-	{ 0xB2074, 0x93 },
-	{ 0xB2038, 0x94 },
-	{ 0xB1FE0, 0x95 }
-};
-
-static const ResponseInFile nancy1ResponsesConnie[] = {
-	{ 0xB2BC4, 0xE9 },
-	{ 0xB2B6C, 0xEA },
-	{ 0xB2B34, 0xEB },
-	{ 0xB2AF4, 0xEC },
-	{ 0xB2A9C, 0xED },
-	{ 0xB29E0, 0xEE },
-	{ 0xB26D4, 0xEF },
-	{ 0xB2948, 0xF0 },
-	{ 0xB28A8, 0xF5 },
-	{ 0xB2864, 0xE7 }
-};
-
-static const ResponseInFile nancy1ResponsesHal[] = {
-	{ 0xB2EB0, 0x1B3 },
-	{ 0xB27E4, 0x1B5 },
-	{ 0xB2E54, 0x1B6 },
-	{ 0xB2E0C, 0x1B7 },
-	{ 0xB2DB4, 0x1B9 },
-	{ 0xB2D28, 0x1BA },
-	{ 0xB26D4, 0x1BB },
-	{ 0xB2CA8, 0x1BC },
-	{ 0xB2C0C, 0x1BE }
-};
-
-static const ResponseInFile nancy1ResponsesHulk[] = {
-	{ 0xB3144, 0x14D },
-	{ 0xB2B34, 0x150 },
-	{ 0xB30B8, 0x153 },
-	{ 0xB2E0C, 0x154 },
-	{ 0xB306C, 0x155 },
-	{ 0xB26D4, 0x156 },
-	{ 0xB3008, 0x157 },
-	{ 0xB2F90, 0x158 },
-	{ 0xB2EF0, 0x159 }
-};
-
-#define ADD_RESPONSE(x) responses.push_back(PlayerResponse()); responses.back().sceneChange.sceneID = x.scene; responses.back().sceneChange.doNotStartSound = true; addresses.push_back(x.address);
-
-const Common::Array<PlayerResponse> getResponsesNancy1(uint characterID) {
-	Common::Array<PlayerResponse> responses;
-	Common::Array<uint> addresses;
-	State::Scene &scene = NancySceneState;
-
-	switch (characterID) {
-	case 0: // Daryl
-		if (	scene.getEventFlag(0x1D, kTrue) &&
-				scene.getEventFlag(0x39, kFalse)) {
-			ADD_RESPONSE(nancy1ResponsesDaryl[0])
-		}
-
-		if (	scene.getEventFlag(0x13, kTrue) &&
-				scene.getEventFlag(0x37, kFalse)) {
-			ADD_RESPONSE(nancy1ResponsesDaryl[1])
-		}
-
-		if (	scene.getEventFlag(0xB, kTrue) &&
-				scene.getEventFlag(0x38, kFalse)) {
-			ADD_RESPONSE(nancy1ResponsesDaryl[2])
-		}
-
-		if (	scene.getEventFlag(0, kTrue) &&
-				scene.getEventFlag(1, kFalse) &&
-				scene.getEventFlag(0x68, kFalse)) {
-			ADD_RESPONSE(nancy1ResponsesDaryl[3])
-		}
-
-		
-
-		break;
-	case 1: // Connie
-		
-		break;
-	case 2: // Hal
-		
-		break;
-	case 3: // Hulk
-		
-		break;
-	}
-
-	return responses;
-}
-
-const Common::Array<PlayerResponse> getResponses(const uint characterID) {
-	switch (g_nancy->getGameType()) {
-	case kGameTypeNancy1:
-		return getResponsesNancy1(characterID);
-	default:
-		return Common::Array<PlayerResponse>();	
-	}
-}
-
-} // End of namespace Nancy
diff --git a/engines/nancy/dialogueresponses.h b/engines/nancy/dialogueresponses.h
deleted file mode 100644
index 38c802d4e2c..00000000000
--- a/engines/nancy/dialogueresponses.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef NANCY_DIALOGUERESPONSES_H
-#define NANCY_DIALOGUERESPONSES_H
-
-#include "engines/nancy/commontypes.h"
-
-namespace Nancy {
-
-struct PlayerResponse {
-	Common::String text;
-	Common::String soundName;
-	SceneChangeDescription sceneChange;
-};
-
-const Common::Array<PlayerResponse> getResponses(const uint characterID);
-
-} // End of namespace Nancy
-
-#endif // NANCY_DIALOGUERESPONSES_H
diff --git a/engines/nancy/nancy.h b/engines/nancy/nancy.h
index 19099cf2994..d48a9a010ef 100644
--- a/engines/nancy/nancy.h
+++ b/engines/nancy/nancy.h
@@ -52,7 +52,7 @@ class Serializer;
  */
 namespace Nancy {
 
-static const int kSavegameVersion = 1;
+static const int kSavegameVersion = 2;
 
 struct NancyGameDescription;
 
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index 69a3c717638..152098df169 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -93,7 +93,8 @@ void Scene::SceneSummary::read(Common::SeekableReadStream &stream) {
 
 Scene::Scene() :
 		_state (kInit),
-		_lastHint(-1),
+		_lastHintCharacter(-1),
+		_lastHintID(-1),
 		_gameStateRequested(NancyState::kNone),
 		_frame(),
 		_viewport(),
@@ -277,10 +278,11 @@ void Scene::clearLogicConditions() {
 	}
 }
 
-void Scene::useHint(int hintID, int hintWeight) {
-	if (_lastHint != hintID) {
-		_hintsRemaining[_difficulty] += hintWeight;
-		_lastHint = hintID;
+void Scene::useHint(uint16 characterID, uint16 hintID) {
+	if (_lastHintID != hintID || _lastHintCharacter != characterID) {
+		_hintsRemaining[_difficulty] += g_nancy->getStaticData().hints[characterID][hintID].hintWeight;
+		_lastHintCharacter = characterID;
+		_lastHintID = hintID;
 	}
 }
 
@@ -385,7 +387,9 @@ void Scene::synchronize(Common::Serializer &ser) {
 
 	ser.syncAsUint16LE(_difficulty);
 	ser.syncArray<uint16>(_hintsRemaining.data(), _hintsRemaining.size(), Common::Serializer::Uint16LE);
-	ser.syncAsSint16LE(_lastHint);
+
+	ser.syncAsSint16LE(_lastHintCharacter);
+	ser.syncAsSint16LE(_lastHintID);
 
 	// Synchronize SliderPuzzle static data
 	ser.syncAsByte(_sliderPuzzleState.playerHasTriedPuzzle);
@@ -445,7 +449,7 @@ void Scene::init() {
 			_hintsRemaining.push_back(chunk->readByte());
 		}
 
-		_lastHint = -1;
+		_lastHintCharacter = _lastHintID = -1;
 	}
 
 	_sliderPuzzleState.playerHasTriedPuzzle = false;
diff --git a/engines/nancy/state/scene.h b/engines/nancy/state/scene.h
index 76a07d96884..788a53c52af 100644
--- a/engines/nancy/state/scene.h
+++ b/engines/nancy/state/scene.h
@@ -146,7 +146,7 @@ public:
 	uint16 getDifficulty() const { return _difficulty; }
 
 	byte getHintsRemaining() const { return _hintsRemaining[_difficulty]; }
-	void useHint(int hintID, int hintWeight);
+	void useHint(uint16 characterID, uint16 hintID);
 
 	void requestStateChange(NancyState::NancyState state) { _gameStateRequested = state; }
 	void resetStateToInit() { _state = kInit; }
@@ -252,7 +252,8 @@ private:
 	SliderPuzzleState _sliderPuzzleState;
 	uint16 _difficulty;
 	Common::Array<uint16> _hintsRemaining;
-	int16 _lastHint;
+	int16 _lastHintCharacter;
+	int16 _lastHintID;
 	NancyState::NancyState _gameStateRequested;
 
 	Common::Rect _mapHotspot;


Commit: 900e4666c02f094549848676d89518744dab0bb1
    https://github.com/scummvm/scummvm/commit/900e4666c02f094549848676d89518744dab0bb1
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-03T17:35:58+02:00

Commit Message:
NANCY: Upgrade debug console

Added several new console commands and made changes to
existing ones in preparation of the removal of the Cheat dialogs.

Changed paths:
    engines/nancy/action/actionmanager.cpp
    engines/nancy/action/actionmanager.h
    engines/nancy/action/actionrecord.h
    engines/nancy/console.cpp
    engines/nancy/console.h
    engines/nancy/graphics.cpp
    engines/nancy/graphics.h


diff --git a/engines/nancy/action/actionmanager.cpp b/engines/nancy/action/actionmanager.cpp
index 68da5f248fe..200dab318dd 100644
--- a/engines/nancy/action/actionmanager.cpp
+++ b/engines/nancy/action/actionmanager.cpp
@@ -146,89 +146,6 @@ bool ActionManager::addNewActionRecord(Common::SeekableReadStream &inputData) {
 
 	_records.push_back(newRecord);
 
-	debugC(1, kDebugActionRecord, "Loaded action record %i, type %s, typeID %i, description \"%s\", execType == %s",
-			_records.size() - 1,
-			newRecord->getRecordTypeName().c_str(),
-			newRecord->_type,
-			newRecord->_description.c_str(),
-			newRecord->_execType == ActionRecord::kRepeating ? "kRepeating" : "kOneShot");
-	for (uint i = 0; i < newRecord->_dependencies.size(); ++i) {
-		debugCN(1, kDebugActionRecord, "\tDependency %i: type ", i);
-		DependencyRecord &dep = newRecord->_dependencies[i];
-		switch (dep.type) {
-		case DependencyType::kNone :
-			debugCN(1, kDebugActionRecord, "kNone");
-			break;
-		case DependencyType::kInventory :
-			debugCN(1, kDebugActionRecord, "kInventory, item ID %i %s",
-						dep.label,
-						dep.condition == kTrue ? "is in possession" : "is not in possession");
-			break;
-		case DependencyType::kEventFlag :
-			debugCN(1, kDebugActionRecord, "kEventFlag, flag ID %i == %s",
-						dep.label,
-						dep.condition == kTrue ? "true" : "false");
-			break;
-		case DependencyType::kLogicCondition :
-			debugCN(1, kDebugActionRecord, "kLogicCondition, logic condition ID %i == %s",
-						dep.label,
-						dep.condition == kTrue ? "true" : "false");
-			break;
-		case DependencyType::kTotalTime :
-			debugCN(1, kDebugActionRecord, "kTotalTime, %i hours, %i minutes, %i seconds, %i milliseconds",
-						dep.hours,
-						dep.minutes,
-						dep.seconds,
-						dep.milliseconds);
-			break;
-		case DependencyType::kSceneTime :
-			debugCN(1, kDebugActionRecord, "kSceneTime, %i hours, %i minutes, %i seconds, %i milliseconds",
-						dep.hours,
-						dep.minutes,
-						dep.seconds,
-						dep.milliseconds);
-			break;
-		case DependencyType::kPlayerTime :
-			debugCN(1, kDebugActionRecord, "kPlayerTime, %i days, %i hours, %i minutes, %i seconds",
-						dep.hours,
-						dep.minutes,
-						dep.seconds,
-						dep.milliseconds);
-			break;
-		case DependencyType::kSceneCount :
-			debugCN(1, kDebugActionRecord, "kSceneCount, scene ID %i, hit count %s %i",
-						dep.hours,
-						dep.milliseconds == 1 ? ">" : dep.milliseconds == 2 ? "<" : "==",
-						dep.seconds);
-			break;
-		case DependencyType::kResetOnNewDay :
-			debugCN(1, kDebugActionRecord, "kResetOnNewDay");
-			break;
-		case DependencyType::kUseItem :
-			debugCN(1, kDebugActionRecord, "kUseItem, item ID %i %s",
-						dep.label,
-						dep.condition == kTrue ? "is held" : "is not held");
-			break;
-		case DependencyType::kTimeOfDay :
-			debugCN(1, kDebugActionRecord, "kTimeOfDay, %s",
-						dep.label == 0 ? "day" : dep.label == 1 ? "night" : "dusk/dawn");
-			break;
-		case DependencyType::kTimerNotDone :
-			debugCN(1, kDebugActionRecord, "kTimerNotDone");
-			break;
-		case DependencyType::kTimerDone :
-			debugCN(1, kDebugActionRecord, "kTimerDone");
-			break;
-		case DependencyType::kDifficultyLevel :
-			debugCN(1, kDebugActionRecord, "kDifficultyLevel, level %i", dep.condition);
-			break;
-		default:
-			debugCN(1, kDebugActionRecord, "unknown");
-			break;
-		}
-		debugC(1, kDebugActionRecord, ", orFlag == %s", dep.orFlag == true ? "true" : "false");
-	}
-
 	return true;
 }
 
diff --git a/engines/nancy/action/actionmanager.h b/engines/nancy/action/actionmanager.h
index 115806b88d7..f099602f241 100644
--- a/engines/nancy/action/actionmanager.h
+++ b/engines/nancy/action/actionmanager.h
@@ -32,6 +32,7 @@ class SeekableReadStream;
 namespace Nancy {
 
 class NancyEngine;
+class NancyConsole;
 struct NancyInput;
 
 namespace State {
@@ -45,6 +46,7 @@ class ActionRecord;
 // The class that handles ActionRecords and their execution
 class ActionManager {
 	friend class Nancy::State::Scene;
+	friend class Nancy::NancyConsole;
 
 public:
 	ActionManager() {}
diff --git a/engines/nancy/action/actionrecord.h b/engines/nancy/action/actionrecord.h
index 9b5006669be..9f693be5699 100644
--- a/engines/nancy/action/actionrecord.h
+++ b/engines/nancy/action/actionrecord.h
@@ -32,6 +32,7 @@ class SeekableReadStream;
 namespace Nancy {
 
 class NancyEngine;
+class NancyConsole;
 struct NancyInput;
 
 namespace Action {
@@ -78,6 +79,8 @@ struct DependencyRecord {
 // will have to also subclass RenderObject.
 class ActionRecord {
 	friend class ActionManager;
+	friend class Nancy::NancyConsole;
+
 public:
 	enum ExecutionState { kBegin, kRun, kActionTrigger };
 	enum ExecutionType { kOneShot = 1, kRepeating = 2 };
diff --git a/engines/nancy/console.cpp b/engines/nancy/console.cpp
index 4a5ed89c051..60e2d00df14 100644
--- a/engines/nancy/console.cpp
+++ b/engines/nancy/console.cpp
@@ -34,6 +34,8 @@
 
 #include "engines/nancy/state/scene.h"
 
+#include "engines/nancy/action/actionrecord.h"
+
 namespace Nancy {
 
 NancyConsole::NancyConsole() : GUI::Debugger() {
@@ -49,10 +51,18 @@ NancyConsole::NancyConsole() : GUI::Debugger() {
 	registerCmd("play_audio", WRAP_METHOD(NancyConsole, Cmd_playAudio));
 	registerCmd("load_scene", WRAP_METHOD(NancyConsole, Cmd_loadScene));
 	registerCmd("scene_id", WRAP_METHOD(NancyConsole, Cmd_sceneID));
+	registerCmd("list_actionrecords", WRAP_METHOD(NancyConsole, Cmd_listAcionRecords));
+	registerCmd("get_eventflags", WRAP_METHOD(NancyConsole, Cmd_getEventFlags));
+	registerCmd("set_eventflags", WRAP_METHOD(NancyConsole, Cmd_setEventFlags));
+	registerCmd("get_inventory", WRAP_METHOD(NancyConsole, Cmd_getInventory));
+	registerCmd("set_inventory", WRAP_METHOD(NancyConsole, Cmd_setInventory));
+	registerCmd("get_player_time", WRAP_METHOD(NancyConsole, Cmd_getPlayerTime));
+	registerCmd("set_player_time", WRAP_METHOD(NancyConsole, Cmd_setPlayerTime));
+	registerCmd("get_difficulty", WRAP_METHOD(NancyConsole, Cmd_getDifficulty));
+	registerCmd("set_difficulty", WRAP_METHOD(NancyConsole, Cmd_setDifficulty));
 }
 
-NancyConsole::~NancyConsole() {
-}
+NancyConsole::~NancyConsole() {}
 
 void NancyConsole::postEnter() {
 	GUI::Debugger::postEnter();
@@ -60,6 +70,12 @@ void NancyConsole::postEnter() {
 		Video::VideoDecoder *dec = new AVFDecoder;
 
 		if (dec->loadFile(_videoFile)) {
+			Graphics::ManagedSurface surf;
+			
+			if (_paletteFile.size()) {
+				GraphicsManager::loadSurfacePalette(surf, _paletteFile);
+			}
+
 			dec->start();
 			Common::EventManager *ev = g_system->getEventManager();
 			while (!g_nancy->shouldQuit() && !dec->endOfVideo()) {
@@ -73,7 +89,8 @@ void NancyConsole::postEnter() {
 				if (dec->needsUpdate()) {
 					const Graphics::Surface *frame = dec->decodeNextFrame();
 					if (frame) {
-						g_nancy->_graphicsManager->debugDrawToScreen(*frame);
+						GraphicsManager::copyToManaged(*frame, surf, _paletteFile.size());
+						g_nancy->_graphicsManager->debugDrawToScreen(surf);
 					}
 				}
 
@@ -86,14 +103,18 @@ void NancyConsole::postEnter() {
 		}
 
 		_videoFile.clear();
+		_paletteFile.clear();
 		delete dec;
 	}
 
 	if (!_imageFile.empty()) {
-		Graphics::Surface surf;
+		Graphics::ManagedSurface surf;
 		if (g_nancy->_resource->loadImage(_imageFile, surf)) {
+			if (_paletteFile.size()) {
+				GraphicsManager::loadSurfacePalette(surf, _paletteFile);
+			}
+
 			g_nancy->_graphicsManager->debugDrawToScreen(surf);
-			surf.free();
 
 			Common::EventManager *ev = g_system->getEventManager();
 			while (!g_nancy->shouldQuit()) {
@@ -115,6 +136,7 @@ void NancyConsole::postEnter() {
 		}
 
 		_imageFile.clear();
+		_paletteFile.clear();
 	}
 
 	// After calling the console, action end events get sent to it and the input manager
@@ -125,7 +147,7 @@ void NancyConsole::postEnter() {
 bool NancyConsole::Cmd_cifHexDump(int argc, const char **argv) {
 	if (argc < 2 || argc > 3) {
 		debugPrintf("Dumps the specified resource to standard output\n");
-		debugPrintf("Usage: %s name [cal]\n", argv[0]);
+		debugPrintf("Usage: %s <name> [cal]\n", argv[0]);
 		return true;
 	}
 
@@ -144,7 +166,7 @@ bool NancyConsole::Cmd_cifHexDump(int argc, const char **argv) {
 bool NancyConsole::Cmd_cifExport(int argc, const char **argv) {
 	if (argc < 2 || argc > 3) {
 		debugPrintf("Exports the specified resource to .cif file\n");
-		debugPrintf("Usage: %s name [cal]\n", argv[0]);
+		debugPrintf("Usage: %s <name> [cal]\n", argv[0]);
 		return true;
 	}
 
@@ -158,7 +180,7 @@ bool NancyConsole::Cmd_cifList(int argc, const char **argv) {
 	if (argc < 2 || argc > 3) {
 		debugPrintf("List resources of a certain type\n");
 		debugPrintf("Types - 0: all, 2: image, 3: script\n");
-		debugPrintf("Usage: %s type [cal]\n", argv[0]);
+		debugPrintf("Usage: %s <type> [cal]\n", argv[0]);
 		return true;
 	}
 
@@ -178,7 +200,7 @@ bool NancyConsole::Cmd_cifList(int argc, const char **argv) {
 bool NancyConsole::Cmd_cifInfo(int argc, const char **argv) {
 	if (argc < 2 || argc > 3) {
 		debugPrintf("Prints information about a resource\n");
-		debugPrintf("Usage: %s name [cal]\n", argv[0]);
+		debugPrintf("Usage: %s <name> [cal]\n", argv[0]);
 		return true;
 	}
 
@@ -189,7 +211,7 @@ bool NancyConsole::Cmd_cifInfo(int argc, const char **argv) {
 bool NancyConsole::Cmd_chunkHexDump(int argc, const char **argv) {
 	if (argc < 3 || argc > 4) {
 		debugPrintf("Hexdumps an IFF chunk\n");
-		debugPrintf("Usage: %s iffname chunkname [index]\n", argv[0]);
+		debugPrintf("Usage: %s <iffname> <chunkname> [index]\n", argv[0]);
 		return true;
 	}
 
@@ -224,7 +246,7 @@ bool NancyConsole::Cmd_chunkHexDump(int argc, const char **argv) {
 bool NancyConsole::Cmd_chunkList(int argc, const char **argv) {
 	if (argc != 2) {
 		debugPrintf("List chunks inside an IFF\n");
-		debugPrintf("Usage: %s iffname\n", argv[0]);
+		debugPrintf("Usage: %s <iffname>\n", argv[0]);
 		return true;
 	}
 
@@ -248,14 +270,51 @@ bool NancyConsole::Cmd_chunkList(int argc, const char **argv) {
 }
 
 bool NancyConsole::Cmd_showImage(int argc, const char **argv) {
-	if (argc != 2) {
-		debugPrintf("Draws an image on the screen\n");
-		debugPrintf("Usage: %s name [cal]\n", argv[0]);
-		return true;
+	if (g_nancy->getGameType() == kGameTypeVampire) {
+		if (argc != 3) {
+			debugPrintf("Draws an image on the screen\n");
+			debugPrintf("Usage: %s <name> <paletteFile>\n", argv[0]);
+			return true;
+		}
+
+		_imageFile = argv[1];
+		_paletteFile = argv[2];
+		return cmdExit(0, nullptr);
+	} else {
+		if (argc != 2) {
+			debugPrintf("Draws an image on the screen\n");
+			debugPrintf("Usage: %s <name>\n", argv[0]);
+			return true;
+		}
+
+		_imageFile = argv[1];
+		return cmdExit(0, nullptr);
 	}
+}
 
-	_imageFile = argv[1];
-	return cmdExit(0, nullptr);
+bool NancyConsole::Cmd_playVideo(int argc, const char **argv) {
+	if (g_nancy->getGameType() == kGameTypeVampire) {
+		if (argc != 3) {
+			debugPrintf("Plays a video\n");
+			debugPrintf("Usage: %s <name> <paletteFile>\n", argv[0]);
+			return true;
+		}
+
+		_videoFile = argv[1];
+		_videoFile += ".avf";
+		_paletteFile = argv[2];
+		return cmdExit(0, nullptr);
+	} else {
+		if (argc != 2) {
+			debugPrintf("Plays a video\n");
+			debugPrintf("Usage: %s <name>\n", argv[0]);
+			return true;
+		}
+
+		_videoFile = argv[1];
+		_videoFile += ".avf";
+		return cmdExit(0, nullptr);
+	}
 }
 
 bool NancyConsole::Cmd_loadCal(int argc, const char **argv) {
@@ -270,18 +329,6 @@ bool NancyConsole::Cmd_loadCal(int argc, const char **argv) {
 	return true;
 }
 
-bool NancyConsole::Cmd_playVideo(int argc, const char **argv) {
-	if (argc != 2) {
-		debugPrintf("Plays a video\n");
-		debugPrintf("Usage: %s <name>\n", argv[0]);
-		return true;
-	}
-
-	_videoFile = argv[1];
-	_videoFile += ".avf";
-	return cmdExit(0, nullptr);
-}
-
 bool NancyConsole::Cmd_playAudio(int argc, const char **argv) {
 	if (argc != 2) {
 		debugPrintf("Plays an audio file\n");
@@ -310,7 +357,7 @@ bool NancyConsole::Cmd_playAudio(int argc, const char **argv) {
 bool NancyConsole::Cmd_loadScene(int argc, const char **argv) {
 	if (argc != 2) {
 		debugPrintf("Loads a scene\n");
-		debugPrintf("Usage: %s sceneID\n", argv[0]);
+		debugPrintf("Usage: %s <sceneID>\n", argv[0]);
 		return true;
 	}
 
@@ -341,4 +388,340 @@ bool NancyConsole::Cmd_sceneID(int argc, const char **argv) {
 	return true;
 }
 
+bool NancyConsole::Cmd_listAcionRecords(int argc, const char **argv) {
+	using namespace Nancy::Action;
+
+	if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+		debugPrintf("Not in the kScene state\n");
+		return true;
+	}
+
+	Common::Array<ActionRecord *> &records = NancySceneState.getActionManager()._records;
+
+	debugPrintf("Scene %u has %u action records:\n\n", NancySceneState.getSceneInfo().sceneID, records.size());
+
+	for (ActionRecord *rec : records) {
+		debugPrintf("\n%s\n\ttype: %i, %s\n\texecType: %s",
+			rec->_description.c_str(),
+			rec->_type,
+			rec->getRecordTypeName().c_str(),
+			rec->_execType == ActionRecord::kRepeating ? "kRepeating" : "kOneShot");
+
+		if (rec->_dependencies.size()) {
+			debugPrintf("\n\tDependencies:");
+
+			for (DependencyRecord &dep : rec->_dependencies) {
+				debugPrintf("\n\t\t");
+				switch (dep.type) {
+				case DependencyType::kNone :
+					debugPrintf("kNone");
+					break;
+				case DependencyType::kInventory :
+					debugPrintf("kInventory, item %u, %s, %s",
+						dep.label,
+						g_nancy->getStaticData().itemNames[dep.label].c_str(),
+						dep.condition == kTrue ? "kTrue" : "kFalse");
+					break;
+				case DependencyType::kEventFlag :
+					debugPrintf("kEventFlag, flag %u, %s, %s",
+						dep.label,
+						g_nancy->getStaticData().eventFlagNames[dep.label].c_str(),
+						dep.condition == kTrue ? "kTrue" : "kFalse");
+					break;
+				case DependencyType::kLogicCondition :
+					debugPrintf("kLogicCondition, flag %u, %s",
+						dep.label,
+						dep.condition == kTrue ? "kTrue" : "kFalse");
+					break;
+				case DependencyType::kTotalTime :
+					debugPrintf("kTotalTime, %i hours, %i minutes, %i seconds, %i milliseconds",
+						dep.hours,
+						dep.minutes,
+						dep.seconds,
+						dep.milliseconds);
+					break;
+				case DependencyType::kSceneTime :
+					debugPrintf("kSceneTime, %i hours, %i minutes, %i seconds, %i milliseconds",
+						dep.hours,
+						dep.minutes,
+						dep.seconds,
+						dep.milliseconds);
+					break;
+				case DependencyType::kPlayerTime :
+					debugPrintf("kPlayerTime, %i hours, %i minutes, %i seconds, %i milliseconds",
+						dep.hours,
+						dep.minutes,
+						dep.seconds,
+						dep.milliseconds);
+					break;
+				case DependencyType::kSceneCount :
+					debugPrintf("kSceneCount, scene ID %i, hit count %s %i",
+						dep.hours,
+						dep.milliseconds == 1 ? ">" : dep.milliseconds == 2 ? "<" : "==",
+						dep.seconds);
+					break;
+				case DependencyType::kResetOnNewDay :
+					debugPrintf("kResetOnNewDay");
+					break;
+				case DependencyType::kUseItem :
+					debugPrintf("kUseItem, item %u, %s, %s",
+						dep.label,
+						g_nancy->getStaticData().itemNames[dep.label].c_str(),
+						dep.condition == kTrue ? "kTrue" : "kFalse");
+					break;
+				case DependencyType::kTimeOfDay :
+					debugPrintf("kTimeOfDay, %s",
+						dep.label == 0 ? "day" : dep.label == 1 ? "night" : "dusk/dawn");
+					break;
+				case DependencyType::kTimerNotDone :
+					debugPrintf("kTimerNotDone");
+					break;
+				case DependencyType::kTimerDone :
+					debugPrintf("kTimerDone");
+					break;
+				case DependencyType::kDifficultyLevel :
+					debugPrintf("kDifficultyLevel, level %i", dep.condition);
+					break;
+				default:
+					debugPrintf("unknown type %u", (uint)dep.type);
+					break;
+				}
+
+				debugPrintf("\n\t\t\torFlag == %s", dep.orFlag == true ? "true" : "false");
+			}
+		}
+
+		debugPrintf("\n\n");
+	}
+
+	return true;
+}
+
+bool NancyConsole::Cmd_getEventFlags(int argc, const char **argv) {
+	if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+		debugPrintf("Not in the kScene state\n");
+		return true;
+	}
+
+	uint numEventFlags = g_nancy->getStaticData().numEventFlags;
+
+	debugPrintf("Total number of event flags: %u\n", numEventFlags);
+
+	if (argc == 1) {
+		for (uint i = 0; i < numEventFlags; ++i) {
+			debugPrintf("\nFlag %u, %s, %s",
+				i,
+				g_nancy->getStaticData().eventFlagNames[i].c_str(),
+				NancySceneState.getEventFlag(i) == true ? "kTrue" : "kFalse");
+		}
+	} else {
+		for (int i = 1; i < argc; ++i) {
+			int flagID = atoi(argv[i]);
+			if (flagID < 0 || flagID >= (int)numEventFlags) {
+				debugPrintf("\nInvalid flag %s", argv[i]);
+				continue;
+			}
+			debugPrintf("\nFlag %u, %s, %s",
+				flagID,
+				g_nancy->getStaticData().eventFlagNames[flagID].c_str(),
+				NancySceneState.getEventFlag(flagID) == true ? "kTrue" : "kFalse");
+			 
+		}
+	}
+
+	debugPrintf("\n");
+
+	return true;
+}
+
+bool NancyConsole::Cmd_setEventFlags(int argc, const char **argv) {
+	if (argc < 2 || argc % 2 == 0) {
+		debugPrintf("Sets one or more event flags to the provided value.\n");
+		debugPrintf("Usage: %s <flagID> <true/false>...\n", argv[0]);
+		return true;
+	}
+
+	for (int i = 1; i < argc; i += 2) {
+		int flagID = atoi(argv[i]);
+		if (flagID < 0 || flagID >= (int)g_nancy->getStaticData().numEventFlags) {
+			debugPrintf("Invalid flag %s\n", argv[i]);
+			continue;
+		}
+		
+		if (Common::String(argv[i + 1]).compareTo("true") == 0) {
+			NancySceneState.setEventFlag(flagID, Nancy::kTrue);
+			debugPrintf("Set flag %i, %s, to kTrue\n",
+				flagID,
+				g_nancy->getStaticData().eventFlagNames[flagID].c_str());
+		} else if (Common::String(argv[i + 1]).compareTo("false") == 0) {
+			NancySceneState.setEventFlag(flagID, Nancy::kFalse);
+			debugPrintf("Set flag %i, %s, to kFalse\n",
+				flagID,
+				g_nancy->getStaticData().eventFlagNames[flagID].c_str());
+		} else {
+			debugPrintf("Invalid value %s\n", argv[i + 1]);
+			continue;
+		}
+	}
+
+	return cmdExit(0, nullptr);
+}
+
+bool NancyConsole::Cmd_getInventory(int argc, const char **argv) {
+	if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+		debugPrintf("Not in the kScene state\n");
+		return true;
+	}
+
+	uint numItems = g_nancy->getStaticData().numItems;
+
+	debugPrintf("Total number of inventory items: %u\n", numItems);
+
+	if (argc == 1) {
+		for (uint i = 0; i < numItems; ++i) {
+			debugPrintf("\nItem %u, %s, %s",
+				i,
+				g_nancy->getStaticData().itemNames[i].c_str(),
+				NancySceneState.hasItem(i) == NancyFlag::kTrue ? "kTrue" : "kFalse");
+		}
+	} else {
+		for (int i = 1; i < argc; ++i) {
+			int flagID = atoi(argv[i]);
+			if (flagID < 0 || flagID >= (int)numItems) {
+				debugPrintf("\nInvalid flag %s", argv[i]);
+				continue;
+			}
+			debugPrintf("\nItem %u, %s, %s",
+				flagID,
+				g_nancy->getStaticData().itemNames[flagID].c_str(),
+				NancySceneState.hasItem(i) == NancyFlag::kTrue ? "kTrue" : "kFalse");
+			 
+		}
+	}
+
+	debugPrintf("\n");
+
+	return true;
+}
+
+bool NancyConsole::Cmd_setInventory(int argc, const char **argv) {
+	if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+		debugPrintf("Not in the kScene state\n");
+		return true;
+	}
+
+	if (argc < 2 || argc % 2 == 0) {
+		debugPrintf("Sets one or more inventory items to the provided value.\n");
+		debugPrintf("Usage: %s <itemID> <true/false>...\n", argv[0]);
+		return true;
+	}
+
+	for (int i = 1; i < argc; i += 2) {
+		int itemID = atoi(argv[i]);
+		if (itemID < 0 || itemID >= (int)g_nancy->getStaticData().numItems) {
+			debugPrintf("Invalid item %s\n", argv[i]);
+			continue;
+		}
+		
+		if (Common::String(argv[i + 1]).compareTo("true") == 0) {
+			NancySceneState.addItemToInventory(itemID);
+			debugPrintf("Added item %i, %s, to inventory\n",
+				itemID,
+				g_nancy->getStaticData().itemNames[itemID].c_str());
+		} else if (Common::String(argv[i + 1]).compareTo("false") == 0) {
+			NancySceneState.removeItemFromInventory(itemID, false);
+			debugPrintf("Removed item %i, %s, from inventory\n",
+				itemID,
+				g_nancy->getStaticData().itemNames[itemID].c_str());
+		} else {
+			debugPrintf("Invalid value %s\n", argv[i + 1]);
+			continue;
+		}
+	}
+
+	return cmdExit(0, nullptr);
+}
+
+bool NancyConsole::Cmd_getPlayerTime(int argc, const char **argv) {
+	if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+		debugPrintf("Not in the kScene state\n");
+		return true;
+	}
+
+	Time time = NancySceneState._timers.playerTime;
+	debugPrintf("Player time: %u days, %u hours, %u minutes; %u\n",
+		time.getDays(),
+		time.getHours(),
+		time.getMinutes(),
+		(uint32)time);
+	return true;
+}
+
+bool NancyConsole::Cmd_setPlayerTime(int argc, const char **argv) {
+	if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+		debugPrintf("Not in the kScene state\n");
+		return true;
+	}
+
+	if (argc != 2 && argc != 4) {
+		debugPrintf("Sets the in-game time.\n");
+		debugPrintf("Usage: %s <milliseconds> or %s <days> <hours> <minutes>\n", argv[0], argv[0]);
+		return true;
+	}
+
+	Time &time = NancySceneState._timers.playerTime;
+
+	if (argc == 2) {
+		time = atoi(argv[1]);
+	} else {
+		time = 	atoi(argv[1]) * 86400000 +	// days
+				atoi(argv[2]) * 3600000 +	// hours
+				atoi(argv[3]) * 60000;		// minutes
+	}
+
+	debugPrintf("Set player time to: %u days, %u hours, %u minutes; %u\n",
+		time.getDays(),
+		time.getHours(),
+		time.getMinutes(),
+		(uint32)time);
+
+	return cmdExit(0, nullptr);
+}
+
+bool NancyConsole::Cmd_getDifficulty(int argc, const char **argv) {
+	if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+		debugPrintf("Not in the kScene state\n");
+		return true;
+	}
+
+	debugPrintf("Difficulty: %u\n", NancySceneState.getDifficulty());
+
+	return true;
+}
+
+bool NancyConsole::Cmd_setDifficulty(int argc, const char **argv) {
+	if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+		debugPrintf("Not in the kScene state\n");
+		return true;
+	}
+
+	if (argc != 2) {
+		debugPrintf("Set the game difficulty.\n");
+		debugPrintf("Usage: %s <difficulty>\n", argv[0]);
+		return true;
+	}
+
+	int diff = atoi(argv[1]);
+
+	if (diff < 0 || diff > 2) {
+		debugPrintf("Invalid difficulty %s\n", argv[1]);
+		return true;
+	}
+
+	NancySceneState.setDifficulty(diff);
+	debugPrintf("Set difficulty to %i\n", diff);
+
+	return cmdExit(0, nullptr);
+}
+
 } // End of namespace Nancy
diff --git a/engines/nancy/console.h b/engines/nancy/console.h
index 051f413f524..c43e88d1ea3 100644
--- a/engines/nancy/console.h
+++ b/engines/nancy/console.h
@@ -48,9 +48,19 @@ private:
 	bool Cmd_playAudio(int argc, const char **argv);
 	bool Cmd_loadScene(int argc, const char **argv);
 	bool Cmd_sceneID(int argc, const char **argv);
+	bool Cmd_listAcionRecords(int argc, const char **argv);
+	bool Cmd_getEventFlags(int argc, const char **argv);
+	bool Cmd_setEventFlags(int argc, const char **argv);
+	bool Cmd_getInventory(int argc, const char **argv);
+	bool Cmd_setInventory(int argc, const char **argv);
+	bool Cmd_getPlayerTime(int argc, const char **argv);
+	bool Cmd_setPlayerTime(int argc, const char **argv);
+	bool Cmd_getDifficulty(int argc, const char **argv);
+	bool Cmd_setDifficulty(int argc, const char **argv);
 
 	Common::String _videoFile;
 	Common::String _imageFile;
+	Common::String _paletteFile;
 };
 
 } // End of namespace Nancy
diff --git a/engines/nancy/graphics.cpp b/engines/nancy/graphics.cpp
index dd79e7649ce..58c6fd1ab36 100644
--- a/engines/nancy/graphics.cpp
+++ b/engines/nancy/graphics.cpp
@@ -253,7 +253,7 @@ void GraphicsManager::copyToManaged(void *src, Graphics::ManagedSurface &dst, ui
 	copyToManaged(surf, dst, verticalFlip, doubleSize);
 }
 
-void GraphicsManager::debugDrawToScreen(const Graphics::Surface &surf) {
+void GraphicsManager::debugDrawToScreen(const Graphics::ManagedSurface &surf) {
 	_screen.blitFrom(surf, Common::Point());
 	_screen.update();
 }
diff --git a/engines/nancy/graphics.h b/engines/nancy/graphics.h
index 89ddfae0a86..6ac6a1e3ef5 100644
--- a/engines/nancy/graphics.h
+++ b/engines/nancy/graphics.h
@@ -58,7 +58,7 @@ public:
 	static void copyToManaged(void *src, Graphics::ManagedSurface &dst, uint srcW, uint srcH, const Graphics::PixelFormat &format, bool verticalFlip = false, bool doubleSize = false);
 
 	// Debug
-	void debugDrawToScreen(const Graphics::Surface &surf);
+	void debugDrawToScreen(const Graphics::ManagedSurface &surf);
 
 	Graphics::ManagedSurface _object0;
 


Commit: 8a378fb89b03229f11154685838de209681ffd2f
    https://github.com/scummvm/scummvm/commit/8a378fb89b03229f11154685838de209681ffd2f
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-03T17:35:58+02:00

Commit Message:
NANCY: Remove cheat dialogs

Removed the cheat and event flags dialogs, since they were always
a hacky solution and console commands are much easier to maintain.

Changed paths:
    engines/nancy/commontypes.h
    engines/nancy/dialogs.cpp
    engines/nancy/dialogs.h
    engines/nancy/input.cpp
    engines/nancy/input.h
    engines/nancy/nancy.cpp
    engines/nancy/nancy.h
    engines/nancy/state/scene.h


diff --git a/engines/nancy/commontypes.h b/engines/nancy/commontypes.h
index 8453307b625..486271f1e69 100644
--- a/engines/nancy/commontypes.h
+++ b/engines/nancy/commontypes.h
@@ -52,7 +52,7 @@ enum NancyState {
 	kHelp,
 	kScene,
 	// CD change
-	kCheat,
+	// Cheat,
 	kQuit,
 	// regain focus
 	kNone,
diff --git a/engines/nancy/dialogs.cpp b/engines/nancy/dialogs.cpp
index 5a4bdaf4fd8..e7ced7f3ab6 100644
--- a/engines/nancy/dialogs.cpp
+++ b/engines/nancy/dialogs.cpp
@@ -83,308 +83,4 @@ bool NancyOptionsWidget::isInGame() const {
 	return _domain.equals(ConfMan.getActiveDomainName());
 }
 
-// TODO rewrite this class so its layout is not hardcoded
-CheatDialog::CheatDialog() : GUI::Dialog(20, 20, 600, 440) {
-	_backgroundType = GUI::ThemeEngine::kDialogBackgroundSpecial;
-	Common::WinResources *res = Common::WinResources::createFromEXE("game.exe");
-	Common::Array<Common::WinResourceID> dialogIDs = res->getIDList(Common::kWinDialog);
-	State::SceneInfo scene = NancySceneState.getSceneInfo();
-	Time playerTime = NancySceneState._timers.playerTime;
-	Time timerTime = NancySceneState._timers.timerTime;
-	bool timerIsActive = NancySceneState._timers.timerIsActive;
-	if (!timerIsActive) {
-		timerTime = 0;
-	}
-
-	GUI::TabWidget *_tabs = new GUI::TabWidget(this, 0, 0, 600, 370);
-	new GUI::ButtonWidget(this, 420, 410, 60, 20, _("Cancel"), Common::U32String(), GUI::kCloseCmd);
-	new GUI::ButtonWidget(this, 520, 410, 60, 20, _("OK"), Common::U32String(), GUI::kOKCmd);
-
-	_tabs->addTab(_("General"), "Cheat.General");
-
-	new GUI::StaticTextWidget(_tabs, 30, 20, 150, 20, _("Scene Data"), Graphics::kTextAlignLeft);
-	_restartScene = new GUI::CheckboxWidget(_tabs, 35, 50, 150, 20, _("Restart the Scene"));
-	_scene = new GUI::EditTextWidget(_tabs, 35, 75, 45, 20, Common::U32String::format("%u", scene.sceneID), Common::U32String(), kInputSceneNr, kInputSceneNr);
-	new GUI::StaticTextWidget(_tabs, 85, 75, 150, 20, _("Scene Number"), Graphics::kTextAlignLeft);
-	_frame = new GUI::EditTextWidget(_tabs, 35, 100, 45, 20, Common::U32String::format("%u", scene.frameID), Common::U32String(), kInputFrameNr, kInputFrameNr);
-	new GUI::StaticTextWidget(_tabs, 85, 100, 150, 20, _("Frame Number"), Graphics::kTextAlignLeft);
-	_offset = new GUI::EditTextWidget(_tabs, 35, 125, 45, 20, Common::U32String::format("%u", scene.verticalOffset), Common::U32String(), kInputScroll, kInputScroll);
-
-	// I18N: The Y position (a.k.a vertical scroll) of the background
-	new GUI::StaticTextWidget(_tabs, 85, 125, 150, 20, _("Background Top (Y)"), Graphics::kTextAlignLeft);
-
-	new GUI::StaticTextWidget(_tabs, 30, 160, 150, 20, _("Hints Remaining"), Graphics::kTextAlignLeft);
-	new GUI::StaticTextWidget(_tabs, 35, 185, 45, 20, _("Easy"), Graphics::kTextAlignLeft);
-	_hintsRemainingEasy = new GUI::EditTextWidget(_tabs, 35, 205, 45, 20, Common::U32String::format("%u", NancySceneState._hintsRemaining[0]), Common::U32String(), kInputHintsEasy, kInputHintsEasy);
-	new GUI::StaticTextWidget(_tabs, 85, 185, 45, 20, _("Medium"), Graphics::kTextAlignLeft);
-	_hintsRemainingMedium = new GUI::EditTextWidget(_tabs, 85, 205, 45, 20, Common::U32String::format("%u", NancySceneState._hintsRemaining[1]), Common::U32String(), kInputHintsMedium, kInputHintsMedium);
-	new GUI::StaticTextWidget(_tabs, 135, 185, 45, 20, _("Hard"), Graphics::kTextAlignLeft);
-	_hintsRemainingHard = new GUI::EditTextWidget(_tabs, 135, 205, 45, 20, Common::U32String::format("%u", NancySceneState._hintsRemaining[2]), Common::U32String(), kInputHintsHard, kInputHintsHard);
-
-	new GUI::StaticTextWidget(_tabs, 250, 20, 150, 20, _("Player Data"), Graphics::kTextAlignLeft);
-	new GUI::StaticTextWidget(_tabs, 255, 50, 150, 20, _("Player Time:"), Graphics::kTextAlignLeft);
-	_playerTimeDays = new GUI::EditTextWidget(_tabs, 255, 75, 35, 20, Common::U32String::format("%u", playerTime.getDays()), Common::U32String(), kInputPlayerTime, kInputPlayerTime);
-	new GUI::StaticTextWidget(_tabs, 295, 75, 40, 20, _("Days"), Graphics::kTextAlignLeft);
-	_playerTimeHours = new GUI::EditTextWidget(_tabs, 335, 75, 35, 20, Common::U32String::format("%u", playerTime.getHours()), Common::U32String(), kInputPlayerTime, kInputPlayerTime);
-	new GUI::StaticTextWidget(_tabs, 375, 75, 40, 20, _("Hours"), Graphics::kTextAlignLeft);
-	_playerTimeMinutes = new GUI::EditTextWidget(_tabs, 415, 75, 35, 20, Common::U32String::format("%u", playerTime.getMinutes()), Common::U32String(), kInputPlayerTime, kInputPlayerTime);
-	new GUI::StaticTextWidget(_tabs, 455, 75, 50, 20, _("Minutes"), Graphics::kTextAlignLeft);
-	_difficulty = new GUI::EditTextWidget(_tabs, 255, 105, 35, 20, Common::U32String::format("%u", NancySceneState._difficulty), Common::U32String(), kInputDifficulty, kInputDifficulty);
-	new GUI::StaticTextWidget(_tabs, 295, 105, 150, 20, _("Player Difficulty Level"), Graphics::kTextAlignLeft);
-
-	new GUI::StaticTextWidget(_tabs, 250, 140, 150, 20, _("Software Timer"), Graphics::kTextAlignLeft);
-	_timerOn = new GUI::CheckboxWidget(_tabs, 255, 170, 150, 20, _("Timer On"));
-	_timerOn->setState(timerIsActive);
-	_timerHours = new GUI::EditTextWidget(_tabs, 255, 195, 35, 20, Common::U32String::format("%u", timerTime.getTotalHours()), Common::U32String(), kInputTimer, kInputTimer);
-	new GUI::StaticTextWidget(_tabs, 295, 195, 40, 20, _("Hours"), Graphics::kTextAlignLeft);
-	_timerMinutes = new GUI::EditTextWidget(_tabs, 335, 195, 35, 20, Common::U32String::format("%u", timerTime.getMinutes()), Common::U32String(), kInputTimer, kInputTimer);
-	new GUI::StaticTextWidget(_tabs, 375, 195, 50, 20, _("Minutes"), Graphics::kTextAlignLeft);
-	_timerSeconds = new GUI::EditTextWidget(_tabs, 425, 195, 35, 20, Common::U32String::format("%u", timerTime.getSeconds()), Common::U32String(), kInputTimer, kInputTimer);
-	new GUI::StaticTextWidget(_tabs, 465, 195, 50, 20, _("Seconds"), Graphics::kTextAlignLeft);
-
-	_tabs->addTab(_("Inventory"), "Cheat.Inventory");
-
-	for (uint i = 0; i < dialogIDs.size(); ++i) {
-		Common::SeekableReadStream *resStream = res->getResource(Common::kWinDialog, dialogIDs[i].getID());
-
-		Common::String idString;
-		resStream->skip(0x16);
-		while (true) {
-			char add = resStream->readByte();
-			if (add != 0) {
-				idString += add;
-				resStream->skip(1);
-			} else {
-				resStream->skip(1);
-				break;
-			}
-		}
-
-		if (!idString.hasPrefix("Inventory")) {
-			continue;
-		}
-
-		idString.trim();
-		uint numItems = 0;
-
-		while (resStream->pos() < resStream->size()) {
-			if (resStream->readUint16LE() == 0xFFFF && resStream->readSint16LE() == 0x80) {
-				// Found a resource, read its string id
-				Common::String itemLabel;
-
-				while (true) {
-					char add = resStream->readByte();
-					if (add != 0) {
-						itemLabel += add;
-						resStream->skip(1);
-					} else {
-						resStream->skip(1);
-						break;
-					}
-				}
-				GUI::CheckboxWidget *box = new GUI::CheckboxWidget(_tabs, 250 * (numItems / 10) + 20, (350 / 10) * (numItems % 10) + 15, 250, 250/10, Common::U32String(itemLabel));
-				box->setState(NancySceneState.hasItem(numItems) == kTrue);
-				_inventory.push_back(box);
-
-				++numItems;
-			}
-		}
-
-		break;
-	}
-
-	_tabs->setActiveTab(0);
-}
-
-void CheatDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
-	switch (cmd) {
-	case GUI::kOKCmd: {
-		if (_restartScene->getState()) {
-			uint sceneID = atoi(Common::String(_scene->getEditString()).c_str());
-			IFF iff(Common::String::format("S%u", sceneID));
-			if (iff.load()) {
-				NancySceneState.changeScene(
-					atoi(Common::String(_scene->getEditString()).c_str()),
-					atoi(Common::String(_frame->getEditString()).c_str()),
-					atoi(Common::String(_offset->getEditString()).c_str()),
-					true);
-			} else {
-				new GUI::StaticTextWidget(this, 20, 410, 150, 20, _("Invalid Scene ID!"), Graphics::kTextAlignLeft);
-				return;
-			}
-		}
-
-		if (_timerOn->getState()) {
-			NancySceneState._timers.timerIsActive = true;
-			Time &timer = NancySceneState._timers.timerTime;
-			timer = 0;
-			timer += 1000 * atoi(Common::String(_timerSeconds->getEditString()).c_str());
-			timer += 60000 * atoi(Common::String(_timerMinutes->getEditString()).c_str());
-			timer += 3600000 * atoi(Common::String(_timerHours->getEditString()).c_str());
-		} else {
-			NancySceneState.stopTimer();
-		}
-
-		Time &playerTime = NancySceneState._timers.timerTime;
-		playerTime = 0;
-		playerTime += 60000 * atoi(Common::String(_playerTimeMinutes->getEditString()).c_str());
-		playerTime += 3600000 * atoi(Common::String(_playerTimeHours->getEditString()).c_str());
-		playerTime += 86400000 * atoi(Common::String(_playerTimeMinutes->getEditString()).c_str());
-
-		NancySceneState._difficulty = atoi(Common::String(_difficulty->getEditString()).c_str());
-		NancySceneState._hintsRemaining[0] = atoi(Common::String(_hintsRemainingEasy->getEditString()).c_str());
-		NancySceneState._hintsRemaining[1] = atoi(Common::String(_hintsRemainingMedium->getEditString()).c_str());
-		NancySceneState._hintsRemaining[2] = atoi(Common::String(_hintsRemainingHard->getEditString()).c_str());
-
-		for (uint i = 0; i < _inventory.size(); ++i) {
-			if (NancySceneState.hasItem(i) == kTrue && !_inventory[i]->getState()) {
-				NancySceneState.removeItemFromInventory(i, false);
-			} else if (NancySceneState.hasItem(i) == kFalse && _inventory[i]->getState()) {
-				NancySceneState.addItemToInventory(i);
-			}
-		}
-		cmd = GUI::kCloseCmd;
-
-		break;
-	}
-	case kInputSceneNr:
-		sanitizeInput(_scene);
-		break;
-	case kInputFrameNr:
-		sanitizeInput(_frame);
-		break;
-	case kInputScroll:
-		sanitizeInput(_offset);
-		break;
-	case kInputDifficulty:
-		sanitizeInput(_scene, 2);
-		break;
-	case kInputHintsEasy:
-		sanitizeInput(_hintsRemainingEasy);
-		break;
-	case kInputHintsMedium:
-		sanitizeInput(_hintsRemainingMedium);
-		break;
-	case kInputHintsHard:
-		sanitizeInput(_hintsRemainingHard);
-		break;
-	case kInputPlayerTime:
-		sanitizeInput(_playerTimeMinutes, 59);
-		sanitizeInput(_playerTimeHours, 23);
-		sanitizeInput(_playerTimeDays);
-		break;
-	case kInputTimer:
-		sanitizeInput(_timerSeconds, 59);
-		sanitizeInput(_timerMinutes, 59);
-		sanitizeInput(_timerHours, 23);
-		break;
-	default:
-		break;
-	}
-
-	Dialog::handleCommand(sender, cmd, data);
-}
-
-void CheatDialog::sanitizeInput(GUI::EditTextWidget *textWidget, int maxValue) {
-	const Common::U32String &str = textWidget->getEditString();
-	for (uint i = 0; i < str.size(); ++i) {
-		if (!Common::isDigit(str[i])) {
-			textWidget->setEditString(str.substr(0, i));
-			break;
-		}
-	}
-
-	if (maxValue > -1) {
-		int number = atoi(Common::String(str).c_str());
-		if (number > maxValue) {
-			textWidget->setEditString(Common::U32String::format("%d", maxValue));
-		}
-	}
-
-	textWidget->setCaretPos(str.size());
-}
-
-EventFlagDialog::EventFlagDialog() : GUI::Dialog(20, 20, 600, 440) {
-	_backgroundType = GUI::ThemeEngine::kDialogBackgroundSpecial;
-	Common::WinResources *res = Common::WinResources::createFromEXE("game.exe");
-	Common::Array<Common::WinResourceID> dialogIDs = res->getIDList(Common::kWinDialog);
-
-	GUI::TabWidget *_tabs = new GUI::TabWidget(this, 0, 0, 600, 370);
-	new GUI::ButtonWidget(this, 520, 410, 60, 20, _("Close"), Common::U32String(), GUI::kCloseCmd);
-
-	for (uint i = 0; i < dialogIDs.size(); ++i) {
-		Common::SeekableReadStream *resStream = res->getResource(Common::kWinDialog, dialogIDs[i].getID());
-
-		Common::String idString;
-		resStream->skip(0x16);
-		while (true) {
-			char add = resStream->readByte();
-			if (add != 0) {
-				idString += add;
-				resStream->skip(1);
-			} else {
-				resStream->skip(1);
-				break;
-			}
-		}
-
-		if (!idString.hasPrefix("Event")) {
-			continue;
-		}
-
-		idString.trim();
-		_tabs->addTab(idString, Common::String("tab " + idString));
-		uint numFlags = 0;
-
-		while (resStream->pos() < resStream->size()) {
-			if (resStream->readUint16LE() == 0xFFFF && resStream->readSint16LE() == 0x80) {
-				// Found a resource, read its string id
-				Common::String flagLabel;
-
-				while (true) {
-					char add = resStream->readByte();
-					if (add != 0) {
-						flagLabel += add;
-						resStream->skip(1);
-					} else {
-						resStream->skip(1);
-						break;
-					}
-				}
-
-				// String begins with number so we assume it's an event flag radio button
-				if (Common::isDigit(flagLabel.firstChar())) {
-					Common::String num;
-					uint j = 0;
-					while (true) {
-						if (Common::isDigit(flagLabel[j])) {
-							num += flagLabel[j];
-						} else {
-							break;
-						}
-						++j;
-					}
-
-					uint32 command = atoi(num.c_str()) << 16 | 'ev';
-
-					GUI::CheckboxWidget *box = new GUI::CheckboxWidget(_tabs, 300 * (numFlags / 12) + 20, (350 / 12) * (numFlags % 12) + 15, 300, 350/12, Common::U32String(flagLabel), Common::U32String(), command);
-					box->setState(NancySceneState.getEventFlag(command >> 16));
-
-					++numFlags;
-				}
-			}
-		}
-	}
-
-	_tabs->setActiveTab(0);
-}
-
-void EventFlagDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
-	Dialog::handleCommand(sender, cmd, data);
-	if (cmd & 'ev') {
-		cmd >>= 16;
-		NancySceneState.setEventFlag(cmd, data == 0 ? kFalse : kTrue);
-	}
-}
-
 } // End of namespace Nancy
diff --git a/engines/nancy/dialogs.h b/engines/nancy/dialogs.h
index f2f881a76ad..e989ced50a9 100644
--- a/engines/nancy/dialogs.h
+++ b/engines/nancy/dialogs.h
@@ -45,56 +45,6 @@ private:
 	GUI::CheckboxWidget *_secondChanceCheckbox;
 };
 
-class CheatDialog : public GUI::Dialog {
-public:
-	CheatDialog();
-
-protected:
-	enum Commands {
-		kInputSceneNr = 'isnr',
-		kInputFrameNr = 'ifnr',
-		kInputScroll = 'iscr',
-		kInputHintsEasy = 'ihea',
-		kInputHintsMedium = 'ihme',
-		kInputHintsHard = 'ihha',
-		kInputPlayerTime = 'plti',
-		kInputDifficulty = 'diff',
-		kInputTimer = 'time'
-	};
-
-	void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) override;
-	static void sanitizeInput(GUI::EditTextWidget *textWidget, int maxValue = -1);
-
-	GUI::CheckboxWidget *_restartScene;
-	GUI::EditTextWidget *_scene;
-	GUI::EditTextWidget *_frame;
-	GUI::EditTextWidget *_offset;
-
-	GUI::EditTextWidget *_hintsRemainingEasy;
-	GUI::EditTextWidget *_hintsRemainingMedium;
-	GUI::EditTextWidget *_hintsRemainingHard;
-
-	GUI::EditTextWidget *_playerTimeDays;
-	GUI::EditTextWidget *_playerTimeHours;
-	GUI::EditTextWidget *_playerTimeMinutes;
-	GUI::EditTextWidget *_difficulty;
-
-	GUI::CheckboxWidget *_timerOn;
-	GUI::EditTextWidget *_timerHours;
-	GUI::EditTextWidget *_timerMinutes;
-	GUI::EditTextWidget *_timerSeconds;
-
-	Common::Array<GUI::CheckboxWidget *> _inventory;
-};
-
-class EventFlagDialog : public GUI::Dialog {
-public:
-	EventFlagDialog();
-
-protected:
-	void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) override;
-};
-
 } // End of namespace Nancy
 
 #endif // NANCY_DIALOGS_H
diff --git a/engines/nancy/input.cpp b/engines/nancy/input.cpp
index eded7c57fa9..092f3d32ff9 100644
--- a/engines/nancy/input.cpp
+++ b/engines/nancy/input.cpp
@@ -75,12 +75,6 @@ void InputManager::processEvents() {
 			case kNancyActionMoveFast:
 				_inputs |= NancyInput::kMoveFastModifier;
 				break;
-			case kNancyActionRequestCheatMenu:
-				g_nancy->callCheatMenu(false);
-				break;
-			case kNancyActionRequestEventMenu:
-				g_nancy->callCheatMenu(true);
-				break;
 			default:
 				break;
 			}
@@ -247,16 +241,6 @@ void InputManager::initKeymaps(Common::KeymapArray &keymaps) {
 	act->addDefaultInputMapping("C+S+TAB+m");
 	debugKeymap->addAction(act);
 
-	act = new Action("CHEAT", _("Open general cheat menu"));
-	act->setCustomEngineActionEvent(kNancyActionRequestCheatMenu);
-	act->addDefaultInputMapping("C+S+TAB+c");
-	debugKeymap->addAction(act);
-
-	act = new Action("EVENT", _("Open event flags cheat menu"));
-	act->setCustomEngineActionEvent(kNancyActionRequestEventMenu);
-	act->addDefaultInputMapping("C+S+TAB+v");
-	debugKeymap->addAction(act);
-
 	keymaps.push_back(mainKeymap);
 	keymaps.push_back(debugKeymap);
 }
diff --git a/engines/nancy/input.h b/engines/nancy/input.h
index 4af93d192ad..9f73126ef5c 100644
--- a/engines/nancy/input.h
+++ b/engines/nancy/input.h
@@ -81,9 +81,7 @@ enum NancyAction {
 	kNancyActionRequestSaveLoad,
 	kNancyActionRequestSetupMenu,
 	kNancyActionRequestCredits,
-	kNancyActionRequestMap,
-	kNancyActionRequestCheatMenu,
-	kNancyActionRequestEventMenu
+	kNancyActionRequestMap
 };
 
 public:
diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index 1bcf5874c21..c0e98b77de0 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -70,7 +70,6 @@ NancyEngine::NancyEngine(OSystem *syst, const NancyGameDescription *gd) :
 	_resource = nullptr;
 	_startTimeHours = 0;
 	_overrideMovementTimeDeltas = false;
-	_cheatTypeIsEventFlag = false;
 	_horizontalEdgesSize = 0;
 	_verticalEdgesSize = 0;
 }
@@ -194,18 +193,6 @@ void NancyEngine::setState(NancyState::NancyState state, NancyState::NancyState
 
 		return;
 	}
-	case NancyState::kCheat:
-		if (_cheatTypeIsEventFlag) {
-			EventFlagDialog *dialog = new EventFlagDialog();
-			runDialog(*dialog);
-			delete dialog;
-		} else {
-			CheatDialog *dialog = new CheatDialog();
-			runDialog(*dialog);
-			delete dialog;
-		}
-		_input->forceCleanInput();
-		return;
 	default:
 		break;
 	}
@@ -249,11 +236,6 @@ void NancyEngine::setMouseEnabled(bool enabled) {
 	_cursorManager->showCursor(enabled); _input->setMouseInputEnabled(enabled);
 }
 
-void NancyEngine::callCheatMenu(bool eventFlags) {
-	_cheatTypeIsEventFlag = eventFlags;
-	setState(NancyState::kCheat);
-}
-
 Common::Error NancyEngine::run() {
 	setDebugger(new NancyConsole());
 
diff --git a/engines/nancy/nancy.h b/engines/nancy/nancy.h
index d48a9a010ef..98c60321c1f 100644
--- a/engines/nancy/nancy.h
+++ b/engines/nancy/nancy.h
@@ -62,7 +62,6 @@ class InputManager;
 class SoundManager;
 class GraphicsManager;
 class CursorManager;
-class CheatDialog;
 class NancyConsole;
 
 namespace State {
@@ -103,8 +102,6 @@ public:
 
 	void setMouseEnabled(bool enabled);
 
-	void callCheatMenu(bool eventFlags);
-
 	// Managers
 	ResourceManager *_resource;
 	GraphicsManager *_graphicsManager;
@@ -155,8 +152,6 @@ private:
 
 	bool isCompressed();
 
-	bool _cheatTypeIsEventFlag;
-
 	StaticData _staticData;
 	const byte _datFileMajorVersion;
 	const byte _datFileMinorVersion;
diff --git a/engines/nancy/state/scene.h b/engines/nancy/state/scene.h
index 788a53c52af..eda65d3fa58 100644
--- a/engines/nancy/state/scene.h
+++ b/engines/nancy/state/scene.h
@@ -44,7 +44,6 @@ namespace Nancy {
 
 class NancyEngine;
 class NancyConsole;
-class CheatDialog;
 struct SceneChangeDescription;
 
 namespace Action {
@@ -74,7 +73,6 @@ class Scene : public State, public Common::Singleton<Scene> {
 	friend class Nancy::Action::SliderPuzzle;
 	friend class Nancy::NancyConsole;
 	friend class Nancy::NancyEngine;
-	friend class Nancy::CheatDialog;
 
 public:
 	enum GameStateChange : byte {




More information about the Scummvm-git-logs mailing list