aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLe Philousophe2019-05-20 21:00:16 +0200
committerEugene Sandulenko2019-06-01 22:43:48 +0200
commite791122c594cbd3e9c262fce58d6d7a4247093ab (patch)
treef722853f8ea559cc868b674494213447fb69d131
parentf7c7707d15898a0f54880ea27f2abc8432300501 (diff)
downloadscummvm-rg350-e791122c594cbd3e9c262fce58d6d7a4247093ab.tar.gz
scummvm-rg350-e791122c594cbd3e9c262fce58d6d7a4247093ab.tar.bz2
scummvm-rg350-e791122c594cbd3e9c262fce58d6d7a4247093ab.zip
CRYOMNI3D: Implement (final) level 7
-rw-r--r--engines/cryomni3d/versailles/data.cpp15
-rw-r--r--engines/cryomni3d/versailles/engine.cpp10
-rw-r--r--engines/cryomni3d/versailles/engine.h35
-rw-r--r--engines/cryomni3d/versailles/logic.cpp483
4 files changed, 521 insertions, 22 deletions
diff --git a/engines/cryomni3d/versailles/data.cpp b/engines/cryomni3d/versailles/data.cpp
index d2e733f103..a11b1ab428 100644
--- a/engines/cryomni3d/versailles/data.cpp
+++ b/engines/cryomni3d/versailles/data.cpp
@@ -680,27 +680,26 @@ void CryOmni3DEngine_Versailles::initPlacesStates() {
SET_PLACE_STATE(43, nullptr, nullptr, "VS33");
SET_PLACE_STATE(44, nullptr, nullptr, "VS33");
} else if (_currentLevel == 7) {
- // TODO: implement functions
SET_PLACE_STATE(1, nullptr, nullptr, nullptr);
- SET_PLACE_STATE(2, nullptr, nullptr, nullptr);
+ SET_PLACE_STATE(2, nullptr, FILTER_EVENT(7, 2), nullptr);
SET_PLACE_STATE(3, nullptr, nullptr, nullptr);
SET_PLACE_STATE(4, nullptr, nullptr, nullptr);
SET_PLACE_STATE(5, nullptr, nullptr, nullptr);
SET_PLACE_STATE(6, nullptr, nullptr, nullptr);
- SET_PLACE_STATE(7, nullptr, nullptr, nullptr);
+ SET_PLACE_STATE(7, nullptr, nullptr, nullptr); // Filter is a leftover
SET_PLACE_STATE(8, nullptr, nullptr, nullptr);
- SET_PLACE_STATE(9, nullptr, nullptr, nullptr);
- SET_PLACE_STATE(10, nullptr, nullptr, "VS33");
- SET_PLACE_STATE(11, nullptr, nullptr, "VS33");
+ SET_PLACE_STATE(9, nullptr, FILTER_EVENT(7, 9), nullptr);
+ SET_PLACE_STATE(10, nullptr, FILTER_EVENT(7, 10_11_13), "VS31");
+ SET_PLACE_STATE(11, nullptr, FILTER_EVENT(7, 10_11_13), "VS31");
SET_PLACE_STATE(12, nullptr, nullptr, nullptr);
- SET_PLACE_STATE(13, nullptr, nullptr, "VS33");
+ SET_PLACE_STATE(13, nullptr, FILTER_EVENT(7, 10_11_13), "VS31");
SET_PLACE_STATE(14, nullptr, nullptr, nullptr);
SET_PLACE_STATE(15, nullptr, nullptr, nullptr);
SET_PLACE_STATE(16, nullptr, nullptr, nullptr);
SET_PLACE_STATE(17, nullptr, nullptr, nullptr);
SET_PLACE_STATE(18, nullptr, nullptr, nullptr);
SET_PLACE_STATE(19, nullptr, nullptr, nullptr);
- SET_PLACE_STATE(20, nullptr, nullptr, nullptr);
+ SET_PLACE_STATE(20, nullptr, FILTER_EVENT(7, 20), nullptr);
SET_PLACE_STATE(21, nullptr, nullptr, nullptr);
SET_PLACE_STATE(22, nullptr, nullptr, nullptr);
SET_PLACE_STATE(23, nullptr, nullptr, nullptr);
diff --git a/engines/cryomni3d/versailles/engine.cpp b/engines/cryomni3d/versailles/engine.cpp
index fd88f8efc1..e3e91b8d9d 100644
--- a/engines/cryomni3d/versailles/engine.cpp
+++ b/engines/cryomni3d/versailles/engine.cpp
@@ -614,10 +614,8 @@ void CryOmni3DEngine_Versailles::changeLevel(int level) {
}
initCountdown();
_inventory.clear();
- } else if (_currentLevel <= 6) {
- // TODO: remove this when we implemented all levels
- } else {
- error("New level %d is not implemented (yet)", level);
+ } else if (_currentLevel > 7) {
+ error("New level %d is not implemented", level);
}
_gameVariables[GameVariables::kCurrentTime] = 1;
@@ -693,7 +691,8 @@ void CryOmni3DEngine_Versailles::initNewLevel(int level) {
error("Invalid level %d", level);
}
- // TODO: countdown
+ // Level 7 starts countdown
+ _countingDown = (level == 7);
initPlacesStates();
initWhoSpeaksWhere();
setupLevelWarps(level);
@@ -1469,6 +1468,7 @@ void CryOmni3DEngine_Versailles::displayObject(const Common::String &imgName,
void CryOmni3DEngine_Versailles::executeSeeAction(unsigned int actionId) {
if (_currentLevel == 7 && _currentPlaceId != 20) {
+ // Don't display fixed images unless it's the bomb
// Not enough time for paintings
displayMessageBoxWarp(14);
return;
diff --git a/engines/cryomni3d/versailles/engine.h b/engines/cryomni3d/versailles/engine.h
index 743bdf5c27..0b60dceb75 100644
--- a/engines/cryomni3d/versailles/engine.h
+++ b/engines/cryomni3d/versailles/engine.h
@@ -139,8 +139,8 @@ struct GameVariables {
kLoweredChandelier, // OK
kCombedOrangeTree, // OK
kMaineTalked, // OK
- kUsedBougieAllumee,
- kStateBombe,
+ kUsedLitCandle, // OK
+ kBombState, // OK
kInkSpilled, // OK
kCollectedPaperOnTable, // OK // 30
kSafeUnlocked, // OK
@@ -505,23 +505,38 @@ private:
IMG_CB(44161d);
IMG_CB(44161e);
IMG_CB(44161f);
- IMG_CB(45130);
- IMG_CB(45270);
- IMG_CB(45270b);
- IMG_CB(45270c);
- IMG_CB(45270d);
- IMG_CB(45280);
static const unsigned int kEpigraphMaxLetters = 32;
static const char *kEpigraphContent;
static const char *kEpigraphPassword;
bool handleEpigraph(ZonFixedImage *fimg);
void drawEpigraphLetters(Graphics::ManagedSurface &surface,
const Graphics::Surface(&bmpLetters)[26], const Common::String &letters);
+ IMG_CB(45130);
+ IMG_CB(45270);
+ IMG_CB(45270b);
+ IMG_CB(45270c);
+ IMG_CB(45270d);
+ IMG_CB(45280);
IMG_CB(88001);
IMG_CB(88001b);
IMG_CB(88001c);
IMG_CB(88002);
+ IMG_CB(88003);
+ IMG_CB(88003b);
+ IMG_CB(88003c);
+ IMG_CB(88003d);
+ IMG_CB(88003e);
+ IMG_CB(88003f);
+ static const unsigned int kBombPasswordSmallLength = 40;
+ static const unsigned int kBombPasswordMaxLength = 60;
+ static const unsigned short kBombLettersPos[2][kBombPasswordMaxLength][2];
+ static const char *kBombPassword;
+ bool handleBomb(ZonFixedImage *fimg);
+ void drawBombLetters(Graphics::ManagedSurface &surface, const Graphics::Surface(&bmpLetters)[26],
+ const unsigned int kBombPasswordLength,
+ const unsigned char (&bombPossibilites)[kBombPasswordMaxLength][5],
+ const unsigned char (&bombCurrentLetters)[kBombPasswordMaxLength]);
IMG_CB(88004);
IMG_CB(88004b);
#undef IMG_CB
@@ -583,6 +598,10 @@ private:
FILTER_EVENT(6, Orangery);
FILTER_EVENT(6, 19);
+ FILTER_EVENT(7, 2);
+ FILTER_EVENT(7, 9);
+ FILTER_EVENT(7, 10_11_13);
+ FILTER_EVENT(7, 20);
#undef FILTER_EVENT
#undef INIT_PLACE
diff --git a/engines/cryomni3d/versailles/logic.cpp b/engines/cryomni3d/versailles/logic.cpp
index b3acea0223..55608cdb40 100644
--- a/engines/cryomni3d/versailles/logic.cpp
+++ b/engines/cryomni3d/versailles/logic.cpp
@@ -418,7 +418,7 @@ void CryOmni3DEngine_Versailles::setupImgScripts() {
SET_SCRIPT_BY_ID(45280);
SET_SCRIPT_BY_ID(88001);
SET_SCRIPT_BY_ID(88002);
- //SET_SCRIPT_BY_ID(88003); // TODO: implement it
+ SET_SCRIPT_BY_ID(88003);
SET_SCRIPT_BY_ID(88004);
#undef SET_SCRIPT_BY_ID
}
@@ -2675,6 +2675,381 @@ IMG_CB(88002) {
}
}
+IMG_CB(88003) {
+ // Dispatch to the correct state
+ if (_gameVariables[GameVariables::kBombState] >= 1 &&
+ _gameVariables[GameVariables::kBombState] <= 5) {
+ FixedImgCallback callback;
+ switch (_gameVariables[GameVariables::kBombState]) {
+ case 1:
+ callback = &CryOmni3DEngine_Versailles::img_88003b;
+ break;
+ case 2:
+ callback = &CryOmni3DEngine_Versailles::img_88003c;
+ break;
+ case 3:
+ callback = &CryOmni3DEngine_Versailles::img_88003d;
+ break;
+ case 4:
+ callback = &CryOmni3DEngine_Versailles::img_88003e;
+ break;
+ case 5:
+ callback = &CryOmni3DEngine_Versailles::img_88003f;
+ break;
+ }
+ ZonFixedImage::CallbackFunctor *functor =
+ new Common::Functor1Mem<ZonFixedImage *, void, CryOmni3DEngine_Versailles>(this, callback);
+ fimg->changeCallback(functor);
+ return;
+ }
+
+ fimg->load("70Z_10.GIF");
+
+ // Draw countdown there and not in fixed image class directly
+ Graphics::ManagedSurface tempSurf;
+ const Graphics::Surface *fimgSurface = fimg->surface();
+ tempSurf.create(fimgSurface->w, fimgSurface->h, fimgSurface->format);
+ tempSurf.blitFrom(*fimgSurface);
+ drawCountdown(&tempSurf);
+ fimg->updateSurface(&tempSurf.rawSurface());
+
+ while (1) {
+ fimg->manage();
+ if (fimg->_exit || fimg->_zoneLow) {
+ fimg->_exit = true;
+ break;
+ }
+ if (fimg->_currentZone == 0 && fimg->_usedObject &&
+ fimg->_usedObject->idOBJ() == 145) {
+ // Now we know how to reach the bomb
+ _gameVariables[GameVariables::kBombState] = 1;
+ ZonFixedImage::CallbackFunctor *functor =
+ new Common::Functor1Mem<ZonFixedImage *, void, CryOmni3DEngine_Versailles>(this,
+ &CryOmni3DEngine_Versailles::img_88003b);
+ fimg->changeCallback(functor);
+ break;
+ }
+ if (fimg->_zoneUse) {
+ if (_currentLevel == 7) {
+ // You will need something to reach the bomb
+ displayMessageBox(kFixedimageMsgBoxParameters, fimg->surface(), 10,
+ fimg->getZoneCenter(fimg->_currentZone),
+ Common::Functor0Mem<void, ZonFixedImage>(fimg, &ZonFixedImage::manage));
+ }
+ }
+ if (countDown()) {
+ // Countdown has changed: refresh surface
+ drawCountdown(&tempSurf);
+ fimg->updateSurface(&tempSurf.rawSurface());
+ }
+ }
+}
+
+IMG_CB(88003b) {
+ fimg->load("70Z_11.GIF");
+
+ // Draw countdown there and not in fixed image class directly
+ Graphics::ManagedSurface tempSurf;
+ const Graphics::Surface *fimgSurface = fimg->surface();
+ tempSurf.create(fimgSurface->w, fimgSurface->h, fimgSurface->format);
+ tempSurf.blitFrom(*fimgSurface);
+ drawCountdown(&tempSurf);
+ fimg->updateSurface(&tempSurf.rawSurface());
+
+ while (1) {
+ fimg->manage();
+ if (fimg->_exit || fimg->_zoneLow) {
+ fimg->_exit = true;
+ break;
+ }
+ if (fimg->_currentZone == 0 && fimg->_usedObject &&
+ fimg->_usedObject->idOBJ() == 97) {
+ // Unlock first line with key 1
+ _gameVariables[GameVariables::kBombState] = 2;
+ ZonFixedImage::CallbackFunctor *functor =
+ new Common::Functor1Mem<ZonFixedImage *, void, CryOmni3DEngine_Versailles>(this,
+ &CryOmni3DEngine_Versailles::img_88003c);
+ fimg->changeCallback(functor);
+ break;
+ }
+ if (countDown()) {
+ // Countdown has changed: refresh surface
+ drawCountdown(&tempSurf);
+ fimg->updateSurface(&tempSurf.rawSurface());
+ }
+ }
+}
+
+IMG_CB(88003c) {
+ fimg->load("70Z_12.GIF");
+
+ // Draw countdown there and not in fixed image class directly
+ Graphics::ManagedSurface tempSurf;
+ const Graphics::Surface *fimgSurface = fimg->surface();
+ tempSurf.create(fimgSurface->w, fimgSurface->h, fimgSurface->format);
+ tempSurf.blitFrom(*fimgSurface);
+ drawCountdown(&tempSurf);
+ fimg->updateSurface(&tempSurf.rawSurface());
+
+ while (1) {
+ fimg->manage();
+ if (fimg->_exit || fimg->_zoneLow) {
+ fimg->_exit = true;
+ break;
+ }
+ if (fimg->_currentZone == 1 && fimg->_usedObject &&
+ fimg->_usedObject->idOBJ() == 116) {
+ // Unlock second line with key 2
+ _gameVariables[GameVariables::kBombState] = 3;
+ ZonFixedImage::CallbackFunctor *functor =
+ new Common::Functor1Mem<ZonFixedImage *, void, CryOmni3DEngine_Versailles>(this,
+ &CryOmni3DEngine_Versailles::img_88003d);
+ fimg->changeCallback(functor);
+ break;
+ }
+ if (countDown()) {
+ // Countdown has changed: refresh surface
+ drawCountdown(&tempSurf);
+ fimg->updateSurface(&tempSurf.rawSurface());
+ }
+ }
+}
+
+IMG_CB(88003d) {
+ fimg->load("70Z_13.GIF");
+
+ // Draw countdown there and not in fixed image class directly
+ Graphics::ManagedSurface tempSurf;
+ const Graphics::Surface *fimgSurface = fimg->surface();
+ tempSurf.create(fimgSurface->w, fimgSurface->h, fimgSurface->format);
+ tempSurf.blitFrom(*fimgSurface);
+ drawCountdown(&tempSurf);
+ fimg->updateSurface(&tempSurf.rawSurface());
+
+ while (1) {
+ fimg->manage();
+ if (fimg->_exit || fimg->_zoneLow) {
+ fimg->_exit = true;
+ break;
+ }
+ if (fimg->_currentZone == 2 && fimg->_usedObject &&
+ fimg->_usedObject->idOBJ() == 135) {
+ // Unlock third line with key 3
+ _gameVariables[GameVariables::kBombState] = 4;
+ ZonFixedImage::CallbackFunctor *functor =
+ new Common::Functor1Mem<ZonFixedImage *, void, CryOmni3DEngine_Versailles>(this,
+ &CryOmni3DEngine_Versailles::img_88003e);
+ fimg->changeCallback(functor);
+ break;
+ }
+ if (countDown()) {
+ // Countdown has changed: refresh surface
+ drawCountdown(&tempSurf);
+ fimg->updateSurface(&tempSurf.rawSurface());
+ }
+ }
+}
+
+IMG_CB(88003e) {
+ fimg->load("70Z_14.GIF");
+
+ // Draw countdown there and not in fixed image class directly
+ Graphics::ManagedSurface tempSurf;
+ const Graphics::Surface *fimgSurface = fimg->surface();
+ tempSurf.create(fimgSurface->w, fimgSurface->h, fimgSurface->format);
+ tempSurf.blitFrom(*fimgSurface);
+ drawCountdown(&tempSurf);
+ fimg->updateSurface(&tempSurf.rawSurface());
+
+ while (1) {
+ fimg->manage();
+ if (fimg->_exit || fimg->_zoneLow) {
+ fimg->_exit = true;
+ break;
+ }
+ if (fimg->_currentZone == 3 && fimg->_usedObject &&
+ fimg->_usedObject->idOBJ() == 136) {
+ // Unlock fourth line with key 4
+ _gameVariables[GameVariables::kBombState] = 5;
+ ZonFixedImage::CallbackFunctor *functor =
+ new Common::Functor1Mem<ZonFixedImage *, void, CryOmni3DEngine_Versailles>(this,
+ &CryOmni3DEngine_Versailles::img_88003f);
+ fimg->changeCallback(functor);
+ break;
+ }
+ if (countDown()) {
+ // Countdown has changed: refresh surface
+ drawCountdown(&tempSurf);
+ fimg->updateSurface(&tempSurf.rawSurface());
+ }
+ }
+}
+
+IMG_CB(88003f) {
+ fimg->load("70Z_15.GIF");
+
+ // Draw countdown there and not in fixed image class directly
+ Graphics::ManagedSurface tempSurf;
+ const Graphics::Surface *fimgSurface = fimg->surface();
+ tempSurf.create(fimgSurface->w, fimgSurface->h, fimgSurface->format);
+ tempSurf.blitFrom(*fimgSurface);
+ drawCountdown(&tempSurf);
+ fimg->updateSurface(&tempSurf.rawSurface());
+
+ while (1) {
+ fimg->manage();
+ if (fimg->_exit || fimg->_zoneLow) {
+ fimg->_exit = true;
+ break;
+ }
+ if (fimg->_zoneUse) {
+ if (handleBomb(fimg)) {
+ playInGameVideo("COFFRE");
+ _forcePaletteUpdate = true;
+ // Force reload of the place
+ if (_nextPlaceId == -1u) {
+ _nextPlaceId = _currentPlaceId;
+ }
+ playTransitionEndLevel(7);
+ break;
+ }
+ }
+ if (countDown()) {
+ // Countdown has changed: refresh surface
+ drawCountdown(&tempSurf);
+ fimg->updateSurface(&tempSurf.rawSurface());
+ }
+ }
+}
+
+bool CryOmni3DEngine_Versailles::handleBomb(ZonFixedImage *fimg) {
+ bool success = false;
+ Common::RandomSource rnd("VersaillesBomb");
+ Graphics::Surface bmpLetters[26];
+ unsigned char bombPossibilites[60][5];
+ unsigned char bombCurrentLetters[60];
+ Graphics::ManagedSurface tempSurf;
+
+ const unsigned int kBombPasswordLength = strlen(kBombPassword);
+ if (kBombPasswordLength >= kBombPasswordMaxLength) {
+ error("Bomb password is too long");
+ }
+
+ loadBMPs("bomb_%02d.bmp", bmpLetters, 26);
+ for (unsigned int i = 0; i < kBombPasswordLength; i++) {
+ bombPossibilites[i][0] = toupper(kBombPassword[i]);
+ for (unsigned int j = 1; j < 5; j++) {
+ bool foundSameLetter;
+ do {
+ foundSameLetter = false;
+ bombPossibilites[i][j] = rnd.getRandomNumberRng('A', 'Z');
+ for (unsigned int k = 0; k < j; k++) {
+ if (bombPossibilites[i][k] == bombPossibilites[i][j]) {
+ foundSameLetter = true;
+ }
+ }
+ } while (foundSameLetter);
+ }
+ bombCurrentLetters[i] = rnd.getRandomNumber(4);
+ }
+
+ if (kBombPasswordLength <= kBombPasswordSmallLength) {
+ fimg->load("70z_16.GIF");
+ } else {
+ fimg->load("70z_17.GIF");
+ }
+ const Graphics::Surface *fimgSurface = fimg->surface();
+ tempSurf.create(fimgSurface->w, fimgSurface->h, fimgSurface->format);
+ tempSurf.blitFrom(*fimgSurface);
+ drawBombLetters(tempSurf, bmpLetters, kBombPasswordLength, bombPossibilites, bombCurrentLetters);
+ drawCountdown(&tempSurf);
+ fimg->updateSurface(&tempSurf.rawSurface());
+
+ while (1) {
+ fimg->manage();
+ if (fimg->_exit || fimg->_zoneLow) {
+ break;
+ }
+ if (fimg->_zoneUse) {
+ if (fimg->_currentZone < kBombPasswordLength) {
+ // Safe digit
+ bombCurrentLetters[fimg->_currentZone] = (bombCurrentLetters[fimg->_currentZone] + 1) % 5;
+ // Reset the surface and redraw letters on it
+ tempSurf.blitFrom(*fimgSurface);
+ drawBombLetters(tempSurf, bmpLetters, kBombPasswordLength, bombPossibilites, bombCurrentLetters);
+ drawCountdown(&tempSurf);
+ fimg->updateSurface(&tempSurf.rawSurface());
+
+ waitMouseRelease();
+
+ // Check if password is OK
+ success = true;
+ for (unsigned int i = 0; i < kBombPasswordLength; i++) {
+ unsigned char letterChar = bombPossibilites[i][bombCurrentLetters[i]];
+ if (letterChar != kBombPassword[i]) {
+ success = false;
+ break;
+ }
+ }
+ if (success) {
+ break;
+ }
+ }
+ }
+ if (countDown()) {
+ // Countdown has changed: refresh surface
+ drawCountdown(&tempSurf);
+ fimg->updateSurface(&tempSurf.rawSurface());
+ }
+ }
+
+ for (unsigned int i = 0; i < 26; i++) {
+ bmpLetters[i].free();
+ }
+ return success;
+}
+
+const char *CryOmni3DEngine_Versailles::kBombPassword = "JEMENVAISMAISLETATDEMEURERATOUJOURS";
+// We use brace elision here because it's dumped from the EXE
+const unsigned short CryOmni3DEngine_Versailles::kBombLettersPos[2][kBombPasswordMaxLength][2] = {
+ {
+ 26, 91, 84, 89, 141, 89, 202, 88, 261, 87, 322, 86, 384, 85, 448, 84,
+ 512, 83, 576, 83, 26, 175, 84, 175, 142, 174, 202, 174, 260, 174, 322,
+ 174, 384, 173, 448, 173, 512, 173, 576, 172, 26, 261, 84, 261, 141,
+ 261, 202, 261, 261, 262, 322, 262, 383, 262, 447, 263, 512, 263, 576,
+ 263, 26, 344, 84, 345, 142, 346, 202, 347, 260, 348, 322, 349, 384,
+ 350, 448, 351, 512, 352, 576, 352
+ },
+ {
+ 42, 26, 100, 24, 155, 22, 214, 19, 271, 18, 330, 15, 389, 14, 451, 11,
+ 515, 8, 576, 6, 45, 102, 100, 102, 156, 101, 215, 100, 272, 99, 331,
+ 98, 391, 97, 453, 96, 515, 94, 578, 94, 44, 184, 101, 184, 157, 184,
+ 215, 183, 272, 183, 331, 183, 391, 182, 453, 182, 515, 182, 577, 181,
+ 44, 267, 101, 267, 157, 267, 215, 268, 272, 268, 331, 268, 390, 269,
+ 453, 269, 515, 269, 578, 269, 45, 348, 101, 349, 156, 349, 215, 351,
+ 271, 351, 331, 351, 391, 353, 453, 354, 515, 355, 577, 356, 44, 434,
+ 101, 435, 156, 436, 215, 437, 272, 437, 331, 437, 391, 439, 453, 440,
+ 515, 441, 578, 442
+ },
+};
+
+void CryOmni3DEngine_Versailles::drawBombLetters(Graphics::ManagedSurface &surface,
+ const Graphics::Surface(&bmpLetters)[26], const unsigned int kBombPasswordLength,
+ const unsigned char (&bombPossibilites)[kBombPasswordMaxLength][5],
+ const unsigned char (&bombCurrentLetters)[kBombPasswordMaxLength]) {
+ unsigned int table = kBombPasswordLength <= kBombPasswordSmallLength ? 0 : 1;
+ for (unsigned int i = 0; i < kBombPasswordLength; i++) {
+ unsigned char letterChar = bombPossibilites[i][bombCurrentLetters[i]];
+ unsigned int letterId = 0;
+ if (letterChar >= 'A' && letterChar <= 'Z') {
+ letterId = letterChar - 'A';
+ }
+ const Graphics::Surface &letter = bmpLetters[letterId];
+ Common::Point dst(kBombLettersPos[table][i][0], kBombLettersPos[table][i][1]);
+ surface.transBlitFrom(letter, dst);
+ }
+}
+
IMG_CB(88004) {
fimg->load("31j31.gif");
while (1) {
@@ -4082,6 +4457,112 @@ FILTER_EVENT(6, 19) {
return true;
}
+FILTER_EVENT(7, 2) {
+ if (*event == 37021) {
+ if (_inventory.selectedObject() &&
+ _inventory.selectedObject()->idOBJ() == 103) {
+ // Light the candle
+ _inventory.removeByNameID(103);
+ collectObject(102);
+ }
+ // Handled here
+ return false;
+ } else if (*event == 37022) {
+ if (!_inventory.inInventoryByNameID(97)) {
+ collectObject(97);
+ _inventory.deselectObject();
+ } else {
+ // Jar is empty
+ displayMessageBoxWarp(11);
+ }
+ // Handled here
+ return false;
+ } else if (*event == 7) {
+ // Stairs
+ if (_gameVariables[GameVariables::kUsedLitCandle]) {
+ return true;
+ }
+
+ if (_inventory.selectedObject() &&
+ _inventory.selectedObject()->idOBJ() == 102) {
+ // Now you can go
+ displayMessageBoxWarp(12);
+ _inventory.removeByNameID(102);
+ _inventory.deselectObject();
+ // Save it for later
+ _gameVariables[GameVariables::kUsedLitCandle] = 1;
+
+ return true;
+ }
+
+ // Didn't used lit candle and not using it now: denied
+ // Too dark
+ displayMessageBoxWarp(7);
+ return false;
+ }
+
+ return true;
+}
+
+FILTER_EVENT(7, 9) {
+ if (*event == 37090) {
+ if (_placeStates[9].state == 0) {
+ // Get the candle snuffer
+ collectObject(145);
+ _inventory.deselectObject();
+ setPlaceState(9, 1);
+ }
+ // Handled here
+ return false;
+ }
+
+ return true;
+}
+
+FILTER_EVENT(7, 10_11_13) {
+ if (*event == 37131) {
+ if (_inventory.selectedObject() &&
+ _inventory.selectedObject()->idOBJ() == 143 &&
+ !_inventory.inInventoryByNameID(136)) {
+ collectObject(136);
+ // WORKAROUND: Deselect the tool
+ _inventory.deselectObject();
+ }
+ // Handled here
+ return false;
+ } else if (*event == 37132) {
+ if (_inventory.selectedObject() &&
+ _inventory.selectedObject()->idOBJ() == 143) {
+ // Nothing in this orange tree
+ displayMessageBoxWarp(5);
+ }
+ // Handled here
+ return false;
+ }
+
+ return true;
+}
+
+FILTER_EVENT(7, 20) {
+ if (*event == 21) {
+ fakeTransition(*event);
+
+ playInGameVideo("70z_10");
+
+ executeSeeAction(88003);
+
+ _forcePaletteUpdate = true;
+ // Force reload of the place
+ if (_nextPlaceId == -1u) {
+ _nextPlaceId = _currentPlaceId;
+ }
+ // Handled here
+ return false;
+ }
+
+ return true;
+}
+
#undef FILTER_EVENT
#undef INIT_PLACE