aboutsummaryrefslogtreecommitdiff
path: root/engines/lastexpress
diff options
context:
space:
mode:
authorEvgeny Grechnikov2018-08-25 15:11:24 +0300
committerEugene Sandulenko2018-08-26 12:09:43 +0200
commitf771fa40ad474d78d32ce5bff67afc937547e5de (patch)
tree483ee750c81169142fc58a68e87d5a321a4a96f3 /engines/lastexpress
parentf3cb1fcd84d7ca1dd25b7adb4b54f08c535008ac (diff)
downloadscummvm-rg350-f771fa40ad474d78d32ce5bff67afc937547e5de.tar.gz
scummvm-rg350-f771fa40ad474d78d32ce5bff67afc937547e5de.tar.bz2
scummvm-rg350-f771fa40ad474d78d32ce5bff67afc937547e5de.zip
LASTEXPRESS: multiple fixes in NPC logic
Checked the logic against the original game (to be precise, DOS English version from GOG, although I think AI logic has no significant differences with other versions). Fixed a *lot* of errors with varying visibility for the user. Also, save+exit+load sometimes resulted in memory corruption like ((EntityParametersSSII*)(new EntityParametersIIII))->param8 = 0; load operation did not restore the correct type of NPC logic context, the default one was used (which also has the smallest sizeof). Should be fixed now. Save+load is still unusable because it locks everybody waiting for kActionEndSound (the sound state is not restored), but, at least, it should not corrupt the memory. Hopefully.
Diffstat (limited to 'engines/lastexpress')
-rw-r--r--engines/lastexpress/debug.cpp5
-rw-r--r--engines/lastexpress/entities/abbot.cpp51
-rw-r--r--engines/lastexpress/entities/alexei.cpp64
-rw-r--r--engines/lastexpress/entities/alexei.h6
-rw-r--r--engines/lastexpress/entities/alouan.cpp12
-rw-r--r--engines/lastexpress/entities/anna.cpp121
-rw-r--r--engines/lastexpress/entities/august.cpp137
-rw-r--r--engines/lastexpress/entities/boutarel.cpp36
-rw-r--r--engines/lastexpress/entities/chapters.cpp66
-rw-r--r--engines/lastexpress/entities/cooks.cpp50
-rw-r--r--engines/lastexpress/entities/coudert.cpp86
-rw-r--r--engines/lastexpress/entities/entity.cpp135
-rw-r--r--engines/lastexpress/entities/entity.h144
-rw-r--r--engines/lastexpress/entities/francois.cpp70
-rw-r--r--engines/lastexpress/entities/gendarmes.cpp45
-rw-r--r--engines/lastexpress/entities/hadija.cpp24
-rw-r--r--engines/lastexpress/entities/ivo.cpp23
-rw-r--r--engines/lastexpress/entities/kahina.cpp34
-rw-r--r--engines/lastexpress/entities/kronos.cpp63
-rw-r--r--engines/lastexpress/entities/mahmud.cpp26
-rw-r--r--engines/lastexpress/entities/max.cpp44
-rw-r--r--engines/lastexpress/entities/mertens.cpp193
-rw-r--r--engines/lastexpress/entities/mertens.h2
-rw-r--r--engines/lastexpress/entities/milos.cpp61
-rw-r--r--engines/lastexpress/entities/mmeboutarel.cpp17
-rw-r--r--engines/lastexpress/entities/pascale.cpp24
-rw-r--r--engines/lastexpress/entities/rebecca.cpp78
-rw-r--r--engines/lastexpress/entities/salko.cpp17
-rw-r--r--engines/lastexpress/entities/sophie.cpp7
-rw-r--r--engines/lastexpress/entities/tatiana.cpp56
-rw-r--r--engines/lastexpress/entities/train.cpp21
-rw-r--r--engines/lastexpress/entities/vassili.cpp18
-rw-r--r--engines/lastexpress/entities/verges.cpp67
-rw-r--r--engines/lastexpress/entities/vesna.cpp40
-rw-r--r--engines/lastexpress/entities/waiter1.cpp28
-rw-r--r--engines/lastexpress/entities/waiter2.cpp24
-rw-r--r--engines/lastexpress/entities/yasmin.cpp48
-rw-r--r--engines/lastexpress/game/entities.cpp10
-rw-r--r--engines/lastexpress/game/savegame.cpp2
-rw-r--r--engines/lastexpress/game/savepoint.cpp6
-rw-r--r--engines/lastexpress/game/savepoint.h3
-rw-r--r--engines/lastexpress/game/state.h279
-rw-r--r--engines/lastexpress/shared.h15
-rw-r--r--engines/lastexpress/sound/entry.cpp14
-rw-r--r--engines/lastexpress/sound/entry.h11
-rw-r--r--engines/lastexpress/sound/queue.cpp2
-rw-r--r--engines/lastexpress/sound/sound.cpp59
47 files changed, 1312 insertions, 1032 deletions
diff --git a/engines/lastexpress/debug.cpp b/engines/lastexpress/debug.cpp
index a6cecc7408..dec57a4c39 100644
--- a/engines/lastexpress/debug.cpp
+++ b/engines/lastexpress/debug.cpp
@@ -487,10 +487,7 @@ bool Debugger::cmdPlaySeq(int argc, const char **argv) {
// Handle right-click to interrupt sequence
Common::Event ev;
- if (!_engine->getEventManager()->pollEvent(ev))
- break;
-
- if (ev.type == Common::EVENT_RBUTTONUP)
+ if (_engine->getEventManager()->pollEvent(ev) && ev.type == Common::EVENT_RBUTTONUP)
break;
_engine->_system->delayMillis(175);
diff --git a/engines/lastexpress/entities/abbot.cpp b/engines/lastexpress/entities/abbot.cpp
index 1581916e07..99b9ee3bc2 100644
--- a/engines/lastexpress/entities/abbot.cpp
+++ b/engines/lastexpress/entities/abbot.cpp
@@ -41,18 +41,18 @@ namespace LastExpress {
Abbot::Abbot(LastExpressEngine *engine) : Entity(engine, kEntityAbbot) {
ADD_CALLBACK_FUNCTION(Abbot, reset);
- ADD_CALLBACK_FUNCTION(Abbot, draw);
- ADD_CALLBACK_FUNCTION(Abbot, enterExitCompartment);
- ADD_CALLBACK_FUNCTION(Abbot, enterExitCompartment2);
+ ADD_CALLBACK_FUNCTION_S(Abbot, draw);
+ ADD_CALLBACK_FUNCTION_SI(Abbot, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_SI(Abbot, enterExitCompartment2);
ADD_CALLBACK_FUNCTION(Abbot, callbackActionOnDirection);
- ADD_CALLBACK_FUNCTION(Abbot, draw2);
- ADD_CALLBACK_FUNCTION(Abbot, updateFromTime);
- ADD_CALLBACK_FUNCTION(Abbot, updateFromTicks);
- ADD_CALLBACK_FUNCTION(Abbot, playSound);
- ADD_CALLBACK_FUNCTION(Abbot, savegame);
- ADD_CALLBACK_FUNCTION(Abbot, updateEntity);
- ADD_CALLBACK_FUNCTION(Abbot, callSavepoint);
- ADD_CALLBACK_FUNCTION(Abbot, updatePosition);
+ ADD_CALLBACK_FUNCTION_SSI(Abbot, draw2);
+ ADD_CALLBACK_FUNCTION_I(Abbot, updateFromTime);
+ ADD_CALLBACK_FUNCTION_I(Abbot, updateFromTicks);
+ ADD_CALLBACK_FUNCTION_S(Abbot, playSound);
+ ADD_CALLBACK_FUNCTION_II(Abbot, savegame);
+ ADD_CALLBACK_FUNCTION_II(Abbot, updateEntity);
+ ADD_CALLBACK_FUNCTION_SIIS(Abbot, callSavepoint);
+ ADD_CALLBACK_FUNCTION_SII(Abbot, updatePosition);
ADD_CALLBACK_FUNCTION(Abbot, callbackActionRestaurantOrSalon);
ADD_CALLBACK_FUNCTION(Abbot, chapter1);
ADD_CALLBACK_FUNCTION(Abbot, chapter2);
@@ -79,7 +79,7 @@ Abbot::Abbot(LastExpressEngine *engine) : Entity(engine, kEntityAbbot) {
ADD_CALLBACK_FUNCTION(Abbot, goCompartment4);
ADD_CALLBACK_FUNCTION(Abbot, inCompartment4);
ADD_CALLBACK_FUNCTION(Abbot, chapter4);
- ADD_CALLBACK_FUNCTION(Abbot, doWalkSearchingForCath);
+ ADD_CALLBACK_FUNCTION_II(Abbot, doWalkSearchingForCath);
ADD_CALLBACK_FUNCTION(Abbot, chapter4Handler);
ADD_CALLBACK_FUNCTION(Abbot, leaveDinner);
ADD_CALLBACK_FUNCTION(Abbot, inCompartment);
@@ -616,7 +616,7 @@ IMPLEMENT_FUNCTION(26, Abbot, inSalon1)
break;
case kActionNone:
- if (!Entity::updateParameter(params->param2, getState()->time, 4500))
+ if (!params->param1 || !Entity::updateParameterCheck(params->param2, getState()->time, 4500))
break;
if (getEntities()->isSomebodyInsideRestaurantOrSalon())
@@ -691,7 +691,7 @@ IMPLEMENT_FUNCTION(28, Abbot, openCompartment2)
break;
case kActionNone:
- Entity::timeCheckCallback(kTime2052000, params->param1, 1, WRAP_SETUP_FUNCTION(Abbot, setup_goWander));
+ Entity::timeCheckCallback(kTime2052000, params->param1, 2, WRAP_SETUP_FUNCTION(Abbot, setup_goWander));
break;
case kActionDefault:
@@ -699,7 +699,7 @@ IMPLEMENT_FUNCTION(28, Abbot, openCompartment2)
getEntities()->drawSequenceLeft(kEntityAbbot, "508A");
setCallback(1);
- setup_playSound("abb3013");
+ setup_playSound("Abb3013");
break;
case kActionCallback:
@@ -749,6 +749,9 @@ IMPLEMENT_FUNCTION(29, Abbot, goWander)
break;
case 4:
+ // compare with callback 2.
+ // This is taken from the original game as is,
+ // but do we really want real-time 30s in case 2 but simulated-time 15s (aka real-time 5s) here?
setCallback(5);
setup_updateFromTime(225);
break;
@@ -962,7 +965,7 @@ IMPLEMENT_FUNCTION(32, Abbot, goCompartment3)
case 1:
getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
- setCallback(1);
+ setCallback(2);
setup_enterExitCompartment("617Ac", kObjectCompartmentC);
break;
@@ -1355,7 +1358,7 @@ IMPLEMENT_FUNCTION(42, Abbot, leaveDinner)
case kActionDefault:
getData()->location = kLocationOutsideCompartment;
- getEntities()->updatePositionExit(kEntityAbbot, kCarRestaurant, 67);
+ getEntities()->updatePositionEnter(kEntityAbbot, kCarRestaurant, 67);
setCallback(1);
setup_callSavepoint("029F", kEntityTables4, kActionDrawTablesWithChairs, "029G");
@@ -1406,8 +1409,8 @@ IMPLEMENT_FUNCTION(43, Abbot, inCompartment)
break;
case kActionNone:
- if (params->param1 && params->param4 != kTimeInvalid && params->param2 < getState()->time) {
- if (getState()->time < kTime2452500) {
+ if (params->param1 && params->param4 != kTimeInvalid) {
+ if (getState()->time > kTime2452500) {
params->param4 = kTimeInvalid;
setCallback(1);
@@ -1415,7 +1418,7 @@ IMPLEMENT_FUNCTION(43, Abbot, inCompartment)
break;
} else {
if (!getEntities()->isDistanceBetweenEntities(kEntityAbbot, kEntityPlayer, 1000) || getSoundQueue()->isBuffered(kEntityBoutarel) || !params->param4)
- params->param4 = (uint)getState()->time + 450;
+ params->param4 = (uint)getState()->time;
if (params->param4 < getState()->time) {
params->param4 = kTimeInvalid;
@@ -1655,7 +1658,8 @@ IMPLEMENT_FUNCTION(48, Abbot, afterBomb)
getData()->inventoryItem = kItemNone;
setCallback(4);
- setup_updatePosition("126C", kCarRedSleeping, 52);
+ setup_updatePosition("126C", kCarRestaurant, 52);
+ break;
}
Entity::timeCheckCallbackInventory(kTime2533500, params->param2, 5, WRAP_SETUP_FUNCTION(Abbot, setup_callbackActionRestaurantOrSalon));
@@ -1771,6 +1775,9 @@ IMPLEMENT_FUNCTION(49, Abbot, catchCath)
getSavePoints()->push(kEntityAbbot, kEntityTatiana, kAction238790488);
getObjects()->update(kObjectCompartment2, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
getObjects()->update(kObjectHandleInsideBathroom, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAbbotWrongCompartment);
break;
case kActionDefault:
@@ -1791,7 +1798,7 @@ IMPLEMENT_FUNCTION(49, Abbot, catchCath)
break;
case 1:
- getAction()->playAnimation(getObjects()->get(kObjectCompartment2).model < kObjectModel2 ? kEventAbbotWrongCompartmentBed : kEventAbbotWrongCompartment);
+ getAction()->playAnimation(getObjects()->get(kObjectCompartment2).model == kObjectModel1 ? kEventAbbotWrongCompartmentBed : kEventAbbotWrongCompartment);
getEntities()->updateEntity(kEntityAbbot, kCarRedSleeping, kPosition_6470);
getSound()->playSound(kEntityPlayer, "LIB015");
getScenes()->loadSceneFromObject(kObjectCompartment2, true);
diff --git a/engines/lastexpress/entities/alexei.cpp b/engines/lastexpress/entities/alexei.cpp
index 5ea3ff4898..89027c2d2f 100644
--- a/engines/lastexpress/entities/alexei.cpp
+++ b/engines/lastexpress/entities/alexei.cpp
@@ -37,21 +37,21 @@ namespace LastExpress {
Alexei::Alexei(LastExpressEngine *engine) : Entity(engine, kEntityAlexei) {
ADD_CALLBACK_FUNCTION(Alexei, reset);
- ADD_CALLBACK_FUNCTION(Alexei, playSound);
- ADD_CALLBACK_FUNCTION(Alexei, updateFromTicks);
- ADD_CALLBACK_FUNCTION(Alexei, draw);
- ADD_CALLBACK_FUNCTION(Alexei, updatePosition);
- ADD_CALLBACK_FUNCTION(Alexei, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_S(Alexei, playSound);
+ ADD_CALLBACK_FUNCTION_I(Alexei, updateFromTime);
+ ADD_CALLBACK_FUNCTION_S(Alexei, draw);
+ ADD_CALLBACK_FUNCTION_SII(Alexei, updatePosition);
+ ADD_CALLBACK_FUNCTION_SI(Alexei, enterExitCompartment);
ADD_CALLBACK_FUNCTION(Alexei, callbackActionOnDirection);
- ADD_CALLBACK_FUNCTION(Alexei, callSavepoint);
- ADD_CALLBACK_FUNCTION(Alexei, savegame);
- ADD_CALLBACK_FUNCTION(Alexei, updateEntity);
- ADD_CALLBACK_FUNCTION(Alexei, draw2);
+ ADD_CALLBACK_FUNCTION_SIIS(Alexei, callSavepoint);
+ ADD_CALLBACK_FUNCTION_II(Alexei, savegame);
+ ADD_CALLBACK_FUNCTION_II(Alexei, updateEntity);
+ ADD_CALLBACK_FUNCTION_SSI(Alexei, draw2);
ADD_CALLBACK_FUNCTION(Alexei, callbackActionRestaurantOrSalon);
ADD_CALLBACK_FUNCTION(Alexei, enterComparment);
ADD_CALLBACK_FUNCTION(Alexei, exitCompartment);
ADD_CALLBACK_FUNCTION(Alexei, pacingAtWindow);
- ADD_CALLBACK_FUNCTION(Alexei, compartmentLogic);
+ ADD_CALLBACK_FUNCTION_IS(Alexei, compartmentLogic);
ADD_CALLBACK_FUNCTION(Alexei, chapter1);
ADD_CALLBACK_FUNCTION(Alexei, atDinner);
ADD_CALLBACK_FUNCTION(Alexei, returnCompartment);
@@ -97,8 +97,8 @@ IMPLEMENT_FUNCTION_S(2, Alexei, playSound)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION_I(3, Alexei, updateFromTicks, uint32)
- Entity::updateFromTicks(savepoint);
+IMPLEMENT_FUNCTION_I(3, Alexei, updateFromTime, uint32)
+ Entity::updateFromTime(savepoint);
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
@@ -394,7 +394,7 @@ IMPLEMENT_FUNCTION_IS(16, Alexei, compartmentLogic, TimeValue)
case 7:
setCallback(8);
- setup_updateFromTicks(300);
+ setup_updateFromTime(300);
break;
case 8:
@@ -675,7 +675,7 @@ IMPLEMENT_FUNCTION(20, Alexei, goSalon)
case 4:
getData()->location = kLocationInsideCompartment;
- setup_function26();
+ setup_sitting();
break;
}
break;
@@ -689,7 +689,7 @@ IMPLEMENT_FUNCTION(21, Alexei, sitting)
break;
case kActionNone:
- if (Entity::updateParameterCheck(params->param2, getState()->time, params->param1)) {
+ if (Entity::updateParameterCheck(params->param2, getState()->time, params->param1) && getEntities()->isSomebodyInsideRestaurantOrSalon()) {
getData()->location = kLocationOutsideCompartment;
getData()->inventoryItem = kItemNone;
@@ -738,6 +738,7 @@ IMPLEMENT_FUNCTION(21, Alexei, sitting)
case 3:
getEntities()->drawSequenceLeft(kEntityAlexei, "103B");
getEntities()->updatePositionExit(kEntityAlexei, kCarRestaurant, 52);
+ getData()->location = kLocationInsideCompartment;
break;
}
break;
@@ -751,7 +752,7 @@ IMPLEMENT_FUNCTION(22, Alexei, standingAtWindow)
break;
case kActionNone:
- if (Entity::updateParameter(params->param2, getState()->time, params->param2)) {
+ if (Entity::updateParameterCheck(params->param2, getState()->time, params->param1)) {
if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
getData()->location = kLocationOutsideCompartment;
getData()->inventoryItem = kItemNone;
@@ -768,7 +769,7 @@ IMPLEMENT_FUNCTION(22, Alexei, standingAtWindow)
if (getState()->time > kTime1138500) {
params->param3 = kTimeInvalid;
} else {
- if (!getEntities()->isInSalon(kEntityPlayer) || getEntities()->isInSalon(kEntityPlayer) || !params->param3)
+ if (!getEntities()->isInSalon(kEntityPlayer) && !getEntities()->isInRestaurant(kEntityPlayer) || !params->param3)
params->param3 = (uint)getState()->time;
if (params->param3 >= getState()->time)
@@ -788,7 +789,7 @@ IMPLEMENT_FUNCTION(22, Alexei, standingAtWindow)
break;
case kActionDefault:
- params->param1 = 255 * (4 * rnd(4) + 8);
+ params->param1 = 225 * (4 * rnd(4) + 8);
getEntities()->drawSequenceLeft(kEntityAlexei, "103E");
if (!getEvent(kEventAlexeiSalonPoem))
getData()->inventoryItem = kItemParchemin;
@@ -821,7 +822,7 @@ IMPLEMENT_FUNCTION(22, Alexei, standingAtWindow)
getEntities()->updatePositionExit(kEntityAlexei, kCarRestaurant, 52);
getData()->location = kLocationInsideCompartment;
- setup_standingAtWindow();
+ setup_sitting();
break;
}
break;
@@ -835,7 +836,7 @@ IMPLEMENT_FUNCTION(23, Alexei, waitingForTatiana)
break;
case kActionNone:
- getData()->inventoryItem = (!getEntities()->isInRestaurant(kEntityAlexei) || getEvent(kEventAlexeiSalonPoem)) ? kItemNone : kItemParchemin;
+ getData()->inventoryItem = (!getEntities()->isInRestaurant(kEntityTatiana) || getEvent(kEventAlexeiSalonPoem)) ? kItemNone : kItemParchemin;
break;
case kAction1:
@@ -913,7 +914,7 @@ IMPLEMENT_FUNCTION(24, Alexei, upset)
case 1:
getAction()->playAnimation(kEventAlexeiSalonCath);
- getData()->car = kCarRestaurant;
+ getData()->car = kCarRedSleeping;
getData()->entityPosition = kPosition_9460;
getEntities()->clearSequences(kEntityAlexei);
getScenes()->loadSceneFromPosition(kCarRestaurant, 55);
@@ -1125,7 +1126,7 @@ IMPLEMENT_FUNCTION(30, Alexei, atBreakfast)
break;
case 2:
- getSound()->playSound(kEntityAlexei, "TAt2116A");
+ getSound()->playSound(kEntityAlexei, "TAT2116A");
getEntities()->updatePositionEnter(kEntityAlexei, kCarRestaurant, 63);
setCallback(3);
@@ -1333,7 +1334,7 @@ IMPLEMENT_FUNCTION(35, Alexei, pacing3)
case kActionNone:
if (getEntities()->isInSalon(kEntityPlayer)) {
- if (Entity::updateParameter(params->param2, getState()->time, 2700)) {
+ if (Entity::updateParameterCheck(params->param2, getState()->time, 2700)) {
setCallback(1);
setup_callbackActionRestaurantOrSalon();
break;
@@ -1342,7 +1343,7 @@ IMPLEMENT_FUNCTION(35, Alexei, pacing3)
params->param2 = 0;
}
- if (Entity::updateParameter(params->param3, getState()->time, params->param1)) {
+ if (Entity::updateParameterCheck(params->param3, getState()->time, params->param1)) {
if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
setCallback(3);
setup_pacingAtWindow();
@@ -1535,10 +1536,10 @@ IMPLEMENT_FUNCTION(39, Alexei, meetTatiana)
break;
}
- params->param4 = kTimeInvalid;
+ params->param5 = kTimeInvalid;
- getEntities()->updatePositionEnter(kEntityAlexei, kCarGreenSleeping, 70);
- getEntities()->updatePositionEnter(kEntityAlexei, kCarGreenSleeping, 71);
+ getEntities()->updatePositionExit(kEntityAlexei, kCarGreenSleeping, 70);
+ getEntities()->updatePositionExit(kEntityAlexei, kCarGreenSleeping, 71);
if (getEntities()->isInGreenCarEntrance(kEntityPlayer)) {
getSound()->excuseMe(kEntityAlexei);
@@ -1725,10 +1726,7 @@ IMPLEMENT_FUNCTION(43, Alexei, pacing)
break;
case kActionNone:
- if (getState()->time < kTime1806300 && params->param2 < getState()->time) {
- if (!params->param2)
- params->param2 = (uint)getState()->time + params->param1;
-
+ if (getState()->time < kTime1806300 && Entity::updateParameterCheck(params->param2, getState()->time, params->param1)) {
if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
setCallback(1);
setup_pacingAtWindow();
@@ -1782,7 +1780,7 @@ IMPLEMENT_FUNCTION(44, Alexei, goToPlatform)
break;
case kActionNone:
- if (getState()->time > kTime2457000 && !params->param1) {
+ if (getState()->time > kTime2475000 && !params->param1) {
params->param1 = 1;
getEntities()->updatePositionExit(kEntityAlexei, kCarGreenSleeping, 70);
@@ -1986,7 +1984,7 @@ IMPLEMENT_FUNCTION(47, Alexei, function47)
getData()->entityPosition = kPositionNone;
getData()->location = kLocationOutsideCompartment;
- getData()->car = kCarNone;
+ getData()->car = kCarLocomotive;
getObjects()->update(kObjectCompartment2, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
getObjects()->update(kObjectHandleInsideBathroom, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
diff --git a/engines/lastexpress/entities/alexei.h b/engines/lastexpress/entities/alexei.h
index 5e14039a35..713a8c7847 100644
--- a/engines/lastexpress/entities/alexei.h
+++ b/engines/lastexpress/entities/alexei.h
@@ -47,11 +47,11 @@ public:
DECLARE_FUNCTION_1(playSound, const char *filename)
/**
- * Updates parameter 2 using ticks value
+ * Updates parameter 2 using time value
*
- * @param ticks The number of ticks to add
+ * @param time The time to add
*/
- DECLARE_FUNCTION_1(updateFromTicks, uint32 ticks)
+ DECLARE_FUNCTION_1(updateFromTime, uint32 time)
/**
* Draws the entity
diff --git a/engines/lastexpress/entities/alouan.cpp b/engines/lastexpress/entities/alouan.cpp
index 0667d11697..a4bb10539c 100644
--- a/engines/lastexpress/entities/alouan.cpp
+++ b/engines/lastexpress/entities/alouan.cpp
@@ -34,10 +34,10 @@ namespace LastExpress {
Alouan::Alouan(LastExpressEngine *engine) : Entity(engine, kEntityAlouan) {
ADD_CALLBACK_FUNCTION(Alouan, reset);
- ADD_CALLBACK_FUNCTION(Alouan, enterExitCompartment);
- ADD_CALLBACK_FUNCTION(Alouan, playSound);
- ADD_CALLBACK_FUNCTION(Alouan, updateFromTime);
- ADD_CALLBACK_FUNCTION(Alouan, updateEntity);
+ ADD_CALLBACK_FUNCTION_SI(Alouan, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_S(Alouan, playSound);
+ ADD_CALLBACK_FUNCTION_I(Alouan, updateFromTime);
+ ADD_CALLBACK_FUNCTION_II(Alouan, updateEntity);
ADD_CALLBACK_FUNCTION(Alouan, peekF);
ADD_CALLBACK_FUNCTION(Alouan, peekH);
ADD_CALLBACK_FUNCTION(Alouan, goFtoH);
@@ -287,7 +287,7 @@ IMPLEMENT_FUNCTION(16, Alouan, chapter3Handler)
label_callback1:
if (params->param2 != kTimeInvalid && getState()->time > kTime1989000) {
- if (Entity::timeCheckCar(kTime2119500, params->param5, 5, WRAP_SETUP_FUNCTION(Alouan, setup_peekH)))
+ if (Entity::timeCheckCar(kTime2119500, params->param2, 2, WRAP_SETUP_FUNCTION(Alouan, setup_peekF)))
break;
}
@@ -486,7 +486,7 @@ IMPLEMENT_FUNCTION(23, Alouan, hiding)
case 1:
setCallback(2);
- setup_enterExitCompartment("619AF", kObjectCompartment5);
+ setup_enterExitCompartment("619AF", kObjectCompartment6);
break;
case 2:
diff --git a/engines/lastexpress/entities/anna.cpp b/engines/lastexpress/entities/anna.cpp
index 52e975086a..2b31c7b5c8 100644
--- a/engines/lastexpress/entities/anna.cpp
+++ b/engines/lastexpress/entities/anna.cpp
@@ -22,6 +22,8 @@
#include "lastexpress/entities/anna.h"
+#include "lastexpress/entities/vesna.h"
+
#include "lastexpress/fight/fight.h"
#include "lastexpress/game/action.h"
@@ -41,23 +43,23 @@ namespace LastExpress {
Anna::Anna(LastExpressEngine *engine) : Entity(engine, kEntityAnna) {
ADD_CALLBACK_FUNCTION(Anna, reset);
- ADD_CALLBACK_FUNCTION(Anna, draw);
- ADD_CALLBACK_FUNCTION(Anna, updatePosition);
- ADD_CALLBACK_FUNCTION(Anna, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_S(Anna, draw);
+ ADD_CALLBACK_FUNCTION_SII(Anna, updatePosition);
+ ADD_CALLBACK_FUNCTION_SI(Anna, enterExitCompartment);
ADD_CALLBACK_FUNCTION(Anna, callbackActionOnDirection);
- ADD_CALLBACK_FUNCTION(Anna, callSavepoint);
- ADD_CALLBACK_FUNCTION(Anna, playSound);
+ ADD_CALLBACK_FUNCTION_SIIS(Anna, callSavepoint);
+ ADD_CALLBACK_FUNCTION_S(Anna, playSound);
ADD_CALLBACK_FUNCTION(Anna, callbackActionRestaurantOrSalon);
- ADD_CALLBACK_FUNCTION(Anna, savegame);
- ADD_CALLBACK_FUNCTION(Anna, updateEntity);
- ADD_CALLBACK_FUNCTION(Anna, updateFromTime);
+ ADD_CALLBACK_FUNCTION_II(Anna, savegame);
+ ADD_CALLBACK_FUNCTION_II(Anna, updateEntity);
+ ADD_CALLBACK_FUNCTION_I(Anna, updateFromTime);
ADD_CALLBACK_FUNCTION(Anna, practiceMusic);
- ADD_CALLBACK_FUNCTION(Anna, draw2);
- ADD_CALLBACK_FUNCTION(Anna, updateFromTicks);
- ADD_CALLBACK_FUNCTION(Anna, compartmentLogic);
+ ADD_CALLBACK_FUNCTION_SSI(Anna, draw2);
+ ADD_CALLBACK_FUNCTION_I(Anna, updateFromTicks);
+ ADD_CALLBACK_FUNCTION_IS(Anna, compartmentLogic);
ADD_CALLBACK_FUNCTION(Anna, chapter1);
- ADD_CALLBACK_FUNCTION(Anna, doWalkP1);
- ADD_CALLBACK_FUNCTION(Anna, diningLogic);
+ ADD_CALLBACK_FUNCTION_II(Anna, doWalkP1);
+ ADD_CALLBACK_FUNCTION_I(Anna, diningLogic);
ADD_CALLBACK_FUNCTION(Anna, fleeTyler);
ADD_CALLBACK_FUNCTION(Anna, waitDinner);
ADD_CALLBACK_FUNCTION(Anna, goDinner);
@@ -78,13 +80,13 @@ Anna::Anna(LastExpressEngine *engine) : Entity(engine, kEntityAnna) {
ADD_CALLBACK_FUNCTION(Anna, goVassili);
ADD_CALLBACK_FUNCTION(Anna, function37);
ADD_CALLBACK_FUNCTION(Anna, speakTatiana);
- ADD_CALLBACK_FUNCTION(Anna, doWalk1019);
+ ADD_CALLBACK_FUNCTION_II(Anna, doWalk1019);
ADD_CALLBACK_FUNCTION(Anna, leaveTatiana);
ADD_CALLBACK_FUNCTION(Anna, goBackToSleep);
ADD_CALLBACK_FUNCTION(Anna, chapter2);
ADD_CALLBACK_FUNCTION(Anna, inPart2);
ADD_CALLBACK_FUNCTION(Anna, chapter3);
- ADD_CALLBACK_FUNCTION(Anna, exitCompartment);
+ ADD_CALLBACK_FUNCTION_I(Anna, exitCompartment);
ADD_CALLBACK_FUNCTION(Anna, practicing);
ADD_CALLBACK_FUNCTION(Anna, goLunch);
ADD_CALLBACK_FUNCTION(Anna, lunch);
@@ -111,7 +113,7 @@ Anna::Anna(LastExpressEngine *engine) : Entity(engine, kEntityAnna) {
ADD_CALLBACK_FUNCTION(Anna, goSalon4);
ADD_CALLBACK_FUNCTION(Anna, returnCompartment4);
ADD_CALLBACK_FUNCTION(Anna, enterCompartmentCathFollowsAnna);
- ADD_CALLBACK_FUNCTION(Anna, doWalkCathFollowsAnna);
+ ADD_CALLBACK_FUNCTION_II(Anna, doWalkCathFollowsAnna);
ADD_CALLBACK_FUNCTION(Anna, letDownHair);
ADD_CALLBACK_FUNCTION(Anna, chapter5);
ADD_CALLBACK_FUNCTION(Anna, tiedUp);
@@ -125,7 +127,7 @@ Anna::Anna(LastExpressEngine *engine) : Entity(engine, kEntityAnna) {
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION(1, Anna, reset)
- Entity::reset(savepoint, true, true);
+ Entity::reset(savepoint, kClothes3, true);
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
@@ -311,7 +313,7 @@ IMPLEMENT_FUNCTION(12, Anna, practiceMusic)
}
params->param4 = 0;
- params->param5 = 0;
+ params->param5 = 1;
} else {
getSoundQueue()->removeFromQueue(kEntityAnna);
@@ -335,7 +337,7 @@ IMPLEMENT_FUNCTION(12, Anna, practiceMusic)
getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
getObjects()->update(kObjectOutsideAnnaCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
- if (getEntities()->isPlayerPosition(kCarRedSleeping, 49))
+ if (getEntities()->isPlayerPosition(kCarRedSleeping, 78))
getScenes()->loadSceneFromPosition(kCarRedSleeping, 49);
getEntities()->drawSequenceLeft(kEntityAnna, "418C");
@@ -357,7 +359,7 @@ IMPLEMENT_FUNCTION(12, Anna, practiceMusic)
if (getEntities()->isPlayerPosition(kCarRedSleeping, 60)) {
++params->param3;
if (params->param3 == 2) {
- setCallback(2);
+ setCallback(5);
setup_draw("418B");
}
}
@@ -606,6 +608,7 @@ IMPLEMENT_FUNCTION_II(17, Anna, doWalkP1, uint32, uint32)
break;
case kActionDefault:
+ getData()->inventoryItem = kItemNone;
if (getProgress().jacket == kJacketGreen) {
if (!getEvent(kEventGotALight) && !getEvent(kEventGotALightD) && !getEvent(kEventAugustPresentAnna) && !getEvent(kEventAugustPresentAnnaFirstIntroduction))
params->param3 = kItemInvalid;
@@ -729,7 +732,7 @@ IMPLEMENT_FUNCTION_I(18, Anna, diningLogic, TimeValue)
case 2:
getAction()->playAnimation(kEventDinerMindJoin);
- params->param2 &= 0xFFFFFFF7;
+ params->param2 &= 0xFFFFFF7F;
if (getProgress().jacket == kJacketGreen
&& !getEvent(kEventAnnaGiveScarfAsk)
@@ -992,6 +995,7 @@ IMPLEMENT_FUNCTION(25, Anna, eatingDinner)
break;
case 2:
+ setCallback(3);
setup_callbackActionRestaurantOrSalon();
break;
@@ -1021,10 +1025,10 @@ IMPLEMENT_FUNCTION(26, Anna, leaveDinner)
case kActionDefault:
getData()->location = kLocationOutsideCompartment;
- getEntities()->updatePositionExit(kEntityAnna, kCarRestaurant, 62);
+ getEntities()->updatePositionEnter(kEntityAnna, kCarRestaurant, 62);
setCallback(1);
- setup_callSavepoint("001L", kEntityTables0, kActionDrawTablesWithChairs, "001H");
+ setup_callSavepoint("001L", kEntityTables0, kActionDrawTablesWithChairs, "001M");
break;
case kActionCallback:
@@ -1222,7 +1226,7 @@ IMPLEMENT_FUNCTION(29, Anna, waitAugust)
case 2:
getAction()->playAnimation((getEvent(kEventAugustPresentAnna) || getEvent(kEventAugustPresentAnnaFirstIntroduction)) ? kEventAnnaConversationGoodNight : kEventAnnaIntroductionRejected);
- getData()->inventoryItem = (InventoryItem)(getData()->inventoryItem & kItemToggleLow);
+ getData()->inventoryItem = (InventoryItem)(getData()->inventoryItem & kItemToggleHigh);
if (getProgress().jacket == kJacketGreen
&& !getEvent(kEventAnnaGiveScarfAsk)
@@ -1698,7 +1702,7 @@ IMPLEMENT_FUNCTION_II(39, Anna, doWalk1019, CarIndex, EntityPosition)
case kActionCallback:
if (getCallback() == 1) {
- getAction()->playAnimation(getData()->direction == kDirectionNone ? kEventAnnaGoodNight : kEventAnnaGoodNightInverse);
+ getAction()->playAnimation(getData()->direction == kDirectionUp ? kEventAnnaGoodNight : kEventAnnaGoodNightInverse);
getData()->inventoryItem = kItemNone;
getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + (750 * (getData()->direction == kDirectionUp ? -1 : 1))), getData()->direction == kDirectionUp);
@@ -1807,8 +1811,8 @@ IMPLEMENT_FUNCTION(41, Anna, goBackToSleep)
if (!Entity::updateParameter(params->param2, getState()->time, 2700))
break;
- params->param5++;
- switch (params->param5) {
+ params->param1++;
+ switch (params->param1) {
default:
break;
@@ -2127,7 +2131,7 @@ label_callback_4:
break;
case kActionDefault:
- getEntities()->drawSequenceLeft(kEntityAnna, "026C");
+ getEntities()->drawSequenceLeft(kEntityAnna, "026c");
getData()->location = kLocationInsideCompartment;
setCallback(1);
@@ -2220,7 +2224,7 @@ IMPLEMENT_FUNCTION(50, Anna, leaveLunch)
case kActionDefault:
setCallback(1);
- setup_playSound("ann3141");
+ setup_playSound("Ann3141");
break;
case kActionCallback:
@@ -2266,7 +2270,7 @@ IMPLEMENT_FUNCTION(51, Anna, afterLunch)
break;
case kActionDefault:
- getSound()->playSound(kEntityAnna, "Aug3142", kFlagInvalid, 30);
+ getSound()->playSound(kEntityAnna, "Ann3142", kFlagInvalid, 30);
getEntities()->updatePositionEnter(kEntityAnna, kCarRestaurant, 57);
getEntities()->drawSequenceRight(kEntityAnna, "112A");
if (getEntities()->isInRestaurant(kEntityPlayer))
@@ -2401,7 +2405,7 @@ IMPLEMENT_FUNCTION(53, Anna, dressing)
if (params->param3) {
if (Entity::updateParameter(params->param6, getState()->time, 9000)) {
params->param4 = !params->param4;
- getEntities()->drawSequenceLeft(kEntityAnna, params->param4 ? "417B" : "417A");
+ getEntities()->drawSequenceLeft(kEntityAnna, params->param4 ? "417A" : "417B");
params->param6 = 0;
}
}
@@ -2549,7 +2553,7 @@ IMPLEMENT_FUNCTION(54, Anna, giveMaxToConductor2)
if (Entity::updateParameter(params->param6, getState()->time, 9000)) {
params->param4 = !params->param4;
- getEntities()->drawSequenceLeft(kEntityAnna, params->param4 ? "417B" : "417A");
+ getEntities()->drawSequenceLeft(kEntityAnna, params->param4 ? "417A" : "417B");
params->param6 = 0;
}
}
@@ -2729,7 +2733,7 @@ IMPLEMENT_FUNCTION(55, Anna, goConcert)
case 1:
getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
setCallback(2);
- setup_updateEntity(kCarRedSleeping, kPosition_9270);
+ setup_updateEntity(kCarKronos, kPosition_9270);
break;
case 2:
@@ -3072,7 +3076,7 @@ IMPLEMENT_FUNCTION(61, Anna, goBaggageCompartment)
getState()->timeDelta = 3;
setCallback(1);
- setup_savegame(kSavegameTypeIndex, 0);
+ setup_savegame(kSavegameTypeTime, 0);
break;
case kActionCallback:
@@ -3132,7 +3136,7 @@ IMPLEMENT_FUNCTION(62, Anna, function62)
break;
case kActionNone:
- if (getState()->time > kTime2259000 && !params->param2) {
+ if (params->param1 && getState()->time > kTime2259000 && !params->param2) {
params->param2 = 1;
getSavePoints()->push(kEntityAnna, kEntityVesna, kAction189299008);
setup_deadBaggageCompartment();
@@ -3222,6 +3226,7 @@ IMPLEMENT_FUNCTION(64, Anna, baggageFight)
getScenes()->loadSceneFromPosition(kCarBaggage, 96);
getProgress().field_54 = 0;
+ RESET_ENTITY_STATE(kEntityVesna, Vesna, setup_inCompartment);
getState()->time = kTime2266200;
setup_prepareVienna();
@@ -3302,7 +3307,7 @@ label_next:
case kAction1:
getData()->inventoryItem = kItemNone;
- getData()->location = kLocationInsideCompartment;
+ getEntityData(kEntityPlayer)->location = kLocationInsideCompartment;
setCallback(1);
setup_savegame(kSavegameTypeEvent, kEventAnnaConversation_34);
@@ -3329,9 +3334,11 @@ label_next:
break;
case kActionDrawScene:
- getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
- params->param1 = 0;
- params->param2 = 0;
+ if (params->param1 || params->param2) {
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ params->param1 = 0;
+ params->param2 = 0;
+ }
break;
case kActionCallback:
@@ -3743,7 +3750,7 @@ IMPLEMENT_FUNCTION(75, Anna, tiedUp)
else
getAction()->playAnimation(getEvent(kEventAnnaKissTrainHijacked) ? kEventAnnaBaggageTies3 : kEventAnnaBaggageTies4);
- getScenes()->loadSceneFromPosition(kCarBaggage, 8);
+ getScenes()->loadSceneFromPosition(kCarBaggageRear, 88);
setup_function76();
}
break;
@@ -3806,7 +3813,7 @@ IMPLEMENT_FUNCTION(77, Anna, readyToScore)
getObjects()->update(kObject106, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
getAction()->playAnimation(kEventAnnaDialogGoToJerusalem);
- getState()->time = kTimeCityConstantinople;
+ getState()->time = kTime4914000;
getState()->timeDelta = 0;
getSavePoints()->push(kEntityAnna, kEntityTatiana, kAction236060709);
@@ -3837,10 +3844,12 @@ IMPLEMENT_FUNCTION(78, Anna, kidnapped)
break;
}
- getState()->time = kTimeInvalid2;
+ if (getEntities()->isInSalon(kEntityPlayer)) {
+ getState()->time = kTime4920300;
- setCallback(getInventory()->get(kItemFirebird)->location == kObjectLocation4 ? 2 : 1);
- setup_savegame(kSavegameTypeEvent, getInventory()->get(kItemFirebird)->location == kObjectLocation4 ? kEventKronosHostageAnna : kEventKronosHostageAnnaNoFirebird);
+ setCallback(getInventory()->get(kItemFirebird)->location == kObjectLocation4 ? 2 : 1);
+ setup_savegame(kSavegameTypeEvent, getInventory()->get(kItemFirebird)->location == kObjectLocation4 ? kEventKronosHostageAnna : kEventKronosHostageAnnaNoFirebird);
+ }
break;
case kActionCallback:
@@ -3871,9 +3880,9 @@ IMPLEMENT_FUNCTION(79, Anna, waiting)
break;
case kActionEndSound:
- getState()->time = kTime5933;
+ getState()->time = kTime4923000;
setCallback(1);
- setup_savegame(kSavegameTypeEvent, kEventKahinaPunch);
+ setup_savegame(kSavegameTypeEvent, kEventKahinaPunchBaggageCarEntrance);
break;
case kActionDrawScene:
@@ -3883,7 +3892,7 @@ IMPLEMENT_FUNCTION(79, Anna, waiting)
}
if (getEntities()->isInSalon(kEntityPlayer) && !getEvent(kEventKahinaPunch)) {
- getState()->time = kTime5933;
+ getState()->time = kTime4923000;
setCallback(2);
setup_savegame(kSavegameTypeEvent, kEventKahinaPunch);
}
@@ -3908,7 +3917,7 @@ IMPLEMENT_FUNCTION(79, Anna, waiting)
break;
case 2:
- getAction()->playAnimation(kEventKahinaPunchSalon);
+ getAction()->playAnimation(kEventKahinaPunch);
break;
}
@@ -3932,17 +3941,17 @@ IMPLEMENT_FUNCTION(80, Anna, finalSequence)
case kActionEndSound:
getSound()->playSound(kEntityPlayer, "Kro5002", kFlagDefault);
- getState()->time = kTime4923000;
+ getState()->time = kTime4929300;
- setCallback(1);
- setup_savegame(kSavegameTypeEvent, kEventKronosBringFirebird);
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventKahinaPunch);
break;
case kActionDefault:
- getState()->time = kTime4929300;
+ getState()->time = kTime4923000;
- setCallback(2);
- setup_savegame(kSavegameTypeEvent, kEventKahinaPunch);
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventKronosBringFirebird);
break;
case kActionCallback:
@@ -3997,8 +4006,8 @@ IMPLEMENT_FUNCTION(81, Anna, openFirebird)
if (!Entity::updateParameter(params->param1, getState()->timeTicks, 180))
break;
- getSound()->playSound(kEntityTrain, "LIB069");
- getLogic()->gameOver(kSavegameTypeIndex, 2, kSceneNone, true);
+ getSound()->playSound(kEntityTrain, "LIB069", kFlagDefault);
+ getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, true);
break;
case kActionCallback:
diff --git a/engines/lastexpress/entities/august.cpp b/engines/lastexpress/entities/august.cpp
index 1176d9d473..01dc0b76c9 100644
--- a/engines/lastexpress/entities/august.cpp
+++ b/engines/lastexpress/entities/august.cpp
@@ -43,28 +43,28 @@ namespace LastExpress {
August::August(LastExpressEngine *engine) : Entity(engine, kEntityAugust) {
ADD_CALLBACK_FUNCTION(August, reset);
- ADD_CALLBACK_FUNCTION(August, updateFromTime);
- ADD_CALLBACK_FUNCTION(August, draw);
- ADD_CALLBACK_FUNCTION(August, updatePosition);
- ADD_CALLBACK_FUNCTION(August, enterExitCompartment);
- ADD_CALLBACK_FUNCTION(August, enterExitCompartment2);
- ADD_CALLBACK_FUNCTION(August, enterExitCompartment3);
+ ADD_CALLBACK_FUNCTION_I(August, updateFromTime);
+ ADD_CALLBACK_FUNCTION_S(August, draw);
+ ADD_CALLBACK_FUNCTION_SII(August, updatePosition);
+ ADD_CALLBACK_FUNCTION_SI(August, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_SI(August, enterExitCompartment2);
+ ADD_CALLBACK_FUNCTION_SI(August, enterExitCompartment3);
ADD_CALLBACK_FUNCTION(August, callbackActionOnDirection);
- ADD_CALLBACK_FUNCTION(August, callSavepoint);
- ADD_CALLBACK_FUNCTION(August, callSavepointNoDrawing);
- ADD_CALLBACK_FUNCTION(August, draw2);
- ADD_CALLBACK_FUNCTION(August, playSound);
- ADD_CALLBACK_FUNCTION(August, playSound16);
+ ADD_CALLBACK_FUNCTION_SIIS(August, callSavepoint);
+ ADD_CALLBACK_FUNCTION_IIS(August, callSavepointNoDrawing);
+ ADD_CALLBACK_FUNCTION_SSI(August, draw2);
+ ADD_CALLBACK_FUNCTION_S(August, playSound);
+ ADD_CALLBACK_FUNCTION_S(August, playSound16);
ADD_CALLBACK_FUNCTION(August, callbackActionRestaurantOrSalon);
- ADD_CALLBACK_FUNCTION(August, savegame);
- ADD_CALLBACK_FUNCTION(August, updateEntity);
- ADD_CALLBACK_FUNCTION(August, function17);
- ADD_CALLBACK_FUNCTION(August, updateEntity2);
- ADD_CALLBACK_FUNCTION(August, function19);
- ADD_CALLBACK_FUNCTION(August, function20);
- ADD_CALLBACK_FUNCTION(August, function21);
+ ADD_CALLBACK_FUNCTION_II(August, savegame);
+ ADD_CALLBACK_FUNCTION_II(August, updateEntity);
+ ADD_CALLBACK_FUNCTION_I(August, function17);
+ ADD_CALLBACK_FUNCTION_II(August, updateEntity2);
+ ADD_CALLBACK_FUNCTION_TYPE(August, function19, EntityParametersIISS);
+ ADD_CALLBACK_FUNCTION_TYPE(August, function20, EntityParametersISSI);
+ ADD_CALLBACK_FUNCTION_I(August, function21);
ADD_CALLBACK_FUNCTION(August, chapter1);
- ADD_CALLBACK_FUNCTION(August, function23);
+ ADD_CALLBACK_FUNCTION_I(August, function23);
ADD_CALLBACK_FUNCTION(August, dinner);
ADD_CALLBACK_FUNCTION(August, chapter1Handler);
ADD_CALLBACK_FUNCTION(August, function26);
@@ -82,8 +82,8 @@ August::August(LastExpressEngine *engine) : Entity(engine, kEntityAugust) {
ADD_CALLBACK_FUNCTION(August, function38);
ADD_CALLBACK_FUNCTION(August, function39);
ADD_CALLBACK_FUNCTION(August, chapter3);
- ADD_CALLBACK_FUNCTION(August, function41);
- ADD_CALLBACK_FUNCTION(August, function42);
+ ADD_CALLBACK_FUNCTION_II(August, function41);
+ ADD_CALLBACK_FUNCTION_III(August, function42);
ADD_CALLBACK_FUNCTION(August, chapter3Handler);
ADD_CALLBACK_FUNCTION(August, function44);
ADD_CALLBACK_FUNCTION(August, function45);
@@ -116,7 +116,7 @@ August::August(LastExpressEngine *engine) : Entity(engine, kEntityAugust) {
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION(1, August, reset)
- Entity::reset(savepoint, true);
+ Entity::reset(savepoint, kClothes2, true);
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
@@ -141,7 +141,7 @@ IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION_SI(6, August, enterExitCompartment2, ObjectIndex)
- Entity::enterExitCompartment(savepoint, kPosition_6470, kPosition_6130, kCarGreenSleeping, kObjectCompartment3, true);
+ Entity::enterExitCompartment(savepoint, kPosition_6470, kPosition_6130, kCarGreenSleeping, kObjectCompartment3, true, true);
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
@@ -250,7 +250,7 @@ IMPLEMENT_FUNCTION_I(17, August, function17, TimeValue)
ENTITY_PARAM(0, 1) = 0;
setCallback(1);
- setup_updateEntity(kCarRedSleeping, kPosition_540);
+ setup_updateEntity2(kCarRedSleeping, kPosition_540);
break;
case kActionCallback:
@@ -397,7 +397,7 @@ IMPLEMENT_FUNCTION_II(19, August, function19, bool, bool)
strcat((char *)&parameters->seq2, parameters->param1 ? "Fc" : "Dc");
setCallback(3);
- setup_enterExitCompartment((char *)&parameters->seq2, kObjectCompartment3);
+ setup_enterExitCompartment2((char *)&parameters->seq2, kObjectCompartment3);
break;
case 3:
@@ -451,7 +451,7 @@ IMPLEMENT_FUNCTION_I(20, August, function20, bool)
break;
}
- if (params->param1) {
+ if (parameters->param1) {
Common::String sequence = Common::String::format("%s%s", (char *)&parameters->seq1, "Gc");
assert(sequence.size() <= 13);
@@ -575,7 +575,7 @@ label_continue:
case kActionOpenDoor:
if (getProgress().chapter == kChapter1 && !getProgress().eventMetAugust && getProgress().jacket == kJacketGreen) {
getObjects()->update(kObjectOutsideTylerCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
- getData()->location = kLocationInsideCompartment;
+ getEntityData(kEntityPlayer)->location = kLocationInsideCompartment;
setCallback(6);
setup_savegame(kSavegameTypeEvent, kEventMeetAugustHisCompartment);
@@ -648,7 +648,7 @@ label_continue:
params->param2 = 0;
params->param3 = 0;
params->param5 = 0;
- params->param6 = 0;
+ params->param6 = 1;
CURRENT_PARAM(1, 1) = 0;
break;
@@ -694,7 +694,11 @@ label_continue:
case 11:
case 12:
case 13:
- getObjects()->update(kObjectCompartment3, kEntityAugust, kObjectLocation1, kCursorTalk, (getProgress().eventMetAugust || getProgress().jacket != kJacketGreen) ? kCursorNormal : kCursorHand);
+ {
+ CursorStyle cursor1 = (getCallback() == 12 || getCallback() == 13) ? kCursorNormal : kCursorTalk;
+ CursorStyle cursor2 = (getProgress().eventMetAugust || getProgress().jacket != kJacketGreen) ? kCursorNormal : kCursorHand;
+ getObjects()->update(kObjectCompartment3, kEntityAugust, kObjectLocation1, cursor1, cursor2);
+ }
if (getCallback() == 12 || getCallback() == 13) {
params->param2 = 0;
@@ -806,10 +810,10 @@ IMPLEMENT_FUNCTION_I(23, August, function23, TimeValue)
if (!params->param2) {
if (!CURRENT_PARAM(1, 3))
- CURRENT_PARAM(1, 3) = getState()->timeTicks + 45;
+ CURRENT_PARAM(1, 3) = getState()->timeTicks + 75;
if (CURRENT_PARAM(1, 3) >= getState()->timeTicks)
- break;
+ goto label_callback_9;
if (!params->param5) {
setCallback(8);
@@ -892,7 +896,7 @@ label_callback_9:
} else {
if (getProgress().eventCorpseMovedFromFloor && getProgress().jacket != kJacketBlood) {
- params->param7 = (getObjects()->get(kObjectCompartment1).model == kObjectModel1) ? 8 : 7;
+ params->param7 = (getObjects()->get(kObjectCompartment1).model == kObjectModel1) ? kEventMeetAugustTylerCompartmentBed : kEventMeetAugustTylerCompartment;
getObjects()->update(kObjectOutsideTylerCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
setCallback(4);
@@ -916,14 +920,14 @@ label_callback_9:
getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorNormal);
setCallback(17);
- setup_playSound("AUG1002A");
+ setup_playSound16("AUG1002A");
}
break;
case kActionOpenDoor:
if (getProgress().eventCorpseMovedFromFloor && getProgress().jacket != kJacketBlood) {
if (params->param3) {
- getData()->location = kLocationInsideCompartment;
+ getEntityData(kEntityPlayer)->location = kLocationInsideCompartment;
params->param7 = (getObjects()->get(kObjectCompartment1).model == kObjectModel1) ? kEventMeetAugustHisCompartmentBed : kEventMeetAugustHisCompartment;
} else {
@@ -1057,7 +1061,7 @@ label_callback_9:
break;
case 14:
- if (!params->param2)
+ if (!params->param3)
getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).status == kObjectLocation1 ? "LIB032" : "LIB014");
getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
@@ -1436,16 +1440,16 @@ IMPLEMENT_FUNCTION(29, August, function29)
break;
case kActionNone:
- if (!getProgress().field_28 || (params->param2 && params->param3 == kTimeInvalid))
+ if (!getProgress().field_28 || params->param2 || params->param3 == kTimeInvalid)
break;
- if (getState()->time < kTime1134000) {
+ if (getState()->time <= kTime1134000) {
if (!getEntities()->isInRestaurant(kEntityPlayer)
- || getSoundQueue()->isBuffered("MRB1076") || getSoundQueue()->isBuffered("MRB1078") || getSoundQueue()->isBuffered("MRB1078A"))
+ || getSoundQueue()->isBuffered("MRB1076") || getSoundQueue()->isBuffered("MRB1078") || getSoundQueue()->isBuffered("MRB1078A") || !params->param3)
params->param3 = (uint)getState()->time + 225;
- if (params->param3 > getState()->time)
+ if (params->param3 >= getState()->time)
break;
}
@@ -1528,7 +1532,7 @@ IMPLEMENT_FUNCTION(30, August, restaurant)
if (getProgress().eventMetAugust)
getData()->inventoryItem = kItemNone;
- getSound()->playSound(kEntityAugust, "Aug1003A");
+ getSound()->playSound(kEntityAugust, "AUG1003A");
} else {
getData()->inventoryItem = kItemNone;
getSavePoints()->push(kEntityAugust, kEntityAnna, kAction201437056);
@@ -1576,7 +1580,12 @@ IMPLEMENT_FUNCTION(30, August, restaurant)
break;
case 4:
-
+ getAction()->playAnimation(getProgress().eventMetAugust ? kEventAugustPresentAnna : kEventAugustPresentAnnaFirstIntroduction);
+ getSavePoints()->push(kEntityAugust, kEntityAnna, kAction201437056);
+ getEntities()->drawSequenceRight(kEntityAugust, getProgress().eventMetAugust ? "803GS" : "010P");
+ getScenes()->loadSceneFromPosition(kCarRestaurant, getProgress().eventMetAugust ? 55 : 65);
+ setCallback(getProgress().eventMetAugust ? 5 : 6);
+ setup_callbackActionOnDirection();
break;
case 5:
@@ -1623,7 +1632,7 @@ IMPLEMENT_FUNCTION(31, August, function31)
break;
case 2:
- setCallback(2);
+ setCallback(3);
setup_function21(kTime1161000);
break;
@@ -1648,7 +1657,7 @@ IMPLEMENT_FUNCTION(32, August, function32)
break;
case kActionNone:
- if (Entity::updateParameterTime(kTime1179000, (!getEntities()->isInSalon(kEntityAnna) || getEntities()->isInSalon(kEntityPlayer)), params->param6, 0)) {
+ if (params->param6 != kTimeInvalid && Entity::updateParameterTime(kTime1179000, (!getEntities()->isInSalon(kEntityAnna) || getEntities()->isInSalon(kEntityPlayer)), params->param6, 0)) {
getSavePoints()->push(kEntityAugust, kEntityAnna, kAction123712592);
}
@@ -2003,6 +2012,7 @@ IMPLEMENT_FUNCTION(38, August, function38)
case 2:
getScenes()->loadSceneFromItemPosition(kItem3);
getData()->location = kLocationInsideCompartment;
+ getEntities()->drawSequenceLeft(kEntityAugust, "109B");
break;
case 3:
@@ -2125,6 +2135,7 @@ IMPLEMENT_FUNCTION_II(41, August, function41, CarIndex, EntityPosition)
getData()->inventoryItem = kItemNone;
if (getEntities()->updateEntity(kEntityAugust, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ getData()->inventoryItem = kItemNone;
callbackAction();
break;
}
@@ -2232,6 +2243,7 @@ IMPLEMENT_FUNCTION(43, August, chapter3Handler)
// Set as same position as Anna
if (params->param1) {
getData()->entityPosition = getEntityData(kEntityAnna)->entityPosition;
+ getData()->location = getEntityData(kEntityAnna)->location;
getData()->car = getEntityData(kEntityAnna)->car;
}
@@ -2328,7 +2340,7 @@ IMPLEMENT_FUNCTION(44, August, function44)
getData()->location = kLocationOutsideCompartment;
setCallback(1);
- setup_updatePosition("122H", kCarRestaurant, 57);
+ setup_updatePosition("112H", kCarRestaurant, 57);
break;
case kActionCallback:
@@ -2417,10 +2429,10 @@ IMPLEMENT_FUNCTION_END
IMPLEMENT_FUNCTION(46, August, function46)
switch (savepoint.action) {
default:
- Entity::timeCheckCallback(kTime2088000, params->param1, 1, WRAP_SETUP_FUNCTION(August, setup_function47));
break;
case kActionNone:
+ Entity::timeCheckCallback(kTime2088000, params->param1, 1, WRAP_SETUP_FUNCTION(August, setup_function47));
break;
case kActionDrawScene:
@@ -2655,7 +2667,7 @@ IMPLEMENT_FUNCTION(52, August, function52)
case kActionKnock:
case kActionOpenDoor:
if (getInventory()->hasItem(kItemBriefcase)) {
- getData()->location = kLocationInsideCompartment;
+ getEntityData(kEntityPlayer)->location = kLocationInsideCompartment;
if (savepoint.action == kActionKnock)
getSound()->playSound(kEntityPlayer, "LIB012");
@@ -2779,13 +2791,13 @@ IMPLEMENT_FUNCTION(54, August, function54)
break;
case kActionNone:
- if (!params->param4 || params->param2 || getProgress().field_44)
+ if (!params->param3 || params->param1 || getProgress().field_44)
getData()->inventoryItem = kItemNone;
else
getData()->inventoryItem = kItemInvalid;
- if (!params->param2 && params->param1) {
- if (!Entity::updateParameter(params->param5, getState()->time, params->param1))
+ if (getEvent(kEventAugustTalkCigar) && params->param2 && !params->param1) {
+ if (!Entity::updateParameter(params->param4, getState()->time, 9000))
break;
getData()->inventoryItem = kItemNone;
@@ -2811,10 +2823,10 @@ IMPLEMENT_FUNCTION(54, August, function54)
break;
case kActionDrawScene:
- if (!getEntities()->isPlayerPosition(kCarRestaurant, 60) || params->param3) {
- if (!params->param2 && getEntities()->isPlayerPosition(kCarRestaurant, 57))
+ if (!getEntities()->isPlayerPosition(kCarRestaurant, 60) || params->param2 || params->param1) {
+ if (!params->param1 && getEntities()->isPlayerPosition(kCarRestaurant, 57))
getScenes()->loadSceneFromPosition(kCarRestaurant, 50);
- } else if (!params->param2) {
+ } else {
getEntities()->updatePositionEnter(kEntityAugust, kCarRestaurant, 57);
getEntities()->drawSequenceRight(kEntityAugust, "105C3");
}
@@ -2837,36 +2849,32 @@ IMPLEMENT_FUNCTION(54, August, function54)
getData()->location = kLocationInsideCompartment;
getSavePoints()->push(kEntityAugust, kEntityAbbot, kAction123712592);
getEntities()->drawSequenceLeft(kEntityAugust, "105B3");
- params->param4 = 1;
+ params->param3 = 1;
break;
case 3:
getAction()->playAnimation(kEventAugustTalkCigar);
- getEntities()->drawSequenceLeft(kEntityAugust, params->param3 ? "122B" : "105B3");
+ getEntities()->drawSequenceLeft(kEntityAugust, params->param2 ? "122B" : "105B3");
getScenes()->processScene();
- params->param1 = 9000;
- params->param4 = 0;
+ params->param3 = 0;
break;
}
break;
case kAction122288808:
getEntities()->drawSequenceLeft(kEntityAugust, "122B");
- params->param2 = 0;
-
- if (getEvent(kEventAugustTalkCigar))
- params->param1 = 9000;
+ params->param1 = 0;
break;
case kAction122358304:
getEntities()->drawSequenceLeft(kEntityAugust, "BLANK");
+ params->param1 = 1;
params->param2 = 1;
- params->param3 = 1;
break;
case kAction136196244:
- params->param2 = 1;
+ params->param1 = 1;
getData()->inventoryItem = kItemNone;
break;
}
@@ -2973,7 +2981,7 @@ IMPLEMENT_FUNCTION(58, August, chapter4Handler)
case kActionDefault:
setCallback(1);
- setup_function20(false);
+ setup_function20(true);
break;
case kActionCallback:
@@ -3047,7 +3055,6 @@ IMPLEMENT_FUNCTION(60, August, function60)
case kActionNone: {
bool pushSavepoint = false;
if (!params->param2) {
- pushSavepoint = true;
params->param2 = (uint)getState()->time + 450;
}
@@ -3252,7 +3259,7 @@ IMPLEMENT_FUNCTION(63, August, function63)
if (!Entity::updateParameter(params->param5, getState()->timeTicks, params->param1))
break;
- params->param2 = (params->param6 < 1 ? 1 : 0);
+ params->param2 = (params->param2 == 0 ? 1 : 0);
getEntities()->drawSequenceLeft(kEntityAugust, params->param2 ? "122H" : "122F");
diff --git a/engines/lastexpress/entities/boutarel.cpp b/engines/lastexpress/entities/boutarel.cpp
index 0385eb084d..2ee7136269 100644
--- a/engines/lastexpress/entities/boutarel.cpp
+++ b/engines/lastexpress/entities/boutarel.cpp
@@ -39,23 +39,23 @@ namespace LastExpress {
Boutarel::Boutarel(LastExpressEngine *engine) : Entity(engine, kEntityBoutarel) {
ADD_CALLBACK_FUNCTION(Boutarel, reset);
- ADD_CALLBACK_FUNCTION(Boutarel, playSound);
- ADD_CALLBACK_FUNCTION(Boutarel, draw);
- ADD_CALLBACK_FUNCTION(Boutarel, updateFromTime);
- ADD_CALLBACK_FUNCTION(Boutarel, updatePosition);
- ADD_CALLBACK_FUNCTION(Boutarel, enterExitCompartment);
- ADD_CALLBACK_FUNCTION(Boutarel, enterExitCompartment2);
+ ADD_CALLBACK_FUNCTION_S(Boutarel, playSound);
+ ADD_CALLBACK_FUNCTION_S(Boutarel, draw);
+ ADD_CALLBACK_FUNCTION_I(Boutarel, updateFromTime);
+ ADD_CALLBACK_FUNCTION_SII(Boutarel, updatePosition);
+ ADD_CALLBACK_FUNCTION_SI(Boutarel, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_SI(Boutarel, enterExitCompartment2);
ADD_CALLBACK_FUNCTION(Boutarel, callbackActionOnDirection);
ADD_CALLBACK_FUNCTION(Boutarel, callbackActionRestaurantOrSalon);
- ADD_CALLBACK_FUNCTION(Boutarel, updateEntity);
- ADD_CALLBACK_FUNCTION(Boutarel, function11);
+ ADD_CALLBACK_FUNCTION_II(Boutarel, updateEntity);
+ ADD_CALLBACK_FUNCTION_I(Boutarel, function11);
ADD_CALLBACK_FUNCTION(Boutarel, enterTableWithMmeBoutarel);
ADD_CALLBACK_FUNCTION(Boutarel, leaveTableWithMmeBoutarel);
- ADD_CALLBACK_FUNCTION(Boutarel, function14);
- ADD_CALLBACK_FUNCTION(Boutarel, function15);
- ADD_CALLBACK_FUNCTION(Boutarel, function16);
- ADD_CALLBACK_FUNCTION(Boutarel, function17);
- ADD_CALLBACK_FUNCTION(Boutarel, function18);
+ ADD_CALLBACK_FUNCTION_I(Boutarel, function14);
+ ADD_CALLBACK_FUNCTION_IS(Boutarel, function15);
+ ADD_CALLBACK_FUNCTION_IS(Boutarel, function16);
+ ADD_CALLBACK_FUNCTION_IS(Boutarel, function17);
+ ADD_CALLBACK_FUNCTION_I(Boutarel, function18);
ADD_CALLBACK_FUNCTION(Boutarel, chapter1);
ADD_CALLBACK_FUNCTION(Boutarel, function20);
ADD_CALLBACK_FUNCTION(Boutarel, chapter1Handler);
@@ -257,8 +257,8 @@ IMPLEMENT_FUNCTION(12, Boutarel, enterTableWithMmeBoutarel)
if (getEntities()->isInSalon(kEntityPlayer)) {
getEntities()->updateFrame(kEntityBoutarel);
- getEntityData(kEntityMmeBoutarel)->location = getData()->location;
- getEntityData(kEntityTables2)->location = getData()->location;
+ getEntityData(kEntityMmeBoutarel)->field_4A1 = getData()->field_4A1;
+ getEntityData(kEntityTables2)->field_4A1 = getData()->field_4A1;
}
break;
}
@@ -836,7 +836,7 @@ IMPLEMENT_FUNCTION(24, Boutarel, chapter2Handler)
break;
case kActionNone:
- Entity::timeCheckCallback(kTime1759500, params->param2, 1, false, WRAP_SETUP_FUNCTION_B(Boutarel, setup_function14));
+ Entity::timeCheckCallback(kTime1759500, params->param2, 1, true, WRAP_SETUP_FUNCTION_B(Boutarel, setup_function14));
break;
case kActionDefault:
@@ -961,7 +961,7 @@ IMPLEMENT_FUNCTION(29, Boutarel, function29)
}
}
- Entity::timeCheckCallback(kTime2002500, params->param4, 1, true, WRAP_SETUP_FUNCTION_B(Boutarel, setup_function14));
+ Entity::timeCheckCallback(kTime2002500, params->param4, 2, true, WRAP_SETUP_FUNCTION_B(Boutarel, setup_function14));
break;
case kActionDefault:
@@ -974,7 +974,7 @@ IMPLEMENT_FUNCTION(29, Boutarel, function29)
break;
case 1:
- Entity::timeCheckCallback(kTime2002500, params->param4, 1, true, WRAP_SETUP_FUNCTION_B(Boutarel, setup_function14));
+ Entity::timeCheckCallback(kTime2002500, params->param4, 2, true, WRAP_SETUP_FUNCTION_B(Boutarel, setup_function14));
break;
case 2:
diff --git a/engines/lastexpress/entities/chapters.cpp b/engines/lastexpress/entities/chapters.cpp
index f1a7d02384..8ed458c89c 100644
--- a/engines/lastexpress/entities/chapters.cpp
+++ b/engines/lastexpress/entities/chapters.cpp
@@ -72,9 +72,9 @@
namespace LastExpress {
Chapters::Chapters(LastExpressEngine *engine) : Entity(engine, kEntityChapters) {
- ADD_CALLBACK_FUNCTION(Chapters, savegame);
- ADD_CALLBACK_FUNCTION(Chapters, enterStation);
- ADD_CALLBACK_FUNCTION(Chapters, exitStation);
+ ADD_CALLBACK_FUNCTION_II(Chapters, savegame);
+ ADD_CALLBACK_FUNCTION_SI(Chapters, enterStation);
+ ADD_CALLBACK_FUNCTION_S(Chapters, exitStation);
ADD_CALLBACK_FUNCTION(Chapters, chapter1);
ADD_CALLBACK_FUNCTION(Chapters, resetMainEntities);
ADD_CALLBACK_FUNCTION(Chapters, firstDream);
@@ -92,8 +92,8 @@ Chapters::Chapters(LastExpressEngine *engine) : Entity(engine, kEntityChapters)
ADD_CALLBACK_FUNCTION(Chapters, chapter4Init);
ADD_CALLBACK_FUNCTION(Chapters, chapter4Handler);
ADD_CALLBACK_FUNCTION(Chapters, chapter5);
- ADD_CALLBACK_FUNCTION(Chapters, chapter4Init);
- ADD_CALLBACK_FUNCTION(Chapters, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Chapters, chapter5Init);
+ ADD_CALLBACK_FUNCTION(Chapters, chapter5Handler);
}
//////////////////////////////////////////////////////////////////////////
@@ -135,6 +135,7 @@ IMPLEMENT_FUNCTION(5, Chapters, resetMainEntities)
RESET_ENTITY_STATE(kEntityHadija, Hadija, setup_reset);
RESET_ENTITY_STATE(kEntityIvo, Ivo, setup_reset);
RESET_ENTITY_STATE(kEntityKahina, Kahina, setup_reset);
+ RESET_ENTITY_STATE(kEntityKronos, Kronos, setup_reset);
RESET_ENTITY_STATE(kEntityMmeBoutarel, MmeBoutarel, setup_reset);
RESET_ENTITY_STATE(kEntityMahmud, Mahmud, setup_reset);
RESET_ENTITY_STATE(kEntityMax, Max, setup_reset);
@@ -258,17 +259,13 @@ IMPLEMENT_FUNCTION(6, Chapters, firstDream)
if (getSoundQueue()->isBuffered("ZFX1005"))
getSoundQueue()->processEntry("ZFX1005");
-
- if (getSoundQueue()->isBuffered("ZFX1006"))
+ else if (getSoundQueue()->isBuffered("ZFX1006"))
getSoundQueue()->processEntry("ZFX1006");
-
- if (getSoundQueue()->isBuffered("ZFX1007"))
+ else if (getSoundQueue()->isBuffered("ZFX1007"))
getSoundQueue()->processEntry("ZFX1007");
-
- if (getSoundQueue()->isBuffered("ZFX1007A"))
+ else if (getSoundQueue()->isBuffered("ZFX1007A"))
getSoundQueue()->processEntry("ZFX1007A");
-
- if (getSoundQueue()->isBuffered("ZFX1007B"))
+ else if (getSoundQueue()->isBuffered("ZFX1007B"))
getSoundQueue()->processEntry("ZFX1007B");
getSound()->playSound(kEntityPlayer, "MUS008", kFlagDefault);
@@ -321,7 +318,7 @@ IMPLEMENT_FUNCTION(7, Chapters, chapter1Init)
getProgress().chapter = kChapter1;
getSoundQueue()->resetState();
- getState()->time = kTimeChapter1;
+ getState()->time = kTimeStartGame;
getState()->timeDelta = 0;
getProgress().isTrainRunning = true;
getProgress().portrait = kPortraitOriginal;
@@ -376,8 +373,8 @@ IMPLEMENT_FUNCTION(7, Chapters, chapter1Init)
getObjects()->update(kObject65, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
getObjects()->update(kObject69, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
getObjects()->update(kObject98, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
- getObjects()->update(kObjectHandleOutsideLeft, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHandKnock);
- getObjects()->update(kObjectHandleOutsideRight, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHandKnock);
+ getObjects()->update(kObjectHandleOutsideLeft, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHand);
+ getObjects()->update(kObjectHandleOutsideRight, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHand);
getObjects()->update(kObject101, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
setup_chapter1Handler();
@@ -972,7 +969,7 @@ label_callback_4:
break;
label_callback_5:
- if (timeCheckExitStation(kTimeEnterWels, CURRENT_PARAM(1, 3), 6, "Wels"))
+ if (timeCheckExitStation(kTimeExitWels, CURRENT_PARAM(1, 3), 6, "Wels"))
break;
label_callback_6:
@@ -980,7 +977,7 @@ label_callback_6:
break;
label_callback_7:
- if (timeCheckExitStation(kTimeCityLinz, CURRENT_PARAM(1, 5), 8, "Linz"))
+ if (timeCheckExitStation(kTimeExitLinz, CURRENT_PARAM(1, 5), 8, "Linz"))
break;
label_callback_8:
@@ -1024,7 +1021,7 @@ label_callback_8:
getSound()->playSteam((CityIndex)ENTITY_PARAM(0, 4));
ENTITY_PARAM(0, 2) = 0;
- if (params->param1)
+ if (params->param3)
setup_viennaEvents();
break;
@@ -1086,6 +1083,30 @@ IMPLEMENT_FUNCTION(16, Chapters, viennaEvents)
break;
case kActionDefault:
+ getEntityData(kEntityPlayer)->car = kCarLocomotive;
+ if (getSoundQueue()->isBuffered(kEntityAbbot))
+ getSoundQueue()->processEntry(kEntityAbbot);
+
+ if (!getEvent(kEventAugustBringBriefcase)) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventViennaAugustUnloadGuns);
+ break;
+ }
+
+ if (getInventory()->get(kItemFirebird)->location == kObjectLocation5) {
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventViennaKronosFirebird);
+ break;
+ }
+
+ if (ENTITY_PARAM(0, 1)) {
+ setCallback(3);
+ setup_savegame(kSavegameTypeEvent, kEventVergesAnnaDead);
+ break;
+ }
+
+ setCallback(4);
+ setup_savegame(kSavegameTypeEvent, kEventViennaContinueGame);
break;
case kActionCallback:
@@ -1108,10 +1129,7 @@ IMPLEMENT_FUNCTION(16, Chapters, viennaEvents)
if (getEvent(kEventKronosBringEggCeiling))
getLogic()->gameOver(kSavegameTypeEvent2, kEventKronosBringEggCeiling, kSceneGameOverVienna1, true);
else if (getEvent(kEventKronosBringEgg)) {
- if (getEvent(kEventKronosBringEggCeiling))
- getLogic()->gameOver(kSavegameTypeEvent2, kEventKronosBringEggCeiling, kSceneGameOverVienna1, true);
- else
- getLogic()->gameOver(kSavegameTypeTime, kTime2155500, kSceneGameOverVienna1, true);
+ getLogic()->gameOver(kSavegameTypeTime, kTime2155500, kSceneGameOverVienna1, true);
} else {
if (getProgress().field_C0) {
if (getEvent(kEventKronosReturnBriefcase))
@@ -1733,7 +1751,7 @@ IMPLEMENT_FUNCTION(22, Chapters, chapter5Handler)
setCallback(1);
setup_savegame(kSavegameTypeEvent, kEventTrainStopped);
} else {
- getLogic()->gameOver(kSavegameTypeTime, kTimeTrainStopped2, kSceneGameOverTrainStopped, true);
+ getLogic()->gameOver(kSavegameTypeTime, kTime2934000, kSceneGameOverTrainStopped, true);
}
break;
diff --git a/engines/lastexpress/entities/cooks.cpp b/engines/lastexpress/entities/cooks.cpp
index 749e93999b..34cd4a787f 100644
--- a/engines/lastexpress/entities/cooks.cpp
+++ b/engines/lastexpress/entities/cooks.cpp
@@ -35,8 +35,8 @@
namespace LastExpress {
Cooks::Cooks(LastExpressEngine *engine) : Entity(engine, kEntityCooks) {
- ADD_CALLBACK_FUNCTION(Cooks, draw);
- ADD_CALLBACK_FUNCTION(Cooks, playSound);
+ ADD_CALLBACK_FUNCTION_S(Cooks, draw);
+ ADD_CALLBACK_FUNCTION_S(Cooks, playSound);
ADD_CALLBACK_FUNCTION(Cooks, uptrainVersion);
ADD_CALLBACK_FUNCTION(Cooks, downtrainVersion);
ADD_CALLBACK_FUNCTION(Cooks, chapter1);
@@ -98,26 +98,17 @@ IMPLEMENT_FUNCTION(3, Cooks, uptrainVersion)
break;
}
- if (getEntities()->isPlayerPosition(kCarRestaurant, 46)) {
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 76)) {
getEntities()->drawSequenceLeft(kEntityCooks, "308D");
- if (!getSoundQueue()->isBuffered(kEntityCooks)) {
- if (params->param1) {
- if (!getEntities()->hasValidFrame(kEntityCooks)) {
- getSound()->playSound(kEntityCooks, "LIB015");
- getEntities()->clearSequences(kEntityCooks);
- callbackAction();
- }
- break;
- }
-
+ if (!getSoundQueue()->isBuffered(kEntityCooks) && !params->param1) {
// Kitchen apprentice getting a lesson :D
getSound()->playSound(kEntityCooks, "KIT1011A");
params->param1 = 1;
}
}
- if (params->param1 && !getEntities()->hasValidFrame(kEntityCooks)) {
+ if (params->param1 && !getEntities()->hasValidFrame(kEntityCooks) && !getSoundQueue()->isBuffered(kEntityCooks)) {
getSound()->playSound(kEntityCooks, "LIB015");
getEntities()->clearSequences(kEntityCooks);
callbackAction();
@@ -159,22 +150,21 @@ IMPLEMENT_FUNCTION(4, Cooks, downtrainVersion)
switch (getProgress().chapter) {
default:
+ getSound()->playSound(kEntityCooks, "KIT1011");
+ setCallback(3);
+ setup_draw("308B");
break;
case kChapter1:
- setCallback(2);
- setup_playSound("ZFX1011");
+ setCallback(1);
+ setup_playSound("KIT1010");
break;
case kChapter3:
setCallback(2);
- setup_playSound("ZFX1011");
+ setup_playSound("KIT1012");
break;
}
-
- getSound()->playSound(kEntityCooks, "KIT1011");
- setCallback(3);
- setup_draw("308B");
break;
case kActionDrawScene:
@@ -187,23 +177,14 @@ IMPLEMENT_FUNCTION(4, Cooks, downtrainVersion)
if (getEntities()->isPlayerPosition(kCarRestaurant, 80)) {
getEntities()->drawSequenceLeft(kEntityCooks, "308D");
- if (!getSoundQueue()->isBuffered(kEntityCooks)) {
- if (params->param1) {
- if (!getEntities()->hasValidFrame(kEntityCooks)) {
- getSound()->playSound(kEntityCooks, "LIB015");
- getEntities()->clearSequences(kEntityCooks);
- callbackAction();
- }
- break;
- }
-
+ if (!getSoundQueue()->isBuffered(kEntityCooks) && !params->param1) {
// Kitchen apprentice getting a lesson :D
getSound()->playSound(kEntityCooks, "KIT1011A");
params->param1 = 1;
}
}
- if (params->param1 && !getEntities()->hasValidFrame(kEntityCooks)) {
+ if (params->param1 && !getEntities()->hasValidFrame(kEntityCooks) && !getSoundQueue()->isBuffered(kEntityCooks)) {
getSound()->playSound(kEntityCooks, "LIB015");
getEntities()->clearSequences(kEntityCooks);
callbackAction();
@@ -225,7 +206,7 @@ IMPLEMENT_FUNCTION(4, Cooks, downtrainVersion)
case 3:
getEntities()->drawSequenceLeft(kEntityCooks, "308C");
getEntities()->updatePositionExit(kEntityCooks, kCarRestaurant, 75);
- getEntities()->updatePositionEnter(kEntityCooks, kCarRestaurant, 78);
+ getEntities()->updatePositionExit(kEntityCooks, kCarRestaurant, 78);
break;
}
break;
@@ -388,6 +369,9 @@ IMPLEMENT_FUNCTION(9, Cooks, inKitchenBreakfast)
break;
case kActionDrawScene:
+ if (!getEntities()->isInKitchen(kEntityPlayer))
+ break;
+
if (params->param2) {
setCallback(1);
setup_playSound("ZFX1011");
diff --git a/engines/lastexpress/entities/coudert.cpp b/engines/lastexpress/entities/coudert.cpp
index 66e6b83620..dd1377da87 100644
--- a/engines/lastexpress/entities/coudert.cpp
+++ b/engines/lastexpress/entities/coudert.cpp
@@ -39,25 +39,25 @@ namespace LastExpress {
Coudert::Coudert(LastExpressEngine *engine) : Entity(engine, kEntityCoudert) {
ADD_CALLBACK_FUNCTION(Coudert, reset);
- ADD_CALLBACK_FUNCTION(Coudert, bloodJacket);
- ADD_CALLBACK_FUNCTION(Coudert, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_S(Coudert, bloodJacket);
+ ADD_CALLBACK_FUNCTION_SI(Coudert, enterExitCompartment);
ADD_CALLBACK_FUNCTION(Coudert, callbackActionOnDirection);
- ADD_CALLBACK_FUNCTION(Coudert, enterExitCompartment2);
- ADD_CALLBACK_FUNCTION(Coudert, playSound);
- ADD_CALLBACK_FUNCTION(Coudert, playSound16);
- ADD_CALLBACK_FUNCTION(Coudert, savegame);
- ADD_CALLBACK_FUNCTION(Coudert, updateEntity);
- ADD_CALLBACK_FUNCTION(Coudert, updateFromTime);
- ADD_CALLBACK_FUNCTION(Coudert, updateFromTicks);
- ADD_CALLBACK_FUNCTION(Coudert, excuseMe);
- ADD_CALLBACK_FUNCTION(Coudert, function13);
- ADD_CALLBACK_FUNCTION(Coudert, function14);
- ADD_CALLBACK_FUNCTION(Coudert, function15);
+ ADD_CALLBACK_FUNCTION_SIII(Coudert, enterExitCompartment2);
+ ADD_CALLBACK_FUNCTION_S(Coudert, playSound);
+ ADD_CALLBACK_FUNCTION_S(Coudert, playSound16);
+ ADD_CALLBACK_FUNCTION_II(Coudert, savegame);
+ ADD_CALLBACK_FUNCTION_II(Coudert, updateEntity);
+ ADD_CALLBACK_FUNCTION_I(Coudert, updateFromTime);
+ ADD_CALLBACK_FUNCTION_I(Coudert, updateFromTicks);
+ ADD_CALLBACK_FUNCTION_I(Coudert, excuseMe);
+ ADD_CALLBACK_FUNCTION_II(Coudert, function13);
+ ADD_CALLBACK_FUNCTION_I(Coudert, function14);
+ ADD_CALLBACK_FUNCTION_I(Coudert, function15);
ADD_CALLBACK_FUNCTION(Coudert, function16);
- ADD_CALLBACK_FUNCTION(Coudert, function17);
+ ADD_CALLBACK_FUNCTION_I(Coudert, function17);
ADD_CALLBACK_FUNCTION(Coudert, function18);
- ADD_CALLBACK_FUNCTION(Coudert, function19);
- ADD_CALLBACK_FUNCTION(Coudert, function20);
+ ADD_CALLBACK_FUNCTION_I(Coudert, function19);
+ ADD_CALLBACK_FUNCTION_II(Coudert, function20);
ADD_CALLBACK_FUNCTION(Coudert, function21);
ADD_CALLBACK_FUNCTION(Coudert, function22);
ADD_CALLBACK_FUNCTION(Coudert, function23);
@@ -67,12 +67,12 @@ Coudert::Coudert(LastExpressEngine *engine) : Entity(engine, kEntityCoudert) {
ADD_CALLBACK_FUNCTION(Coudert, function27);
ADD_CALLBACK_FUNCTION(Coudert, visitCompartmentB);
ADD_CALLBACK_FUNCTION(Coudert, visitCompartmentA);
- ADD_CALLBACK_FUNCTION(Coudert, function30);
- ADD_CALLBACK_FUNCTION(Coudert, function31);
+ ADD_CALLBACK_FUNCTION_TYPE2(Coudert, function30, EntityParametersI5S, EntityParametersSIIS);
+ ADD_CALLBACK_FUNCTION_I(Coudert, function31);
ADD_CALLBACK_FUNCTION(Coudert, function32);
ADD_CALLBACK_FUNCTION(Coudert, function33);
- ADD_CALLBACK_FUNCTION(Coudert, function34);
- ADD_CALLBACK_FUNCTION(Coudert, function35);
+ ADD_CALLBACK_FUNCTION_I(Coudert, function34);
+ ADD_CALLBACK_FUNCTION_I(Coudert, function35);
ADD_CALLBACK_FUNCTION(Coudert, chapter1);
ADD_CALLBACK_FUNCTION(Coudert, function37);
ADD_CALLBACK_FUNCTION(Coudert, function38);
@@ -84,7 +84,7 @@ Coudert::Coudert(LastExpressEngine *engine) : Entity(engine, kEntityCoudert) {
ADD_CALLBACK_FUNCTION(Coudert, chapter3);
ADD_CALLBACK_FUNCTION(Coudert, function45);
ADD_CALLBACK_FUNCTION(Coudert, function46);
- ADD_CALLBACK_FUNCTION(Coudert, function47);
+ ADD_CALLBACK_FUNCTION_I(Coudert, function47);
ADD_CALLBACK_FUNCTION(Coudert, function48);
ADD_CALLBACK_FUNCTION(Coudert, function49);
ADD_CALLBACK_FUNCTION(Coudert, function50);
@@ -105,7 +105,7 @@ Coudert::Coudert(LastExpressEngine *engine) : Entity(engine, kEntityCoudert) {
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION(1, Coudert, reset)
- Entity::reset(savepoint, true);
+ Entity::reset(savepoint, kClothes1, true);
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
@@ -115,7 +115,7 @@ IMPLEMENT_FUNCTION_S(2, Coudert, bloodJacket)
break;
case kActionNone:
- Entity::savegameBloodJacket();
+ Entity::savegameBloodJacket(1);
break;
case kActionExitCompartment:
@@ -142,7 +142,7 @@ IMPLEMENT_FUNCTION_SI(3, Coudert, enterExitCompartment, ObjectIndex)
break;
case kActionNone:
- Entity::savegameBloodJacket();
+ Entity::savegameBloodJacket(1);
return;
case kActionCallback:
@@ -168,7 +168,7 @@ IMPLEMENT_FUNCTION(4, Coudert, callbackActionOnDirection)
break;
}
- Entity::savegameBloodJacket();
+ Entity::savegameBloodJacket(1);
break;
case kActionExitCompartment:
@@ -191,7 +191,7 @@ IMPLEMENT_FUNCTION_SIII(5, Coudert, enterExitCompartment2, ObjectIndex, EntityPo
break;
case kActionNone:
- Entity::savegameBloodJacket();
+ Entity::savegameBloodJacket(1);
return;
case kActionCallback:
@@ -212,7 +212,7 @@ IMPLEMENT_FUNCTION_S(6, Coudert, playSound)
break;
case kActionNone:
- Entity::savegameBloodJacket();
+ Entity::savegameBloodJacket(1);
break;
case kActionEndSound:
@@ -241,7 +241,7 @@ IMPLEMENT_FUNCTION_NOSETUP(7, Coudert, playSound16)
break;
case kActionNone:
- Entity::savegameBloodJacket();
+ Entity::savegameBloodJacket(1);
break;
case kActionEndSound:
@@ -354,7 +354,7 @@ IMPLEMENT_FUNCTION_I(10, Coudert, updateFromTime, uint32)
break;
case kActionNone:
- Entity::savegameBloodJacket();
+ Entity::savegameBloodJacket(1);
if (!Entity::updateParameter(params->param2, getState()->time, params->param1))
break;
@@ -378,7 +378,7 @@ IMPLEMENT_FUNCTION_I(11, Coudert, updateFromTicks, uint32)
break;
case kActionNone:
- Entity::savegameBloodJacket();
+ Entity::savegameBloodJacket(1);
if (!Entity::updateParameter(params->param2, getState()->timeTicks, params->param1))
break;
@@ -453,7 +453,8 @@ IMPLEMENT_FUNCTION_II(13, Coudert, function13, bool, EntityIndex)
break;
case kActionNone:
- Entity::savegameBloodJacket();
+ if (Entity::savegameBloodJacket(1))
+ break;
if (!params->param2 && !params->param3) {
@@ -576,7 +577,7 @@ IMPLEMENT_FUNCTION_I(14, Coudert, function14, EntityIndex)
break;
case kActionNone:
- Entity::savegameBloodJacket();
+ Entity::savegameBloodJacket(4);
break;
case kActionDefault:
@@ -678,7 +679,7 @@ IMPLEMENT_FUNCTION_I(15, Coudert, function15, bool)
if (params->param1)
getSound()->playSound(kEntityCoudert, "Tat3163");
else
- getSound()->playSound(kEntityCoudert, (getProgress().chapter != kChapter3 || getState()->time > kTime1449000) ? "Tat3162A" : "Tat3161A");
+ getSound()->playSound(kEntityCoudert, (getProgress().chapter != kChapter3 || getState()->time >= kTime1449000) ? "Tat3162A" : "Tat3161A");
setCallback(3);
setup_enterExitCompartment("627Xb", kObjectCompartmentB);
@@ -808,6 +809,7 @@ IMPLEMENT_FUNCTION(18, Coudert, function18)
if (ENTITY_PARAM(0, 3) || ENTITY_PARAM(0, 5) || ENTITY_PARAM(0, 4)) {
getEntities()->drawSequenceLeft(kEntityCoudert, "627K");
getScenes()->loadSceneFromItemPosition(kItem5);
+ ENTITY_PARAM(2, 1) = 1;
callbackAction();
break;
@@ -1305,7 +1307,7 @@ IMPLEMENT_FUNCTION(26, Coudert, function26)
break;
case kActionNone:
- if (params->param1) {
+ if (!params->param1) {
if (!Entity::updateParameter(params->param2, getState()->timeTicks, 75))
break;
@@ -1963,7 +1965,7 @@ IMPLEMENT_FUNCTION(36, Coudert, chapter1)
break;
case kActionNone:
- Entity::timeCheckCallback(kTimeChapter1, params->param1, 1, WRAP_SETUP_FUNCTION(Coudert, setup_chapter1Handler));
+ Entity::timeCheckCallback(kTimeChapter1, params->param1, 1, WRAP_SETUP_FUNCTION(Coudert, setup_function18));
break;
case kActionDefault:
@@ -2088,7 +2090,7 @@ switch (savepoint.action) {
case kAction191477936:
getData()->entityPosition = kPosition_4070;
getData()->location = kLocationOutsideCompartment;
- getObjects()->update(kObjectCompartment4, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
setCallback(1);
setup_updateEntity(kCarRedSleeping, kPosition_2000);
@@ -2152,7 +2154,7 @@ IMPLEMENT_FUNCTION(39, Coudert, function39)
case 7:
setCallback(8);
- setup_enterExitCompartment("MME1151", kObjectCompartmentD);
+ setup_enterExitCompartment("697Ad", kObjectCompartmentD);
break;
case 8:
@@ -2271,7 +2273,7 @@ label_callback_9:
if (ENTITY_PARAM(0, 1) && !getSoundQueue()->isBuffered(kEntityCoudert))
getSound()->playSound(kEntityCoudert, rnd(2) ? "JAC1065" : "JAC1065A");
- if (getState()->time > kTime1107000 && !ENTITY_PARAM(0, 1) && !getEvent(kEventVassiliSeizure)) {
+ if (getState()->time > kTime1107000 && !params->param1 && !getEvent(kEventVassiliSeizure)) {
getData()->inventoryItem = kItemNone;
setCallback(10);
@@ -2601,7 +2603,7 @@ IMPLEMENT_FUNCTION(43, Coudert, function43)
}
label_callback1:
- if (!ENTITY_PARAM(1, 1)) {
+ if (ENTITY_PARAM(1, 1)) {
setCallback(2);
setup_function15(false);
break;
@@ -3366,7 +3368,7 @@ IMPLEMENT_FUNCTION(51, Coudert, function51)
case kActionNone:
if (getState()->time > kTime2133000 && !getProgress().field_40) {
- getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentB);
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentB, true);
getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
@@ -3439,7 +3441,7 @@ IMPLEMENT_FUNCTION(51, Coudert, function51)
break;
case 5:
- setCallback(5);
+ setCallback(6);
setup_function18();
break;
}
@@ -4095,7 +4097,7 @@ IMPLEMENT_FUNCTION(62, Coudert, function62)
case 3:
++params->param3;
- if (params->param3 == 1 || params->param2) {
+ if (params->param3 == 1 || params->param3 == 2) {
getObjects()->update(kObjectCompartmentH, kEntityCoudert, kObjectLocation1, kCursorNormal, kCursorNormal);
setCallback(params->param3 == 1 ? 4 : 5);
setup_playSound(params->param3 == 1 ? "Jac5002" : "Jac5002A");
diff --git a/engines/lastexpress/entities/entity.cpp b/engines/lastexpress/entities/entity.cpp
index 170248de52..faf937c3e0 100644
--- a/engines/lastexpress/entities/entity.cpp
+++ b/engines/lastexpress/entities/entity.cpp
@@ -147,11 +147,35 @@ void EntityData::updateParameters(uint32 index) const {
error("[EntityData::updateParameters] Invalid param index to update (was:%d, max:32)", index);
}
-void EntityData::saveLoadWithSerializer(Common::Serializer &s) {
- for (uint i = 0; i < ARRAYSIZE(_parameters); i++)
- _parameters[i].saveLoadWithSerializer(s);
+void EntityData::saveLoadWithSerializer(Common::Serializer &s, const Common::Array<TypeSetter>* paramsTypeSetters) {
+ if (s.isSaving()) {
+ for (uint i = 0; i < ARRAYSIZE(_parameters); i++)
+ _parameters[i].saveLoadWithSerializer(s);
- _data.saveLoadWithSerializer(s);
+ _data.saveLoadWithSerializer(s);
+ } else {
+ // to correctly deserialize parameters, we need to know their runtime type
+ // but we don't know it until callbacks[] array will be deserialized
+ // all types of parameters are serialized to 32*4 bytes
+ // (the original game has same-size-PODs and just memcpy-s them.
+ // *sigh* Why does this implementation even need the extra byte in strings?
+ // Well, big-endian vs little-endian is also a thing...)
+ byte buf[ARRAYSIZE(_parameters) * 32 * 4];
+ s.syncBytes(buf, sizeof(buf));
+
+ _data.saveLoadWithSerializer(s);
+
+ for (uint i = 0; i < 8; i++) {
+ if (!paramsTypeSetters || _data.callbacks[i] >= paramsTypeSetters->size())
+ resetParametersType<EntityParametersIIII>(&_parameters[i]);
+ else
+ (*paramsTypeSetters)[_data.callbacks[i]](&_parameters[i]);
+ }
+ Common::MemoryReadStream paramsStream(buf, sizeof(buf));
+ Common::Serializer paramsSerializer(&paramsStream, NULL);
+ for (uint i = 0; i < ARRAYSIZE(_parameters); i++)
+ _parameters[i].saveLoadWithSerializer(paramsSerializer);
+ }
}
//////////////////////////////////////////////////////////////////////////
@@ -162,6 +186,7 @@ Entity::Entity(LastExpressEngine *engine, EntityIndex index) : _engine(engine),
// Add first empty entry to callbacks array
_callbacks.push_back(NULL);
+ _paramsTypeSetters.push_back(&EntityData::resetParametersType<EntityData::EntityParametersIIII>);
}
Entity::~Entity() {
@@ -211,7 +236,7 @@ void Entity::setup(ChapterIndex index) {
// Shared functions
//////////////////////////////////////////////////////////////////////////
-void Entity::reset(const SavePoint &savepoint, bool resetClothes, bool resetItem) {
+void Entity::reset(const SavePoint &savepoint, ClothesIndex maxClothes, bool resetItem) {
EXPOSE_PARAMS(EntityData::EntityParametersIIII)
switch (savepoint.action) {
@@ -219,10 +244,10 @@ void Entity::reset(const SavePoint &savepoint, bool resetClothes, bool resetItem
break;
case kAction1:
- if (resetClothes) {
+ if (maxClothes != kClothesDefault) {
// Select next available clothes
getData()->clothes = (ClothesIndex)(getData()->clothes + 1);
- if (getData()->clothes > kClothes3)
+ if (getData()->clothes > maxClothes)
getData()->clothes = kClothesDefault;
}
break;
@@ -263,26 +288,16 @@ void Entity::savegame(const SavePoint &savepoint) {
}
}
-void Entity::savegameBloodJacket() {
+bool Entity::savegameBloodJacket(byte callback) {
if (getProgress().jacket == kJacketBlood
&& getEntities()->isDistanceBetweenEntities(_entityIndex, kEntityPlayer, 1000)
&& !getEntities()->isInsideCompartments(kEntityPlayer)
&& !getEntities()->checkFields10(kEntityPlayer)) {
- setCallback(1);
-
- switch (_entityIndex) {
- default:
- break;
-
- case kEntityCoudert:
- setup_savegame(kSavegameTypeEvent, kEventCoudertBloodJacket);
- break;
-
- case kEntityMertens:
- setup_savegame(kSavegameTypeEvent, kEventCoudertBloodJacket);
- break;
- }
+ setCallback(callback);
+ setup_savegame(kSavegameTypeEvent, kEventMertensBloodJacket);
+ return true;
}
+ return false;
}
void Entity::playSound(const SavePoint &savepoint, bool resetItem, SoundFlag flag) {
@@ -355,7 +370,7 @@ void Entity::updateFromTicks(const SavePoint &savepoint) {
break;
case kActionNone:
- if (Entity::updateParameter(params->param2, getState()->timeTicks, params->param1))
+ if (!Entity::updateParameter(params->param2, getState()->timeTicks, params->param1))
break;
callbackAction();
@@ -371,7 +386,7 @@ void Entity::updateFromTime(const SavePoint &savepoint) {
break;
case kActionNone:
- if (Entity::updateParameter(params->param2, getState()->time, params->param1))
+ if (!Entity::updateParameter(params->param2, getState()->time, params->param1))
break;
callbackAction();
@@ -388,7 +403,7 @@ void Entity::callbackActionOnDirection(const SavePoint &savepoint) {
callbackAction();
break;
- case kActionDefault:
+ case kActionNone:
if (getData()->direction != kDirectionRight)
callbackAction();
break;
@@ -609,22 +624,22 @@ void Entity::callbackAction() {
//////////////////////////////////////////////////////////////////////////
// Setup functions
//////////////////////////////////////////////////////////////////////////
-void Entity::setup(const char *name, uint index) {
+void Entity::setup(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter) {
debugC(6, kLastExpressDebugLogic, "Entity: %s()", name);
_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
_data->setCurrentCallback(index);
- _data->resetCurrentParameters<EntityData::EntityParametersIIII>();
+ paramsTypeSetter(_data->getCurrentCallParameters());
_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
}
-void Entity::setupI(const char *name, uint index, uint param1) {
+void Entity::setupI(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1) {
debugC(6, kLastExpressDebugLogic, "Entity: %s(%u)", name, param1);
_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
_data->setCurrentCallback(index);
- _data->resetCurrentParameters<EntityData::EntityParametersIIII>();
+ paramsTypeSetter(_data->getCurrentCallParameters());
EntityData::EntityParametersIIII *params = (EntityData::EntityParametersIIII *)_data->getCurrentParameters();
params->param1 = (unsigned int)param1;
@@ -632,12 +647,12 @@ void Entity::setupI(const char *name, uint index, uint param1) {
_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
}
-void Entity::setupII(const char *name, uint index, uint param1, uint param2) {
+void Entity::setupII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2) {
debugC(6, kLastExpressDebugLogic, "Entity: %s(%u, %u)", name, param1, param2);
_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
_data->setCurrentCallback(index);
- _data->resetCurrentParameters<EntityData::EntityParametersIIII>();
+ paramsTypeSetter(_data->getCurrentCallParameters());
EntityData::EntityParametersIIII *params = (EntityData::EntityParametersIIII *)_data->getCurrentParameters();
params->param1 = param1;
@@ -646,12 +661,12 @@ void Entity::setupII(const char *name, uint index, uint param1, uint param2) {
_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
}
-void Entity::setupIII(const char *name, uint index, uint param1, uint param2, uint param3) {
+void Entity::setupIII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2, uint param3) {
debugC(6, kLastExpressDebugLogic, "Entity: %s(%u, %u, %u)", name, param1, param2, param3);
_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
_data->setCurrentCallback(index);
- _data->resetCurrentParameters<EntityData::EntityParametersIIII>();
+ paramsTypeSetter(_data->getCurrentCallParameters());
EntityData::EntityParametersIIII *params = (EntityData::EntityParametersIIII *)_data->getCurrentParameters();
params->param1 = param1;
@@ -661,12 +676,12 @@ void Entity::setupIII(const char *name, uint index, uint param1, uint param2, ui
_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
}
-void Entity::setupS(const char *name, uint index, const char *seq1) {
+void Entity::setupS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1) {
debugC(6, kLastExpressDebugLogic, "Entity: %s(%s)", name, seq1);
_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
_data->setCurrentCallback(index);
- _data->resetCurrentParameters<EntityData::EntityParametersSIIS>();
+ paramsTypeSetter(_data->getCurrentCallParameters());
EntityData::EntityParametersSIIS *params = (EntityData::EntityParametersSIIS*)_data->getCurrentParameters();
strncpy(params->seq1, seq1, 12);
@@ -674,12 +689,12 @@ void Entity::setupS(const char *name, uint index, const char *seq1) {
_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
}
-void Entity::setupSS(const char *name, uint index, const char *seq1, const char *seq2) {
+void Entity::setupSS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, const char *seq2) {
debugC(6, kLastExpressDebugLogic, "Entity: %s(%s, %s)", name, seq1, seq2);
_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
_data->setCurrentCallback(index);
- _data->resetCurrentParameters<EntityData::EntityParametersSSII>();
+ paramsTypeSetter(_data->getCurrentCallParameters());
EntityData::EntityParametersSSII *params = (EntityData::EntityParametersSSII*)_data->getCurrentParameters();
strncpy(params->seq1, seq1, 12);
@@ -688,12 +703,12 @@ void Entity::setupSS(const char *name, uint index, const char *seq1, const char
_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
}
-void Entity::setupSI(const char *name, uint index, const char *seq1, uint param4) {
+void Entity::setupSI(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, uint param4) {
debugC(6, kLastExpressDebugLogic, "Entity: %s(%s, %u)", name, seq1, param4);
_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
_data->setCurrentCallback(index);
- _data->resetCurrentParameters<EntityData::EntityParametersSIIS>();
+ paramsTypeSetter(_data->getCurrentCallParameters());
EntityData::EntityParametersSIIS *params = (EntityData::EntityParametersSIIS *)_data->getCurrentParameters();
strncpy(params->seq1, seq1, 12);
@@ -702,27 +717,27 @@ void Entity::setupSI(const char *name, uint index, const char *seq1, uint param4
_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
}
-void Entity::setupSII(const char *name, uint index, const char *seq1, uint param4, uint param5) {
+void Entity::setupSII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, uint param4, uint param5) {
debugC(6, kLastExpressDebugLogic, "Entity: %s(%s, %u, %u)", name, seq1, param4, param5);
_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
_data->setCurrentCallback(index);
- _data->resetCurrentParameters<EntityData::EntityParametersSIIS>();
+ paramsTypeSetter(_data->getCurrentCallParameters());
- EntityData::EntityParametersSIIS *params = (EntityData::EntityParametersSIIS *)_data->getCurrentParameters();
- strncpy(params->seq1, seq1, 12);
+ EntityData::EntityParametersSIII *params = (EntityData::EntityParametersSIII *)_data->getCurrentParameters();
+ strncpy(params->seq, seq1, 12);
params->param4 = param4;
params->param5 = param5;
_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
}
-void Entity::setupSIII(const char *name, uint index, const char *seq, uint param4, uint param5, uint param6) {
+void Entity::setupSIII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq, uint param4, uint param5, uint param6) {
debugC(6, kLastExpressDebugLogic, "Entity: %s(%s, %u, %u, %u)", name, seq, param4, param5, param6);
_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
_data->setCurrentCallback(index);
- _data->resetCurrentParameters<EntityData::EntityParametersSIII>();
+ paramsTypeSetter(_data->getCurrentCallParameters());
EntityData::EntityParametersSIII *params = (EntityData::EntityParametersSIII *)_data->getCurrentParameters();
strncpy(params->seq, seq, 12);
@@ -733,12 +748,12 @@ void Entity::setupSIII(const char *name, uint index, const char *seq, uint param
_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
}
-void Entity::setupSIIS(const char *name, uint index, const char *seq1, uint param4, uint param5, const char *seq2) {
+void Entity::setupSIIS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, uint param4, uint param5, const char *seq2) {
debugC(6, kLastExpressDebugLogic, "Entity: %s(%s, %u, %u, %s)", name, seq1, param4, param5, seq2);
_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
_data->setCurrentCallback(index);
- _data->resetCurrentParameters<EntityData::EntityParametersSIIS>();
+ paramsTypeSetter(_data->getCurrentCallParameters());
EntityData::EntityParametersSIIS *params = (EntityData::EntityParametersSIIS *)_data->getCurrentParameters();
strncpy(params->seq1, seq1, 12);
@@ -749,12 +764,12 @@ void Entity::setupSIIS(const char *name, uint index, const char *seq1, uint para
_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
}
-void Entity::setupSSI(const char *name, uint index, const char *seq1, const char *seq2, uint param7) {
+void Entity::setupSSI(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, const char *seq2, uint param7) {
debugC(6, kLastExpressDebugLogic, "Entity: %s(%s, %s, %u)", name, seq1, seq2, param7);
_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
_data->setCurrentCallback(index);
- _data->resetCurrentParameters<EntityData::EntityParametersSSII>();
+ paramsTypeSetter(_data->getCurrentCallParameters());
EntityData::EntityParametersSSII *params = (EntityData::EntityParametersSSII *)_data->getCurrentParameters();
strncpy(params->seq1, seq1, 12);
@@ -764,12 +779,12 @@ void Entity::setupSSI(const char *name, uint index, const char *seq1, const char
_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
}
-void Entity::setupIS(const char *name, uint index, uint param1, const char *seq) {
+void Entity::setupIS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, const char *seq) {
debugC(6, kLastExpressDebugLogic, "Entity: %s(%u, %s)", name, param1, seq);
_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
_data->setCurrentCallback(index);
- _data->resetCurrentParameters<EntityData::EntityParametersISII>();
+ paramsTypeSetter(_data->getCurrentCallParameters());
EntityData::EntityParametersISII *params = (EntityData::EntityParametersISII *)_data->getCurrentParameters();
params->param1 = (unsigned int)param1;
@@ -778,12 +793,12 @@ void Entity::setupIS(const char *name, uint index, uint param1, const char *seq)
_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
}
-void Entity::setupISS(const char *name, uint index, uint param1, const char *seq1, const char *seq2) {
+void Entity::setupISS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, const char *seq1, const char *seq2) {
debugC(6, kLastExpressDebugLogic, "Entity: %s(%u, %s, %s)", name, param1, seq1, seq2);
_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
_data->setCurrentCallback(index);
- _data->resetCurrentParameters<EntityData::EntityParametersISSI>();
+ paramsTypeSetter(_data->getCurrentCallParameters());
EntityData::EntityParametersISSI *params = (EntityData::EntityParametersISSI *)_data->getCurrentParameters();
params->param1 = param1;
@@ -793,12 +808,12 @@ void Entity::setupISS(const char *name, uint index, uint param1, const char *seq
_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
}
-void Entity::setupIIS(const char *name, uint index, uint param1, uint param2, const char *seq) {
+void Entity::setupIIS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2, const char *seq) {
debugC(6, kLastExpressDebugLogic, "Entity: %s(%u, %u, %s)", name, param1, param2, seq);
_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
_data->setCurrentCallback(index);
- _data->resetCurrentParameters<EntityData::EntityParametersIISI>();
+ paramsTypeSetter(_data->getCurrentCallParameters());
EntityData::EntityParametersIISI *params = (EntityData::EntityParametersIISI *)_data->getCurrentParameters();
params->param1 = param1;
@@ -808,12 +823,12 @@ void Entity::setupIIS(const char *name, uint index, uint param1, uint param2, co
_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
}
-void Entity::setupIISS(const char *name, uint index, uint param1, uint param2, const char *seq1, const char *seq2) {
+void Entity::setupIISS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2, const char *seq1, const char *seq2) {
debugC(6, kLastExpressDebugLogic, "Entity: %s(%u, %u, %s, %s)", name, param1, param2, seq1, seq2);
_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
_data->setCurrentCallback(index);
- _data->resetCurrentParameters<EntityData::EntityParametersIISS>();
+ paramsTypeSetter(_data->getCurrentCallParameters());
EntityData::EntityParametersIISS *params = (EntityData::EntityParametersIISS *)_data->getCurrentParameters();
params->param1 = param1;
@@ -855,12 +870,12 @@ bool Entity::updateParameterTime(TimeValue timeValue, bool check, uint &paramete
}
bool Entity::updateParameterCheck(uint &parameter, uint timeType, uint delta) const {
- if (parameter && parameter >= timeType)
- return false;
-
if (!parameter)
parameter = (uint)(timeType + delta);
+ if (parameter && parameter >= timeType)
+ return false;
+
return true;
}
diff --git a/engines/lastexpress/entities/entity.h b/engines/lastexpress/entities/entity.h
index 25c481c5cf..0e01b08830 100644
--- a/engines/lastexpress/entities/entity.h
+++ b/engines/lastexpress/entities/entity.h
@@ -76,11 +76,37 @@ struct SavePoint;
#define ENTITY_CALLBACK(class, name, pointer) \
Common::Functor1Mem<const SavePoint&, void, class>(pointer, &class::name)
-#define ADD_CALLBACK_FUNCTION(class, name) \
- _callbacks.push_back(new ENTITY_CALLBACK(class, name, this));
+#define ADD_CALLBACK_FUNCTION_TYPE(class, name, type) \
+ _callbacks.push_back(new ENTITY_CALLBACK(class, name, this)); \
+ _paramsTypeSetters.push_back(&EntityData::resetParametersType<EntityData::type>);
+
+#define ADD_CALLBACK_FUNCTION_TYPE2(class, name, type1, type2) \
+ _callbacks.push_back(new ENTITY_CALLBACK(class, name, this)); \
+ _paramsTypeSetters.push_back(&EntityData::resetParametersType<EntityData::type1, EntityData::type2>);
+
+#define ADD_CALLBACK_FUNCTION_TYPE3(class, name, type1, type2, type3) \
+ _callbacks.push_back(new ENTITY_CALLBACK(class, name, this)); \
+ _paramsTypeSetters.push_back(&EntityData::resetParametersType<EntityData::type1, EntityData::type2, EntityData::type3>);
+
+#define ADD_CALLBACK_FUNCTION(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersIIII)
+#define ADD_CALLBACK_FUNCTION_I(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersIIII)
+#define ADD_CALLBACK_FUNCTION_II(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersIIII)
+#define ADD_CALLBACK_FUNCTION_III(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersIIII)
+#define ADD_CALLBACK_FUNCTION_S(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSIIS)
+#define ADD_CALLBACK_FUNCTION_SI(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSIIS)
+#define ADD_CALLBACK_FUNCTION_SII(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSIII)
+#define ADD_CALLBACK_FUNCTION_SIII(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSIII)
+#define ADD_CALLBACK_FUNCTION_SIIS(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSIIS)
+#define ADD_CALLBACK_FUNCTION_SS(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSSII)
+#define ADD_CALLBACK_FUNCTION_SSI(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSSII)
+#define ADD_CALLBACK_FUNCTION_IS(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersISII)
+#define ADD_CALLBACK_FUNCTION_ISS(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersISSI)
+#define ADD_CALLBACK_FUNCTION_IIS(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersIISI)
+#define ADD_CALLBACK_FUNCTION_IISS(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersIISS)
#define ADD_NULL_FUNCTION() \
- _callbacks.push_back(new ENTITY_CALLBACK(Entity, nullfunction, this));
+ _callbacks.push_back(new ENTITY_CALLBACK(Entity, nullfunction, this)); \
+ _paramsTypeSetters.push_back(&(EntityData::resetParametersType<EntityData::EntityParametersIIII>));
#define WRAP_SETUP_FUNCTION(className, method) \
new Common::Functor0Mem<void, className>(this, &className::method)
@@ -125,7 +151,7 @@ struct SavePoint;
// simple setup with no parameters
#define IMPLEMENT_FUNCTION(index, class, name) \
void class::setup_##name() { \
- Entity::setup(#class "::setup_" #name, index); \
+ Entity::setup(#class "::setup_" #name, index, _paramsTypeSetters[index]); \
} \
void class::name(const SavePoint &savepoint) { \
EXPOSE_PARAMS(EntityData::EntityParametersIIII) \
@@ -136,13 +162,13 @@ struct SavePoint;
// nullfunction call
#define IMPLEMENT_NULL_FUNCTION(index, class) \
void class::setup_nullfunction() { \
- Entity::setup(#class "::setup_nullfunction", index); \
+ Entity::setup(#class "::setup_nullfunction", index, _paramsTypeSetters[index]); \
}
// setup with one uint parameter
#define IMPLEMENT_FUNCTION_I(index, class, name, paramType) \
void class::setup_##name(paramType param1) { \
- Entity::setupI(#class "::setup_" #name, index, param1); \
+ Entity::setupI(#class "::setup_" #name, index, _paramsTypeSetters[index], param1); \
} \
void class::name(const SavePoint &savepoint) { \
EXPOSE_PARAMS(EntityData::EntityParametersIIII) \
@@ -151,7 +177,7 @@ struct SavePoint;
// setup with two uint parameters
#define IMPLEMENT_FUNCTION_II(index, class, name, paramType1, paramType2) \
void class::setup_##name(paramType1 param1, paramType2 param2) { \
- Entity::setupII(#class "::setup_" #name, index, param1, param2); \
+ Entity::setupII(#class "::setup_" #name, index, _paramsTypeSetters[index], param1, param2); \
} \
void class::name(const SavePoint &savepoint) { \
EXPOSE_PARAMS(EntityData::EntityParametersIIII) \
@@ -160,7 +186,7 @@ struct SavePoint;
// setup with three uint parameters
#define IMPLEMENT_FUNCTION_III(index, class, name, paramType1, paramType2, paramType3) \
void class::setup_##name(paramType1 param1, paramType2 param2, paramType3 param3) { \
- Entity::setupIII(#class "::setup_" #name, index, param1, param2, param3); \
+ Entity::setupIII(#class "::setup_" #name, index, _paramsTypeSetters[index], param1, param2, param3); \
} \
void class::name(const SavePoint &savepoint) { \
EXPOSE_PARAMS(EntityData::EntityParametersIIII) \
@@ -169,7 +195,7 @@ struct SavePoint;
// setup with one char *parameter
#define IMPLEMENT_FUNCTION_S(index, class, name) \
void class::setup_##name(const char *seq1) { \
- Entity::setupS(#class "::setup_" #name, index, seq1); \
+ Entity::setupS(#class "::setup_" #name, index, _paramsTypeSetters[index], seq1); \
} \
void class::name(const SavePoint &savepoint) { \
EXPOSE_PARAMS(EntityData::EntityParametersSIIS) \
@@ -178,7 +204,7 @@ struct SavePoint;
// setup with one char *parameter and one uint
#define IMPLEMENT_FUNCTION_SI(index, class, name, paramType2) \
void class::setup_##name(const char *seq1, paramType2 param4) { \
- Entity::setupSI(#class "::setup_" #name, index, seq1, param4); \
+ Entity::setupSI(#class "::setup_" #name, index, _paramsTypeSetters[index], seq1, param4); \
} \
void class::name(const SavePoint &savepoint) { \
EXPOSE_PARAMS(EntityData::EntityParametersSIIS) \
@@ -187,16 +213,16 @@ struct SavePoint;
// setup with one char *parameter and two uints
#define IMPLEMENT_FUNCTION_SII(index, class, name, paramType2, paramType3) \
void class::setup_##name(const char *seq1, paramType2 param4, paramType3 param5) { \
- Entity::setupSII(#class "::setup_" #name, index, seq1, param4, param5); \
+ Entity::setupSII(#class "::setup_" #name, index, _paramsTypeSetters[index], seq1, param4, param5); \
} \
void class::name(const SavePoint &savepoint) { \
- EXPOSE_PARAMS(EntityData::EntityParametersSIIS) \
- debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%s, %d, %d) - action: %s", (char *)&params->seq1, params->param4, params->param5, ACTION_NAME(savepoint.action));
+ EXPOSE_PARAMS(EntityData::EntityParametersSIII) \
+ debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%s, %d, %d) - action: %s", (char *)&params->seq, params->param4, params->param5, ACTION_NAME(savepoint.action));
// setup with one char *parameter and three uints
#define IMPLEMENT_FUNCTION_SIII(index, class, name, paramType2, paramType3, paramType4) \
void class::setup_##name(const char *seq, paramType2 param4, paramType3 param5, paramType4 param6) { \
- Entity::setupSIII(#class "::setup_" #name, index, seq, param4, param5, param6); \
+ Entity::setupSIII(#class "::setup_" #name, index, _paramsTypeSetters[index], seq, param4, param5, param6); \
} \
void class::name(const SavePoint &savepoint) { \
EXPOSE_PARAMS(EntityData::EntityParametersSIII) \
@@ -204,7 +230,7 @@ struct SavePoint;
#define IMPLEMENT_FUNCTION_SIIS(index, class, name, paramType2, paramType3) \
void class::setup_##name(const char *seq1, paramType2 param4, paramType3 param5, const char *seq2) { \
- Entity::setupSIIS(#class "::setup_" #name, index, seq1, param4, param5, seq2); \
+ Entity::setupSIIS(#class "::setup_" #name, index, _paramsTypeSetters[index], seq1, param4, param5, seq2); \
} \
void class::name(const SavePoint &savepoint) { \
EXPOSE_PARAMS(EntityData::EntityParametersSIIS) \
@@ -212,7 +238,7 @@ struct SavePoint;
#define IMPLEMENT_FUNCTION_SS(index, class, name) \
void class::setup_##name(const char *seq1, const char *seq2) { \
- Entity::setupSS(#class "::setup_" #name, index, seq1, seq2); \
+ Entity::setupSS(#class "::setup_" #name, index, _paramsTypeSetters[index], seq1, seq2); \
} \
void class::name(const SavePoint &savepoint) { \
EXPOSE_PARAMS(EntityData::EntityParametersSSII) \
@@ -220,7 +246,7 @@ struct SavePoint;
#define IMPLEMENT_FUNCTION_SSI(index, class, name, paramType3) \
void class::setup_##name(const char *seq1, const char *seq2, paramType3 param7) { \
- Entity::setupSSI(#class "::setup_" #name, index, seq1, seq2, param7); \
+ Entity::setupSSI(#class "::setup_" #name, index, _paramsTypeSetters[index], seq1, seq2, param7); \
} \
void class::name(const SavePoint &savepoint) { \
EXPOSE_PARAMS(EntityData::EntityParametersSSII) \
@@ -228,7 +254,7 @@ struct SavePoint;
#define IMPLEMENT_FUNCTION_IS(index, class, name, paramType) \
void class::setup_##name(paramType param1, const char *seq) { \
- Entity::setupIS(#class "::setup_" #name, index, param1, seq); \
+ Entity::setupIS(#class "::setup_" #name, index, _paramsTypeSetters[index], param1, seq); \
} \
void class::name(const SavePoint &savepoint) { \
EXPOSE_PARAMS(EntityData::EntityParametersISII) \
@@ -236,7 +262,7 @@ struct SavePoint;
#define IMPLEMENT_FUNCTION_ISS(index, class, name, paramType) \
void class::setup_##name(paramType param1, const char *seq1, const char *seq2) { \
- Entity::setupISS(#class "::setup_" #name, index, param1, seq1, seq2); \
+ Entity::setupISS(#class "::setup_" #name, index, _paramsTypeSetters[index], param1, seq1, seq2); \
} \
void class::name(const SavePoint &savepoint) { \
EXPOSE_PARAMS(EntityData::EntityParametersISSI) \
@@ -244,7 +270,7 @@ struct SavePoint;
#define IMPLEMENT_FUNCTION_IIS(index, class, name, paramType1, paramType2) \
void class::setup_##name(paramType1 param1, paramType2 param2, const char *seq) { \
- Entity::setupIIS(#class "::setup_" #name, index, param1, param2, seq); \
+ Entity::setupIIS(#class "::setup_" #name, index, _paramsTypeSetters[index], param1, param2, seq); \
} \
void class::name(const SavePoint &savepoint) { \
EXPOSE_PARAMS(EntityData::EntityParametersIISI) \
@@ -252,7 +278,7 @@ struct SavePoint;
#define IMPLEMENT_FUNCTION_IISS(index, class, name, paramType1, paramType2) \
void class::setup_##name(paramType1 param1, paramType2 param2, const char *seq1, const char *seq2) { \
- Entity::setupIISS(#class "::setup_" #name, index, param1, param2, seq1, seq2); \
+ Entity::setupIISS(#class "::setup_" #name, index, _paramsTypeSetters[index], param1, param2, seq1, seq2); \
} \
void class::name(const SavePoint &savepoint) { \
EXPOSE_PARAMS(EntityData::EntityParametersIISS) \
@@ -260,7 +286,7 @@ struct SavePoint;
//////////////////////////////////////////////////////////////////////////
-class EntityData : Common::Serializable {
+class EntityData {
public:
struct EntityParameters : Common::Serializable {
@@ -688,6 +714,23 @@ public:
memset(&seq, 0, 13);
}
+ Common::String toString() {
+ return Common::String::format("I5S: %d %d %d %d %d %s\n", param1, param2, param3, param4, param5, seq);
+ }
+
+ void update(uint32 index) {
+ switch (index) {
+ default:
+ error("[EntityParametersI5S::update] Invalid index (was: %d)", index);
+
+ case 0: param1 = 1; break;
+ case 1: param2 = 1; break;
+ case 2: param3 = 1; break;
+ case 3: param4 = 1; break;
+ case 4: param5 = 1; break;
+ }
+ }
+
void saveLoadWithSerializer(Common::Serializer &s) {
s.syncAsUint32LE(param1);
s.syncAsUint32LE(param2);
@@ -830,13 +873,13 @@ public:
EntityData() {}
- template<class T>
- void resetCurrentParameters() {
- EntityCallParameters *params = &_parameters[_data.currentCall];
+ template<class T1, class T2 = EntityParametersIIII, class T3 = EntityParametersIIII>
+ static void resetParametersType(EntityCallParameters* params) {
params->clear();
-
- for (int i = 0; i < 4; i++)
- params->parameters[i] = new T();
+ params->parameters[0] = new T1();
+ params->parameters[1] = new T2();
+ params->parameters[2] = new T3();
+ params->parameters[3] = new EntityParametersIIII();
}
EntityCallData *getCallData() { return &_data; }
@@ -853,7 +896,8 @@ public:
void updateParameters(uint32 index) const;
// Serializable
- void saveLoadWithSerializer(Common::Serializer &ser);
+ typedef void(*TypeSetter)(EntityCallParameters*);
+ void saveLoadWithSerializer(Common::Serializer &ser, const Common::Array<TypeSetter>* paramsTypeSetters);
private:
@@ -890,7 +934,7 @@ public:
virtual void setup_playSound(const char*) { error("[Entity::setup_playSound] Trying to call the parent setup function. Use the specific entity function directly"); }
// Serializable
- void saveLoadWithSerializer(Common::Serializer &ser) { _data->saveLoadWithSerializer(ser); }
+ void saveLoadWithSerializer(Common::Serializer &ser) { _data->saveLoadWithSerializer(ser, &_paramsTypeSetters); }
void nullfunction(const SavePoint &savepoint) {}
@@ -901,6 +945,7 @@ protected:
EntityIndex _entityIndex;
EntityData *_data;
Common::Array<Callback *> _callbacks;
+ Common::Array<EntityData::TypeSetter> _paramsTypeSetters;
/**
* Saves the game
@@ -914,9 +959,10 @@ protected:
/**
* Saves the game before being found out with a blood covered jacket.
*
- * @param saveFunction The setup function to call to save the game
+ * @param callback argument for setCallback()
+ * @return true if the event has been processed, false if nothing happened
*/
- void savegameBloodJacket();
+ bool savegameBloodJacket(byte callback);
/**
* Play sound
@@ -968,10 +1014,10 @@ protected:
* Resets an entity
*
* @param savepoint The savepoint.
- * @param resetClothes true to reset clothes.
+ * @param maxClothes cycles clothes from kClothesDefault to maxClothes inclusively
* @param resetItem true to reset inventoryItem to kItemInvalid
*/
- void reset(const SavePoint &savepoint, bool resetClothes = false, bool resetItem = false);
+ void reset(const SavePoint &savepoint, ClothesIndex maxClothes = kClothesDefault, bool resetItem = false);
/**
* Process callback action when the entity direction is not kDirectionRight
@@ -1064,21 +1110,21 @@ protected:
//////////////////////////////////////////////////////////////////////////
// Setup functions
//////////////////////////////////////////////////////////////////////////
- void setup(const char *name, uint index);
- void setupI(const char *name, uint index, uint param1);
- void setupII(const char *name, uint index, uint param1, uint param2);
- void setupIII(const char *name, uint index, uint param1, uint param2, uint param3);
- void setupS(const char *name, uint index, const char *seq1);
- void setupSS(const char *name, uint index, const char *seq1, const char *seq2);
- void setupSI(const char *name, uint index, const char *seq1, uint param4);
- void setupSII(const char *name, uint index, const char *seq1, uint param4, uint param5);
- void setupSIII(const char *name, uint index, const char *seq, uint param4, uint param5, uint param6);
- void setupSIIS(const char *name, uint index, const char *seq1, uint param4, uint param5, const char *seq2);
- void setupSSI(const char *name, uint index, const char *seq1, const char *seq2, uint param7);
- void setupIS(const char *name, uint index, uint param1, const char *seq);
- void setupISS(const char *name, uint index, uint param1, const char *seq1, const char *seq2);
- void setupIIS(const char *name, uint index, uint param1, uint param2, const char *seq);
- void setupIISS(const char *name, uint index, uint param1, uint param2, const char *seq1, const char *seq2);
+ void setup(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter);
+ void setupI(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1);
+ void setupII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2);
+ void setupIII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2, uint param3);
+ void setupS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1);
+ void setupSS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, const char *seq2);
+ void setupSI(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, uint param4);
+ void setupSII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, uint param4, uint param5);
+ void setupSIII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq, uint param4, uint param5, uint param6);
+ void setupSIIS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, uint param4, uint param5, const char *seq2);
+ void setupSSI(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, const char *seq2, uint param7);
+ void setupIS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, const char *seq);
+ void setupISS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, const char *seq1, const char *seq2);
+ void setupIIS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2, const char *seq);
+ void setupIISS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2, const char *seq1, const char *seq2);
//////////////////////////////////////////////////////////////////////////
// Helper functions
diff --git a/engines/lastexpress/entities/francois.cpp b/engines/lastexpress/entities/francois.cpp
index d2fb66c7ce..9eb12fbfce 100644
--- a/engines/lastexpress/entities/francois.cpp
+++ b/engines/lastexpress/entities/francois.cpp
@@ -38,19 +38,19 @@ namespace LastExpress {
Francois::Francois(LastExpressEngine *engine) : Entity(engine, kEntityFrancois) {
ADD_CALLBACK_FUNCTION(Francois, reset);
- ADD_CALLBACK_FUNCTION(Francois, updateFromTime);
- ADD_CALLBACK_FUNCTION(Francois, draw);
- ADD_CALLBACK_FUNCTION(Francois, enterExitCompartment);
- ADD_CALLBACK_FUNCTION(Francois, enterExitCompartment2);
- ADD_CALLBACK_FUNCTION(Francois, playSound);
- ADD_CALLBACK_FUNCTION(Francois, savegame);
- ADD_CALLBACK_FUNCTION(Francois, doWalk);
+ ADD_CALLBACK_FUNCTION_I(Francois, updateFromTime);
+ ADD_CALLBACK_FUNCTION_S(Francois, draw);
+ ADD_CALLBACK_FUNCTION_SI(Francois, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_SI(Francois, enterExitCompartment2);
+ ADD_CALLBACK_FUNCTION_S(Francois, playSound);
+ ADD_CALLBACK_FUNCTION_II(Francois, savegame);
+ ADD_CALLBACK_FUNCTION_II(Francois, doWalk);
ADD_CALLBACK_FUNCTION(Francois, exitCompartment);
ADD_CALLBACK_FUNCTION(Francois, enterCompartment);
- ADD_CALLBACK_FUNCTION(Francois, rampage);
+ ADD_CALLBACK_FUNCTION_I(Francois, rampage);
ADD_CALLBACK_FUNCTION(Francois, takeWalk);
ADD_CALLBACK_FUNCTION(Francois, haremVisit);
- ADD_CALLBACK_FUNCTION(Francois, chaseBeetle);
+ ADD_CALLBACK_FUNCTION_TYPE(Francois, chaseBeetle, EntityParametersIISS);
ADD_CALLBACK_FUNCTION(Francois, findCath);
ADD_CALLBACK_FUNCTION(Francois, letsGo);
ADD_CALLBACK_FUNCTION(Francois, chapter1);
@@ -72,7 +72,7 @@ Francois::Francois(LastExpressEngine *engine) : Entity(engine, kEntityFrancois)
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION(1, Francois, reset)
- Entity::reset(savepoint, true);
+ Entity::reset(savepoint, kClothes1, true);
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
@@ -113,6 +113,7 @@ IMPLEMENT_FUNCTION_II(8, Francois, doWalk, CarIndex, EntityPosition)
case kActionNone:
if (getEntities()->updateEntity(_entityIndex, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ getData()->inventoryItem = kItemNone;
callbackAction();
} else {
if (!getEntities()->isDistanceBetweenEntities(kEntityFrancois, kEntityPlayer, 2000)
@@ -126,6 +127,8 @@ IMPLEMENT_FUNCTION_II(8, Francois, doWalk, CarIndex, EntityPosition)
&& !getEvent(kEventFrancoisShowBeetle)
&& !getEvent(kEventFrancoisShowBeetleD))
getData()->inventoryItem = kItemMatchBox;
+ else
+ getData()->inventoryItem = kItemNone;
} else {
getData()->inventoryItem = kItemFirebird;
}
@@ -145,12 +148,12 @@ IMPLEMENT_FUNCTION_II(8, Francois, doWalk, CarIndex, EntityPosition)
default:
break;
- case 1:
+ case kItemMatchBox:
setCallback(2);
setup_savegame(kSavegameTypeEvent, kEventFrancoisShowBeetle);
break;
- case 18:
+ case kItemFirebird:
if (isNight())
getAction()->playAnimation(getData()->entityPosition < getEntityData(kEntityPlayer)->entityPosition ? kEventFrancoisShowEggNightD : kEventFrancoisShowEggNight);
else
@@ -588,6 +591,9 @@ IMPLEMENT_FUNCTION(13, Francois, haremVisit)
}
getEntities()->drawSequenceLeft(kEntityFrancois, "605He");
+ getEntities()->enterCompartment(kEntityFrancois, kObjectCompartmentE, true);
+ setCallback(8);
+ setup_playSound(rnd(2) ? "Fra2005B" : "Fra2005C");
break;
case 8:
@@ -683,7 +689,7 @@ IMPLEMENT_FUNCTION_IIS(14, Francois, chaseBeetle, ObjectIndex, EntityPosition)
break;
case 8:
- getEntities()->exitCompartment(kEntityFrancois, (ObjectIndex)parameters->param1);
+ getEntities()->exitCompartment(kEntityFrancois, (ObjectIndex)parameters->param1, true);
// fall through
case 9:
@@ -788,6 +794,7 @@ IMPLEMENT_FUNCTION(16, Francois, letsGo)
case kActionNone:
getData()->entityPosition = getEntityData(kEntityBoutarel)->entityPosition;
getData()->location = getEntityData(kEntityBoutarel)->location;
+ getData()->car = getEntityData(kEntityBoutarel)->car;
break;
case kActionDefault:
@@ -828,6 +835,7 @@ IMPLEMENT_FUNCTION(16, Francois, letsGo)
getData()->entityPosition = kPosition_5790;
getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityFrancois);
callbackAction();
break;
@@ -996,8 +1004,22 @@ label_callback_4:
}
label_callback_5:
- if (getInventory()->get(kItemWhistle)->location != kObjectLocation3) {
- // TODO: do we also need to check if the whistle is in the inventory?
+ if (getInventory()->get(kItemBeetle)->location != kObjectLocation3) {
+ if (!getInventory()->hasItem(kItemWhistle) && getInventory()->get(kItemWhistle)->location != kObjectLocation3) {
+ // BUG in the original game: condition is always false
+ if (getState()->time < kTime1782000 && getState()->time > kTime1782000 && !params->param8) {
+ params->param8 = 1;
+ setCallback(9);
+ setup_takeWalk();
+ break;
+ }
+ if (getState()->time < kTime1813500 && getState()->time > kTime1813500 && !CURRENT_PARAM(1, 1)) {
+ CURRENT_PARAM(1, 1) = 1;
+ setCallback(10);
+ setup_takeWalk();
+ break;
+ }
+ }
break;
}
@@ -1010,11 +1032,11 @@ label_callback_5:
}
label_callback_6:
- if (timeCheckCallbackCompartment(kTime1782000, params->param6, 7, kObjectCompartmentC, kPosition_6470, "c"))
+ if (timeCheckCallbackCompartment(kTime1782000, params->param6, 7, kObjectCompartmentF, kPosition_4070, "f"))
break;
label_callback_7:
- timeCheckCallbackCompartment(kTime1813500, params->param7, 8, kObjectCompartmentF, kPosition_4070, "f");
+ timeCheckCallbackCompartment(kTime1813500, params->param7, 8, kObjectCompartmentC, kPosition_6470, "c");
break;
case kActionCallback:
@@ -1128,13 +1150,13 @@ label_callback_10:
}
label_callback_11:
- if (getInventory()->get(kItemWhistle)->location == kObjectLocation3) {
+ if (getInventory()->get(kItemBeetle)->location == kObjectLocation3) {
if (getState()->time <= kTimeEnd)
- if (!getEntities()->isDistanceBetweenEntities(kEntityFrancois, kEntityPlayer, 2000) || !params->param4)
- params->param4 = (uint)(getState()->time + 75);
+ if (!getEntities()->isDistanceBetweenEntities(kEntityFrancois, kEntityPlayer, 2000) || !CURRENT_PARAM(1, 4))
+ CURRENT_PARAM(1, 4) = (uint)(getState()->time + 75);
- if (params->param4 < getState()->time || getState()->time > kTimeEnd) {
- params->param4 = kTimeInvalid;
+ if (CURRENT_PARAM(1, 4) < getState()->time || getState()->time > kTimeEnd) {
+ CURRENT_PARAM(1, 4) = kTimeInvalid;
setCallback(12);
setup_playSound("Fra2010");
@@ -1146,11 +1168,11 @@ label_callback_12:
break;
label_callback_13:
- if (timeCheckCallbackCompartment(kTime2040300, CURRENT_PARAM(1, 6), 14, kObjectCompartmentF, kPosition_4070, "f"))
+ if (timeCheckCallbackCompartment(kTime2146500, CURRENT_PARAM(1, 6), 14, kObjectCompartmentF, kPosition_4070, "f"))
break;
label_callback_14:
- timeCheckCallbackCompartment(kTime2040300, CURRENT_PARAM(1, 7), 15, kObjectCompartmentB, kPosition_7500, "b");
+ timeCheckCallbackCompartment(kTime2218500, CURRENT_PARAM(1, 7), 15, kObjectCompartmentB, kPosition_7500, "b");
}
}
break;
diff --git a/engines/lastexpress/entities/gendarmes.cpp b/engines/lastexpress/entities/gendarmes.cpp
index 572f47c99a..981ad461d6 100644
--- a/engines/lastexpress/entities/gendarmes.cpp
+++ b/engines/lastexpress/entities/gendarmes.cpp
@@ -37,14 +37,14 @@ namespace LastExpress {
Gendarmes::Gendarmes(LastExpressEngine *engine) : Entity(engine, kEntityGendarmes) {
ADD_CALLBACK_FUNCTION(Gendarmes, reset);
ADD_CALLBACK_FUNCTION(Gendarmes, chapter1);
- ADD_CALLBACK_FUNCTION(Gendarmes, doDraw);
- ADD_CALLBACK_FUNCTION(Gendarmes, doDialog);
- ADD_CALLBACK_FUNCTION(Gendarmes, doDialogFullVolume);
- ADD_CALLBACK_FUNCTION(Gendarmes, doWait);
- ADD_CALLBACK_FUNCTION(Gendarmes, savegame);
- ADD_CALLBACK_FUNCTION(Gendarmes, doWalk);
- ADD_CALLBACK_FUNCTION(Gendarmes, doCompartment);
- ADD_CALLBACK_FUNCTION(Gendarmes, trappedCath);
+ ADD_CALLBACK_FUNCTION_S(Gendarmes, doDraw);
+ ADD_CALLBACK_FUNCTION_S(Gendarmes, doDialog);
+ ADD_CALLBACK_FUNCTION_S(Gendarmes, doDialogFullVolume);
+ ADD_CALLBACK_FUNCTION_I(Gendarmes, doWait);
+ ADD_CALLBACK_FUNCTION_II(Gendarmes, savegame);
+ ADD_CALLBACK_FUNCTION_II(Gendarmes, doWalk);
+ ADD_CALLBACK_FUNCTION_TYPE3(Gendarmes, doCompartment, EntityParametersIISS, EntityParametersSSS, EntityParametersISII);
+ ADD_CALLBACK_FUNCTION_III(Gendarmes, trappedCath);
ADD_CALLBACK_FUNCTION(Gendarmes, chapter1Handler);
ADD_CALLBACK_FUNCTION(Gendarmes, searchTrain);
ADD_CALLBACK_FUNCTION(Gendarmes, function13);
@@ -156,7 +156,7 @@ IMPLEMENT_FUNCTION_IISS(9, Gendarmes, doCompartment, CarIndex, EntityPosition)
parameters2->param7 = kPosition_7850;
}
- if (params->param1 == kCarBaggageRear)
+ if (params->param1 == kCarRedSleeping)
parameters2->param5 += 31; // Switch to next compartment car
if (parameters2->param6) {
@@ -184,7 +184,7 @@ IMPLEMENT_FUNCTION_IISS(9, Gendarmes, doCompartment, CarIndex, EntityPosition)
setup_trappedCath((CarIndex)params->param1, (EntityPosition)params->param2, (ObjectIndex)parameters2->param5);
} else {
getEntities()->drawSequenceLeft(kEntityGendarmes, (char *)&parameters1->seq1);
- getEntities()->enterCompartment(kEntityGendarmes, (ObjectIndex)CURRENT_PARAM(2, 5));
+ getEntities()->enterCompartment(kEntityGendarmes, (ObjectIndex)CURRENT_PARAM(2, 5), true);
setCallback(parameters2->param6 ? 2 : 3);
setup_doDialog(parameters2->param6 ? "POL1044A" : "POL1044B");
@@ -234,7 +234,7 @@ IMPLEMENT_FUNCTION_IISS(9, Gendarmes, doCompartment, CarIndex, EntityPosition)
case 6:
getData()->location = kLocationOutsideCompartment;
- getEntities()->exitCompartment(kEntityGendarmes, (ObjectIndex)parameters2->param5);
+ getEntities()->exitCompartment(kEntityGendarmes, (ObjectIndex)parameters2->param5, true);
callbackAction();
break;
}
@@ -249,10 +249,10 @@ IMPLEMENT_FUNCTION_III(10, Gendarmes, trappedCath, CarIndex, EntityPosition, Obj
break;
case kActionNone:
- if (!params->param5 || getState()->timeTicks > (uint32)params->param5) {
- if (!params->param5)
- params->param5 = getState()->timeTicks + 75;
+ if (!params->param5)
+ params->param5 = getState()->timeTicks + 75;
+ if (getState()->timeTicks > (uint32)params->param5) {
if (!getEntities()->isOutsideAlexeiWindow() && getObjects()->get((ObjectIndex)params->param3).status != kObjectLocation1) {
setCallback(2);
setup_savegame(kSavegameTypeEvent, kEventGendarmesArrestation);
@@ -321,7 +321,7 @@ IMPLEMENT_FUNCTION_III(10, Gendarmes, trappedCath, CarIndex, EntityPosition, Obj
break;
case 3:
- getAction()->playAnimation((params->param1 < kCarRedSleeping) ? kEventMertensBloodJacket : kEventCoudertBloodJacket);
+ getAction()->playAnimation((params->param1 == kCarGreenSleeping) ? kEventMertensBloodJacket : kEventCoudertBloodJacket);
getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
getObjects()->update((ObjectIndex)params->param3, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
@@ -338,6 +338,7 @@ IMPLEMENT_FUNCTION_III(10, Gendarmes, trappedCath, CarIndex, EntityPosition, Obj
case 5:
getObjects()->update((ObjectIndex)params->param3, kEntityGendarmes, getObjects()->get((ObjectIndex)params->param3).status, kCursorNormal, kCursorHand);
+ params->param4 = 1;
break;
case 6:
@@ -574,7 +575,7 @@ void Gendarmes::handleAction(const SavePoint &savepoint, bool shouldPlaySound, S
ENTITY_PARAM(0, 1) = 1;
}
- if (getEntities()->isDistanceBetweenEntities(kEntityGendarmes, kEntityPlayer, 1000) && !getEntityData(kEntityPlayer)->location) {
+ if (getEntities()->isDistanceBetweenEntities(kEntityGendarmes, kEntityPlayer, shouldUpdateEntity ? 1750 : 1000) && !getEntityData(kEntityPlayer)->location) {
if (shouldUpdateEntity)
if (getEntities()->isPlayerPosition(kCarRedSleeping, 22) && !getEntities()->isDistanceBetweenEntities(kEntityGendarmes, kEntityPlayer, 250))
@@ -585,13 +586,21 @@ void Gendarmes::handleAction(const SavePoint &savepoint, bool shouldPlaySound, S
}
break;
+ case kActionEndSound:
+ if (shouldPlaySound && !checkCallback && !shouldUpdateEntity) {
+ callbackAction();
+ }
+ break;
+
case kActionExitCompartment:
- callbackAction();
+ if (!shouldPlaySound && !checkCallback && !shouldUpdateEntity) {
+ callbackAction();
+ }
break;
case kActionDefault:
// Only handle when passing SIIS params
- if (!checkCallback) {
+ if (!checkCallback && !shouldUpdateEntity) {
EXPOSE_PARAMS(EntityData::EntityParametersSIIS);
if (!shouldPlaySound)
diff --git a/engines/lastexpress/entities/hadija.cpp b/engines/lastexpress/entities/hadija.cpp
index eb255d77f8..d925dd1163 100644
--- a/engines/lastexpress/entities/hadija.cpp
+++ b/engines/lastexpress/entities/hadija.cpp
@@ -34,10 +34,10 @@ namespace LastExpress {
Hadija::Hadija(LastExpressEngine *engine) : Entity(engine, kEntityHadija) {
ADD_CALLBACK_FUNCTION(Hadija, reset);
- ADD_CALLBACK_FUNCTION(Hadija, enterExitCompartment);
- ADD_CALLBACK_FUNCTION(Hadija, playSound);
- ADD_CALLBACK_FUNCTION(Hadija, updateFromTime);
- ADD_CALLBACK_FUNCTION(Hadija, updateEntity);
+ ADD_CALLBACK_FUNCTION_SI(Hadija, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_S(Hadija, playSound);
+ ADD_CALLBACK_FUNCTION_I(Hadija, updateFromTime);
+ ADD_CALLBACK_FUNCTION_II(Hadija, updateEntity);
ADD_CALLBACK_FUNCTION(Hadija, peekF);
ADD_CALLBACK_FUNCTION(Hadija, peekH);
ADD_CALLBACK_FUNCTION(Hadija, goFtoH);
@@ -151,15 +151,15 @@ label_callback2:
return;
}
}
-
- if (params->param3 >= getState()->time)
- return;
}
+ if (getState()->time > kTime1134000 || getState()->time > params->param3) {
- params->param3 = kTimeInvalid;
+ params->param3 = kTimeInvalid;
- setCallback(3);
- setup_peekH();
+ setCallback(3);
+ setup_peekH();
+ break;
+ }
}
label_callback3:
@@ -343,10 +343,6 @@ label_callback4:
}
break;
- case kActionDefault:
- getSavePoints()->push(kEntityAlouan, kEntityTrain, kAction191070912, kPosition_4840);
- break;
-
case kActionCallback:
switch (getCallback()) {
default:
diff --git a/engines/lastexpress/entities/ivo.cpp b/engines/lastexpress/entities/ivo.cpp
index 12a23e7d37..bd38d69b8d 100644
--- a/engines/lastexpress/entities/ivo.cpp
+++ b/engines/lastexpress/entities/ivo.cpp
@@ -38,15 +38,15 @@ namespace LastExpress {
Ivo::Ivo(LastExpressEngine *engine) : Entity(engine, kEntityIvo) {
ADD_CALLBACK_FUNCTION(Ivo, reset);
- ADD_CALLBACK_FUNCTION(Ivo, draw);
- ADD_CALLBACK_FUNCTION(Ivo, enterExitCompartment);
- ADD_CALLBACK_FUNCTION(Ivo, updateFromTime);
- ADD_CALLBACK_FUNCTION(Ivo, updateFromTicks);
- ADD_CALLBACK_FUNCTION(Ivo, updateEntity);
+ ADD_CALLBACK_FUNCTION_S(Ivo, draw);
+ ADD_CALLBACK_FUNCTION_SI(Ivo, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_I(Ivo, updateFromTime);
+ ADD_CALLBACK_FUNCTION_I(Ivo, updateFromTicks);
+ ADD_CALLBACK_FUNCTION_II(Ivo, updateEntity);
ADD_CALLBACK_FUNCTION(Ivo, callbackActionOnDirection);
- ADD_CALLBACK_FUNCTION(Ivo, playSound);
+ ADD_CALLBACK_FUNCTION_S(Ivo, playSound);
ADD_CALLBACK_FUNCTION(Ivo, callbackActionRestaurantOrSalon);
- ADD_CALLBACK_FUNCTION(Ivo, savegame);
+ ADD_CALLBACK_FUNCTION_II(Ivo, savegame);
ADD_CALLBACK_FUNCTION(Ivo, goCompartment);
ADD_CALLBACK_FUNCTION(Ivo, sitAtTableWithSalko);
ADD_CALLBACK_FUNCTION(Ivo, leaveTableWithSalko);
@@ -270,6 +270,7 @@ IMPLEMENT_FUNCTION(15, Ivo, chapter1Handler)
case kActionNone:
getData()->entityPosition = getEntityData(kEntityMilos)->entityPosition;
getData()->location = getEntityData(kEntityMilos)->location;
+ getData()->car = getEntityData(kEntityMilos)->car;
break;
case kActionCallback:
@@ -318,7 +319,7 @@ IMPLEMENT_FUNCTION(16, Ivo, inCompartment)
case 1:
getEntities()->drawSequenceLeft(kEntityIvo, "613Ch");
- getEntities()->enterCompartment(kEntityIvo, kObjectCompartmentH);
+ getEntities()->enterCompartment(kEntityIvo, kObjectCompartmentH, true);
getSavePoints()->push(kEntityIvo, kEntityCoudert, kAction88652208);
break;
@@ -384,7 +385,7 @@ IMPLEMENT_FUNCTION(18, Ivo, chapter2)
getData()->inventoryItem = kItemNone;
getObjects()->update(kObjectCompartmentH, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
- getObjects()->update(kObject47, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ getObjects()->update(kObject47, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
break;
}
@@ -744,7 +745,7 @@ IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION(31, Ivo, chapter5Handler)
- if (savepoint.action == kActionProceedChapter5)
+ if (savepoint.action == kAction192637492)
setup_fightCath();
IMPLEMENT_FUNCTION_END
@@ -780,7 +781,7 @@ IMPLEMENT_FUNCTION(32, Ivo, fightCath)
case 2:
params->param1 = getFight()->setup(kFightIvo);
if (params->param1) {
- getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, true);
+ getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, params->param1 == Fight::kFightEndLost);
} else {
getScenes()->loadSceneFromPosition(kCarBaggageRear, 96);
setup_knockedOut();
diff --git a/engines/lastexpress/entities/kahina.cpp b/engines/lastexpress/entities/kahina.cpp
index 047e3f0bd9..3b150531f5 100644
--- a/engines/lastexpress/entities/kahina.cpp
+++ b/engines/lastexpress/entities/kahina.cpp
@@ -39,14 +39,14 @@ namespace LastExpress {
Kahina::Kahina(LastExpressEngine *engine) : Entity(engine, kEntityKahina) {
ADD_CALLBACK_FUNCTION(Kahina, reset);
- ADD_CALLBACK_FUNCTION(Kahina, playSound);
- ADD_CALLBACK_FUNCTION(Kahina, savegame);
- ADD_CALLBACK_FUNCTION(Kahina, updateFromTime);
- ADD_CALLBACK_FUNCTION(Kahina, updateFromTicks);
- ADD_CALLBACK_FUNCTION(Kahina, lookingForCath);
- ADD_CALLBACK_FUNCTION(Kahina, updateEntity2);
- ADD_CALLBACK_FUNCTION(Kahina, updateEntity);
- ADD_CALLBACK_FUNCTION(Kahina, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_S(Kahina, playSound);
+ ADD_CALLBACK_FUNCTION_II(Kahina, savegame);
+ ADD_CALLBACK_FUNCTION_I(Kahina, updateFromTime);
+ ADD_CALLBACK_FUNCTION_I(Kahina, updateFromTicks);
+ ADD_CALLBACK_FUNCTION_I(Kahina, lookingForCath);
+ ADD_CALLBACK_FUNCTION_II(Kahina, updateEntity2);
+ ADD_CALLBACK_FUNCTION_II(Kahina, updateEntity);
+ ADD_CALLBACK_FUNCTION_SI(Kahina, enterExitCompartment);
ADD_CALLBACK_FUNCTION(Kahina, chapter1);
ADD_CALLBACK_FUNCTION(Kahina, chapter1Handler);
ADD_CALLBACK_FUNCTION(Kahina, awaitingCath);
@@ -56,7 +56,7 @@ Kahina::Kahina(LastExpressEngine *engine) : Entity(engine, kEntityKahina) {
ADD_CALLBACK_FUNCTION(Kahina, chapter2);
ADD_CALLBACK_FUNCTION(Kahina, inSeclusionPart2);
ADD_CALLBACK_FUNCTION(Kahina, chapter3);
- ADD_CALLBACK_FUNCTION(Kahina, function19);
+ ADD_CALLBACK_FUNCTION_II(Kahina, function19);
ADD_CALLBACK_FUNCTION(Kahina, beforeConcert);
ADD_CALLBACK_FUNCTION(Kahina, concert);
ADD_CALLBACK_FUNCTION(Kahina, finished);
@@ -194,12 +194,12 @@ IMPLEMENT_FUNCTION_II(7, Kahina, updateEntity2, CarIndex, EntityPosition)
default:
break;
- case kActionNone:
+ case kActionDefault:
if (getEntities()->updateEntity(_entityIndex, (CarIndex)params->param1, (EntityPosition)params->param2))
callbackAction();
break;
- case kActionDefault:
+ case kActionNone:
if (getEntities()->updateEntity(_entityIndex, (CarIndex)params->param1, (EntityPosition)params->param2)) {
callbackAction();
} else if (getEntities()->isDistanceBetweenEntities(kEntityKahina, kEntityPlayer, 1000)
@@ -579,14 +579,14 @@ IMPLEMENT_FUNCTION(17, Kahina, inSeclusionPart2)
break;
case kActionNone:
- if (params->param1) {
+ if (!params->param1) {
if (Entity::updateParameter(params->param2, getState()->time, 9000)) {
params->param1 = 1;
params->param2 = 0;
}
}
- if (getEvent(kEventKahinaAskSpeakFirebird) && getEvent(kEventKronosConversationFirebird) && getEntities()->isInsideTrainCar(kEntityPlayer, kCarKronos)) {
+ if (getEvent(kEventKahinaAskSpeakFirebird) && !getEvent(kEventKronosConversationFirebird) && getEntities()->isInsideTrainCar(kEntityPlayer, kCarKronos)) {
if (Entity::updateParameter(params->param3, getState()->time, 900)) {
setCallback(1);
setup_savegame(kSavegameTypeEvent, kEventKronosConversationFirebird);
@@ -927,7 +927,7 @@ IMPLEMENT_FUNCTION(21, Kahina, concert)
if (!params->param3)
params->param3 = (uint)getState()->time + 4500;
- if (params->param6 != kTimeInvalid) {
+ if (params->param5 != kTimeInvalid) {
if (Entity::updateParameterTime((TimeValue)params->param3, (getEntities()->isPlayerPosition(kCarKronos, 80) || getEntities()->isPlayerPosition(kCarKronos, 88)), params->param5, 0)) {
setCallback(2);
setup_findFirebird();
@@ -1043,7 +1043,7 @@ IMPLEMENT_FUNCTION(22, Kahina, finished)
break;
case kActionDrawScene:
- if (getData()->car > kCarGreenSleeping || (getData()->car == kCarGreenSleeping && getData()->entityPosition > kPosition_2740))
+ if (getEntityData(kEntityPlayer)->car > kCarGreenSleeping || (getEntityData(kEntityPlayer)->car == kCarGreenSleeping && getEntityData(kEntityPlayer)->entityPosition > kPosition_2740))
params->param1 = 1;
break;
}
@@ -1181,7 +1181,7 @@ IMPLEMENT_FUNCTION(24, Kahina, seekCath)
case 2:
if (getEntityData(kEntityPlayer)->entityPosition >= getData()->entityPosition)
- getAction()->playAnimation(getData()->car < kCarRedSleeping ? kEventKahinaGunYellow : kEventKahinaGunBlue);
+ getAction()->playAnimation(getData()->car == kCarRedSleeping ? kEventKahinaGunYellow : kEventKahinaGunBlue);
else
getAction()->playAnimation(kEventKahinaGun);
@@ -1396,7 +1396,7 @@ IMPLEMENT_FUNCTION(26, Kahina, searchTatiana)
break;
case 1:
- if (getEntities()->checkFields19(kEntityPlayer, kCarGreenSleeping, kPosition_7850)) {
+ if (getEntities()->checkFields19(kEntityPlayer, kCarRedSleeping, kPosition_7850)) {
setCallback(2);
setup_function19(kCarRedSleeping, kPosition_9460);
} else {
diff --git a/engines/lastexpress/entities/kronos.cpp b/engines/lastexpress/entities/kronos.cpp
index 61c164115b..60be35e8fa 100644
--- a/engines/lastexpress/entities/kronos.cpp
+++ b/engines/lastexpress/entities/kronos.cpp
@@ -63,11 +63,11 @@ static const struct {
Kronos::Kronos(LastExpressEngine *engine) : Entity(engine, kEntityKronos) {
ADD_CALLBACK_FUNCTION(Kronos, reset);
- ADD_CALLBACK_FUNCTION(Kronos, savegame);
- ADD_CALLBACK_FUNCTION(Kronos, updateEntity);
- ADD_CALLBACK_FUNCTION(Kronos, playSound);
- ADD_CALLBACK_FUNCTION(Kronos, updateFromTime);
- ADD_CALLBACK_FUNCTION(Kronos, updateFromTicks);
+ ADD_CALLBACK_FUNCTION_II(Kronos, savegame);
+ ADD_CALLBACK_FUNCTION_II(Kronos, updateEntity);
+ ADD_CALLBACK_FUNCTION_S(Kronos, playSound);
+ ADD_CALLBACK_FUNCTION_I(Kronos, updateFromTime);
+ ADD_CALLBACK_FUNCTION_I(Kronos, updateFromTicks);
ADD_CALLBACK_FUNCTION(Kronos, chapter1);
ADD_CALLBACK_FUNCTION(Kronos, chapter1Handler);
ADD_CALLBACK_FUNCTION(Kronos, greetCath);
@@ -147,7 +147,16 @@ IMPLEMENT_FUNCTION(8, Kronos, chapter1Handler)
break;
case kActionNone:
- Entity::timeCheck(kTime1489500, params->param2, WRAP_SETUP_FUNCTION(Kronos, setup_function11));
+ if (Entity::timeCheck(kTime1489500, params->param2, WRAP_SETUP_FUNCTION(Kronos, setup_function11)))
+ break;
+
+ if (params->param1 && getEntities()->isInsideTrainCar(kEntityPlayer, kCarKronos)) {
+ if (Entity::updateParameter(params->param3, getState()->timeTicks, 150)) {
+ setup_greetCath();
+ break;
+ }
+ }
+
break;
case kAction171849314:
@@ -260,7 +269,7 @@ IMPLEMENT_FUNCTION(14, Kronos, chapter3Handler)
break;
case kActionNone:
- if (getState()->time > kTime1993500 && !params->param1 && !params->param2 && !params->param3)
+ if (getState()->time > kTime1993500 && params->param1 && params->param2 && params->param3)
setup_function15();
break;
@@ -301,7 +310,7 @@ IMPLEMENT_FUNCTION(15, Kronos, function15)
if (params->param3 != kTimeInvalid && getState()->time > kTime2002500) {
if (getState()->time <= kTime2052000) {
- if (!getEntities()->isInSalon(kEntityPlayer) || getEntities()->isInSalon(kEntityPlayer) || !params->param3)
+ if (!getEntities()->isInSalon(kEntityPlayer) || getEntities()->isInSalon(kEntityBoutarel) || !params->param3)
params->param3 = (uint)getState()->time + 900;
if (params->param3 >= getState()->time)
@@ -381,7 +390,7 @@ IMPLEMENT_FUNCTION(17, Kronos, returnCompartment)
getData()->car = kCarRedSleeping;
setCallback(1);
- setup_updateEntity(kCarGreenSleeping, kPosition_9270);
+ setup_updateEntity(kCarKronos, kPosition_9270);
break;
case kActionCallback:
@@ -435,6 +444,19 @@ IMPLEMENT_FUNCTION(19, Kronos, startConcert)
break;
case kActionNone:
+ if (getState()->time > kTime2115000 && !params->param1) {
+ params->param1 = 1;
+ getSound()->playSound(kEntityKronos, "1917.lnk");
+ setup_duringConcert();
+ break;
+ }
+
+ if (getEntities()->isInKronosSanctum(kEntityPlayer)) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventKahinaPunchSuite4);
+ break;
+ }
+
break;
case kActionDefault:
@@ -442,6 +464,14 @@ IMPLEMENT_FUNCTION(19, Kronos, startConcert)
break;
case kActionDrawScene:
+ if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarKronos)
+ && !getEntities()->isInKronosSanctum(kEntityPlayer)
+ && !getInventory()->hasItem(kItemFirebird)
+ && !getEvent(kEventConcertStart)) {
+ getEntities()->drawSequenceLeft(kEntityKronos, "201a");
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventConcertStart);
+ }
break;
case kActionCallback:
@@ -479,6 +509,7 @@ IMPLEMENT_FUNCTION(20, Kronos, duringConcert)
break;
case kActionNone:
+ // TODO: should *2 really be there? should it be /2?
params->param5 = getSoundQueue()->getEntryTime(kEntityKronos)* 2;
if (params->param6 < ARRAYSIZE(concertData) && params->param5 > concertData[params->param6].time) {
@@ -734,12 +765,14 @@ IMPLEMENT_FUNCTION(22, Kronos, awaitingCath)
break;
case kActionNone:
- if (getProgress().field_44) {
- setCallback(5);
- setup_savegame(kSavegameTypeEvent, kEventKahinaPunchBaggageCarEntrance);
- } else {
- setCallback(6);
- setup_savegame(kSavegameTypeEvent, kEventKahinaWrongDoor);
+ if (getEntities()->isInKronosSanctum(kEntityPlayer)) {
+ if (getProgress().field_44) {
+ setCallback(5);
+ setup_savegame(kSavegameTypeEvent, kEventKahinaPunchBaggageCarEntrance);
+ } else {
+ setCallback(6);
+ setup_savegame(kSavegameTypeEvent, kEventKahinaWrongDoor);
+ }
}
break;
diff --git a/engines/lastexpress/entities/mahmud.cpp b/engines/lastexpress/entities/mahmud.cpp
index 08edda5276..9f43c695ea 100644
--- a/engines/lastexpress/entities/mahmud.cpp
+++ b/engines/lastexpress/entities/mahmud.cpp
@@ -41,15 +41,15 @@ namespace LastExpress {
Mahmud::Mahmud(LastExpressEngine *engine) : Entity(engine, kEntityMahmud) {
ADD_CALLBACK_FUNCTION(Mahmud, reset);
- ADD_CALLBACK_FUNCTION(Mahmud, draw);
- ADD_CALLBACK_FUNCTION(Mahmud, enterExitCompartment);
- ADD_CALLBACK_FUNCTION(Mahmud, enterExitCompartment2);
- ADD_CALLBACK_FUNCTION(Mahmud, playSound);
- ADD_CALLBACK_FUNCTION(Mahmud, playSoundMertens);
- ADD_CALLBACK_FUNCTION(Mahmud, updateFromTime);
- ADD_CALLBACK_FUNCTION(Mahmud, savegame);
- ADD_CALLBACK_FUNCTION(Mahmud, updateEntity);
- ADD_CALLBACK_FUNCTION(Mahmud, function10);
+ ADD_CALLBACK_FUNCTION_S(Mahmud, draw);
+ ADD_CALLBACK_FUNCTION_SI(Mahmud, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_SIII(Mahmud, enterExitCompartment2);
+ ADD_CALLBACK_FUNCTION_S(Mahmud, playSound);
+ ADD_CALLBACK_FUNCTION_S(Mahmud, playSoundMertens);
+ ADD_CALLBACK_FUNCTION_I(Mahmud, updateFromTime);
+ ADD_CALLBACK_FUNCTION_II(Mahmud, savegame);
+ ADD_CALLBACK_FUNCTION_II(Mahmud, updateEntity);
+ ADD_CALLBACK_FUNCTION_II(Mahmud, function10);
ADD_CALLBACK_FUNCTION(Mahmud, function11);
ADD_CALLBACK_FUNCTION(Mahmud, function12);
ADD_CALLBACK_FUNCTION(Mahmud, function13);
@@ -128,7 +128,7 @@ IMPLEMENT_FUNCTION_END
IMPLEMENT_FUNCTION_II(9, Mahmud, updateEntity, CarIndex, EntityPosition)
if (savepoint.action == kActionExcuseMeCath) {
if (getInventory()->hasItem(kItemPassengerList))
- getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1025" : "CAT1025Q");
+ getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1025" : "CAT1025A");
else
getSound()->excuseMeCath();
@@ -189,7 +189,7 @@ IMPLEMENT_FUNCTION_II(10, Mahmud, function10, ObjectIndex, bool)
break;
case 1:
- getSound()->playSound(kEntityMahmud, "MAH1174");
+ getSound()->playSound(kEntityMahmud, params->param2 ? "MAH1170E" : "MAH1173A");
break;
case 2:
@@ -197,7 +197,7 @@ IMPLEMENT_FUNCTION_II(10, Mahmud, function10, ObjectIndex, bool)
break;
case 3:
- getSound()->playSound(kEntityMahmud, params->param2 ? "MAH1170E" : "MAH1173A");
+ getSound()->playSound(kEntityMahmud, "MAH1174");
break;
}
}
@@ -720,7 +720,7 @@ IMPLEMENT_FUNCTION(14, Mahmud, chaptersHandler)
break;
case kAction290410610:
- params->param3 = (params->param3 < 1) ? 1 : 0;
+ params->param3 = (params->param3 == 0) ? 1 : 0;
setCallback(11);
setup_function10((ObjectIndex)savepoint.param.intValue, (bool)params->param3);
break;
diff --git a/engines/lastexpress/entities/max.cpp b/engines/lastexpress/entities/max.cpp
index d75b6af7f5..180bc1d1ca 100644
--- a/engines/lastexpress/entities/max.cpp
+++ b/engines/lastexpress/entities/max.cpp
@@ -38,10 +38,10 @@ namespace LastExpress {
Max::Max(LastExpressEngine *engine) : Entity(engine, kEntityMax) {
ADD_CALLBACK_FUNCTION(Max, reset);
- ADD_CALLBACK_FUNCTION(Max, playSound);
- ADD_CALLBACK_FUNCTION(Max, draw);
- ADD_CALLBACK_FUNCTION(Max, enterExitCompartment);
- ADD_CALLBACK_FUNCTION(Max, savegame);
+ ADD_CALLBACK_FUNCTION_S(Max, playSound);
+ ADD_CALLBACK_FUNCTION_S(Max, draw);
+ ADD_CALLBACK_FUNCTION_SI(Max, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_II(Max, savegame);
ADD_CALLBACK_FUNCTION(Max, withAnna);
ADD_CALLBACK_FUNCTION(Max, guardingCompartment);
ADD_CALLBACK_FUNCTION(Max, inCageFriendly);
@@ -95,12 +95,12 @@ IMPLEMENT_FUNCTION(6, Max, withAnna)
if (!getSoundQueue()->isBuffered(kEntityMax))
getSound()->playSound(kEntityMax, "Max1122");
- params->param1 = 255 * (4 * rnd(20) + 40);
+ params->param1 = 225 * (4 * rnd(20) + 40);
params->param2 = 0;
break;
case kActionDefault:
- params->param1 = 255 * (4 * rnd(20) + 40);
+ params->param1 = 225 * (4 * rnd(20) + 40);
break;
case kAction71277948:
@@ -111,7 +111,7 @@ IMPLEMENT_FUNCTION(6, Max, withAnna)
case kAction158007856:
if (!getSoundQueue()->isBuffered(kEntityMax)) {
getSound()->playSound(kEntityMax, "Max1122");
- params->param1 = 255 * (4 * rnd(20) + 40);
+ params->param1 = 225 * (4 * rnd(20) + 40);
}
break;
}
@@ -130,7 +130,7 @@ IMPLEMENT_FUNCTION(7, Max, guardingCompartment)
if (!getSoundQueue()->isBuffered(kEntityMax))
getSound()->playSound(kEntityMax, "Max1122");
- params->param1 = 255 * (4 * rnd(20) + 40);
+ params->param1 = 225 * (4 * rnd(20) + 40);
params->param2 = 0;
break;
@@ -147,7 +147,7 @@ IMPLEMENT_FUNCTION(7, Max, guardingCompartment)
break;
case kActionDefault:
- params->param1 = 255 * (4 * rnd(20) + 40);
+ params->param1 = 225 * (4 * rnd(20) + 40);
getData()->entityPosition = kPosition_4070;
getData()->location = kLocationInsideCompartment;
@@ -160,7 +160,7 @@ IMPLEMENT_FUNCTION(7, Max, guardingCompartment)
case kActionDrawScene:
if (!getSoundQueue()->isBuffered(kEntityMax)) {
if (getEntities()->isPlayerPosition(kCarRedSleeping, 56) || getEntities()->isPlayerPosition(kCarRedSleeping, 78))
- getSound()->playSound(kEntityMax, "Max1120");
+ getSound()->playSound(kEntityMax, "MAX1120");
}
break;
@@ -173,7 +173,7 @@ IMPLEMENT_FUNCTION(7, Max, guardingCompartment)
case 1:
case 2:
setCallback(3);
- setup_playSound("Max1122");
+ setup_playSound("MAX1122");
break;
case 3:
@@ -201,7 +201,7 @@ IMPLEMENT_FUNCTION(7, Max, guardingCompartment)
case kAction158007856:
if (!getSoundQueue()->isBuffered(kEntityMax)) {
getSound()->playSound(kEntityMax, "Max1122");
- params->param1 = 255 * (4 * rnd(20) + 40);
+ params->param1 = 225 * (4 * rnd(20) + 40);
}
break;
}
@@ -220,7 +220,7 @@ IMPLEMENT_FUNCTION(8, Max, inCageFriendly)
if (!getSoundQueue()->isBuffered(kEntityMax))
getSound()->playSound(kEntityMax, "Max3101");
- params->param2 = 255 * (4 * rnd(20) + 40);
+ params->param2 = 225 * (4 * rnd(4) + 8);
params->param3 = 0;
break;
@@ -241,7 +241,7 @@ IMPLEMENT_FUNCTION(8, Max, inCageFriendly)
break;
case kActionDefault:
- params->param2 = 255 * (4 * rnd(20) + 40);
+ params->param2 = 225 * (4 * rnd(4) + 8);
getObjects()->update(kObjectCageMax, kEntityMax, kObjectLocationNone, kCursorNormal, kCursorHand);
getEntities()->clearSequences(kEntityMax);
@@ -360,7 +360,7 @@ IMPLEMENT_FUNCTION(11, Max, chapter2)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(13, Max, chapter3)
+IMPLEMENT_FUNCTION(12, Max, chapter3)
switch (savepoint.action) {
default:
break;
@@ -390,6 +390,8 @@ IMPLEMENT_FUNCTION(13, Max, chapter3Handler)
case kActionNone:
if (params->param2) {
getData()->entityPosition = getEntityData(kEntityCoudert)->entityPosition;
+ getData()->location = getEntityData(kEntityCoudert)->location;
+ getData()->car = getEntityData(kEntityCoudert)->car;
break;
}
@@ -399,12 +401,12 @@ IMPLEMENT_FUNCTION(13, Max, chapter3Handler)
if (!getSoundQueue()->isBuffered(kEntityMax))
getSound()->playSound(kEntityMax, "Max1122");
- params->param1 = 255 * (4 * rnd(20) + 40);
+ params->param1 = 225 * (4 * rnd(20) + 40);
params->param3 = 0;
break;
case kActionDefault:
- params->param1 = 255 * (4 * rnd(20) + 40);
+ params->param1 = 225 * (4 * rnd(20) + 40);
getData()->entityPosition = kPosition_4070;
getData()->location = kLocationInsideCompartment;
@@ -430,7 +432,7 @@ IMPLEMENT_FUNCTION(13, Max, chapter3Handler)
if (!getSoundQueue()->isBuffered(kEntityMax)) {
getSound()->playSound(kEntityMax, "Max1122");
- params->param1 = 255 * (4 * rnd(20) + 40);
+ params->param1 = 225 * (4 * rnd(20) + 40);
}
break;
}
@@ -450,7 +452,7 @@ IMPLEMENT_FUNCTION(14, Max, inCageMad)
// Save game after freeing Max from his cage
case kActionOpenDoor:
if (getEvent(kEventCathMaxCage)) {
- if (getEvent(kEventCathMaxFree)) {
+ if (!getEvent(kEventCathMaxFree)) {
setCallback(2);
setup_savegame(kSavegameTypeEvent, kEventCathMaxFree);
}
@@ -512,6 +514,7 @@ IMPLEMENT_FUNCTION(15, Max, letMeIn)
case kActionNone:
if (params->param2) {
getData()->entityPosition = getEntityData(kEntityCoudert)->entityPosition;
+ getData()->location = getEntityData(kEntityCoudert)->location;
getData()->car = getEntityData(kEntityCoudert)->car;
}
@@ -532,7 +535,7 @@ IMPLEMENT_FUNCTION(15, Max, letMeIn)
getSound()->playSound(kEntityMax, "Max3010");
setCallback(1);
- setup_enterExitCompartment("630Bf", kObjectCompartment4);
+ setup_enterExitCompartment("630Bf", kObjectCompartmentF);
break;
case kActionCallback:
@@ -585,6 +588,7 @@ IMPLEMENT_FUNCTION(17, Max, function17)
case kActionNone:
if (params->param1) {
getData()->entityPosition = getEntityData(kEntityCoudert)->entityPosition;
+ getData()->location = getEntityData(kEntityCoudert)->location;
getData()->car = getEntityData(kEntityCoudert)->car;
}
break;
diff --git a/engines/lastexpress/entities/mertens.cpp b/engines/lastexpress/entities/mertens.cpp
index 7126adbfdc..573a35013e 100644
--- a/engines/lastexpress/entities/mertens.cpp
+++ b/engines/lastexpress/entities/mertens.cpp
@@ -40,36 +40,36 @@ namespace LastExpress {
Mertens::Mertens(LastExpressEngine *engine) : Entity(engine, kEntityMertens) {
ADD_CALLBACK_FUNCTION(Mertens, reset);
- ADD_CALLBACK_FUNCTION(Mertens, bloodJacket);
- ADD_CALLBACK_FUNCTION(Mertens, enterExitCompartment);
- ADD_CALLBACK_FUNCTION(Mertens, enterExitCompartment2);
- ADD_CALLBACK_FUNCTION(Mertens, enterExitCompartment3);
+ ADD_CALLBACK_FUNCTION_S(Mertens, bloodJacket);
+ ADD_CALLBACK_FUNCTION_SI(Mertens, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_SI(Mertens, enterExitCompartment2);
+ ADD_CALLBACK_FUNCTION_SIII(Mertens, enterExitCompartment3);
ADD_CALLBACK_FUNCTION(Mertens, callbackActionOnDirection);
- ADD_CALLBACK_FUNCTION(Mertens, playSound);
- ADD_CALLBACK_FUNCTION(Mertens, playSound16);
- ADD_CALLBACK_FUNCTION(Mertens, savegame);
- ADD_CALLBACK_FUNCTION(Mertens, updateEntity);
- ADD_CALLBACK_FUNCTION(Mertens, function11);
- ADD_CALLBACK_FUNCTION(Mertens, bonsoir);
- ADD_CALLBACK_FUNCTION(Mertens, function13);
- ADD_CALLBACK_FUNCTION(Mertens, function14);
- ADD_CALLBACK_FUNCTION(Mertens, function15);
- ADD_CALLBACK_FUNCTION(Mertens, function16);
+ ADD_CALLBACK_FUNCTION_S(Mertens, playSound);
+ ADD_CALLBACK_FUNCTION_S(Mertens, playSound16);
+ ADD_CALLBACK_FUNCTION_II(Mertens, savegame);
+ ADD_CALLBACK_FUNCTION_II(Mertens, updateEntity);
+ ADD_CALLBACK_FUNCTION_I(Mertens, function11);
+ ADD_CALLBACK_FUNCTION_I(Mertens, bonsoir);
+ ADD_CALLBACK_FUNCTION_II(Mertens, function13);
+ ADD_CALLBACK_FUNCTION_I(Mertens, function14);
+ ADD_CALLBACK_FUNCTION_I(Mertens, function15);
+ ADD_CALLBACK_FUNCTION_I(Mertens, function16);
ADD_CALLBACK_FUNCTION(Mertens, function17);
ADD_CALLBACK_FUNCTION(Mertens, function18);
ADD_CALLBACK_FUNCTION(Mertens, function19);
ADD_CALLBACK_FUNCTION(Mertens, function20);
- ADD_CALLBACK_FUNCTION(Mertens, function21);
+ ADD_CALLBACK_FUNCTION_II(Mertens, function21);
ADD_CALLBACK_FUNCTION(Mertens, function22);
ADD_CALLBACK_FUNCTION(Mertens, function23);
ADD_CALLBACK_FUNCTION(Mertens, function24);
ADD_CALLBACK_FUNCTION(Mertens, function25);
- ADD_CALLBACK_FUNCTION(Mertens, function26);
- ADD_CALLBACK_FUNCTION(Mertens, tylerCompartment);
- ADD_CALLBACK_FUNCTION(Mertens, function28);
- ADD_CALLBACK_FUNCTION(Mertens, function29);
- ADD_CALLBACK_FUNCTION(Mertens, function30);
- ADD_CALLBACK_FUNCTION(Mertens, function31);
+ ADD_CALLBACK_FUNCTION_I(Mertens, function26);
+ ADD_CALLBACK_FUNCTION_I(Mertens, tylerCompartment);
+ ADD_CALLBACK_FUNCTION_S(Mertens, function28);
+ ADD_CALLBACK_FUNCTION_SS(Mertens, function29);
+ ADD_CALLBACK_FUNCTION_I(Mertens, function30);
+ ADD_CALLBACK_FUNCTION_I(Mertens, function31);
ADD_CALLBACK_FUNCTION(Mertens, function32);
ADD_CALLBACK_FUNCTION(Mertens, function33);
ADD_CALLBACK_FUNCTION(Mertens, chapter1);
@@ -107,7 +107,7 @@ IMPLEMENT_FUNCTION_S(2, Mertens, bloodJacket)
break;
case kActionNone:
- Entity::savegameBloodJacket();
+ Entity::savegameBloodJacket(1);
break;
case kActionExitCompartment:
@@ -134,7 +134,7 @@ IMPLEMENT_FUNCTION_SI(3, Mertens, enterExitCompartment, ObjectIndex)
break;
case kActionNone:
- Entity::savegameBloodJacket();
+ Entity::savegameBloodJacket(1);
return;
case kActionCallback:
@@ -155,7 +155,7 @@ IMPLEMENT_FUNCTION_SI(4, Mertens, enterExitCompartment2, ObjectIndex)
break;
case kActionNone:
- Entity::savegameBloodJacket();
+ Entity::savegameBloodJacket(1);
return;
case kAction4:
@@ -181,7 +181,7 @@ IMPLEMENT_FUNCTION_SIII(5, Mertens, enterExitCompartment3, ObjectIndex, EntityPo
break;
case kActionNone:
- Entity::savegameBloodJacket();
+ Entity::savegameBloodJacket(1);
break;
case kActionExitCompartment:
@@ -223,7 +223,7 @@ IMPLEMENT_FUNCTION(6, Mertens, callbackActionOnDirection)
break;
}
- Entity::savegameBloodJacket();
+ Entity::savegameBloodJacket(1);
break;
case kActionExitCompartment:
@@ -246,7 +246,7 @@ IMPLEMENT_FUNCTION_S(7, Mertens, playSound)
break;
case kActionNone:
- Entity::savegameBloodJacket();
+ Entity::savegameBloodJacket(1);
break;
case kActionEndSound:
@@ -273,7 +273,7 @@ IMPLEMENT_FUNCTION_S(8, Mertens, playSound16)
break;
case kActionNone:
- Entity::savegameBloodJacket();
+ Entity::savegameBloodJacket(1);
break;
case kActionEndSound:
@@ -352,6 +352,7 @@ IMPLEMENT_FUNCTION_II(10, Mertens, updateEntity, CarIndex, EntityPosition)
case kAction1:
params->param3 = 0;
+ getData()->inventoryItem = kItemNone;
if (getProgress().eventCorpseFound || getEvent(kEventMertensAskTylerCompartment) || getEvent(kEventMertensAskTylerCompartmentD)) {
if (ENTITY_PARAM(0, 4) && getProgress().jacket == kJacketGreen && !getEvent(kEventMertensDontMakeBed) && !getProgress().eventCorpseThrown) {
setCallback(6);
@@ -462,7 +463,8 @@ IMPLEMENT_FUNCTION_I(11, Mertens, function11, uint32)
break;
case kActionNone:
- Entity::savegameBloodJacket();
+ if (Entity::savegameBloodJacket(1))
+ break;
if (!Entity::updateParameter(params->param2, getState()->time, params->param1))
break;
@@ -483,7 +485,7 @@ IMPLEMENT_FUNCTION_END
IMPLEMENT_FUNCTION_I(12, Mertens, bonsoir, EntityIndex)
EntityIndex entity = (EntityIndex)params->param1;
- if (savepoint.action == kActionDefault)
+ if (savepoint.action != kActionDefault)
return;
if (getSoundQueue()->isBuffered(kEntityMertens)) {
@@ -495,7 +497,7 @@ IMPLEMENT_FUNCTION_I(12, Mertens, bonsoir, EntityIndex)
if (Entities::isFemale(entity)) {
getSound()->playSound(kEntityMertens, rnd(2) ? "CON1112" : "CON1112A");
} else {
- if (entity || getProgress().field_18 != 2) {
+ if (entity != kEntityPlayer || getProgress().field_18 != 2) {
getSound()->playSound(kEntityMertens, "CON1112F");
} else {
switch (rnd(3)) {
@@ -525,15 +527,16 @@ IMPLEMENT_FUNCTION_I(12, Mertens, bonsoir, EntityIndex)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION_II(13, Mertens, function13, bool, bool)
+IMPLEMENT_FUNCTION_II(13, Mertens, function13, bool, EntityIndex)
switch (savepoint.action) {
default:
break;
case kActionNone:
- Entity::savegameBloodJacket();
+ if (Entity::savegameBloodJacket(4))
+ break;
- if (!params->param2 && !params->param3) {
+ if (params->param2 == kEntityPlayer && !params->param3) {
if (Entity::updateParameter(params->param4, getState()->timeTicks, 75)) {
getData()->inventoryItem = kItemNone;
setCallback(5);
@@ -569,11 +572,29 @@ IMPLEMENT_FUNCTION_II(13, Mertens, function13, bool, bool)
break;
case kActionDefault:
- if (params->param2)
+ if (params->param2 != kEntityPlayer)
params->param3 = 1;
if (!getSoundQueue()->isBuffered(kEntityMertens)) {
-
+ if (getProgress().chapter == kChapter3 && !params->param1 && getState()->time < kTime2173500 &&
+ (getState()->time > kTime2106000 || params->param2 != kEntityPlayer && getState()->time > kTime2079000)) {
+ // guide guests to the concert
+ if (params->param2 == kEntityAugust)
+ getSound()->playSound(kEntityMertens, "CON3052");
+ else if (Entities::isFemale((EntityIndex)params->param2))
+ getSound()->playSound(kEntityMertens, "CON3051");
+ else if (params->param2 == kEntityPlayer)
+ getSound()->playSound(kEntityMertens, getProgress().field_40 ? "CON3054" : "CON3053");
+ else {
+ setCallback(1);
+ setup_bonsoir((EntityIndex)params->param2);
+ break;
+ }
+ } else {
+ setCallback(2);
+ setup_bonsoir((EntityIndex)params->param2);
+ break;
+ }
}
setCallback(3);
@@ -583,7 +604,7 @@ IMPLEMENT_FUNCTION_II(13, Mertens, function13, bool, bool)
case kAction16:
params->param3--;
- if (params->param2 && !params->param3) {
+ if (params->param2 != kEntityPlayer && !params->param3) {
getData()->inventoryItem = kItemNone;
setCallback(10);
setup_function18();
@@ -594,6 +615,12 @@ IMPLEMENT_FUNCTION_II(13, Mertens, function13, bool, bool)
if (getEntities()->isPlayerPosition(kCarGreenSleeping, 23) && ENTITY_PARAM(0, 7) && !getEvent(kEventKronosConversation)) {
setCallback(8);
setup_savegame(kSavegameTypeEvent, kEventMertensKronosInvitation);
+ break;
+ }
+ if (!params->param3) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(9);
+ setup_function18();
}
break;
@@ -631,13 +658,14 @@ IMPLEMENT_FUNCTION_II(13, Mertens, function13, bool, bool)
case 8:
getAction()->playAnimation(kEventMertensKronosInvitation);
+ getProgress().eventMertensKronosInvitation = true;
ENTITY_PARAM(0, 6) = 0;
ENTITY_PARAM(0, 7) = 0;
getScenes()->processScene();
if (!params->param3) {
getData()->inventoryItem = kItemNone;
- setCallback(10);
+ setCallback(9);
setup_function18();
}
break;
@@ -653,7 +681,7 @@ IMPLEMENT_FUNCTION_I(14, Mertens, function14, EntityIndex)
break;
case kActionNone:
- Entity::savegameBloodJacket();
+ Entity::savegameBloodJacket(4);
break;
case kActionDefault:
@@ -1167,7 +1195,7 @@ IMPLEMENT_FUNCTION(22, Mertens, function22)
case 4:
getEntities()->drawSequenceLeft(kEntityMertens, "601Nh");
- getEntities()->enterCompartment(kEntityMertens, kObjectCompartment8);
+ getEntities()->enterCompartment(kEntityMertens, kObjectCompartment8, true);
getSavePoints()->push(kEntityMertens, kEntityMahmud, kAction225563840);
break;
@@ -1257,7 +1285,7 @@ IMPLEMENT_FUNCTION(23, Mertens, function23)
break;
case 4:
- getEntities()->exitCompartment(kEntityMertens, kObjectCompartment4);
+ getEntities()->exitCompartment(kEntityMertens, kObjectCompartment4, true);
getData()->location = kLocationInsideCompartment;
getEntities()->clearSequences(kEntityMertens);
@@ -1669,7 +1697,7 @@ label_callback11:
break;
}
} else {
- setCallback(26);
+ setCallback(19);
setup_function26(false);
}
@@ -1742,7 +1770,7 @@ label_callback11:
case kActionKnock:
if (params->param1) {
- getObjects()->update(kObjectCompartment1, kEntityMertens, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorNormal);
switch (params->param1) {
default:
@@ -1774,7 +1802,7 @@ label_callback11:
break;
case kActionOpenDoor:
- getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).status == kObjectLocation1 ? "LIB012" : "LIB014");
+ getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).status == kObjectLocation1 ? "LIB032" : "LIB014");
if (getProgress().eventCorpseMovedFromFloor) {
@@ -1855,7 +1883,7 @@ label_callback11:
} else {
if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarGreenSleeping)) {
setCallback(2);
- setup_enterExitCompartment("601Ra", kObjectCompartment1);
+ setup_enterExitCompartment2("601Ra", kObjectCompartment1);
} else {
getScenes()->loadSceneFromPosition(kCarNone, 1);
@@ -2222,7 +2250,7 @@ IMPLEMENT_FUNCTION_I(30, Mertens, function30, MertensActionType)
if (params->param3)
getObjects()->update(kObjectCompartment2, kEntityPlayer, getObjects()->get(kObjectCompartment2).status, kCursorHandKnock, kCursorHand);
- getEntities()->exitCompartment(kEntityMertens, kObjectCompartment2);
+ getEntities()->exitCompartment(kEntityMertens, kObjectCompartment2, true);
if (getProgress().field_14 == 3)
getProgress().field_14 = 0;
@@ -2243,7 +2271,7 @@ IMPLEMENT_FUNCTION_I(30, Mertens, function30, MertensActionType)
if (params->param3)
getObjects()->update(kObjectCompartment3, kEntityPlayer, getObjects()->get(kObjectCompartment3).status, kCursorHandKnock, kCursorHand);
- getEntities()->exitCompartment(kEntityMertens, kObjectCompartment3);
+ getEntities()->exitCompartment(kEntityMertens, kObjectCompartment3, true);
if (getProgress().field_14 == 3)
getProgress().field_14 = 0;
@@ -2465,6 +2493,7 @@ IMPLEMENT_FUNCTION(33, Mertens, function33)
break;
}
+ ENTITY_PARAM(1, 8) = 0;
callbackAction();
break;
@@ -2478,12 +2507,14 @@ IMPLEMENT_FUNCTION(33, Mertens, function33)
break;
}
+ ENTITY_PARAM(1, 8) = 0;
callbackAction();
break;
case 13:
ENTITY_PARAM(2, 2) = 0;
+ ENTITY_PARAM(1, 8) = 0;
callbackAction();
break;
}
@@ -2631,14 +2662,12 @@ IMPLEMENT_FUNCTION(36, Mertens, function36)
break;
case 2:
- if (ENTITY_PARAM(0, 6)) {
- if (getEntities()->isPlayerInCar(kCarGreenSleeping) && getData()->entityPosition < getEntityData(kEntityPlayer)->entityPosition) {
- setCallback(3);
- setup_updateEntity(kCarGreenSleeping, kPosition_9460);
- } else {
- setCallback(7);
- setup_tylerCompartment(kMertensAction2);
- }
+ if (ENTITY_PARAM(0, 6) && getEntities()->isPlayerInCar(kCarGreenSleeping) && getData()->entityPosition < getEntityData(kEntityPlayer)->entityPosition) {
+ setCallback(3);
+ setup_updateEntity(kCarGreenSleeping, kPosition_9460);
+ } else if (!getProgress().eventMertensKronosInvitation) {
+ setCallback(7);
+ setup_tylerCompartment(kMertensAction2);
} else {
ENTITY_PARAM(0, 6) = 0;
ENTITY_PARAM(0, 7) = 0;
@@ -2657,7 +2686,7 @@ IMPLEMENT_FUNCTION(36, Mertens, function36)
break;
case 4:
- if (ENTITY_PARAM(0, 6)) {
+ if (!getProgress().eventMertensKronosInvitation) {
setCallback(7);
setup_tylerCompartment(kMertensAction2);
} else {
@@ -2720,9 +2749,9 @@ IMPLEMENT_FUNCTION(37, Mertens, function37)
break;
case kActionEndSound:
- ++params->param6;
+ ++params->param1;
- if (params->param6 == 1)
+ if (params->param1 == 1)
getSound()->playSound(kEntityMertens, getEntities()->isDistanceBetweenEntities(kEntityMertens, kEntityPlayer, 2000) ? "CON1152" : "CON1151");
break;
@@ -2737,7 +2766,7 @@ IMPLEMENT_FUNCTION(37, Mertens, function37)
break;
case 1:
- setCallback(1);
+ setCallback(2);
setup_updateEntity(kCarRedSleeping, kPosition_1500);
break;
@@ -3039,10 +3068,10 @@ label_callback_8:
break;
}
+label_callback_9:
if (getProgress().field_14 == 29)
goto label_callback_13;
-label_callback_9:
if (ENTITY_PARAM(1, 6)) {
getData()->inventoryItem = kItemNone;
setCallback(10);
@@ -3141,7 +3170,7 @@ label_callback_19:
if (!ENTITY_PARAM(0, 1) && !ENTITY_PARAM(2, 1)) {
getData()->inventoryItem = kItemNone;
setCallback(20);
- setup_function13((bool)savepoint.param.intValue, (bool)savepoint.entity2);
+ setup_function13((bool)savepoint.param.intValue, savepoint.entity2);
}
break;
@@ -3172,13 +3201,13 @@ label_callback_2_4:
if ((getEntities()->isPlayerPosition(kCarGreenSleeping, 1) || getEntities()->isPlayerPosition(kCarGreenSleeping, 23)) && !ENTITY_PARAM(0, 1) && !ENTITY_PARAM(2, 1)) {
getData()->inventoryItem = kItemNone;
setCallback(getEntities()->isPlayerPosition(kCarGreenSleeping, 1) ? 5 : 6);
- setup_function13(getEntities()->isPlayerPosition(kCarGreenSleeping, 1), false);
+ setup_function13(getEntities()->isPlayerPosition(kCarGreenSleeping, 1), kEntityPlayer);
break;
}
label_callback_5_6:
if (getEntities()->isPlayerInCar(kCarGreenSleeping) && getData()->entityPosition < getEntityData(kEntityPlayer)->entityPosition) {
- if (getProgress().jacket == kJacketOriginal || ENTITY_PARAM(0, 7)) {
+ if (getProgress().jacket == kJacketBlood || ENTITY_PARAM(0, 7)) {
getData()->inventoryItem = kItemNone;
setCallback(7);
setup_function32();
@@ -3325,13 +3354,13 @@ IMPLEMENT_FUNCTION(43, Mertens, chapter2)
ENTITY_PARAM(0, 6) = 0;
ENTITY_PARAM(0, 8) = 0;
- ENTITY_PARAM(0, 1) = 0;
- ENTITY_PARAM(0, 2) = 0;
- ENTITY_PARAM(0, 3) = 0;
- ENTITY_PARAM(0, 4) = 0;
- ENTITY_PARAM(0, 5) = 0;
- ENTITY_PARAM(0, 6) = 0;
- ENTITY_PARAM(0, 7) = 0;
+ ENTITY_PARAM(1, 1) = 0;
+ ENTITY_PARAM(1, 2) = 0;
+ ENTITY_PARAM(1, 3) = 0;
+ ENTITY_PARAM(1, 4) = 0;
+ ENTITY_PARAM(1, 5) = 0;
+ ENTITY_PARAM(1, 6) = 0;
+ ENTITY_PARAM(1, 7) = 0;
break;
case kActionCallback:
@@ -3380,7 +3409,7 @@ label_callback3:
case kAction11:
if (!ENTITY_PARAM(2, 1)) {
setCallback(5);
- setup_function13((bool)savepoint.param.intValue, (bool)savepoint.entity2);
+ setup_function13((bool)savepoint.param.intValue, savepoint.entity2);
}
break;
@@ -3390,11 +3419,11 @@ label_callback3:
if (getEntities()->isPlayerPosition(kCarGreenSleeping, 1)) {
setCallback(6);
- setup_function13(true, false);
+ setup_function13(true, kEntityPlayer);
} else if (getEntities()->isPlayerPosition(kCarGreenSleeping, 23)) {
setCallback(7);
- setup_function13(false, false);
+ setup_function13(false, kEntityPlayer);
}
break;
@@ -3470,7 +3499,7 @@ IMPLEMENT_FUNCTION(45, Mertens, chapter3)
ENTITY_PARAM(1, 6) = 0;
ENTITY_PARAM(1, 7) = 0;
- ENTITY_PARAM(2, 3) = 0;
+ ENTITY_PARAM(2, 4) = 0;
break;
case kActionCallback:
@@ -3554,7 +3583,7 @@ label_callback_10:
case kAction11:
if (!ENTITY_PARAM(2, 1)) {
setCallback(12);
- setup_function13((bool)savepoint.param.intValue, savepoint.entity2 != kEntityPlayer);
+ setup_function13((bool)savepoint.param.intValue, savepoint.entity2);
}
break;
@@ -3565,10 +3594,10 @@ label_callback_10:
if (!ENTITY_PARAM(2, 1)) {
if (getEntities()->isPlayerPosition(kCarGreenSleeping, 1)) {
setCallback(13);
- setup_function13(true, false);
+ setup_function13(true, kEntityPlayer);
} else if (getEntities()->isPlayerPosition(kCarGreenSleeping, 23)) {
setCallback(14);
- setup_function13(false, false);
+ setup_function13(false, kEntityPlayer);
}
}
break;
@@ -3668,7 +3697,7 @@ IMPLEMENT_FUNCTION(47, Mertens, chapter4)
ENTITY_PARAM(1, 6) = 0;
ENTITY_PARAM(1, 7) = 0;
- ENTITY_PARAM(2, 4) = 0;
+ ENTITY_PARAM(2, 3) = 0;
break;
case kActionCallback:
@@ -3762,7 +3791,7 @@ label_callback_8:
case kAction11:
if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1)) {
setCallback(9);
- setup_function13((bool)savepoint.param.intValue, savepoint.entity2 != kEntityPlayer);
+ setup_function13((bool)savepoint.param.intValue, savepoint.entity2);
}
break;
@@ -3778,10 +3807,10 @@ label_callback_8:
if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1)) {
if (getEntities()->isPlayerPosition(kCarGreenSleeping, 1)) {
setCallback(10);
- setup_function13(true, false);
+ setup_function13(true, kEntityPlayer);
} else if (getEntities()->isPlayerPosition(kCarGreenSleeping, 23)) {
setCallback(11);
- setup_function13(false, false);
+ setup_function13(false, kEntityPlayer);
}
}
break;
@@ -4008,7 +4037,7 @@ IMPLEMENT_FUNCTION(53, Mertens, function53)
break;
params->param1 = 0;
- params->param2 = 0;
+ params->param2 = 1;
getObjects()->update(kObjectCompartment4, kEntityMertens, kObjectLocation1, kCursorNormal, kCursorNormal);
}
diff --git a/engines/lastexpress/entities/mertens.h b/engines/lastexpress/entities/mertens.h
index 1b6d1d2f31..55c2ddd0bc 100644
--- a/engines/lastexpress/entities/mertens.h
+++ b/engines/lastexpress/entities/mertens.h
@@ -126,7 +126,7 @@ public:
* @param entity The entity
*/
DECLARE_FUNCTION_1(bonsoir, EntityIndex entity)
- DECLARE_FUNCTION_2(function13, bool, bool)
+ DECLARE_FUNCTION_2(function13, bool, EntityIndex entity)
DECLARE_FUNCTION_1(function14, EntityIndex entity)
DECLARE_FUNCTION_1(function15, bool)
DECLARE_FUNCTION_1(function16, bool)
diff --git a/engines/lastexpress/entities/milos.cpp b/engines/lastexpress/entities/milos.cpp
index 65cad07b1b..8177f99ff6 100644
--- a/engines/lastexpress/entities/milos.cpp
+++ b/engines/lastexpress/entities/milos.cpp
@@ -43,16 +43,16 @@ namespace LastExpress {
Milos::Milos(LastExpressEngine *engine) : Entity(engine, kEntityMilos) {
ADD_CALLBACK_FUNCTION(Milos, reset);
- ADD_CALLBACK_FUNCTION(Milos, draw);
- ADD_CALLBACK_FUNCTION(Milos, enterExitCompartment);
- ADD_CALLBACK_FUNCTION(Milos, enterExitCompartment2);
+ ADD_CALLBACK_FUNCTION_S(Milos, draw);
+ ADD_CALLBACK_FUNCTION_SI(Milos, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_SI(Milos, enterExitCompartment2);
ADD_CALLBACK_FUNCTION(Milos, callbackActionOnDirection);
- ADD_CALLBACK_FUNCTION(Milos, playSound);
- ADD_CALLBACK_FUNCTION(Milos, playSound16);
- ADD_CALLBACK_FUNCTION(Milos, savegame);
- ADD_CALLBACK_FUNCTION(Milos, updateFromTime);
- ADD_CALLBACK_FUNCTION(Milos, enterCompartmentDialog);
- ADD_CALLBACK_FUNCTION(Milos, function11);
+ ADD_CALLBACK_FUNCTION_S(Milos, playSound);
+ ADD_CALLBACK_FUNCTION_S(Milos, playSound16);
+ ADD_CALLBACK_FUNCTION_II(Milos, savegame);
+ ADD_CALLBACK_FUNCTION_I(Milos, updateFromTime);
+ ADD_CALLBACK_FUNCTION_II(Milos, enterCompartmentDialog);
+ ADD_CALLBACK_FUNCTION_I(Milos, function11);
ADD_CALLBACK_FUNCTION(Milos, chapter1);
ADD_CALLBACK_FUNCTION(Milos, function13);
ADD_CALLBACK_FUNCTION(Milos, function14);
@@ -67,8 +67,8 @@ Milos::Milos(LastExpressEngine *engine) : Entity(engine, kEntityMilos) {
ADD_CALLBACK_FUNCTION(Milos, function23);
ADD_CALLBACK_FUNCTION(Milos, function24);
ADD_CALLBACK_FUNCTION(Milos, function25);
- ADD_CALLBACK_FUNCTION(Milos, function26);
- ADD_CALLBACK_FUNCTION(Milos, function27);
+ ADD_CALLBACK_FUNCTION_I(Milos, function26);
+ ADD_CALLBACK_FUNCTION_II(Milos, function27);
ADD_CALLBACK_FUNCTION(Milos, chapter4);
ADD_CALLBACK_FUNCTION(Milos, chapter4Handler);
ADD_CALLBACK_FUNCTION(Milos, function30);
@@ -180,11 +180,12 @@ IMPLEMENT_FUNCTION_I(11, Milos, function11, TimeValue)
params->param2 = 0;
params->param3 = 1;
getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation1, kCursorNormal, kCursorNormal);
+ params->param8 = 0;
}
+ } else {
+ params->param8 = 0;
}
- params->param8 = 0;
-
if (getProgress().chapter != kChapter1 || params->param5)
break;
@@ -344,7 +345,7 @@ IMPLEMENT_FUNCTION_I(11, Milos, function11, TimeValue)
break;
case kAction123852928:
- params->param1 = 13;
+ setCallback(13);
setup_enterExitCompartment("611Dg", kObjectCompartmentG);
break;
@@ -737,6 +738,7 @@ IMPLEMENT_FUNCTION(15, Milos, chapter1Handler)
}
}
+label_callback_1:
if (getEntities()->isPlayerPosition(kCarRestaurant, 70) && !params->param2) {
if (!Entity::updateParameter(params->param5, getState()->timeTicks, 45))
break;
@@ -759,7 +761,7 @@ IMPLEMENT_FUNCTION(15, Milos, chapter1Handler)
case 1:
getEntities()->drawSequenceLeft(kEntityMilos, "009A");
params->param1 = 1;
- break;
+ goto label_callback_1;
case 2:
getEntities()->drawSequenceLeft(kEntityMilos, "009A");
@@ -891,9 +893,11 @@ IMPLEMENT_FUNCTION(19, Milos, chapter2)
case kActionDefault:
getEntities()->clearSequences(kEntityMilos);
- getData()->entityPosition = kPosition_4689;
- getData()->location = kLocationInsideCompartment;
- getData()->car = kCarRestaurant;
+ getData()->entityPosition = kPosition_540;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->inventoryItem = kItemNone;
+ getData()->clothes = kClothesDefault;
getObjects()->update(kObjectCompartmentG, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
getObjects()->update(kObject46, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
@@ -969,6 +973,7 @@ IMPLEMENT_FUNCTION(21, Milos, function21)
case kActionOpenDoor:
getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorNormal, kCursorNormal);
+ getEntityData(kEntityPlayer)->location = kLocationInsideCompartment;
setCallback(3);
setup_savegame(kSavegameTypeEvent, kEventMilosCompartmentVisitAugust);
@@ -1156,7 +1161,7 @@ IMPLEMENT_FUNCTION(24, Milos, function24)
setCallback(12);
setup_playSound("LIB013");
} else {
- getData()->location = kLocationInsideCompartment;
+ getEntityData(kEntityPlayer)->location = kLocationInsideCompartment;
setCallback(11);
setup_savegame(kSavegameTypeEvent, kEventMilosCompartmentVisitAugust);
@@ -1354,7 +1359,7 @@ IMPLEMENT_FUNCTION(25, Milos, function25)
RESET_ENTITY_STATE(kEntityVesna, Vesna, setup_inCompartment);
- getData()->location = kLocationInsideCompartment;
+ getEntityData(kEntityPlayer)->location = kLocationInsideCompartment;
setCallback(4);
setup_savegame(kSavegameTypeEvent, kEventMilosCompartmentVisitTyler);
@@ -1390,6 +1395,7 @@ IMPLEMENT_FUNCTION_I(26, Milos, function26, TimeValue)
case kActionNone:
if (params->param1 < getState()->time && !params->param2) {
+ params->param2 = 1;
callbackAction();
break;
}
@@ -1556,7 +1562,7 @@ IMPLEMENT_FUNCTION(29, Milos, chapter4Handler)
break;
case 2:
- getEntities()->exitCompartment(kEntityMilos, kObjectCompartmentG);
+ getEntities()->exitCompartment(kEntityMilos, kObjectCompartmentG, true);
getData()->location = kLocationInsideCompartment;
getData()->entityPosition = kPosition_3050;
@@ -1600,7 +1606,7 @@ IMPLEMENT_FUNCTION(30, Milos, function30)
default:
break;
- case kActionNone:
+ case kActionDefault:
setCallback(1);
setup_function11(kTime2410200);
break;
@@ -1638,7 +1644,7 @@ IMPLEMENT_FUNCTION(31, Milos, function31)
default:
break;
- case kActionNone:
+ case kActionDefault:
setCallback(1);
setup_enterExitCompartment("609CG", kObjectCompartmentG);
break;
@@ -1721,7 +1727,7 @@ IMPLEMENT_FUNCTION(34, Milos, chapter5Handler)
break;
case 1:
- getAction()->playAnimation(isNight() ? kEventLocomotiveMilosShovelingNight : kEventLocomotiveMilosShovelingDay);
+ getAction()->playAnimation(getProgress().isNightTime ? kEventLocomotiveMilosShovelingDay : kEventLocomotiveMilosShovelingNight);
getScenes()->processScene();
break;
@@ -1733,7 +1739,7 @@ IMPLEMENT_FUNCTION(34, Milos, chapter5Handler)
getSoundQueue()->removeFromQueue("ARRIVE");
getSoundQueue()->processEntries();
- getAction()->playAnimation(isNight() ? kEventLocomotiveMilosNight : kEventLocomotiveMilosDay);
+ getAction()->playAnimation(getProgress().isNightTime ? kEventLocomotiveMilosDay : kEventLocomotiveMilosNight);
getSoundQueue()->setupEntry(kSoundType7, kEntityMilos);
getScenes()->loadSceneFromPosition(kCarCoalTender, 1);
break;
@@ -1787,11 +1793,12 @@ IMPLEMENT_FUNCTION(34, Milos, chapter5Handler)
if (!getProgress().isNightTime) {
setCallback(3);
setup_savegame(kSavegameTypeEvent, kEventLocomotiveAnnaStopsTrain);
+ break;
}
getSoundQueue()->processEntry(kEntityMilos);
- if (getState()->time < kTimeTrainStopped2)
- getState()->time = kTimeTrainStopped2;
+ if (getState()->time < kTime2949300)
+ getState()->time = kTime2949300;
setCallback(4);
setup_savegame(kSavegameTypeEvent, kEventLocomotiveRestartTrain);
diff --git a/engines/lastexpress/entities/mmeboutarel.cpp b/engines/lastexpress/entities/mmeboutarel.cpp
index f00fb7a9cb..994a0ceda6 100644
--- a/engines/lastexpress/entities/mmeboutarel.cpp
+++ b/engines/lastexpress/entities/mmeboutarel.cpp
@@ -38,13 +38,13 @@ namespace LastExpress {
MmeBoutarel::MmeBoutarel(LastExpressEngine *engine) : Entity(engine, kEntityMmeBoutarel) {
ADD_CALLBACK_FUNCTION(MmeBoutarel, reset);
- ADD_CALLBACK_FUNCTION(MmeBoutarel, playSound);
- ADD_CALLBACK_FUNCTION(MmeBoutarel, draw);
- ADD_CALLBACK_FUNCTION(MmeBoutarel, updateFromTime);
- ADD_CALLBACK_FUNCTION(MmeBoutarel, enterExitCompartment);
- ADD_CALLBACK_FUNCTION(MmeBoutarel, enterExitCompartment2);
- ADD_CALLBACK_FUNCTION(MmeBoutarel, updateEntity);
- ADD_CALLBACK_FUNCTION(MmeBoutarel, function8);
+ ADD_CALLBACK_FUNCTION_S(MmeBoutarel, playSound);
+ ADD_CALLBACK_FUNCTION_S(MmeBoutarel, draw);
+ ADD_CALLBACK_FUNCTION_I(MmeBoutarel, updateFromTime);
+ ADD_CALLBACK_FUNCTION_SI(MmeBoutarel, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_SI(MmeBoutarel, enterExitCompartment2);
+ ADD_CALLBACK_FUNCTION_II(MmeBoutarel, updateEntity);
+ ADD_CALLBACK_FUNCTION_S(MmeBoutarel, function8);
ADD_CALLBACK_FUNCTION(MmeBoutarel, function9);
ADD_CALLBACK_FUNCTION(MmeBoutarel, chapter1);
ADD_CALLBACK_FUNCTION(MmeBoutarel, function11);
@@ -163,6 +163,7 @@ IMPLEMENT_FUNCTION(9, MmeBoutarel, function9)
if (!params->param1) {
getData()->entityPosition = getEntityData(kEntityBoutarel)->entityPosition;
getData()->location = getEntityData(kEntityBoutarel)->location;
+ getData()->car = getEntityData(kEntityBoutarel)->car;
}
break;
@@ -912,6 +913,7 @@ IMPLEMENT_FUNCTION(21, MmeBoutarel, chapter3Handler)
getObjects()->update(kObject51, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
getObjects()->update(kObject43, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "501");
+ getSavePoints()->push(kEntityMmeBoutarel, kEntityFrancois, kAction189872836);
break;
case kActionCallback:
@@ -968,6 +970,7 @@ IMPLEMENT_FUNCTION(21, MmeBoutarel, chapter3Handler)
case 9:
getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "501");
params->param1 = 1;
+ getSavePoints()->push(kEntityMmeBoutarel, kEntityFrancois, kAction190390860);
break;
}
break;
diff --git a/engines/lastexpress/entities/pascale.cpp b/engines/lastexpress/entities/pascale.cpp
index 24b7f0409b..f5fa1aab30 100644
--- a/engines/lastexpress/entities/pascale.cpp
+++ b/engines/lastexpress/entities/pascale.cpp
@@ -36,13 +36,13 @@
namespace LastExpress {
Pascale::Pascale(LastExpressEngine *engine) : Entity(engine, kEntityPascale) {
- ADD_CALLBACK_FUNCTION(Pascale, draw);
+ ADD_CALLBACK_FUNCTION_S(Pascale, draw);
ADD_CALLBACK_FUNCTION(Pascale, callbackActionRestaurantOrSalon);
ADD_CALLBACK_FUNCTION(Pascale, callbackActionOnDirection);
- ADD_CALLBACK_FUNCTION(Pascale, updateFromTime);
- ADD_CALLBACK_FUNCTION(Pascale, updatePosition);
- ADD_CALLBACK_FUNCTION(Pascale, playSound);
- ADD_CALLBACK_FUNCTION(Pascale, draw2);
+ ADD_CALLBACK_FUNCTION_I(Pascale, updateFromTime);
+ ADD_CALLBACK_FUNCTION_SII(Pascale, updatePosition);
+ ADD_CALLBACK_FUNCTION_S(Pascale, playSound);
+ ADD_CALLBACK_FUNCTION_SSI(Pascale, draw2);
ADD_CALLBACK_FUNCTION(Pascale, welcomeSophieAndRebecca);
ADD_CALLBACK_FUNCTION(Pascale, sitSophieAndRebecca);
ADD_CALLBACK_FUNCTION(Pascale, welcomeCath);
@@ -188,9 +188,9 @@ IMPLEMENT_FUNCTION(9, Pascale, sitSophieAndRebecca)
break;
case kActionDefault:
- getEntities()->drawSequenceLeft(kEntityPascale, "012C1");
- getEntities()->drawSequenceLeft(kEntityRebecca, "012C2");
- getEntities()->drawSequenceLeft(kEntityTables3, "012C3");
+ getEntities()->drawSequenceRight(kEntityPascale, "012C1");
+ getEntities()->drawSequenceRight(kEntityRebecca, "012C2");
+ getEntities()->drawSequenceRight(kEntityTables3, "012C3");
break;
}
IMPLEMENT_FUNCTION_END
@@ -353,7 +353,7 @@ IMPLEMENT_FUNCTION(13, Pascale, greetAugust)
break;
case 2:
- getEntities()->drawSequenceLeft(kEntityPascale, "010B");
+ getEntities()->drawSequenceLeft(kEntityAugust, "010B");
setCallback(3);
setup_draw("905");
@@ -739,7 +739,7 @@ IMPLEMENT_FUNCTION(24, Pascale, welcomeAbbot)
default:
break;
- case kActionNone:
+ case kActionEndSound:
if (!params->param1) {
getSound()->playSound(kEntityPascale, "ABB3015A");
params->param1 = 1;
@@ -1132,7 +1132,7 @@ label_callback1:
break;
params->param1 = 0;
- params->param2 = 2;
+ params->param2 = 1;
getObjects()->update(kObjectCompartmentG, kEntityPascale, kObjectLocation1, kCursorNormal, kCursorNormal);
}
@@ -1192,7 +1192,7 @@ label_callback1:
if (params->param3 == 1 || params->param3 == 2) {
getObjects()->update(kObjectCompartmentG, kEntityPascale, kObjectLocation1, kCursorNormal, kCursorNormal);
setCallback(params->param3 == 1 ? 5 : 6);
- setup_playSound(params->param3 == 1 ? "Wat5001" : "Wat5002");
+ setup_playSound(params->param3 == 1 ? "Wat5001" : "Wat5001A");
}
break;
diff --git a/engines/lastexpress/entities/rebecca.cpp b/engines/lastexpress/entities/rebecca.cpp
index b8b4aa1275..acb58f7870 100644
--- a/engines/lastexpress/entities/rebecca.cpp
+++ b/engines/lastexpress/entities/rebecca.cpp
@@ -23,6 +23,7 @@
#include "lastexpress/entities/rebecca.h"
#include "lastexpress/game/entities.h"
+#include "lastexpress/game/inventory.h"
#include "lastexpress/game/logic.h"
#include "lastexpress/game/object.h"
#include "lastexpress/game/savepoint.h"
@@ -37,25 +38,25 @@ namespace LastExpress {
Rebecca::Rebecca(LastExpressEngine *engine) : Entity(engine, kEntityRebecca) {
ADD_CALLBACK_FUNCTION(Rebecca, reset);
- ADD_CALLBACK_FUNCTION(Rebecca, updateFromTime);
- ADD_CALLBACK_FUNCTION(Rebecca, playSound);
- ADD_CALLBACK_FUNCTION(Rebecca, playSound16);
- ADD_CALLBACK_FUNCTION(Rebecca, callSavepoint);
- ADD_CALLBACK_FUNCTION(Rebecca, draw);
- ADD_CALLBACK_FUNCTION(Rebecca, enterExitCompartment);
- ADD_CALLBACK_FUNCTION(Rebecca, enterExitCompartment2);
- ADD_CALLBACK_FUNCTION(Rebecca, enterExitCompartment3);
+ ADD_CALLBACK_FUNCTION_I(Rebecca, updateFromTime);
+ ADD_CALLBACK_FUNCTION_S(Rebecca, playSound);
+ ADD_CALLBACK_FUNCTION_S(Rebecca, playSound16);
+ ADD_CALLBACK_FUNCTION_SIIS(Rebecca, callSavepoint);
+ ADD_CALLBACK_FUNCTION_S(Rebecca, draw);
+ ADD_CALLBACK_FUNCTION_SI(Rebecca, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_SI(Rebecca, enterExitCompartment2);
+ ADD_CALLBACK_FUNCTION_SI(Rebecca, enterExitCompartment3);
ADD_CALLBACK_FUNCTION(Rebecca, callbackActionOnDirection);
ADD_CALLBACK_FUNCTION(Rebecca, callbackActionRestaurantOrSalon);
- ADD_CALLBACK_FUNCTION(Rebecca, updateEntity);
- ADD_CALLBACK_FUNCTION(Rebecca, updatePosition);
- ADD_CALLBACK_FUNCTION(Rebecca, draw2);
+ ADD_CALLBACK_FUNCTION_II(Rebecca, updateEntity);
+ ADD_CALLBACK_FUNCTION_SII(Rebecca, updatePosition);
+ ADD_CALLBACK_FUNCTION_SSI(Rebecca, draw2);
ADD_CALLBACK_FUNCTION(Rebecca, function15);
- ADD_CALLBACK_FUNCTION(Rebecca, function16);
- ADD_CALLBACK_FUNCTION(Rebecca, function17);
+ ADD_CALLBACK_FUNCTION_I(Rebecca, function16);
+ ADD_CALLBACK_FUNCTION_I(Rebecca, function17);
ADD_CALLBACK_FUNCTION(Rebecca, function18);
ADD_CALLBACK_FUNCTION(Rebecca, function19);
- ADD_CALLBACK_FUNCTION(Rebecca, function20);
+ ADD_CALLBACK_FUNCTION_I(Rebecca, function20);
ADD_CALLBACK_FUNCTION(Rebecca, chapter1);
ADD_CALLBACK_FUNCTION(Rebecca, chapter1Handler);
ADD_CALLBACK_FUNCTION(Rebecca, function23);
@@ -129,6 +130,11 @@ IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION_SI(9, Rebecca, enterExitCompartment3, ObjectIndex)
+ if (savepoint.action == kAction4) {
+ getEntities()->exitCompartment(_entityIndex, (ObjectIndex)params->param4);
+ callbackAction();
+ return;
+ }
Entity::enterExitCompartment(savepoint);
IMPLEMENT_FUNCTION_END
@@ -239,7 +245,7 @@ IMPLEMENT_FUNCTION_I(16, Rebecca, function16, bool)
if (getEntities()->isInSalon(kEntityPlayer))
getEntities()->updateFrame(kEntityRebecca);
- setCallback(4);
+ setCallback(5);
setup_callbackActionOnDirection();
break;
@@ -442,7 +448,7 @@ IMPLEMENT_FUNCTION(19, Rebecca, function19)
if (getEntities()->isInRestaurant(kEntityPlayer))
getEntities()->updateFrame(kEntityRebecca);
- setCallback(4);
+ setCallback(3);
setup_callbackActionOnDirection();
break;
@@ -563,6 +569,30 @@ label_callback:
case kActionKnock:
case kActionOpenDoor:
+ if (params->param2) {
+ getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject52, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+ if (savepoint.param.intValue == kObject52) {
+ setCallback(8);
+ setup_playSound(getSound()->justAMinuteCath());
+ } else if (getInventory()->hasItem(kItemPassengerList)) {
+ if (rnd(2)) {
+ setCallback(9);
+ setup_playSound(getSound()->wrongDoorCath());
+ } else {
+ setCallback(10);
+ setup_playSound(params->param4 ? "CAT1509" : (rnd(2) ? "CAT1508" : "CAT1508A"));
+ }
+ } else {
+ setCallback(11);
+ setup_playSound(getSound()->wrongDoorCath());
+ }
+ } else {
+ getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject52, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+ setCallback(savepoint.action == kActionKnock ? 4 : 5);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ }
break;
case kActionDefault:
@@ -955,7 +985,7 @@ IMPLEMENT_FUNCTION(25, Rebecca, function25)
case 1:
setCallback(2);
- setup_function17(false);
+ setup_function17(true);
break;
case 2:
@@ -1109,7 +1139,7 @@ IMPLEMENT_FUNCTION(30, Rebecca, function30)
}
}
- if (!params->param3 && !params->param2 && params->param5 != kTimeInvalid) {
+ if (params->param3 && !params->param2 && params->param5 != kTimeInvalid) {
if (getState()->time <= kTime10881000) {
if (!getEntities()->isInSalon(kEntityPlayer) || !params->param5)
@@ -1231,13 +1261,15 @@ IMPLEMENT_FUNCTION(34, Rebecca, function34)
break;
case kActionNone:
- if (params->param2 == kTimeInvalid) {
+ if (params->param2 != kTimeInvalid) {
if (getState()->time <= kTime1386000) {
if (!getEntities()->isInRestaurant(kEntityPlayer) || !params->param2)
params->param2 = (uint)getState()->time;
if (params->param2 >= getState()->time) {
- Entity::timeCheckCallback(kTime2052000, params->param3, 1, WRAP_SETUP_FUNCTION(Rebecca, setup_function19));
+ if (params->param1) {
+ Entity::timeCheckCallback(kTime2052000, params->param3, 3, WRAP_SETUP_FUNCTION(Rebecca, setup_function19));
+ }
break;
}
}
@@ -1247,7 +1279,9 @@ IMPLEMENT_FUNCTION(34, Rebecca, function34)
getSavePoints()->push(kEntityRebecca, kEntityWaiter1, kAction223712416);
}
- Entity::timeCheckCallback(kTime2052000, params->param3, 1, WRAP_SETUP_FUNCTION(Rebecca, setup_function19));
+ if (params->param1) {
+ Entity::timeCheckCallback(kTime2052000, params->param3, 3, WRAP_SETUP_FUNCTION(Rebecca, setup_function19));
+ }
break;
case kActionEndSound:
@@ -1785,7 +1819,7 @@ IMPLEMENT_FUNCTION(48, Rebecca, function48)
getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
if (params->param1) {
- params->param1 = 0;
+ params->param2 = 1;
setCallback(2);
setup_playSound(getSound()->justCheckingCath());
diff --git a/engines/lastexpress/entities/salko.cpp b/engines/lastexpress/entities/salko.cpp
index 26f512b900..f93d13c849 100644
--- a/engines/lastexpress/entities/salko.cpp
+++ b/engines/lastexpress/entities/salko.cpp
@@ -40,12 +40,12 @@ namespace LastExpress {
Salko::Salko(LastExpressEngine *engine) : Entity(engine, kEntitySalko) {
ADD_CALLBACK_FUNCTION(Salko, reset);
- ADD_CALLBACK_FUNCTION(Salko, enterExitCompartment);
- ADD_CALLBACK_FUNCTION(Salko, draw);
- ADD_CALLBACK_FUNCTION(Salko, updateEntity);
- ADD_CALLBACK_FUNCTION(Salko, updateFromTime);
- ADD_CALLBACK_FUNCTION(Salko, savegame);
- ADD_CALLBACK_FUNCTION(Salko, function7);
+ ADD_CALLBACK_FUNCTION_SI(Salko, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_S(Salko, draw);
+ ADD_CALLBACK_FUNCTION_II(Salko, updateEntity);
+ ADD_CALLBACK_FUNCTION_I(Salko, updateFromTime);
+ ADD_CALLBACK_FUNCTION_II(Salko, savegame);
+ ADD_CALLBACK_FUNCTION_II(Salko, function7);
ADD_CALLBACK_FUNCTION(Salko, function8);
ADD_CALLBACK_FUNCTION(Salko, chapter1);
ADD_CALLBACK_FUNCTION(Salko, chapter1Handler);
@@ -176,6 +176,7 @@ IMPLEMENT_FUNCTION(10, Salko, chapter1Handler)
case kActionNone:
getData()->entityPosition = getEntityData(kEntityIvo)->entityPosition;
getData()->location = getEntityData(kEntityIvo)->location;
+ getData()->car = getEntityData(kEntityIvo)->car;
break;
case kActionCallback:
@@ -357,6 +358,8 @@ label_callback3:
break;
case 2:
+ getEntities()->drawSequenceLeft(kEntitySalko, "612AF");
+ getEntities()->enterCompartment(kEntitySalko, kObjectCompartmentF, true);
break;
case 3:
@@ -416,7 +419,7 @@ IMPLEMENT_FUNCTION(17, Salko, function17)
getData()->inventoryItem = kItemNone;
setCallback(1);
- setup_updateEntity(kCarGreenSleeping, kPosition_2740);
+ setup_updateEntity(kCarRedSleeping, kPosition_2740);
break;
case kActionCallback:
diff --git a/engines/lastexpress/entities/sophie.cpp b/engines/lastexpress/entities/sophie.cpp
index ac4732556d..cda72bdfff 100644
--- a/engines/lastexpress/entities/sophie.cpp
+++ b/engines/lastexpress/entities/sophie.cpp
@@ -33,7 +33,7 @@ namespace LastExpress {
Sophie::Sophie(LastExpressEngine *engine) : Entity(engine, kEntitySophie) {
ADD_CALLBACK_FUNCTION(Sophie, reset);
- ADD_CALLBACK_FUNCTION(Sophie, updateEntity);
+ ADD_CALLBACK_FUNCTION_II(Sophie, updateEntity);
ADD_CALLBACK_FUNCTION(Sophie, chaptersHandler);
ADD_CALLBACK_FUNCTION(Sophie, chapter1);
ADD_CALLBACK_FUNCTION(Sophie, function5);
@@ -70,8 +70,8 @@ IMPLEMENT_FUNCTION_II(2, Sophie, updateEntity, CarIndex, EntityPosition)
CarIndex rebeccaCar = getEntityData(kEntityRebecca)->car;
if (getEntities()->isDistanceBetweenEntities(kEntitySophie, kEntityRebecca, 500)
- || (direction == kDirectionUp && car >= rebeccaCar && position > rebecca_position)
- || (direction == kDirectionDown && car <= rebeccaCar && position < rebecca_position)) {
+ || (direction == kDirectionUp && (car > rebeccaCar || car == rebeccaCar && position > rebecca_position))
+ || (direction == kDirectionDown && (car < rebeccaCar || car == rebeccaCar && position < rebecca_position))) {
getData()->field_49B = 0;
params->param3 = 1;
}
@@ -108,6 +108,7 @@ IMPLEMENT_FUNCTION(3, Sophie, chaptersHandler)
case kActionNone:
getData()->entityPosition = getEntityData(kEntityRebecca)->entityPosition;
+ getData()->location = getEntityData(kEntityRebecca)->location;
getData()->car = getEntityData(kEntityRebecca)->car;
break;
diff --git a/engines/lastexpress/entities/tatiana.cpp b/engines/lastexpress/entities/tatiana.cpp
index 807a8449c4..5dd61e3f46 100644
--- a/engines/lastexpress/entities/tatiana.cpp
+++ b/engines/lastexpress/entities/tatiana.cpp
@@ -42,21 +42,21 @@ namespace LastExpress {
Tatiana::Tatiana(LastExpressEngine *engine) : Entity(engine, kEntityTatiana) {
ADD_CALLBACK_FUNCTION(Tatiana, reset);
- ADD_CALLBACK_FUNCTION(Tatiana, playSound);
- ADD_CALLBACK_FUNCTION(Tatiana, draw);
- ADD_CALLBACK_FUNCTION(Tatiana, updatePosition);
- ADD_CALLBACK_FUNCTION(Tatiana, enterExitCompartment);
- ADD_CALLBACK_FUNCTION(Tatiana, enterExitCompartment2);
- ADD_CALLBACK_FUNCTION(Tatiana, callSavepoint);
+ ADD_CALLBACK_FUNCTION_S(Tatiana, playSound);
+ ADD_CALLBACK_FUNCTION_S(Tatiana, draw);
+ ADD_CALLBACK_FUNCTION_SII(Tatiana, updatePosition);
+ ADD_CALLBACK_FUNCTION_SI(Tatiana, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_SI(Tatiana, enterExitCompartment2);
+ ADD_CALLBACK_FUNCTION_SIIS(Tatiana, callSavepoint);
ADD_CALLBACK_FUNCTION(Tatiana, callbackActionOnDirection);
- ADD_CALLBACK_FUNCTION(Tatiana, updateFromTicks);
- ADD_CALLBACK_FUNCTION(Tatiana, updateFromTime);
+ ADD_CALLBACK_FUNCTION_I(Tatiana, updateFromTicks);
+ ADD_CALLBACK_FUNCTION_I(Tatiana, updateFromTime);
ADD_CALLBACK_FUNCTION(Tatiana, callbackActionRestaurantOrSalon);
- ADD_CALLBACK_FUNCTION(Tatiana, savegame);
- ADD_CALLBACK_FUNCTION(Tatiana, updateEntity);
+ ADD_CALLBACK_FUNCTION_II(Tatiana, savegame);
+ ADD_CALLBACK_FUNCTION_II(Tatiana, updateEntity);
ADD_CALLBACK_FUNCTION(Tatiana, enterCompartment);
ADD_CALLBACK_FUNCTION(Tatiana, exitCompartment);
- ADD_CALLBACK_FUNCTION(Tatiana, handleCompartment);
+ ADD_CALLBACK_FUNCTION_I(Tatiana, handleCompartment);
ADD_CALLBACK_FUNCTION(Tatiana, chapter1);
ADD_CALLBACK_FUNCTION(Tatiana, function18);
ADD_CALLBACK_FUNCTION(Tatiana, chapter1Handler);
@@ -72,7 +72,7 @@ Tatiana::Tatiana(LastExpressEngine *engine) : Entity(engine, kEntityTatiana) {
ADD_CALLBACK_FUNCTION(Tatiana, leaveBreakfast);
ADD_CALLBACK_FUNCTION(Tatiana, returnToCompartment2);
ADD_CALLBACK_FUNCTION(Tatiana, chapter3);
- ADD_CALLBACK_FUNCTION(Tatiana, playChess);
+ ADD_CALLBACK_FUNCTION_TYPE2(Tatiana, playChess, EntityParametersI5S, EntityParametersSIII);
ADD_CALLBACK_FUNCTION(Tatiana, returnToCompartment3);
ADD_CALLBACK_FUNCTION(Tatiana, beforeConcert);
ADD_CALLBACK_FUNCTION(Tatiana, concert);
@@ -82,11 +82,11 @@ Tatiana::Tatiana(LastExpressEngine *engine) : Entity(engine, kEntityTatiana) {
ADD_CALLBACK_FUNCTION(Tatiana, function39);
ADD_CALLBACK_FUNCTION(Tatiana, function40);
ADD_CALLBACK_FUNCTION(Tatiana, trapCath);
- ADD_CALLBACK_FUNCTION(Tatiana, function42);
+ ADD_CALLBACK_FUNCTION_II(Tatiana, function42);
ADD_CALLBACK_FUNCTION(Tatiana, chapter4);
ADD_CALLBACK_FUNCTION(Tatiana, inCompartment4);
ADD_CALLBACK_FUNCTION(Tatiana, meetAlexei);
- ADD_CALLBACK_FUNCTION(Tatiana, withAlexei);
+ ADD_CALLBACK_FUNCTION_TYPE(Tatiana, withAlexei, EntityParametersI5S);
ADD_CALLBACK_FUNCTION(Tatiana, thinking);
ADD_CALLBACK_FUNCTION(Tatiana, seekCath);
ADD_CALLBACK_FUNCTION(Tatiana, function49);
@@ -100,7 +100,7 @@ Tatiana::Tatiana(LastExpressEngine *engine) : Entity(engine, kEntityTatiana) {
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION(1, Tatiana, reset)
- Entity::reset(savepoint, true);
+ Entity::reset(savepoint, kClothes3, true);
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
@@ -421,7 +421,7 @@ IMPLEMENT_FUNCTION(19, Tatiana, chapter1Handler)
break;
case kActionNone:
- if (getSoundQueue()->isBuffered(kEntityTatiana) || !params->param4 || params->param3 == 2 || getSoundQueue()->isBuffered("TAT1066"))
+ if (getSoundQueue()->isBuffered(kEntityTatiana) || !params->param4 || params->param3 >= 2 || getSoundQueue()->isBuffered("TAT1066"))
goto label_tatiana_chapter1_2;
if (Entity::updateParameter(params->param5, getState()->timeTicks, 450)) {
@@ -616,6 +616,8 @@ IMPLEMENT_FUNCTION(22, Tatiana, getSomeAir)
goto label_update;
if (Entity::updateParameterTime(kTime1233000, ((!getEvent(kEventTatianaAskMatchSpeakRussian) && !getEvent(kEventTatianaAskMatch)) || getEntities()->isInGreenCarEntrance(kEntityPlayer)), params->param1, 0)) {
+ params->param1 = kTimeInvalid;
+
label_update:
if (!getEvent(kEventTatianaAskMatchSpeakRussian)
&& !getEvent(kEventTatianaAskMatch)
@@ -624,10 +626,9 @@ label_update:
getObjects()->update(kObject25, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorForward);
getObjects()->update(kObjectTrainTimeTable, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorForward);
}
+ break;
}
- params->param1 = kTimeInvalid;
-
getObjects()->update(kObject25, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
getObjects()->update(kObjectTrainTimeTable, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
getEntities()->updatePositionExit(kEntityTatiana, kCarGreenSleeping, 70);
@@ -796,7 +797,7 @@ IMPLEMENT_FUNCTION(26, Tatiana, chapter2Handler)
case kAction1:
getData()->inventoryItem = kItemNone;
- setup_joinAlexei();
+ setup_breakfastClick();
break;
case kActionDefault:
@@ -1023,7 +1024,7 @@ IMPLEMENT_FUNCTION(32, Tatiana, playChess)
}
if (parameters->param4 && parameters->param5) {
- if (Entity::updateParameterCheck(parameters->param4, getState()->time, 6300)) {
+ if (Entity::updateParameterCheck(parameters1->param4, getState()->time, 6300)) {
if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
getData()->location = kLocationOutsideCompartment;
@@ -1035,7 +1036,6 @@ IMPLEMENT_FUNCTION(32, Tatiana, playChess)
break;
case kActionEndSound:
- parameters->param2 = 0;
++parameters->param3;
switch (parameters->param3) {
@@ -1080,7 +1080,7 @@ IMPLEMENT_FUNCTION(32, Tatiana, playChess)
case 6:
parameters->param1 = 4500;
getEntities()->drawSequenceLeft(kEntityTatiana, "110B");
- strcpy((char *)&parameters->seq, "Tat3160B");
+ strcpy((char *)&parameters->seq, "Tat3160F");
break;
}
break;
@@ -1165,6 +1165,7 @@ IMPLEMENT_FUNCTION(34, Tatiana, beforeConcert)
getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
getObjects()->update(kObject49, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ setCallback(2);
setup_exitCompartment();
break;
@@ -1238,7 +1239,7 @@ IMPLEMENT_FUNCTION(36, Tatiana, leaveConcert)
getData()->location = kLocationOutsideCompartment;
setCallback(1);
- setup_updateEntity(kCarGreenSleeping, kPosition_7500);
+ setup_updateEntity(kCarRedSleeping, kPosition_7500);
break;
case kActionCallback:
@@ -1247,7 +1248,7 @@ IMPLEMENT_FUNCTION(36, Tatiana, leaveConcert)
break;
case 1:
- if (!getEntities()->checkFields19(kEntityPlayer, kCarGreenSleeping, kPosition_7850) || getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_8200)) {
+ if (!getEntities()->checkFields19(kEntityPlayer, kCarRedSleeping, kPosition_7850) || getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_8200)) {
setCallback(2);
setup_enterCompartment();
break;
@@ -1262,6 +1263,7 @@ IMPLEMENT_FUNCTION(36, Tatiana, leaveConcert)
}
getScenes()->loadSceneFromObject(kObjectCompartmentB);
+ setup_afterConcert();
break;
case 2:
@@ -1543,7 +1545,7 @@ IMPLEMENT_FUNCTION(40, Tatiana, function40)
case kActionExcuseMe:
if (getEvent(kEventTatianaAskMatchSpeakRussian) || getEvent(kEventTatianaAskMatch) || getEvent(kEventVassiliSeizure))
- getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1001A" : "CAT1010");
+ getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1010A" : "CAT1010");
else
getSound()->excuseMeCath();
break;
@@ -1732,7 +1734,7 @@ IMPLEMENT_FUNCTION(45, Tatiana, meetAlexei)
getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
getData()->location = kLocationOutsideCompartment;
- setCallback(1);
+ setCallback(2);
setup_updateEntity(kCarGreenSleeping, kPosition_540);
break;
@@ -1782,7 +1784,7 @@ IMPLEMENT_FUNCTION(46, Tatiana, withAlexei)
if (CURRENT_PARAM(1, 1) == kTimeInvalid || getState()->time <= kTime2394000)
break;
- if (getState()->time >= kTime2398500) {
+ if (getState()->time > kTime2398500) {
CURRENT_PARAM(1, 1) = kTimeInvalid;
} else {
if (getEntities()->isInGreenCarEntrance(kEntityPlayer) || !CURRENT_PARAM(1, 1))
diff --git a/engines/lastexpress/entities/train.cpp b/engines/lastexpress/entities/train.cpp
index f707b02ccf..c8cfe8cca8 100644
--- a/engines/lastexpress/entities/train.cpp
+++ b/engines/lastexpress/entities/train.cpp
@@ -38,14 +38,14 @@
namespace LastExpress {
Train::Train(LastExpressEngine *engine) : Entity(engine, kEntityTrain) {
- ADD_CALLBACK_FUNCTION(Train, savegame);
+ ADD_CALLBACK_FUNCTION_II(Train, savegame);
ADD_CALLBACK_FUNCTION(Train, chapter1);
ADD_CALLBACK_FUNCTION(Train, chapter2);
ADD_CALLBACK_FUNCTION(Train, chapter3);
ADD_CALLBACK_FUNCTION(Train, chapter4);
ADD_CALLBACK_FUNCTION(Train, chapter5);
- ADD_CALLBACK_FUNCTION(Train, harem);
- ADD_CALLBACK_FUNCTION(Train, process);
+ ADD_CALLBACK_FUNCTION_II(Train, harem);
+ ADD_CALLBACK_FUNCTION_TYPE2(Train, process, EntityParametersIIII, EntityParametersIIIS);
}
//////////////////////////////////////////////////////////////////////////
@@ -111,7 +111,7 @@ IMPLEMENT_FUNCTION_II(7, Train, harem, ObjectIndex, uint32)
}
params->param4 = getEntities()->isInsideCompartment(kEntityAlouan, kCarGreenSleeping, (EntityPosition)params->param3);
- params->param5 = (ENTITY_PARAM(0, 7) - params->param3) < 1 ? true : false;
+ params->param5 = (ENTITY_PARAM(0, 7) == params->param3) ? true : false;
params->param6 = getEntities()->isInsideCompartment(kEntityYasmin, kCarGreenSleeping, (EntityPosition)params->param3);
params->param7 = getEntities()->isInsideCompartment(kEntityHadija, kCarGreenSleeping, (EntityPosition)params->param3);
@@ -374,7 +374,10 @@ label_process:
break;
case kCarRestaurant:
- getEntities()->drawSequenceLeft(kEntityTrain, isNight() ? "RCWNN" : "RCWND");
+ if (getProgress().isNightTime)
+ getEntities()->drawSequenceLeft(kEntityTrain, "RCWNM");
+ else
+ getEntities()->drawSequenceLeft(kEntityTrain, isNight() ? "RCWNN" : "RCWND");
break;
}
@@ -478,7 +481,7 @@ label_process:
break;
case kAction203863200:
- if (!strcmp(savepoint.param.charValue, "")) {
+ if (strcmp(savepoint.param.charValue, "")) {
params->param8 = 1;
strcpy((char *)&params1->seq, savepoint.param.charValue); // this is the sound file name
}
@@ -502,7 +505,7 @@ label_process:
case kObjectCompartment4:
case kObjectCompartmentC:
case kObjectCompartmentD:
- params1->param1 = (savepoint.param.intValue == kObjectCompartment1 || savepoint.param.intValue == kObjectCompartment2) ? kCarGreenSleeping : kCarRedSleeping;
+ params1->param1 = (savepoint.param.intValue == kObjectCompartment3 || savepoint.param.intValue == kObjectCompartment4) ? kCarGreenSleeping : kCarRedSleeping;
params1->param2 = (savepoint.param.intValue == kObjectCompartment3 || savepoint.param.intValue == kObjectCompartmentC) ? kPosition_6470 : kPosition_5790;
params1->param3 = kPosition_6130;
break;
@@ -511,7 +514,7 @@ label_process:
case kObjectCompartment6:
case kObjectCompartmentE:
case kObjectCompartmentF:
- params1->param1 = (savepoint.param.intValue == kObjectCompartment1 || savepoint.param.intValue == kObjectCompartment2) ? kCarGreenSleeping : kCarRedSleeping;
+ params1->param1 = (savepoint.param.intValue == kObjectCompartment5 || savepoint.param.intValue == kObjectCompartment6) ? kCarGreenSleeping : kCarRedSleeping;
params1->param2 = (savepoint.param.intValue == kObjectCompartment5 || savepoint.param.intValue == kObjectCompartmentE) ? kPosition_4840 : kPosition_4070;
params1->param3 = kPosition_4455;
break;
@@ -520,7 +523,7 @@ label_process:
case kObjectCompartment8:
case kObjectCompartmentG:
case kObjectCompartmentH:
- params1->param1 = (savepoint.param.intValue == kObjectCompartment1 || savepoint.param.intValue == kObjectCompartment2) ? kCarGreenSleeping : kCarRedSleeping;
+ params1->param1 = (savepoint.param.intValue == kObjectCompartment7 || savepoint.param.intValue == kObjectCompartment8) ? kCarGreenSleeping : kCarRedSleeping;
params1->param2 = (savepoint.param.intValue == kObjectCompartment7 || savepoint.param.intValue == kObjectCompartmentG) ? kPosition_3050 : kPosition_2740;
params1->param3 = kPositionNone;
break;
diff --git a/engines/lastexpress/entities/vassili.cpp b/engines/lastexpress/entities/vassili.cpp
index e28ace95be..1c25ce2cb0 100644
--- a/engines/lastexpress/entities/vassili.cpp
+++ b/engines/lastexpress/entities/vassili.cpp
@@ -42,8 +42,8 @@ namespace LastExpress {
Vassili::Vassili(LastExpressEngine *engine) : Entity(engine, kEntityVassili) {
ADD_CALLBACK_FUNCTION(Vassili, reset);
- ADD_CALLBACK_FUNCTION(Vassili, draw);
- ADD_CALLBACK_FUNCTION(Vassili, savegame);
+ ADD_CALLBACK_FUNCTION_S(Vassili, draw);
+ ADD_CALLBACK_FUNCTION_II(Vassili, savegame);
ADD_CALLBACK_FUNCTION(Vassili, chapter1);
ADD_CALLBACK_FUNCTION(Vassili, chapter1Handler);
ADD_CALLBACK_FUNCTION(Vassili, inBed);
@@ -103,14 +103,10 @@ IMPLEMENT_FUNCTION(5, Vassili, chapter1Handler)
if (params->param1) {
getData()->entityPosition = getEntityData(kEntityTatiana)->entityPosition;
getData()->location = getEntityData(kEntityTatiana)->location;
+ getData()->car = getEntityData(kEntityTatiana)->car;
} else {
- if (params->param3 && params->param3 >= getState()->time) {
+ if (!Entity::updateParameterCheck(params->param3, getState()->time, 450))
break;
- }else {
- params->param3 = (uint)getState()->time + 450;
- if (params->param3 == 0)
- break;
- }
if (!params->param2 && getObjects()->get(kObjectCompartmentA).status == kObjectLocation1) {
params->param2 = 1;
@@ -215,9 +211,9 @@ IMPLEMENT_FUNCTION(7, Vassili, function7)
if (params->param1 != kTimeInvalid && getState()->time > kTime1503000) {
if (getState()->time <= kTime1512000) {
- if (getEntities()->isPlayerInCar(kCarRedSleeping) || !params->param1) {
+ if (!getEntities()->isPlayerInCar(kCarRedSleeping) || !params->param1) {
params->param1 = (uint)getState()->time + 150;
- if (params->param1) {
+ if (!params->param1) {
setup_function8();
break;
}
@@ -345,7 +341,7 @@ IMPLEMENT_FUNCTION(10, Vassili, seizure)
if (getCallback() != 1)
break;
- getData()->location = kLocationInsideCompartment;
+ getEntityData(kEntityPlayer)->location = kLocationInsideCompartment;
getAction()->playAnimation(kEventVassiliSeizure);
getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
diff --git a/engines/lastexpress/entities/verges.cpp b/engines/lastexpress/entities/verges.cpp
index b16217b5eb..c3e56d98c1 100644
--- a/engines/lastexpress/entities/verges.cpp
+++ b/engines/lastexpress/entities/verges.cpp
@@ -39,21 +39,21 @@ namespace LastExpress {
Verges::Verges(LastExpressEngine *engine) : Entity(engine, kEntityVerges) {
ADD_CALLBACK_FUNCTION(Verges, reset);
- ADD_CALLBACK_FUNCTION(Verges, draw);
+ ADD_CALLBACK_FUNCTION_S(Verges, draw);
ADD_CALLBACK_FUNCTION(Verges, callbackActionOnDirection);
- ADD_CALLBACK_FUNCTION(Verges, playSound);
- ADD_CALLBACK_FUNCTION(Verges, playSound16);
+ ADD_CALLBACK_FUNCTION_S(Verges, playSound);
+ ADD_CALLBACK_FUNCTION_S(Verges, playSound16);
ADD_CALLBACK_FUNCTION(Verges, callbackActionRestaurantOrSalon);
- ADD_CALLBACK_FUNCTION(Verges, savegame);
- ADD_CALLBACK_FUNCTION(Verges, updateEntity);
- ADD_CALLBACK_FUNCTION(Verges, walkBetweenCars);
- ADD_CALLBACK_FUNCTION(Verges, makeAnnouncement);
+ ADD_CALLBACK_FUNCTION_II(Verges, savegame);
+ ADD_CALLBACK_FUNCTION_II(Verges, updateEntity);
+ ADD_CALLBACK_FUNCTION_S(Verges, walkBetweenCars);
+ ADD_CALLBACK_FUNCTION_IIS(Verges, makeAnnouncement);
ADD_CALLBACK_FUNCTION(Verges, function11);
ADD_CALLBACK_FUNCTION(Verges, function12);
- ADD_CALLBACK_FUNCTION(Verges, baggageCar);
- ADD_CALLBACK_FUNCTION(Verges, updateFromTime);
- ADD_CALLBACK_FUNCTION(Verges, dialog);
- ADD_CALLBACK_FUNCTION(Verges, dialog2);
+ ADD_CALLBACK_FUNCTION_I(Verges, baggageCar);
+ ADD_CALLBACK_FUNCTION_I(Verges, updateFromTime);
+ ADD_CALLBACK_FUNCTION_IS(Verges, dialog);
+ ADD_CALLBACK_FUNCTION_ISS(Verges, dialog2);
ADD_CALLBACK_FUNCTION(Verges, talkAboutPassengerList);
ADD_CALLBACK_FUNCTION(Verges, chapter1);
ADD_CALLBACK_FUNCTION(Verges, talkHarem);
@@ -67,7 +67,7 @@ Verges::Verges(LastExpressEngine *engine) : Entity(engine, kEntityVerges) {
ADD_CALLBACK_FUNCTION(Verges, chapter2);
ADD_CALLBACK_FUNCTION(Verges, chapter2Handler);
ADD_CALLBACK_FUNCTION(Verges, chapter3);
- ADD_CALLBACK_FUNCTION(Verges, function30);
+ ADD_CALLBACK_FUNCTION_S(Verges, function30);
ADD_CALLBACK_FUNCTION(Verges, talkAboutMax);
ADD_CALLBACK_FUNCTION(Verges, function32);
ADD_CALLBACK_FUNCTION(Verges, function33);
@@ -492,7 +492,7 @@ IMPLEMENT_FUNCTION_ISS(16, Verges, dialog2, EntityIndex)
break;
case kActionNone:
- if (CURRENT_PARAM(1, 1) && params->param8) {
+ if (CURRENT_PARAM(1, 1) >= 2 && params->param8) {
getSavePoints()->push(kEntityVerges, (EntityIndex)params->param1, kAction125499160);
if (!getEntities()->isPlayerPosition(kCarGreenSleeping, 2) && !getEntities()->isPlayerPosition(kCarRedSleeping, 2))
@@ -742,7 +742,7 @@ IMPLEMENT_FUNCTION(25, Verges, policeSearch)
getData()->car = kCarRedSleeping;
getData()->entityPosition = kPosition_9270;
} else {
- if (getEntityData(kEntityPlayer)->car > kCarGreenSleeping
+ if (getEntityData(kEntityPlayer)->car < kCarGreenSleeping
|| (getEntityData(kEntityPlayer)->car == kCarGreenSleeping && getEntityData(kEntityPlayer)->entityPosition < kPosition_4840)) {
getSound()->playSound(kEntityPlayer, "BUMP");
getScenes()->loadSceneFromObject(kObjectCompartment5, true);
@@ -777,7 +777,7 @@ IMPLEMENT_FUNCTION(25, Verges, policeSearch)
setup_makeAnnouncement(kCarGreenSleeping, kPosition_540, "TRA1005");
} else {
setCallback(7);
- setup_makeAnnouncement(kCarRedSleeping, kPosition_9460, "TRA1006");
+ setup_makeAnnouncement(kCarRedSleeping, kPosition_9460, "TRA1005");
}
break;
}
@@ -911,15 +911,13 @@ label_callback3:
break;
label_callback4:
- if (Entity::timeCheckCallback(kTime1089000, params->param8, 5, WRAP_SETUP_FUNCTION(Verges, setup_function12)))
- break;
-
- params->param8 = 1;
-
- if (!params->param5) {
- setCallback(5);
- setup_function12();
- break;
+ if (getState()->time > kTime1089000 && !params->param8) {
+ params->param8 = 1;
+ if (!params->param5) {
+ setCallback(5);
+ setup_function12();
+ break;
+ }
}
label_callback8:
@@ -970,7 +968,7 @@ label_callback15:
case kActionOpenDoor:
setCallback(17);
- setup_baggageCar(savepoint.param.intValue < 106 ? true : false);
+ setup_baggageCar(savepoint.param.intValue == kObject105 ? true : false);
break;
case kActionDefault:
@@ -1130,7 +1128,7 @@ label_callback_6:
case kActionOpenDoor:
setCallback(8);
- setup_baggageCar(savepoint.param.intValue < 106);
+ setup_baggageCar(savepoint.param.intValue == kObject105);
break;
case kActionDefault:
@@ -1318,7 +1316,7 @@ IMPLEMENT_FUNCTION(32, Verges, function32)
break;
case 1:
- getData()->entityPosition = kPosition_8500;
+ getData()->entityPosition = kPosition_5800;
getData()->location = kLocationOutsideCompartment;
getSound()->playSound(kEntityVerges, "TRA3004");
@@ -1400,12 +1398,12 @@ IMPLEMENT_FUNCTION(33, Verges, function33)
getData()->entityPosition = kPosition_5799;
setCallback(getProgress().field_3C ? 4 : 5);
- setup_playSound(getProgress().field_3C ? "ABB3035A" : "ABB3035");
+ setup_playSound(getProgress().field_3C ? "ABB3035A" : "Abb3035");
break;
case 4:
setCallback(5);
- setup_playSound("ABB3035");
+ setup_playSound("Abb3035");
break;
case 5:
@@ -1480,7 +1478,7 @@ label_callback_9:
case kActionOpenDoor:
setCallback(11);
- setup_baggageCar(savepoint.param.intValue < 106);
+ setup_baggageCar(savepoint.param.intValue == kObject105);
break;
case kActionCallback:
@@ -1542,7 +1540,7 @@ IMPLEMENT_FUNCTION(35, Verges, organizeConcertInvitations)
case 2:
setCallback(3);
- setup_dialog(kEntityMertens, "Tra3011A");
+ setup_dialog(kEntityCoudert, "Tra3011A");
break;
case 3:
@@ -1614,7 +1612,7 @@ IMPLEMENT_FUNCTION(37, Verges, chapter4Handler)
}
label_callback_1:
- if (ENTITY_PARAM(0, 6)) {
+ if (!ENTITY_PARAM(0, 6)) {
if (ENTITY_PARAM(0, 3)) {
setCallback(2);
setup_talkAboutPassengerList();
@@ -1652,7 +1650,7 @@ label_callback_8:
case kActionOpenDoor:
setCallback(10);
- setup_baggageCar(savepoint.param.intValue < 106);
+ setup_baggageCar(savepoint.param.intValue == kObject105);
break;
case kActionDefault:
@@ -1739,7 +1737,7 @@ IMPLEMENT_FUNCTION(38, Verges, resetState)
getData()->entityPosition = kPosition_5790;
setCallback(1);
- setup_updateEntity(kCarGreenSleeping, kPosition_540);
+ setup_updateEntity(kCarRedSleeping, kPosition_540);
break;
}
IMPLEMENT_FUNCTION_END
@@ -1905,6 +1903,7 @@ void Verges::talk(const SavePoint &savepoint, const char *sound1, const char *so
break;
case 5:
+ setCallback(6);
setup_function11();
break;
diff --git a/engines/lastexpress/entities/vesna.cpp b/engines/lastexpress/entities/vesna.cpp
index 8ab3902b16..7ac53ce6e7 100644
--- a/engines/lastexpress/entities/vesna.cpp
+++ b/engines/lastexpress/entities/vesna.cpp
@@ -38,16 +38,16 @@ namespace LastExpress {
Vesna::Vesna(LastExpressEngine *engine) : Entity(engine, kEntityVesna) {
ADD_CALLBACK_FUNCTION(Vesna, reset);
- ADD_CALLBACK_FUNCTION(Vesna, playSound);
- ADD_CALLBACK_FUNCTION(Vesna, enterExitCompartment);
- ADD_CALLBACK_FUNCTION(Vesna, draw);
- ADD_CALLBACK_FUNCTION(Vesna, updateEntity);
- ADD_CALLBACK_FUNCTION(Vesna, updateFromTime);
- ADD_CALLBACK_FUNCTION(Vesna, updateEntity2);
+ ADD_CALLBACK_FUNCTION_S(Vesna, playSound);
+ ADD_CALLBACK_FUNCTION_SI(Vesna, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_S(Vesna, draw);
+ ADD_CALLBACK_FUNCTION_II(Vesna, updateEntity);
+ ADD_CALLBACK_FUNCTION_I(Vesna, updateFromTime);
+ ADD_CALLBACK_FUNCTION_II(Vesna, updateEntity2);
ADD_CALLBACK_FUNCTION(Vesna, callbackActionRestaurantOrSalon);
ADD_CALLBACK_FUNCTION(Vesna, callbackActionOnDirection);
- ADD_CALLBACK_FUNCTION(Vesna, savegame);
- ADD_CALLBACK_FUNCTION(Vesna, homeAlone);
+ ADD_CALLBACK_FUNCTION_II(Vesna, savegame);
+ ADD_CALLBACK_FUNCTION_TYPE(Vesna, homeAlone, EntityParametersIIIS);
ADD_CALLBACK_FUNCTION(Vesna, chapter1);
ADD_CALLBACK_FUNCTION(Vesna, withMilos);
ADD_CALLBACK_FUNCTION(Vesna, homeTogether);
@@ -56,7 +56,7 @@ Vesna::Vesna(LastExpressEngine *engine) : Entity(engine, kEntityVesna) {
ADD_CALLBACK_FUNCTION(Vesna, chapter2Handler);
ADD_CALLBACK_FUNCTION(Vesna, checkTrain);
ADD_CALLBACK_FUNCTION(Vesna, chapter3);
- ADD_CALLBACK_FUNCTION(Vesna, inCompartment);
+ ADD_CALLBACK_FUNCTION_TYPE(Vesna, inCompartment, EntityParametersIIIS);
ADD_CALLBACK_FUNCTION(Vesna, takeAWalk);
ADD_CALLBACK_FUNCTION(Vesna, killAnna);
ADD_CALLBACK_FUNCTION(Vesna, killedAnna);
@@ -93,7 +93,7 @@ IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION_II(5, Vesna, updateEntity, CarIndex, EntityPosition)
if (savepoint.action == kActionExcuseMeCath) {
- getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT10150" : "CAT1015A");
+ getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1015" : "CAT1015A");
return;
}
@@ -116,8 +116,8 @@ IMPLEMENT_FUNCTION_II(7, Vesna, updateEntity2, CarIndex, EntityPosition)
params->param3 = 0;
if (getEntities()->isDistanceBetweenEntities(kEntityVesna, kEntityMilos, 500)
- || (((getData()->direction == kDirectionUp && (getData()->car > getEntityData(kEntityMilos)->car)) || (getData()->car == getEntityData(kEntityMilos)->car && getData()->entityPosition > getEntityData(kEntityMilos)->entityPosition)))
- || (((getData()->direction == kDirectionDown && (getData()->car < getEntityData(kEntityMilos)->car)) || (getData()->car == getEntityData(kEntityMilos)->car && getData()->entityPosition < getEntityData(kEntityMilos)->entityPosition)))) {
+ || (getData()->direction == kDirectionUp && (getData()->car > getEntityData(kEntityMilos)->car || (getData()->car == getEntityData(kEntityMilos)->car && getData()->entityPosition > getEntityData(kEntityMilos)->entityPosition)))
+ || (getData()->direction == kDirectionDown && (getData()->car < getEntityData(kEntityMilos)->car || (getData()->car == getEntityData(kEntityMilos)->car && getData()->entityPosition < getEntityData(kEntityMilos)->entityPosition)))) {
getData()->field_49B = 0;
params->param3 = 1;
}
@@ -277,6 +277,7 @@ IMPLEMENT_FUNCTION(13, Vesna, withMilos)
case kActionNone:
getData()->entityPosition = getEntityData(kEntityMilos)->entityPosition;
getData()->location = getEntityData(kEntityMilos)->location;
+ getData()->car = getEntityData(kEntityMilos)->car;
break;
case kActionCallback:
@@ -373,7 +374,7 @@ IMPLEMENT_FUNCTION(18, Vesna, checkTrain)
case kActionDefault:
setCallback(1);
- setup_enterExitCompartment("610Bg", kObjectCompartmentG);
+ setup_enterExitCompartment("610BG", kObjectCompartmentG);
break;
case kActionCallback:
@@ -449,7 +450,7 @@ IMPLEMENT_FUNCTION(18, Vesna, checkTrain)
case 10:
setCallback(11);
- setup_enterExitCompartment("610Ag", kObjectCompartmentG);
+ setup_enterExitCompartment("610AG", kObjectCompartmentG);
break;
case 11:
@@ -538,6 +539,8 @@ IMPLEMENT_FUNCTION(20, Vesna, inCompartment)
switch (parameters->param3) {
default:
+ strcpy((char *)&parameters->seq, "VES1015C");
+ parameters->param3 = 0;
break;
case 1:
@@ -547,11 +550,6 @@ IMPLEMENT_FUNCTION(20, Vesna, inCompartment)
case 2:
strcpy((char *)&parameters->seq, "VES1015B");
break;
-
- case 3:
- strcpy((char *)&parameters->seq, "VES1015C");
- parameters->param3 = 0;
- break;
}
getObjects()->update(kObjectCompartmentG, kEntityVesna, kObjectLocation3, kCursorNormal, kCursorNormal);
@@ -1083,7 +1081,7 @@ IMPLEMENT_FUNCTION(30, Vesna, climbing)
case kActionNone:
if (!params->param1) {
if (Entity::updateParameter(params->param3, getState()->timeTicks, 120)) {
- getSound()->playSound(kEntityVesna, "Ves50001", kFlagDefault);
+ getSound()->playSound(kEntityVesna, "Ves5001", kFlagDefault);
params->param1 = 1;
}
}
@@ -1117,7 +1115,7 @@ IMPLEMENT_FUNCTION(30, Vesna, climbing)
params->param2 = getFight()->setup(kFightVesna);
if (params->param2) {
- getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, params->param2 != Fight::kFightEndExit);
+ getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, params->param2 == Fight::kFightEndLost);
} else {
getSound()->playSound(kEntityPlayer, "TUNNEL");
diff --git a/engines/lastexpress/entities/waiter1.cpp b/engines/lastexpress/entities/waiter1.cpp
index 80ec471f1b..0743d7760b 100644
--- a/engines/lastexpress/entities/waiter1.cpp
+++ b/engines/lastexpress/entities/waiter1.cpp
@@ -40,12 +40,12 @@ namespace LastExpress {
}
Waiter1::Waiter1(LastExpressEngine *engine) : Entity(engine, kEntityWaiter1) {
- ADD_CALLBACK_FUNCTION(Waiter1, callSavepoint);
- ADD_CALLBACK_FUNCTION(Waiter1, updateFromTime);
- ADD_CALLBACK_FUNCTION(Waiter1, draw);
- ADD_CALLBACK_FUNCTION(Waiter1, updatePosition);
+ ADD_CALLBACK_FUNCTION_SIIS(Waiter1, callSavepoint);
+ ADD_CALLBACK_FUNCTION_I(Waiter1, updateFromTime);
+ ADD_CALLBACK_FUNCTION_S(Waiter1, draw);
+ ADD_CALLBACK_FUNCTION_SII(Waiter1, updatePosition);
ADD_CALLBACK_FUNCTION(Waiter1, callbackActionOnDirection);
- ADD_CALLBACK_FUNCTION(Waiter1, playSound);
+ ADD_CALLBACK_FUNCTION_S(Waiter1, playSound);
ADD_CALLBACK_FUNCTION(Waiter1, rebeccaFeedUs);
ADD_CALLBACK_FUNCTION(Waiter1, rebeccaClearOurTable);
ADD_CALLBACK_FUNCTION(Waiter1, abbotCheckMe);
@@ -296,7 +296,7 @@ IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION(18, Waiter1, clearAugust1)
- serveTable(savepoint, "911", kEntityTables3, "010L", "010H", "913", &ENTITY_PARAM(0, 7));
+ serveTable(savepoint, "911", kEntityTables3, "010L", "010M", "913", &ENTITY_PARAM(0, 7));
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
@@ -325,7 +325,7 @@ IMPLEMENT_FUNCTION(20, Waiter1, servingDinner)
}
}
- if (!getEntities()->isInKitchen(kEntityWaiter1) && !getEntities()->isSomebodyInsideRestaurantOrSalon())
+ if (!getEntities()->isInKitchen(kEntityWaiter1) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
break;
HANDLE_TABLE(0, 1, 1, setup_annaOrder);
@@ -536,7 +536,7 @@ IMPLEMENT_FUNCTION(28, Waiter1, serving3)
break;
case kActionNone:
- if (!getEntities()->isInKitchen(kEntityWaiter2) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
+ if (!getEntities()->isInKitchen(kEntityWaiter1) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
break;
if (ENTITY_PARAM(1, 5)) {
@@ -734,12 +734,14 @@ IMPLEMENT_FUNCTION(32, Waiter1, serving4)
break;
case kActionNone:
- if (Entity::updateParameter(params->param2, getState()->time, 3600)) {
- ENTITY_PARAM(1, 8) = 1;
- params->param1 = 0;
+ if (params->param1) {
+ if (Entity::updateParameter(params->param2, getState()->time, 3600)) {
+ ENTITY_PARAM(1, 8) = 1;
+ params->param1 = 0;
+ }
}
- if (!getEntities()->isInKitchen(kEntityWaiter2) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
+ if (!getEntities()->isInKitchen(kEntityWaiter1) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
break;
if (ENTITY_PARAM(1, 7)) {
@@ -964,7 +966,7 @@ void Waiter1::handleServer(const SavePoint &savepoint, const char *name, EntityI
case kActionCallback:
if (getCallback() == 1) {
// Prepare or draw sequences depending of value of string
- if (strcmp(name2, ""))
+ if (!strcmp(name2, ""))
getEntities()->clearSequences(kEntityWaiter1);
else
getEntities()->drawSequenceLeft(kEntityWaiter1, name2);
diff --git a/engines/lastexpress/entities/waiter2.cpp b/engines/lastexpress/entities/waiter2.cpp
index 52a48a77d5..2be7b4e7c6 100644
--- a/engines/lastexpress/entities/waiter2.cpp
+++ b/engines/lastexpress/entities/waiter2.cpp
@@ -33,12 +33,12 @@
namespace LastExpress {
Waiter2::Waiter2(LastExpressEngine *engine) : Entity(engine, kEntityWaiter2) {
- ADD_CALLBACK_FUNCTION(Waiter2, updateFromTime);
- ADD_CALLBACK_FUNCTION(Waiter2, draw);
- ADD_CALLBACK_FUNCTION(Waiter2, updatePosition);
+ ADD_CALLBACK_FUNCTION_I(Waiter2, updateFromTime);
+ ADD_CALLBACK_FUNCTION_S(Waiter2, draw);
+ ADD_CALLBACK_FUNCTION_SII(Waiter2, updatePosition);
ADD_CALLBACK_FUNCTION(Waiter2, callbackActionOnDirection);
- ADD_CALLBACK_FUNCTION(Waiter2, callSavepoint);
- ADD_CALLBACK_FUNCTION(Waiter2, playSound);
+ ADD_CALLBACK_FUNCTION_SIIS(Waiter2, callSavepoint);
+ ADD_CALLBACK_FUNCTION_S(Waiter2, playSound);
ADD_CALLBACK_FUNCTION(Waiter2, monsieurServeUs);
ADD_CALLBACK_FUNCTION(Waiter2, chapter1);
ADD_CALLBACK_FUNCTION(Waiter2, milosOrder);
@@ -260,7 +260,7 @@ IMPLEMENT_FUNCTION(10, Waiter2, monsieurOrder)
case 3:
getEntities()->clearSequences(kEntityWaiter2);
getData()->entityPosition = kPosition_5900;
- ENTITY_PARAM(0, 2) = 0;
+ ENTITY_PARAM(1, 2) = 0;
callbackAction();
break;
@@ -290,7 +290,7 @@ switch (savepoint.action) {
default:
break;
- case kActionDefault:
+ case kActionNone:
if (!getEntities()->isInKitchen(kEntityWaiter2) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
break;
@@ -524,7 +524,7 @@ IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION(24, Waiter2, annaBringTea3)
- serveSalon(savepoint, "927", "Ann3143A", kEntityAnna, "Ann31444", "112C", kAction122288808, "928", &ENTITY_PARAM(1, 1));
+ serveSalon(savepoint, "927", "Ann3143A", kEntityAnna, "Ann3144", "112C", kAction122288808, "928", &ENTITY_PARAM(1, 1));
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
@@ -562,7 +562,7 @@ IMPLEMENT_FUNCTION(26, Waiter2, serving4)
break;
case kActionNone:
- if (params->param2) {
+ if (params->param1) {
if (Entity::updateParameter(params->param2, getState()->time, 900)) {
ENTITY_PARAM(1, 5) = 1;
params->param1 = 0;
@@ -740,7 +740,7 @@ void Waiter2::serveSalon(const SavePoint &savepoint, const char *seq1, const cha
if (getEntities()->isInRestaurant(kEntityPlayer))
getEntities()->updateFrame(kEntityWaiter2);
- if (!strcmp(snd1, ""))
+ if (strcmp(snd1, ""))
getSound()->playSound(kEntityWaiter2, snd1);
setCallback(2);
@@ -753,7 +753,9 @@ void Waiter2::serveSalon(const SavePoint &savepoint, const char *seq1, const cha
getSound()->playSound(kEntityWaiter2, snd2);
setCallback(3);
- setup_updatePosition(seq2, kCarRestaurant, 57);
+ // the last arg is actually a constant varying between calls,
+ // but this function already has too many args to add yet another one
+ setup_updatePosition(seq2, kCarRestaurant, strcmp(seq2, "127D") ? 57 : 56);
break;
case 3:
diff --git a/engines/lastexpress/entities/yasmin.cpp b/engines/lastexpress/entities/yasmin.cpp
index 971799fb9b..45837e73ee 100644
--- a/engines/lastexpress/entities/yasmin.cpp
+++ b/engines/lastexpress/entities/yasmin.cpp
@@ -28,6 +28,7 @@
#include "lastexpress/game/savepoint.h"
#include "lastexpress/game/state.h"
+#include "lastexpress/sound/queue.h"
#include "lastexpress/lastexpress.h"
@@ -35,10 +36,10 @@ namespace LastExpress {
Yasmin::Yasmin(LastExpressEngine *engine) : Entity(engine, kEntityYasmin) {
ADD_CALLBACK_FUNCTION(Yasmin, reset);
- ADD_CALLBACK_FUNCTION(Yasmin, enterExitCompartment);
- ADD_CALLBACK_FUNCTION(Yasmin, playSound);
- ADD_CALLBACK_FUNCTION(Yasmin, updateFromTime);
- ADD_CALLBACK_FUNCTION(Yasmin, updateEntity);
+ ADD_CALLBACK_FUNCTION_SI(Yasmin, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION_S(Yasmin, playSound);
+ ADD_CALLBACK_FUNCTION_I(Yasmin, updateFromTime);
+ ADD_CALLBACK_FUNCTION_II(Yasmin, updateEntity);
ADD_CALLBACK_FUNCTION(Yasmin, goEtoG);
ADD_CALLBACK_FUNCTION(Yasmin, goGtoE);
ADD_CALLBACK_FUNCTION(Yasmin, chapter1);
@@ -492,19 +493,46 @@ IMPLEMENT_FUNCTION(21, Yasmin, hiding)
break;
case kActionNone:
+ if (!getSoundQueue()->isBuffered(kEntityYasmin)) {
+ if (Entity::updateParameter(params->param1, getState()->timeTicks, 450)) {
+ getSound()->playSound(kEntityYasmin, "Har5001");
+ params->param1 = 0;
+ }
+ }
+ break;
+
case kActionDefault:
- if (getEntities()->updateEntity(kEntityYasmin, (CarIndex)params->param1, (EntityPosition)params->param2))
- callbackAction();
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_4840);
break;
- case kActionExcuseMeCath:
- getSound()->excuseMeCath();
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("615BE", kObjectCompartment5);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityYasmin);
+ getData()->location = kLocationInsideCompartment;
+ getData()->entityPosition = kPosition_3050;
+ getObjects()->update(kObjectCompartment7, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getSound()->playSound(kEntityYasmin, "Har5001");
+ break;
+ }
break;
- case kActionExcuseMe:
- getSound()->excuseMe(kEntityYasmin);
+ case kAction135800432:
+ setup_nullfunction();
break;
}
IMPLEMENT_FUNCTION_END
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_NULL_FUNCTION(22, Yasmin)
+
} // End of namespace LastExpress
diff --git a/engines/lastexpress/game/entities.cpp b/engines/lastexpress/game/entities.cpp
index b881d34ebe..1afebbbfaf 100644
--- a/engines/lastexpress/game/entities.cpp
+++ b/engines/lastexpress/game/entities.cpp
@@ -241,7 +241,7 @@ int Entities::getCompartments1(int index) const {
// Savegame
//////////////////////////////////////////////////////////////////////////
void Entities::saveLoadWithSerializer(Common::Serializer &s) {
- _header->saveLoadWithSerializer(s);
+ _header->saveLoadWithSerializer(s, NULL);
for (uint i = 1; i < _entities.size(); i++)
_entities[i]->saveLoadWithSerializer(s);
}
@@ -1931,7 +1931,7 @@ void Entities::loadSceneFromEntityPosition(CarIndex car, EntityPosition entityPo
// Determine position
Position position = (alternate ? 1 : 40);
do {
- if (entityPosition > entityPositions[position]) {
+ if (alternate ? entityPosition < entityPositions[position] : entityPosition > entityPositions[position]) {
if (alternate)
break;
@@ -1945,7 +1945,7 @@ void Entities::loadSceneFromEntityPosition(CarIndex car, EntityPosition entityPo
} while (alternate ? position <= 18 : position >= 22);
// For position outside bounds, use minimal value
- if ((alternate && position > 18) || (alternate && position < 22)) {
+ if ((alternate && position > 18) || (!alternate && position < 22)) {
getScenes()->loadSceneFromPosition(car, alternate ? 18 : 22);
return;
}
@@ -2117,7 +2117,7 @@ label_process_entity:
if (checkDistanceFromPosition(entity, kPosition_1500, 750) && entity != kEntityFrancois) {
- if (data->entity != kEntityPlayer) {
+ if (data->entity == kEntityPlayer) {
if (data->direction != kDirectionUp || (position <= kPosition_2000 && data->car == car)) {
if (data->direction == kDirectionDown && (position < kPosition_1500 || data->car != car)) {
if (data->entityPosition > kPosition_1500 && (data->car == kCarGreenSleeping || data->car == kCarRedSleeping)) {
@@ -2282,8 +2282,8 @@ label_process_entity:
}
}
}
- return false;
}
+ return false;
}
} else if (!flag1) {
drawSequences(entity, direction, true);
diff --git a/engines/lastexpress/game/savegame.cpp b/engines/lastexpress/game/savegame.cpp
index e2682ba0d1..ce53e6eadf 100644
--- a/engines/lastexpress/game/savegame.cpp
+++ b/engines/lastexpress/game/savegame.cpp
@@ -802,7 +802,7 @@ void SaveLoad::readEntry(SavegameType *type, EntityIndex *entity, uint32 *val, b
// Skip padding
uint32 offset = (uint32)_savegame->pos() - originalPosition;
if (offset & 0xF) {
- _savegame->seek((~offset & 0xF) + 1, SEEK_SET);
+ _savegame->seek((~offset & 0xF) + 1, SEEK_CUR);
}
}
diff --git a/engines/lastexpress/game/savepoint.cpp b/engines/lastexpress/game/savepoint.cpp
index a8483e6d5c..bd134c637c 100644
--- a/engines/lastexpress/game/savepoint.cpp
+++ b/engines/lastexpress/game/savepoint.cpp
@@ -162,8 +162,8 @@ void SavePoints::call(EntityIndex entity2, EntityIndex entity1, ActionIndex acti
point.action = action;
point.entity2 = entity2;
- assert(param.size() <= 5);
- strncpy((char *)&point.param.charValue, param.c_str(), 5);
+ assert(param.size() <= 6); // "MUS%03d"
+ strncpy((char *)&point.param.charValue, param.c_str(), 6);
Callback *callback = getCallback(entity1);
if (callback != NULL && callback->isValid()) {
@@ -230,6 +230,8 @@ bool SavePoints::updateEntityFromData(const SavePoint &savepoint) {
void SavePoints::saveLoadWithSerializer(Common::Serializer &s) {
// Serialize savepoint data
+ if (s.isLoading())
+ _data.clear();
uint32 dataSize = (s.isLoading() ? _savePointsMaxSize : _data.size());
for (uint i = 0; i < dataSize; i++) {
if (s.isLoading()) {
diff --git a/engines/lastexpress/game/savepoint.h b/engines/lastexpress/game/savepoint.h
index ab6490796b..ea73e7c25d 100644
--- a/engines/lastexpress/game/savepoint.h
+++ b/engines/lastexpress/game/savepoint.h
@@ -58,7 +58,7 @@ struct SavePoint {
EntityIndex entity2;
union {
uint32 intValue;
- char charValue[5];
+ char charValue[7]; // "MUS%03d" with terminating zero
} param;
SavePoint() {
@@ -66,6 +66,7 @@ struct SavePoint {
action = kActionNone;
entity2 = kEntityPlayer;
param.intValue = 0;
+ param.charValue[6] = 0;
}
Common::String toString() {
diff --git a/engines/lastexpress/game/state.h b/engines/lastexpress/game/state.h
index 38cd851aaa..b46807b40e 100644
--- a/engines/lastexpress/game/state.h
+++ b/engines/lastexpress/game/state.h
@@ -313,13 +313,14 @@ public:
* @return true if equal, false if not.
*/
bool isEqual(uint index, uint val) {
- return getValueName(index) == val;
+ return getOrSetValueName(index) == val;
}
- uint32 getValueName(uint index, Common::String *name = NULL) {
- #define EXPOSE_VALUE(idx, entryName) \
+ uint32 getOrSetValueName(uint index, Common::String *name = NULL, const uint32* newValue = NULL) {
+ #define EXPOSE_VALUE(idx, entryName, fieldType) \
case idx: { \
if (name) (*name) = "" #entryName; \
+ if (newValue) {entryName = (fieldType)*newValue;} \
return (uint32)entryName; \
}
@@ -328,134 +329,134 @@ public:
error("[GameProgress::getValueName] Invalid index value (was: %d, max:127)", index);
break;
- EXPOSE_VALUE(0, field_0);
- EXPOSE_VALUE(1, jacket);
- EXPOSE_VALUE(2, eventCorpseMovedFromFloor);
- EXPOSE_VALUE(3, field_C);
- EXPOSE_VALUE(4, eventCorpseFound);
- EXPOSE_VALUE(5, field_14);
- EXPOSE_VALUE(6, field_18);
- EXPOSE_VALUE(7, portrait);
- EXPOSE_VALUE(8, eventCorpseThrown);
- EXPOSE_VALUE(9, field_24);
- EXPOSE_VALUE(10, field_28);
- EXPOSE_VALUE(11, chapter);
- EXPOSE_VALUE(12, field_30);
- EXPOSE_VALUE(13, eventMetAugust);
- EXPOSE_VALUE(14, isNightTime);
- EXPOSE_VALUE(15, field_3C);
- EXPOSE_VALUE(16, field_40);
- EXPOSE_VALUE(17, field_44);
- EXPOSE_VALUE(18, field_48);
- EXPOSE_VALUE(19, field_4C);
- EXPOSE_VALUE(20, isTrainRunning);
- EXPOSE_VALUE(21, field_54);
- EXPOSE_VALUE(22, field_58);
- EXPOSE_VALUE(23, field_5C);
- EXPOSE_VALUE(24, field_60);
- EXPOSE_VALUE(25, field_64);
- EXPOSE_VALUE(26, field_68);
- EXPOSE_VALUE(27, eventMertensAugustWaiting);
- EXPOSE_VALUE(28, eventMertensKronosInvitation);
- EXPOSE_VALUE(29, isEggOpen);
- EXPOSE_VALUE(30, field_78);
- EXPOSE_VALUE(31, field_7C);
- EXPOSE_VALUE(32, field_80);
- EXPOSE_VALUE(33, field_84);
- EXPOSE_VALUE(34, field_88);
- EXPOSE_VALUE(35, field_8C);
- EXPOSE_VALUE(36, field_90);
- EXPOSE_VALUE(37, field_94);
- EXPOSE_VALUE(38, field_98);
- EXPOSE_VALUE(39, field_9C);
- EXPOSE_VALUE(40, field_A0);
- EXPOSE_VALUE(41, field_A4);
- EXPOSE_VALUE(42, field_A8);
- EXPOSE_VALUE(43, field_AC);
- EXPOSE_VALUE(44, field_B0);
- EXPOSE_VALUE(45, field_B4);
- EXPOSE_VALUE(46, field_B8);
- EXPOSE_VALUE(47, field_BC);
- EXPOSE_VALUE(48, field_C0);
- EXPOSE_VALUE(49, field_C4);
- EXPOSE_VALUE(50, field_C8);
- EXPOSE_VALUE(51, field_CC);
- EXPOSE_VALUE(52, eventMetBoutarel);
- EXPOSE_VALUE(53, eventMetHadija);
- EXPOSE_VALUE(54, eventMetYasmin);
- EXPOSE_VALUE(55, field_DC);
- EXPOSE_VALUE(56, field_E0);
- EXPOSE_VALUE(57, field_E4);
- EXPOSE_VALUE(58, field_E8);
- EXPOSE_VALUE(59, field_EC);
- EXPOSE_VALUE(60, field_F0);
- EXPOSE_VALUE(61, field_F4);
- EXPOSE_VALUE(62, field_F8);
- EXPOSE_VALUE(63, field_FC);
- EXPOSE_VALUE(64, field_100);
- EXPOSE_VALUE(65, field_104);
- EXPOSE_VALUE(66, field_108);
- EXPOSE_VALUE(67, field_10C);
- EXPOSE_VALUE(68, field_110);
- EXPOSE_VALUE(69, field_114);
- EXPOSE_VALUE(70, field_118);
- EXPOSE_VALUE(71, field_11C);
- EXPOSE_VALUE(72, field_120);
- EXPOSE_VALUE(73, field_124);
- EXPOSE_VALUE(74, field_128);
- EXPOSE_VALUE(75, field_12C);
- EXPOSE_VALUE(76, field_130);
- EXPOSE_VALUE(77, field_134);
- EXPOSE_VALUE(78, field_138);
- EXPOSE_VALUE(79, field_13C);
- EXPOSE_VALUE(80, field_140);
- EXPOSE_VALUE(81, field_144);
- EXPOSE_VALUE(82, field_148);
- EXPOSE_VALUE(83, field_14C);
- EXPOSE_VALUE(84, field_150);
- EXPOSE_VALUE(85, field_154);
- EXPOSE_VALUE(86, field_158);
- EXPOSE_VALUE(87, field_15C);
- EXPOSE_VALUE(88, field_160);
- EXPOSE_VALUE(89, field_164);
- EXPOSE_VALUE(90, field_168);
- EXPOSE_VALUE(91, field_16C);
- EXPOSE_VALUE(92, field_170);
- EXPOSE_VALUE(93, field_174);
- EXPOSE_VALUE(94, field_178);
- EXPOSE_VALUE(95, field_17C);
- EXPOSE_VALUE(96, field_180);
- EXPOSE_VALUE(97, field_184);
- EXPOSE_VALUE(98, field_188);
- EXPOSE_VALUE(99, field_18C);
- EXPOSE_VALUE(100, field_190);
- EXPOSE_VALUE(101, field_194);
- EXPOSE_VALUE(102, field_198);
- EXPOSE_VALUE(103, field_19C);
- EXPOSE_VALUE(104, field_1A0);
- EXPOSE_VALUE(105, field_1A4);
- EXPOSE_VALUE(106, field_1A8);
- EXPOSE_VALUE(107, field_1AC);
- EXPOSE_VALUE(108, field_1B0);
- EXPOSE_VALUE(109, field_1B4);
- EXPOSE_VALUE(110, field_1B8);
- EXPOSE_VALUE(111, field_1BC);
- EXPOSE_VALUE(112, field_1C0);
- EXPOSE_VALUE(113, field_1C4);
- EXPOSE_VALUE(114, field_1C8);
- EXPOSE_VALUE(115, field_1CC);
- EXPOSE_VALUE(116, field_1D0);
- EXPOSE_VALUE(117, field_1D4);
- EXPOSE_VALUE(118, field_1D8);
- EXPOSE_VALUE(119, field_1DC);
- EXPOSE_VALUE(120, field_1E0);
- EXPOSE_VALUE(121, field_1E4);
- EXPOSE_VALUE(122, field_1E8);
- EXPOSE_VALUE(123, field_1EC);
- EXPOSE_VALUE(124, field_1F0);
- EXPOSE_VALUE(125, field_1F4);
- EXPOSE_VALUE(126, field_1F8);
- EXPOSE_VALUE(127, field_1FC);
+ EXPOSE_VALUE(0, field_0, uint32);
+ EXPOSE_VALUE(1, jacket, JacketType);
+ EXPOSE_VALUE(2, eventCorpseMovedFromFloor, bool);
+ EXPOSE_VALUE(3, field_C, uint32);
+ EXPOSE_VALUE(4, eventCorpseFound, bool);
+ EXPOSE_VALUE(5, field_14, uint32);
+ EXPOSE_VALUE(6, field_18, uint32);
+ EXPOSE_VALUE(7, portrait, uint32);
+ EXPOSE_VALUE(8, eventCorpseThrown, bool);
+ EXPOSE_VALUE(9, field_24, uint32);
+ EXPOSE_VALUE(10, field_28, uint32);
+ EXPOSE_VALUE(11, chapter, ChapterIndex);
+ EXPOSE_VALUE(12, field_30, uint32);
+ EXPOSE_VALUE(13, eventMetAugust, bool);
+ EXPOSE_VALUE(14, isNightTime, bool);
+ EXPOSE_VALUE(15, field_3C, uint32);
+ EXPOSE_VALUE(16, field_40, uint32);
+ EXPOSE_VALUE(17, field_44, uint32);
+ EXPOSE_VALUE(18, field_48, uint32);
+ EXPOSE_VALUE(19, field_4C, uint32);
+ EXPOSE_VALUE(20, isTrainRunning, bool);
+ EXPOSE_VALUE(21, field_54, uint32);
+ EXPOSE_VALUE(22, field_58, uint32);
+ EXPOSE_VALUE(23, field_5C, uint32);
+ EXPOSE_VALUE(24, field_60, uint32);
+ EXPOSE_VALUE(25, field_64, uint32);
+ EXPOSE_VALUE(26, field_68, uint32);
+ EXPOSE_VALUE(27, eventMertensAugustWaiting, bool);
+ EXPOSE_VALUE(28, eventMertensKronosInvitation, bool);
+ EXPOSE_VALUE(29, isEggOpen, bool);
+ EXPOSE_VALUE(30, field_78, uint32);
+ EXPOSE_VALUE(31, field_7C, uint32);
+ EXPOSE_VALUE(32, field_80, uint32);
+ EXPOSE_VALUE(33, field_84, uint32);
+ EXPOSE_VALUE(34, field_88, uint32);
+ EXPOSE_VALUE(35, field_8C, uint32);
+ EXPOSE_VALUE(36, field_90, uint32);
+ EXPOSE_VALUE(37, field_94, uint32);
+ EXPOSE_VALUE(38, field_98, uint32);
+ EXPOSE_VALUE(39, field_9C, uint32);
+ EXPOSE_VALUE(40, field_A0, uint32);
+ EXPOSE_VALUE(41, field_A4, uint32);
+ EXPOSE_VALUE(42, field_A8, uint32);
+ EXPOSE_VALUE(43, field_AC, uint32);
+ EXPOSE_VALUE(44, field_B0, uint32);
+ EXPOSE_VALUE(45, field_B4, uint32);
+ EXPOSE_VALUE(46, field_B8, uint32);
+ EXPOSE_VALUE(47, field_BC, uint32);
+ EXPOSE_VALUE(48, field_C0, uint32);
+ EXPOSE_VALUE(49, field_C4, uint32);
+ EXPOSE_VALUE(50, field_C8, uint32);
+ EXPOSE_VALUE(51, field_CC, uint32);
+ EXPOSE_VALUE(52, eventMetBoutarel, bool);
+ EXPOSE_VALUE(53, eventMetHadija, bool);
+ EXPOSE_VALUE(54, eventMetYasmin, bool);
+ EXPOSE_VALUE(55, field_DC, uint32);
+ EXPOSE_VALUE(56, field_E0, uint32);
+ EXPOSE_VALUE(57, field_E4, uint32);
+ EXPOSE_VALUE(58, field_E8, uint32);
+ EXPOSE_VALUE(59, field_EC, uint32);
+ EXPOSE_VALUE(60, field_F0, uint32);
+ EXPOSE_VALUE(61, field_F4, uint32);
+ EXPOSE_VALUE(62, field_F8, uint32);
+ EXPOSE_VALUE(63, field_FC, uint32);
+ EXPOSE_VALUE(64, field_100, uint32);
+ EXPOSE_VALUE(65, field_104, uint32);
+ EXPOSE_VALUE(66, field_108, uint32);
+ EXPOSE_VALUE(67, field_10C, uint32);
+ EXPOSE_VALUE(68, field_110, uint32);
+ EXPOSE_VALUE(69, field_114, uint32);
+ EXPOSE_VALUE(70, field_118, uint32);
+ EXPOSE_VALUE(71, field_11C, uint32);
+ EXPOSE_VALUE(72, field_120, uint32);
+ EXPOSE_VALUE(73, field_124, uint32);
+ EXPOSE_VALUE(74, field_128, uint32);
+ EXPOSE_VALUE(75, field_12C, uint32);
+ EXPOSE_VALUE(76, field_130, uint32);
+ EXPOSE_VALUE(77, field_134, uint32);
+ EXPOSE_VALUE(78, field_138, uint32);
+ EXPOSE_VALUE(79, field_13C, uint32);
+ EXPOSE_VALUE(80, field_140, uint32);
+ EXPOSE_VALUE(81, field_144, uint32);
+ EXPOSE_VALUE(82, field_148, uint32);
+ EXPOSE_VALUE(83, field_14C, uint32);
+ EXPOSE_VALUE(84, field_150, uint32);
+ EXPOSE_VALUE(85, field_154, uint32);
+ EXPOSE_VALUE(86, field_158, uint32);
+ EXPOSE_VALUE(87, field_15C, uint32);
+ EXPOSE_VALUE(88, field_160, uint32);
+ EXPOSE_VALUE(89, field_164, uint32);
+ EXPOSE_VALUE(90, field_168, uint32);
+ EXPOSE_VALUE(91, field_16C, uint32);
+ EXPOSE_VALUE(92, field_170, uint32);
+ EXPOSE_VALUE(93, field_174, uint32);
+ EXPOSE_VALUE(94, field_178, uint32);
+ EXPOSE_VALUE(95, field_17C, uint32);
+ EXPOSE_VALUE(96, field_180, uint32);
+ EXPOSE_VALUE(97, field_184, uint32);
+ EXPOSE_VALUE(98, field_188, uint32);
+ EXPOSE_VALUE(99, field_18C, uint32);
+ EXPOSE_VALUE(100, field_190, uint32);
+ EXPOSE_VALUE(101, field_194, uint32);
+ EXPOSE_VALUE(102, field_198, uint32);
+ EXPOSE_VALUE(103, field_19C, uint32);
+ EXPOSE_VALUE(104, field_1A0, uint32);
+ EXPOSE_VALUE(105, field_1A4, uint32);
+ EXPOSE_VALUE(106, field_1A8, uint32);
+ EXPOSE_VALUE(107, field_1AC, uint32);
+ EXPOSE_VALUE(108, field_1B0, uint32);
+ EXPOSE_VALUE(109, field_1B4, uint32);
+ EXPOSE_VALUE(110, field_1B8, uint32);
+ EXPOSE_VALUE(111, field_1BC, uint32);
+ EXPOSE_VALUE(112, field_1C0, uint32);
+ EXPOSE_VALUE(113, field_1C4, uint32);
+ EXPOSE_VALUE(114, field_1C8, uint32);
+ EXPOSE_VALUE(115, field_1CC, uint32);
+ EXPOSE_VALUE(116, field_1D0, uint32);
+ EXPOSE_VALUE(117, field_1D4, uint32);
+ EXPOSE_VALUE(118, field_1D8, uint32);
+ EXPOSE_VALUE(119, field_1DC, uint32);
+ EXPOSE_VALUE(120, field_1E0, uint32);
+ EXPOSE_VALUE(121, field_1E4, uint32);
+ EXPOSE_VALUE(122, field_1E8, uint32);
+ EXPOSE_VALUE(123, field_1EC, uint32);
+ EXPOSE_VALUE(124, field_1F0, uint32);
+ EXPOSE_VALUE(125, field_1F4, uint32);
+ EXPOSE_VALUE(126, field_1F8, uint32);
+ EXPOSE_VALUE(127, field_1FC, uint32);
}
}
@@ -464,7 +465,7 @@ public:
for (uint i = 0; i < 128; i++) {
Common::String name = "";
- uint val = getValueName(i, &name);
+ uint val = getOrSetValueName(i, &name, NULL);
ret += Common::String::format("(%03d) %s = %d\n", i, name.c_str(), val);
}
@@ -472,9 +473,17 @@ public:
}
void saveLoadWithSerializer(Common::Serializer &s) {
- for (uint i = 0; i < 128; i++) {
- uint32 val = getValueName(i);
- s.syncAsUint32LE(val);
+ if (s.isLoading()) {
+ for (uint i = 0; i < 128; i++) {
+ uint32 val;
+ s.syncAsUint32LE(val);
+ getOrSetValueName(i, NULL, &val);
+ }
+ } else {
+ for (uint i = 0; i < 128; i++) {
+ uint32 val = getOrSetValueName(i);
+ s.syncAsUint32LE(val);
+ }
}
}
};
diff --git a/engines/lastexpress/shared.h b/engines/lastexpress/shared.h
index 724c4b3fb4..1b703acd09 100644
--- a/engines/lastexpress/shared.h
+++ b/engines/lastexpress/shared.h
@@ -274,6 +274,7 @@ enum TimeValue {
kTime2097000 = 2097000, // Day 2, 14:50
kTimeEnterLinz = 2099700, // Day 2, 14:53
kTimeCityLinz = 2101500, // Day 2, 14:55
+ kTimeExitLinz = 2105100, // Day 2, 14:59
kTime2106000 = 2106000, // Day 2, 15:00
kTime2110500 = 2110500, // Day 2, 15:05
kTime2115000 = 2115000, // Day 2, 15:10
@@ -373,14 +374,18 @@ enum TimeValue {
kTimeTrainStopped = 2898000, // Day 3, 05:40
kTime2907000 = 2907000, // Day 3, 05:50
kTime2916000 = 2916000, // Day 3, 06:00
- kTimeCityBelgrade = 2952000, // Day 3, 06:40
+ kTime2934000 = 2934000, // Day 3, 06:20
kTimeTrainStopped2 = 2943000, // Day 3, 06:30
+ kTime2949300 = 2949300, // Day 3, 06:37
+ kTimeCityBelgrade = 2952000, // Day 3, 06:40
kTime2983500 = 2983500, // Day 3, 07:15
kTimeCityNish = 3205800, // Day 3, 11:22
kTimeCityTzaribrod = 3492000, // Day 3, 16:40
kTime3645000 = 3645000, // Day 3, 19:30
kTimeCitySofia = 3690000, // Day 3, 20:20
kTimeCityAdrianople = 4320900, // Day 4, 08:01
+ kTime4914000 = 4914000, // Day 4, 19:00
+ kTime4920300 = 4920300, // Day 4, 19:07
kTime4923000 = 4923000, // Day 4, 19:10
kTime4929300 = 4929300, // Day 4, 19:17
kTimeCityConstantinople = 4941000, // Day 4, 19:30
@@ -1193,8 +1198,8 @@ enum EventIndex {
kEventVergesSuitcaseNightOtherEntryStart = 137,
kEventMertensAskTylerCompartment = 138,
kEventMertensAskTylerCompartmentD = 139,
- kEventMertensPushCall = 140,
- kEventMertensPushCallNight = 141,
+ kEventMertensPushCallNight = 140,
+ kEventMertensPushCall = 141,
kEventMertensAugustWaiting = 142,
kEventMertensAugustWaitingCompartment = 143,
kEventIntroBroderbrund = 144,
@@ -1232,8 +1237,8 @@ enum EventIndex {
kEventCathSalkoTrainTopWin = 176,
kEventFrancoisWhistle = 177,
kEventFrancoisWhistleD = 178,
- kEventFrancoisWhistleNight = 179,
- kEventFrancoisWhistleNightD = 180,
+ kEventFrancoisWhistleNightD = 179,
+ kEventFrancoisWhistleNight = 180,
kEventFrancoisShowBeetle = 181,
kEventFrancoisShowBeetleD = 182,
kEventFrancoisTradeWhistle = 183,
diff --git a/engines/lastexpress/sound/entry.cpp b/engines/lastexpress/sound/entry.cpp
index 7308214551..87ecd26cdb 100644
--- a/engines/lastexpress/sound/entry.cpp
+++ b/engines/lastexpress/sound/entry.cpp
@@ -93,7 +93,7 @@ void SoundEntry::close() {
_status.status |= kSoundStatusClosed;
// Loop until ready
- //while (!(_status.status1 & 4) && !(getSoundQueue()->getFlag() & 8) && (getSoundQueue()->getFlag() & 1))
+ //while (!(_status.b.status1 & 4) && !(getSoundQueue()->getFlag() & 8) && (getSoundQueue()->getFlag() & 1))
// ; // empty loop body
// The original game remove the entry from the cache here,
@@ -246,7 +246,7 @@ void SoundEntry::loadStream(Common::String name) {
}
void SoundEntry::update(uint val) {
- if (!(_status.status3 & 64)) {
+ if (!(_status.b.status3 & 64)) {
int value2 = val;
_status.status |= kSoundStatus_100000;
@@ -271,10 +271,10 @@ bool SoundEntry::updateSound() {
bool result;
char sub[16];
- if (_status.status2 & 4) {
+ if (_status.b.status2 & 4) {
result = false;
} else {
- if (_status.status2 & 0x80) {
+ if (_status.b.status2 & 0x80) {
if (_field_48 <= getSound()->getData2()) {
_status.status |= 0x20;
_status.status &= ~0x8000;
@@ -288,7 +288,7 @@ bool SoundEntry::updateSound() {
}
} else {
if (!(getSoundQueue()->getFlag() & 0x20)) {
- if (!(_status.status3 & 8)) {
+ if (!(_status.b.status3 & 8)) {
if (_entity) {
if (_entity < 0x80) {
updateEntryFlag(getSound()->getSoundFlag(_entity));
@@ -296,7 +296,7 @@ bool SoundEntry::updateSound() {
}
}
}
- //if (status.status2 & 0x40 && !((uint32)_status.status & 0x180) && v1->soundBuffer)
+ //if (status.b.status2 & 0x40 && !((uint32)_status.status & 0x180) && v1->soundBuffer)
// Sound_FillSoundBuffer(v1);
}
result = true;
@@ -354,7 +354,7 @@ void SoundEntry::showSubtitle(Common::String filename) {
_subtitle = new SubtitleEntry(_engine);
_subtitle->load(filename, this);
- if (_subtitle->getStatus().status2 & 4) {
+ if (_subtitle->getStatus().b.status2 & 4) {
_subtitle->draw();
SAFE_DELETE(_subtitle);
} else {
diff --git a/engines/lastexpress/sound/entry.h b/engines/lastexpress/sound/entry.h
index d92b16a5dd..0ebe550a02 100644
--- a/engines/lastexpress/sound/entry.h
+++ b/engines/lastexpress/sound/entry.h
@@ -76,12 +76,15 @@ namespace LastExpress {
class LastExpressEngine;
class SubtitleEntry;
+// TODO: this union assumes little-endian machine
union SoundStatusUnion {
uint32 status;
- byte status1;
- byte status2;
- byte status3;
- byte status4;
+ struct {
+ byte status1;
+ byte status2;
+ byte status3;
+ byte status4;
+ } b;
SoundStatusUnion() {
status = 0;
diff --git a/engines/lastexpress/sound/queue.cpp b/engines/lastexpress/sound/queue.cpp
index fe6d6f2251..a088da319f 100644
--- a/engines/lastexpress/sound/queue.cpp
+++ b/engines/lastexpress/sound/queue.cpp
@@ -132,7 +132,7 @@ void SoundQueue::updateQueue() {
// and if the sound data buffer is not full, loads a new entry to be played based on
// its priority and filter id
- if (!entry->updateSound() && !(entry->getStatus().status3 & 0x8)) {
+ if (!entry->updateSound() && !(entry->getStatus().b.status3 & 0x8)) {
entry->close();
SAFE_DELETE(entry);
it = _soundList.reverse_erase(it);
diff --git a/engines/lastexpress/sound/sound.cpp b/engines/lastexpress/sound/sound.cpp
index 3a2d0c075c..ca79915c66 100644
--- a/engines/lastexpress/sound/sound.cpp
+++ b/engines/lastexpress/sound/sound.cpp
@@ -136,7 +136,7 @@ SoundManager::~SoundManager() {
// Sound-related functions
//////////////////////////////////////////////////////////////////////////
void SoundManager::playSound(EntityIndex entity, Common::String filename, SoundFlag flag, byte a4) {
- if (_queue->isBuffered(entity) && entity)
+ if (_queue->isBuffered(entity) && entity && entity < kEntityTrain)
_queue->removeFromQueue(entity);
SoundFlag currentFlag = (flag == -1) ? getSoundFlag(entity) : (SoundFlag)(flag | 0x80000);
@@ -372,6 +372,8 @@ void SoundManager::playLocomotiveSound() {
}
const char *SoundManager::getDialogName(EntityIndex entity) const {
+ if (_queue->isBuffered(kEntityTables4))
+ return NULL;
switch (entity) {
case kEntityAnna:
if (getEvent(kEventAnnaDialogGoToJerusalem))
@@ -558,7 +560,7 @@ const char *SoundManager::getDialogName(EntityIndex entity) const {
return "XKRO4";
if (getEvent(kEventKronosConversation)) {
- if (!getEvent(kEventMilosCompartmentVisitAugust))
+ if (getEvent(kEventMilosCompartmentVisitAugust))
return "XKRO3";
else
return "XKRO2";
@@ -675,7 +677,7 @@ const char *SoundManager::getDialogName(EntityIndex entity) const {
// Letters & Messages
//////////////////////////////////////////////////////////////////////////
void SoundManager::readText(int id) {
- if (!_queue->isBuffered(kEntityTables4))
+ if (_queue->isBuffered(kEntityTables4))
return;
if (id < 0 || (id > 8 && id < 50) || id > 64)
@@ -840,9 +842,9 @@ void SoundManager::playWarningCompartment(EntityIndex entity, ObjectIndex compar
}
if (rnd(2) || getEntities()->isInsideCompartment(kEntityAnna, kCarRedSleeping, kPosition_4070))
- getSound()->playSound(kEntityCoudert, "Jac1503", kFlagDefault);
- else
getSound()->playSound(kEntityCoudert, "Jac1503A", kFlagDefault);
+ else
+ getSound()->playSound(kEntityCoudert, "Jac1503", kFlagDefault);
break;
case kObjectCompartmentG:
@@ -851,6 +853,10 @@ void SoundManager::playWarningCompartment(EntityIndex entity, ObjectIndex compar
break;
}
+ // BUG: the original game got isInsideCompartment() inverted
+ // Jac1502A is "the serbian gentleman is not in, monsier",
+ // Jac1502 is a generic response,
+ // so Coudert only says "Milos is not in" when Milos is actually in.
if (rnd(2) || getEntities()->isInsideCompartment(kEntityMilos, kCarRedSleeping, kPosition_3050))
getSound()->playSound(kEntityCoudert, "Jac1502", kFlagDefault);
else
@@ -922,7 +928,7 @@ void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, SoundFlag f
if (Entities::isFemale(entity2)) {
playSound(kEntityPlayer, (rnd(2) ? "CON1111" : "CON1111A"), flag);
} else {
- if (entity2 || getProgress().jacket != kJacketGreen || !rnd(2)) {
+ if (entity2 != kEntityPlayer || getProgress().jacket != kJacketGreen || !rnd(2)) {
switch(rnd(3)) {
default:
break;
@@ -941,9 +947,9 @@ void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, SoundFlag f
}
} else {
if (isNight()) {
- playSound(kEntityPlayer, (getProgress().field_18 == 2 ? "CON1110F" : "CON1110E"));
+ playSound(kEntityPlayer, (getProgress().field_18 == 2 ? "CON1110F" : "CON1110E"), flag);
} else {
- playSound(kEntityPlayer, "CON1110D");
+ playSound(kEntityPlayer, "CON1110D", flag);
}
}
}
@@ -953,7 +959,7 @@ void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, SoundFlag f
if (Entities::isFemale(entity2)) {
playSound(kEntityPlayer, "JAC1111D", flag);
} else {
- if (entity2 || getProgress().jacket != kJacketGreen || !rnd(2)) {
+ if (entity2 != kEntityPlayer || getProgress().jacket != kJacketGreen || !rnd(2)) {
switch(rnd(4)) {
default:
break;
@@ -981,7 +987,7 @@ void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, SoundFlag f
break;
case kEntityPascale:
- playSound(kEntityPlayer, (rnd(2) ? "HDE1002" : "HED1002A"), flag);
+ playSound(kEntityPlayer, (rnd(2) ? "HED1002" : "HED1002A"), flag);
break;
case kEntityWaiter1:
@@ -1006,7 +1012,7 @@ void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, SoundFlag f
case kEntityVerges:
if (Entities::isFemale(entity2)) {
- playSound(kEntityPlayer, (rnd(2) ? "TRA1113A" : "TRA1113B"));
+ playSound(kEntityPlayer, (rnd(2) ? "TRA1113A" : "TRA1113B"), flag);
} else {
playSound(kEntityPlayer, "TRA1112", flag);
}
@@ -1097,7 +1103,7 @@ void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, SoundFlag f
break;
case kEntityRebecca:
- playSound(kEntityPlayer, (rnd(2) ? "REB1106" : "REB110A"), flag);
+ playSound(kEntityPlayer, (rnd(2) ? "REB1106" : "Reb1106A"), flag);
break;
case kEntitySophie: {
@@ -1239,8 +1245,8 @@ SoundFlag SoundManager::getSoundFlag(EntityIndex entity) const {
if (index < 32)
ret = soundFlags[index];
- if (getEntityData(entity)->location == kLocationOutsideTrain) {
- if (getEntityData(entity)->car != kCarKronos
+ if (getEntityData(kEntityPlayer)->location == kLocationOutsideTrain) {
+ if (getEntityData(kEntityPlayer)->car != kCarKronos
&& !getEntities()->isOutsideAlexeiWindow()
&& !getEntities()->isOutsideAnnaWindow())
return kFlagNone;
@@ -1254,25 +1260,24 @@ SoundFlag SoundManager::getSoundFlag(EntityIndex entity) const {
case kCarKronos:
if (getEntities()->isInKronosSalon(entity) != getEntities()->isInKronosSalon(kEntityPlayer))
- ret = (SoundFlag)(ret * 2);
+ ret = (SoundFlag)(ret / 2);
break;
case kCarGreenSleeping:
case kCarRedSleeping:
- if (getEntities()->isInGreenCarEntrance(kEntityPlayer) && !getEntities()->isInKronosSalon(entity))
- ret = (SoundFlag)(ret * 2);
+ if (getEntities()->isInGreenCarEntrance(kEntityPlayer) && !getEntities()->isInGreenCarEntrance(entity))
+ ret = (SoundFlag)(ret / 2);
- if (getEntityData(kEntityPlayer)->location
- && (getEntityData(entity)->entityPosition != kPosition_1 || !getEntities()->isDistanceBetweenEntities(kEntityPlayer, entity, 400)))
- ret = (SoundFlag)(ret * 2);
+ if (getEntityData(kEntityPlayer)->location == kLocationInsideCompartment
+ && (getEntityData(entity)->location != kLocationInsideCompartment || !getEntities()->isDistanceBetweenEntities(kEntityPlayer, entity, 400)))
+ ret = (SoundFlag)(ret / 2);
break;
case kCarRestaurant:
- if (getEntities()->isInSalon(entity) == getEntities()->isInSalon(kEntityPlayer)
- && (getEntities()->isInRestaurant(entity) != getEntities()->isInRestaurant(kEntityPlayer)))
- ret = (SoundFlag)(ret * 2);
- else
- ret = (SoundFlag)(ret * 4);
+ if (getEntities()->isInSalon(entity) != getEntities()->isInSalon(kEntityPlayer))
+ ret = (SoundFlag)(ret / 4);
+ else if (getEntities()->isInRestaurant(entity) != getEntities()->isInRestaurant(kEntityPlayer))
+ ret = (SoundFlag)(ret / 2);
break;
}
@@ -1314,7 +1319,7 @@ void SoundManager::playLoopingSound(int param) {
partNumber = 6;
} else {
if (getEntities()->isInsideCompartments(kEntityPlayer)) {
- int objNum = (getEntityData(kEntityPlayer)->car - 3) < 1 ? 9 : 40; // Weird numbers
+ int objNum = (getEntityData(kEntityPlayer)->car == kCarGreenSleeping) ? 9 : 40; // Weird numbers
numLoops[0] = 0;
@@ -1323,7 +1328,7 @@ void SoundManager::playLoopingSound(int param) {
break;
if (getEntities()->isInsideCompartment(kEntityPlayer, getEntityData(kEntityPlayer)->car, positions[pos])) {
numLoops[0] = 1;
- partNumber = (getObjects()->get((ObjectIndex)objNum).status - 2) < 1 ? 6 : 1;
+ partNumber = (getObjects()->get((ObjectIndex)objNum).status == kObjectLocation2) ? 6 : 1;
}
objNum++;
}