aboutsummaryrefslogtreecommitdiff
path: root/engines/lastexpress/entities
diff options
context:
space:
mode:
Diffstat (limited to 'engines/lastexpress/entities')
-rw-r--r--engines/lastexpress/entities/abbot.cpp1910
-rw-r--r--engines/lastexpress/entities/abbot.h225
-rw-r--r--engines/lastexpress/entities/alexei.cpp1897
-rw-r--r--engines/lastexpress/entities/alexei.h213
-rw-r--r--engines/lastexpress/entities/alouan.cpp504
-rw-r--r--engines/lastexpress/entities/alouan.h139
-rw-r--r--engines/lastexpress/entities/anna.cpp3400
-rw-r--r--engines/lastexpress/entities/anna.h252
-rw-r--r--engines/lastexpress/entities/august.cpp2804
-rw-r--r--engines/lastexpress/entities/august.h275
-rw-r--r--engines/lastexpress/entities/boutarel.cpp1260
-rw-r--r--engines/lastexpress/entities/boutarel.h188
-rw-r--r--engines/lastexpress/entities/chapters.cpp1810
-rw-r--r--engines/lastexpress/entities/chapters.h166
-rw-r--r--engines/lastexpress/entities/cooks.cpp571
-rw-r--r--engines/lastexpress/entities/cooks.h109
-rw-r--r--engines/lastexpress/entities/coudert.cpp3611
-rw-r--r--engines/lastexpress/entities/coudert.h229
-rw-r--r--engines/lastexpress/entities/entity.cpp434
-rw-r--r--engines/lastexpress/entities/entity.h681
-rw-r--r--engines/lastexpress/entities/entity39.cpp103
-rw-r--r--engines/lastexpress/entities/entity39.h78
-rw-r--r--engines/lastexpress/entities/entity_intern.h577
-rw-r--r--engines/lastexpress/entities/francois.cpp1043
-rw-r--r--engines/lastexpress/entities/francois.h170
-rw-r--r--engines/lastexpress/entities/gendarmes.cpp491
-rw-r--r--engines/lastexpress/entities/gendarmes.h99
-rw-r--r--engines/lastexpress/entities/hadija.cpp529
-rw-r--r--engines/lastexpress/entities/hadija.h144
-rw-r--r--engines/lastexpress/entities/ivo.cpp829
-rw-r--r--engines/lastexpress/entities/ivo.h177
-rw-r--r--engines/lastexpress/entities/kahina.cpp944
-rw-r--r--engines/lastexpress/entities/kahina.h166
-rw-r--r--engines/lastexpress/entities/kronos.cpp666
-rw-r--r--engines/lastexpress/entities/kronos.h138
-rw-r--r--engines/lastexpress/entities/mahmud.cpp839
-rw-r--r--engines/lastexpress/entities/mahmud.h153
-rw-r--r--engines/lastexpress/entities/max.cpp628
-rw-r--r--engines/lastexpress/entities/max.h129
-rw-r--r--engines/lastexpress/entities/mertens.cpp4113
-rw-r--r--engines/lastexpress/entities/mertens.h220
-rw-r--r--engines/lastexpress/entities/milos.cpp1077
-rw-r--r--engines/lastexpress/entities/milos.h175
-rw-r--r--engines/lastexpress/entities/mmeboutarel.cpp939
-rw-r--r--engines/lastexpress/entities/mmeboutarel.h164
-rw-r--r--engines/lastexpress/entities/pascale.cpp1232
-rw-r--r--engines/lastexpress/entities/pascale.h166
-rw-r--r--engines/lastexpress/entities/rebecca.cpp1732
-rw-r--r--engines/lastexpress/entities/rebecca.h230
-rw-r--r--engines/lastexpress/entities/salko.cpp642
-rw-r--r--engines/lastexpress/entities/salko.h149
-rw-r--r--engines/lastexpress/entities/servers0.cpp1039
-rw-r--r--engines/lastexpress/entities/servers0.h173
-rw-r--r--engines/lastexpress/entities/servers1.cpp787
-rw-r--r--engines/lastexpress/entities/servers1.h167
-rw-r--r--engines/lastexpress/entities/sophie.cpp279
-rw-r--r--engines/lastexpress/entities/sophie.h98
-rw-r--r--engines/lastexpress/entities/tables.cpp221
-rw-r--r--engines/lastexpress/entities/tables.h77
-rw-r--r--engines/lastexpress/entities/tatiana.cpp1711
-rw-r--r--engines/lastexpress/entities/tatiana.h235
-rw-r--r--engines/lastexpress/entities/train.cpp575
-rw-r--r--engines/lastexpress/entities/train.h95
-rw-r--r--engines/lastexpress/entities/vassili.cpp589
-rw-r--r--engines/lastexpress/entities/vassili.h110
-rw-r--r--engines/lastexpress/entities/verges.cpp1898
-rw-r--r--engines/lastexpress/entities/verges.h182
-rw-r--r--engines/lastexpress/entities/vesna.cpp1161
-rw-r--r--engines/lastexpress/entities/vesna.h176
-rw-r--r--engines/lastexpress/entities/yasmin.cpp490
-rw-r--r--engines/lastexpress/entities/yasmin.h142
71 files changed, 49625 insertions, 0 deletions
diff --git a/engines/lastexpress/entities/abbot.cpp b/engines/lastexpress/entities/abbot.cpp
new file mode 100644
index 0000000000..d46bb325be
--- /dev/null
+++ b/engines/lastexpress/entities/abbot.cpp
@@ -0,0 +1,1910 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/abbot.h"
+
+#include "lastexpress/entities/verges.h"
+
+#include "lastexpress/game/action.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"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+
+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(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(Abbot, callbackActionRestaurantOrSalon);
+ ADD_CALLBACK_FUNCTION(Abbot, chapter1);
+ ADD_CALLBACK_FUNCTION(Abbot, chapter2);
+ ADD_CALLBACK_FUNCTION(Abbot, chapter3);
+ ADD_CALLBACK_FUNCTION(Abbot, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Abbot, function19);
+ ADD_CALLBACK_FUNCTION(Abbot, function20);
+ ADD_CALLBACK_FUNCTION(Abbot, function21);
+ ADD_CALLBACK_FUNCTION(Abbot, function22);
+ ADD_CALLBACK_FUNCTION(Abbot, function23);
+ ADD_CALLBACK_FUNCTION(Abbot, function24);
+ ADD_CALLBACK_FUNCTION(Abbot, function25);
+ ADD_CALLBACK_FUNCTION(Abbot, function26);
+ ADD_CALLBACK_FUNCTION(Abbot, function27);
+ ADD_CALLBACK_FUNCTION(Abbot, function28);
+ ADD_CALLBACK_FUNCTION(Abbot, function29);
+ ADD_CALLBACK_FUNCTION(Abbot, function30);
+ ADD_CALLBACK_FUNCTION(Abbot, function31);
+ ADD_CALLBACK_FUNCTION(Abbot, function32);
+ ADD_CALLBACK_FUNCTION(Abbot, function33);
+ ADD_CALLBACK_FUNCTION(Abbot, function34);
+ ADD_CALLBACK_FUNCTION(Abbot, function35);
+ ADD_CALLBACK_FUNCTION(Abbot, function36);
+ ADD_CALLBACK_FUNCTION(Abbot, function37);
+ ADD_CALLBACK_FUNCTION(Abbot, function38);
+ ADD_CALLBACK_FUNCTION(Abbot, chapter4);
+ ADD_CALLBACK_FUNCTION(Abbot, function40);
+ ADD_CALLBACK_FUNCTION(Abbot, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Abbot, function42);
+ ADD_CALLBACK_FUNCTION(Abbot, function43);
+ ADD_CALLBACK_FUNCTION(Abbot, function44);
+ ADD_CALLBACK_FUNCTION(Abbot, function45);
+ ADD_CALLBACK_FUNCTION(Abbot, function46);
+ ADD_CALLBACK_FUNCTION(Abbot, drinkAfterDefuse);
+ ADD_CALLBACK_FUNCTION(Abbot, function48);
+ ADD_CALLBACK_FUNCTION(Abbot, pickBomb);
+ ADD_CALLBACK_FUNCTION(Abbot, chapter5);
+ ADD_CALLBACK_FUNCTION(Abbot, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(Abbot, function52);
+ ADD_CALLBACK_FUNCTION(Abbot, function53);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Abbot, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(2, Abbot, draw)
+ Entity::draw(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(3, Abbot, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(4, Abbot, enterExitCompartment2, ObjectIndex)
+ Entity::enterExitCompartment(savepoint, kPosition_6470, kPosition_6130, kCarRedSleeping, kObjectCompartmentC, true, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(5, Abbot, callbackActionOnDirection)
+ Entity::callbackActionOnDirection(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SSI(6, Abbot, draw2, EntityIndex)
+ Entity::draw2(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(7, Abbot, updateFromTime, uint32)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(8, Abbot, updateFromTicks, uint32)
+ Entity::updateFromTicks(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(9, Abbot, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(10, Abbot, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(11, Abbot, updateEntity, CarIndex, EntityPosition)
+ if (savepoint.action == kActionExcuseMeCath) {
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 18) || getEntities()->isPlayerPosition(kCarRedSleeping, 18)) {
+ getSound()->excuseMe(kEntityAbbot);
+ } else {
+ if (getEvent(kEventAbbotIntroduction))
+ getSound()->playSound(kEntityPlayer, "CAT1013");
+ else
+ getSound()->excuseMeCath();
+ }
+ return;
+ }
+
+ Entity::updateEntity(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SIIS(12, Abbot, callSavepoint, EntityIndex, ActionIndex)
+ Entity::callSavepoint(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SII(13, Abbot, updatePosition, CarIndex, Position)
+ Entity::updatePosition(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Abbot, callbackActionRestaurantOrSalon)
+ Entity::callbackActionRestaurantOrSalon(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Abbot, chapter1)
+ if (savepoint.action == kActionDefault)
+ getSavePoints()->addData(kEntityAbbot, kAction203073664, 0);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Abbot, chapter2)
+ if (savepoint.action == kActionDefault)
+ getEntities()->clearSequences(kEntityAbbot);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Abbot, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAbbot);
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+ getData()->clothes = kClothesDefault;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Abbot, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_draw("804DD");
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityAbbot, kEntityCooks, kAction236976550);
+ getEntities()->drawSequenceRight(kEntityAbbot, "804DS");
+
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityAbbot);
+
+ setCallback(3);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_updateEntity(kCarRedSleeping, kPosition_6470);
+ break;
+
+ case 4:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(5);
+ setup_enterExitCompartment("617AC", kObjectCompartmentC);
+ break;
+
+ case 5:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getData()->entityPosition = kPosition_6470;
+ getData()->location = kLocationInsideCompartment;
+
+ setup_function19();
+ break;
+ }
+ break;
+
+ case kAction192054567:
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Abbot, function19)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime1953000) {
+ if (!params->param1) {
+ params->param1 = 1;
+ setCallback(3);
+ setup_playSound("MrB3010");
+ }
+ }
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityAbbot, "508A");
+ getSavePoints()->push(kEntityAbbot, kEntityBoutarel, kAction122358304);
+
+ setCallback(1);
+ setup_playSound("Abb3010");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateFromTime(900);
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityAbbot, "508B");
+ break;
+
+ case 3:
+ getSavePoints()->push(kEntityAbbot, kEntityBoutarel, kAction122288808);
+ setup_function20();
+ break;
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Abbot, function20)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime1966500 && getEntities()->isInRestaurant(kEntityBoutarel))
+ setup_function21();
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityAbbot, "509A");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Abbot, function21)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_draw("509B");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject50, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ setCallback(2);
+ setup_enterExitCompartment("617Mc", kObjectCompartmentC);
+ break;
+
+ case 2:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(3);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 4:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(5);
+ setup_draw("804US");
+ break;
+
+ case 5:
+ getEntities()->drawSequenceRight(kEntityAbbot, "029J");
+ if (getEntities()->isInSalon(kEntityPlayer))
+ getEntities()->updateFrame(kEntityAbbot);
+
+ setCallback(6);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 6:
+ getEntities()->drawSequenceLeft(kEntityAbbot, "029H");
+ getSavePoints()->push(kEntityAbbot, kEntityPascale, kAction207769280);
+ break;
+
+ case 7:
+ setup_function22();
+ break;
+ }
+ break;
+
+ case kAction122288808:
+ getSavePoints()->push(kEntityAbbot, kEntityTables4, kAction136455232);
+ getData()->location = kLocationInsideCompartment;
+
+ setCallback(7);
+ setup_draw("029B");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Abbot, function22)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_SAVEPOINT(kTime1971000, params->param1, kEntityAbbot, kEntityServers0, kAction218586752);
+
+ if (getState()->time > kTime1989000 && getEntities()->isSomebodyInsideRestaurantOrSalon()) {
+ getData()->inventoryItem = kItemNone;
+ setup_function23();
+ }
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAbbotIntroduction);
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityAbbot, "029E");
+ if (!getEvent(kEventAbbotIntroduction))
+ getData()->inventoryItem = (InventoryItem)kCursorProcess;
+ break;
+
+ case kActionCallback:
+ if (getCallback() != 1)
+ break;
+
+ getAction()->playAnimation(kEventAbbotIntroduction);
+ getSound()->playSound(kEntityPlayer, "LIB036");
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 61);
+ break;
+
+ case kAction122288808:
+ getEntities()->drawSequenceLeft(kEntityAbbot, "029E");
+ break;
+
+ case kAction122358304:
+ getEntities()->drawSequenceLeft(kEntityAbbot, "BLANK");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Abbot, function23)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->location = kLocationOutsideCompartment;
+ getEntities()->updatePositionEnter(kEntityAbbot, kCarRestaurant, 67);
+
+ setCallback(1);
+ setup_callSavepoint("029F", kEntityTables4, kActionDrawTablesWithChairs, "029G");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->updatePositionExit(kEntityAbbot, kCarRestaurant, 67);
+ getSavePoints()->push(kEntityAbbot, kEntityServers0, kAction270068760);
+ getSavePoints()->push(kEntityAbbot, kEntityAnna, kAction238936000);
+ getEntities()->drawSequenceRight(kEntityAbbot, "804DS");
+
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityAbbot);
+
+ setCallback(2);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_updateEntity(kCarRedSleeping, kPosition_6470);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_enterExitCompartment2("617Cc", kObjectCompartmentC);
+ break;
+
+ case 4:
+ getData()->location = kLocationInsideCompartment;
+
+ setup_function24();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Abbot, function24)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param1, getState()->time, 900);
+
+ setup_function25();
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ getObjects()->update(kObjectCompartmentC, kEntityAbbot, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject50, kEntityAbbot, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ if (savepoint.action == kActionKnock) {
+ setCallback(1);
+ setup_playSound("LIB012");
+ } else {
+ setCallback(2);
+ setup_playSound("LIB013");
+ }
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAbbot);
+ getObjects()->update(kObjectCompartmentC, kEntityAbbot, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject50, kEntityAbbot, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ setCallback(3);
+ setup_playSound("Abb3001");
+ break;
+
+ case 3:
+ getObjects()->update(kObjectCompartmentC, kEntityAbbot, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject50, kEntityAbbot, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, Abbot, function25)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_enterExitCompartment("617Dc", kObjectCompartmentC);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject50, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(4);
+ setup_updatePosition("115A", kCarRestaurant, 56);
+ break;
+
+ case 4:
+ getData()->location = kLocationInsideCompartment;
+ getScenes()->loadSceneFromItemPosition(kItem3);
+
+ setup_function26();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(26, Abbot, function26)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param2, getState()->time, 4500);
+
+ if (getEntities()->isSomebodyInsideRestaurantOrSalon())
+ setup_function27();
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityAbbot, kEntityKronos, kAction157159392);
+ getEntities()->drawSequenceLeft(kEntityAbbot, "115B");
+ break;
+
+ case kAction101169422:
+ params->param1 = 1;
+ break;
+
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(27, Abbot, function27)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_updatePosition("115C", kCarRestaurant, 56);
+ break;
+
+ case 2:
+ getInventory()->setLocationAndProcess(kItem3, kObjectLocation1);
+
+ setCallback(3);
+ setup_updateEntity(kCarRedSleeping, kPosition_6470);
+ break;
+
+ case 3:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(4);
+ setup_enterExitCompartment("617Ac", kObjectCompartmentC);
+ break;
+
+ case 4:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getData()->entityPosition = kPosition_6470;
+ getData()->location = kLocationInsideCompartment;
+
+ setup_function28();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(28, Abbot, function28)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CALLBACK(kTime2052000, params->param1, 1, setup_function29);
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityAbbot, kEntityBoutarel, kAction122358304);
+ getEntities()->drawSequenceLeft(kEntityAbbot, "508A");
+
+ setCallback(1);
+ setup_playSound("abb3013");
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ getEntities()->drawSequenceLeft(kEntityAbbot, "508B");
+ break;
+
+ case kAction222609266:
+ setup_function30();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(29, Abbot, function29)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityAbbot, kEntityBoutarel, kAction122288808);
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(1);
+ setup_enterExitCompartment("617Bc", kObjectCompartmentC);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_9460);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_updateFromTicks(450);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_updateEntity(kCarGreenSleeping, kPosition_540);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_updateFromTime(225);
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_updateEntity(kCarRedSleeping, kPosition_6470);
+ break;
+
+ case 6:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(7);
+ setup_enterExitCompartment("617Ac", kObjectCompartmentC);
+ break;
+
+ case 7:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getSavePoints()->push(kEntityAbbot, kEntityBoutarel, kAction122358304);
+ getEntities()->drawSequenceLeft(kEntityAbbot, "508B");
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(30, Abbot, function30)
+switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_playSound("Abb3030");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityAbbot, kEntityBoutarel, kAction122288808);
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(2);
+ setup_enterExitCompartment("617Bc", kObjectCompartmentC);
+ break;
+
+ case 2:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(3);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 4:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(5);
+ setup_updatePosition("115A", kCarRestaurant, 56);
+ break;
+
+ case 5:
+ getScenes()->loadSceneFromItemPosition(kItem3);
+ getData()->location = kLocationInsideCompartment;
+
+ setup_function31();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(31, Abbot, function31)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param4 != kTimeInvalid && params->param2 < getState()->time) {
+ if (getState()->time < getState()->time) {
+ params->param4 = kTimeInvalid;
+
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+ } else {
+ if (!getEntities()->isInSalon(kEntityPlayer) || !params->param4)
+ params->param4 = getState()->time + 450;
+
+ if (params->param4 < getState()->time) {
+ params->param4 = kTimeInvalid;
+
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+ }
+ }
+ }
+
+ if (!params->param1)
+ break;
+
+ UPDATE_PARAM(params->param5, getState()->time, 450);
+
+ setCallback(6);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case kActionDefault:
+ params->param2 = getState()->time + 4500;
+ params->param3 = getState()->time + 18000;
+
+ getEntities()->drawSequenceLeft(kEntityAbbot, "115B");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_updatePosition("115E", kCarRestaurant, 56);
+ break;
+
+ case 2:
+ getInventory()->setLocationAndProcess(kItem3, kObjectLocation1);
+ getSavePoints()->push(kEntityAbbot, kEntityAlexei, kAction122358304);
+ getSound()->playSound(kEntityAbbot, "Abb3020");
+
+ setCallback(3);
+ setup_updatePosition("125A", kCarRestaurant, 52);
+ break;
+
+ case 3:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->drawSequenceLeft(kEntityAbbot, "125B");
+
+ setCallback(4);
+ setup_playSound("Abb3021");
+ break;
+
+ case 4:
+ getSound()->playSound(kEntityAbbot, "Abb3023");
+ getEntities()->updatePositionEnter(kEntityAbbot, kCarRestaurant, 52);
+
+ setCallback(5);
+ setup_draw2("125C1", "125C2", kEntityAlexei);
+ break;
+
+ case 5:
+ getEntities()->updatePositionExit(kEntityAbbot, kCarRestaurant, 52);
+ getEntities()->drawSequenceLeft(kEntityAbbot, "125D");
+ getSavePoints()->push(kEntityAbbot, kEntityAlexei, kAction122288808);
+ params->param1 = 1;
+
+ UPDATE_PARAM(params->param5, getState()->time, 450);
+
+ setCallback(6);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 6:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(7);
+ setup_updatePosition("125E", kCarRestaurant, 52);
+ break;
+
+ case 7:
+ setup_function32();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(32, Abbot, function32)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_6470);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(1);
+ setup_enterExitCompartment("617Ac", kObjectCompartmentC);
+ break;
+
+ case 2:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getData()->entityPosition = kPosition_6470;
+ getData()->location = kLocationInsideCompartment;
+ getSavePoints()->push(kEntityAbbot, kEntityBoutarel, kAction122358304);
+
+ setup_function33();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(33, Abbot, function33)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1 != kTimeInvalid && getState()->time > kTime2115000) {
+ if (getState()->time <= kTime2124000) {
+ if (!getEntities()->isDistanceBetweenEntities(kEntityAbbot, kEntityPlayer, 2000) || !params->param1)
+ params->param1 = getState()->time;
+
+ if (params->param1 >= getState()->time)
+ break;
+ }
+
+ params->param1 = kTimeInvalid;
+
+ setCallback(1);
+ setup_playSound("Abb3014");
+ }
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityAbbot, "508A");
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ getEntities()->drawSequenceLeft(kEntityAbbot, "508B");
+ break;
+
+ case kAction123712592:
+ setup_function34();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(34, Abbot, function34)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_playSound("Abb3031");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityAbbot, kEntityBoutarel, kAction122288808);
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(2);
+ setup_enterExitCompartment("617Bc", kObjectCompartmentC);
+ break;
+
+ case 2:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(3);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 4:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(5);
+ setup_updatePosition("115A", kCarRestaurant, 56);
+ break;
+
+ case 5:
+ getScenes()->loadSceneFromItemPosition(kItem3);
+
+ getData()->location = kLocationInsideCompartment;
+ setup_function35();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(35, Abbot, function35)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param2 == kTimeInvalid)
+ break;
+
+ if (params->param1 >= getState()->time) {
+ if (!getEntities()->isInSalon(kEntityPlayer) || !params->param2)
+ params->param2 = getState()->time + 450;
+
+ if (params->param2 >= getState()->time)
+ break;
+ }
+
+ params->param2 = kTimeInvalid;
+
+ getSavePoints()->push(kEntityAbbot, kEntityAugust, kAction136196244);
+
+ setCallback(1);
+ setup_updateFromTime(0);
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityAbbot, "115B");
+ params->param1 = getState()->time + 9000;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 2:
+ getData()->location = kLocationOutsideCompartment;
+ getSound()->playSound(kEntityAbbot, "Abb3040", SoundManager::kFlagInvalid, 45);
+ getEntities()->updatePositionEnter(kEntityAbbot, kCarRestaurant, 57);
+
+ setCallback(3);
+ setup_callSavepoint("121A", kEntityAugust, kAction122358304, "BOGUS");
+ break;
+
+ case 3:
+ getEntities()->updatePositionExit(kEntityAbbot, kCarRestaurant, 57);
+ getInventory()->setLocationAndProcess(kItem3, kObjectLocation1);
+ getData()->location = kLocationInsideCompartment;
+
+ setup_function36();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(36, Abbot, function36)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ switch (params->param2) {
+ default:
+ break;
+
+ case 1:
+ if (params->param3 == kTimeInvalid)
+ break;
+
+ if (params->param1 >= getState()->time) {
+
+ if (!getEntities()->isInSalon(kEntityPlayer) || !params->param3)
+ params->param3 = getState()->time + 675;
+
+ if (params->param3 >= getState()->time)
+ break;
+ }
+
+ params->param3 = kTimeInvalid;
+
+ getSound()->playSound(kEntityAbbot, "Abb3041");
+ break;
+
+ case 2:
+ UPDATE_PARAM(params->param4, getState()->time, 900);
+
+ getSound()->playSound(kEntityAbbot, "Abb3042");
+ break;
+
+ case 3:
+ getSound()->playSound(kEntityAbbot, "Abb3043");
+ getEntities()->updatePositionEnter(kEntityAbbot, kCarRestaurant, 57);
+
+ setCallback(1);
+ setup_callSavepoint("121D", kEntityAugust, kAction122288808, "BOGUS");
+ break;
+ }
+ break;
+
+ case kActionEndSound:
+ ++params->param2;
+ break;
+
+ case kActionDefault:
+ params->param1 = getState()->time + 4500;
+ getEntities()->drawSequenceLeft(kEntityAbbot, "121B");
+ break;
+
+ case kActionDrawScene:
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 57))
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 50);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getEntities()->updatePositionExit(kEntityAbbot, kCarRestaurant, 57);
+ setup_function37();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(37, Abbot, function37)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_6470);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(2);
+ setup_enterExitCompartment("617Ac", kObjectCompartmentC);
+ break;
+
+ case 2:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getData()->entityPosition = kPosition_6470;
+ getData()->location = kLocationInsideCompartment;
+ getSavePoints()->push(kEntityAbbot, kEntityBoutarel, kAction122358304);
+
+ setup_function38();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(38, Abbot, function38)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityAbbot, "508A");
+
+ setCallback(1);
+ setup_playSound("Abb3014A");
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ getEntities()->drawSequenceLeft(kEntityAbbot, "508B");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(39, Abbot, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAbbot);
+
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+
+ ENTITY_PARAM(0, 1) = 0;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(40, Abbot, function40, CarIndex, EntityPosition)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->updateEntity(kEntityAbbot, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ CALLBACK_ACTION();
+ } else if (!getEvent(kEventAbbotInvitationDrink)
+ && getEntities()->isDistanceBetweenEntities(kEntityAbbot, kEntityPlayer, 1000)
+ && !getEntities()->isInsideCompartments(kEntityPlayer)
+ && !getEntities()->checkFields10(kEntityPlayer)) {
+
+ if (getData()->car == kCarGreenSleeping || getData()->car == kCarRedSleeping) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAbbotInvitationDrink);
+ }
+ }
+ break;
+
+ case kActionDefault:
+ if (getEntities()->updateEntity(kEntityAbbot, (CarIndex)params->param1, (EntityPosition)params->param2))
+ CALLBACK_ACTION();
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventAbbotInvitationDrink);
+ getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + (750 * (getData()->direction == kDirectionUp ? -1 : 1))), getData()->direction == kDirectionUp);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(41, Abbot, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_SAVEPOINT(kTime2358000, params->param1, kEntityAbbot, kEntityServers0, kAction218128129);
+
+ if (getState()->time > kTime2389500 && getEntities()->isSomebodyInsideRestaurantOrSalon())
+ setup_function42();
+
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityAbbot, kEntityTables4, kAction136455232);
+ getEntities()->drawSequenceLeft(kEntityAbbot, "029E");
+ getData()->location = kLocationInsideCompartment;
+ break;
+
+ case kAction122288808:
+ getEntities()->drawSequenceLeft(kEntityAbbot, "029E");
+ break;
+
+ case kAction122358304:
+ getEntities()->drawSequenceLeft(kEntityAbbot, "BLANK");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(42, Abbot, function42)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->location = kLocationOutsideCompartment;
+ getEntities()->updatePositionExit(kEntityAbbot, kCarRestaurant, 67);
+
+ setCallback(1);
+ setup_callSavepoint("029F", kEntityTables4, kActionDrawTablesWithChairs, "029G");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->updatePositionExit(kEntityAbbot, kCarRestaurant, 67);
+ getSavePoints()->push(kEntityAbbot, kEntityServers0, kAction270068760);
+ getEntities()->drawSequenceRight(kEntityAbbot, "804DS");
+
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityAbbot);
+
+ setCallback(2);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_updateEntity(kCarRedSleeping, kPosition_6470);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_enterExitCompartment2("617Cc", kObjectCompartmentC);
+ break;
+
+ case 4:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityAbbot);
+
+ setup_function43();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(43, Abbot, function43)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1 && params->param4 != kTimeInvalid && params->param2 < getState()->time) {
+ if (getState()->time < kTime2452500) {
+ params->param4 = kTimeInvalid;
+
+ setCallback(1);
+ setup_playSound("Abb4002");
+ break;
+ } else {
+ if (!getEntities()->isDistanceBetweenEntities(kEntityAbbot, kEntityPlayer, 1000) || getSound()->isBuffered(kEntityBoutarel) || !params->param4)
+ params->param4 = getState()->time + 450;
+
+ if (params->param4 < getState()->time) {
+ params->param4 = kTimeInvalid;
+
+ setCallback(1);
+ setup_playSound("Abb4002");
+ break;
+ }
+ }
+ }
+
+label_callback_1:
+ TIME_CHECK(kTime2466000, params->param5, setup_function44);
+
+ if (params->param3) {
+ UPDATE_PARAM(params->param6, getState()->timeTicks, 75);
+
+ params->param2 = 1;
+ params->param3 = 0;
+
+ getObjects()->update(kObjectCompartmentC, kEntityAbbot, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject50, kEntityAbbot, kObjectLocation1, kCursorNormal, kCursorNormal);
+ }
+
+ params->param6 = 0;
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ getObjects()->update(kObjectCompartmentC, kEntityAbbot, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject50, kEntityAbbot, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ if (params->param3) {
+ setCallback(savepoint.param.intValue == 50 ? 5 : 6);
+ setup_playSound(savepoint.param.intValue == 50 ? getSound()->justAMinuteCath() : getSound()->wrongDoorCath());
+ } else {
+ setCallback(savepoint.action == kActionKnock ? 2 : 3);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ }
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentC, kEntityAbbot, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject50, kEntityAbbot, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionDrawScene:
+ if (params->param2 || params->param3) {
+ getObjects()->update(kObjectCompartmentC, kEntityAbbot, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject50, kEntityAbbot, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ params->param2 = 0;
+ params->param3 = 0;
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_callback_1;
+
+ case 2:
+ case 3:
+ setCallback(4);
+ setup_playSound("Abb3001");
+ break;
+
+ case 4:
+ getObjects()->update(kObjectCompartmentC, kEntityAbbot, kObjectLocation1, kCursorTalk, kCursorNormal);
+ getObjects()->update(kObject50, kEntityAbbot, kObjectLocation1, kCursorTalk, kCursorNormal);
+
+ params->param3 = 1;
+ break;
+
+ case 5:
+ case 6:
+ params->param2 = 1;
+ params->param3 = 0;
+ break;
+ }
+ break;
+
+ case kAction101687594:
+ params->param1 = 1;
+ break;
+
+ case kAction159003408:
+ params->param1 = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(44, Abbot, function44)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_6470;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getEntities()->clearSequences(kEntityAbbot);
+
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject50, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kAction104060776:
+ setup_function45();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(45, Abbot, function45)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_6471;
+ getData()->car = kCarRedSleeping;
+ getData()->location = kLocationOutsideCompartment;
+
+ RESET_ENTITY_STATE(kEntityVerges, Verges, setup_function38);
+
+ getEntities()->drawSequenceLeft(kEntityAbbot, "617Ec");
+ getEntities()->enterCompartment(kEntityAbbot, kObjectCompartmentC, true);
+
+ setCallback(1);
+ setup_playSound("Abb4010");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("617Kc", kObjectCompartmentC);
+ break;
+
+ case 2:
+ getEntities()->exitCompartment(kEntityAbbot, kObjectCompartmentC, true);
+ getSavePoints()->push(kEntityAbbot, kEntityVerges, kAction125233040);
+
+ setup_function46();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(46, Abbot, function46)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_6471;
+
+ setCallback(1);
+ setup_function40(kCarRestaurant, kPosition_850);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_drinkAfterDefuse();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(47, Abbot, drinkAfterDefuse)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kAction1:
+ setCallback(3);
+ setup_savegame(kSavegameTypeEvent, kEventAbbotDrinkGiveDetonator);
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_draw("126A");
+ break;
+
+ case 2:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->drawSequenceLeft(kEntityAbbot, "126B");
+ getData()->inventoryItem = kItemBomb;
+ break;
+
+ case 3:
+ getAction()->playAnimation(kEventAbbotDrinkGiveDetonator);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneNone, true);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(48, Abbot, function48)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (ENTITY_PARAM(0, 1))
+ getData()->inventoryItem = kItemInvalid;
+
+ UPDATE_PARAM_PROC(params->param1, getState()->time, 1800)
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(4);
+ setup_updatePosition("126C", kCarRedSleeping, 52);
+ UPDATE_PARAM_PROC_END
+
+ TIME_CHECK_CALLBACK_INVENTORY(kTime2533500, params->param2, 5, setup_callbackActionRestaurantOrSalon);
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(9);
+ setup_savegame(kSavegameTypeEvent, kEventAbbotDrinkDefuse);
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_850;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->inventoryItem = kItemNone;
+
+ getSavePoints()->push(kEntityAbbot, kEntityVerges, kAction125233040);
+
+ setCallback(1);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 2:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(3);
+ setup_updatePosition("126A", kCarRestaurant, 52);
+ break;
+
+ case 3:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->drawSequenceLeft(kEntityAbbot, "126B");
+ break;
+
+ case 4:
+ if (!getEvent(kEventAbbotDrinkDefuse) && ENTITY_PARAM(0, 1))
+ getData()->inventoryItem = kItemInvalid;
+
+ getEntities()->drawSequenceLeft(kEntityAbbot, "126B");
+ params->param1 = 0;
+
+ TIME_CHECK_CALLBACK_INVENTORY(kTime2533500, params->param2, 5, setup_callbackActionRestaurantOrSalon);
+ break;
+
+ case 5:
+ getData()->location = kLocationInsideCompartment;
+
+ setCallback(6);
+ setup_updatePosition("126D", kCarRestaurant, 52);
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_updateEntity(kCarRedSleeping, kPosition_6470);
+ break;
+
+ case 7:
+ setCallback(8);
+ setup_enterExitCompartment2("617Cc", kObjectCompartmentC);
+ break;
+
+ case 8:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityAbbot);
+
+ setup_function44();
+ break;
+
+ case 9:
+ getAction()->playAnimation(kEventAbbotDrinkDefuse);
+ getEntities()->drawSequenceLeft(kEntityAbbot, "126B");
+ getSavePoints()->push(kEntityAbbot, kEntityAnna, kAction100969180);
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 58);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(49, Abbot, pickBomb)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param1, getState()->timeTicks, 150);
+
+ getSavePoints()->push(kEntityAbbot, kEntityAbbot, kAction157489665);
+ break;
+
+ case kActionKnock:
+ if (!getSound()->isBuffered("LIB012", true))
+ getSound()->playSound(kEntityPlayer, "LIB012");
+ break;
+
+ case kActionOpenDoor:
+ case kAction157489665:
+ getSavePoints()->push(kEntityAbbot, kEntityTatiana, kAction238790488);
+ getObjects()->update(kObjectCompartment2, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectHandleInsideBathroom, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarGreenSleeping;
+ getData()->entityPosition = kPosition_7500;
+ getData()->location = kLocationInsideCompartment;
+
+ getSavePoints()->call(kEntityAbbot, kEntityTables4, kActionDrawTablesWithChairs, "029G");
+ getSavePoints()->push(kEntityAbbot, kEntityServers0, kAction270068760);
+ getSavePoints()->push(kEntityAbbot, kEntityBoutarel, kAction125039808);
+ getObjects()->update(kObjectCompartment2, kEntityAbbot, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectHandleInsideBathroom, kEntityAbbot, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(getObjects()->get(kObjectCompartment2).location2 < kObjectLocation2 ? kEventAbbotWrongCompartmentBed : kEventAbbotWrongCompartment);
+ getEntities()->updateEntity(kEntityAbbot, kCarRedSleeping, kPosition_6470);
+ getSound()->playSound(kEntityPlayer, "LIB015");
+ getScenes()->loadSceneFromObject(kObjectCompartment2, true);
+
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_6470);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_enterExitCompartment2("617Cc", kObjectCompartmentC);
+ break;
+
+ case 3:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityAbbot);
+ getObjects()->update(kObjectCompartmentC, kEntityAbbot, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ setup_function43();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(50, Abbot, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAbbot);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+ getData()->clothes = kClothesDefault;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(51, Abbot, chapter5Handler)
+ if (savepoint.action == kActionProceedChapter5)
+ setup_function52();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(52, Abbot, function52)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAbbot);
+
+ getData()->entityPosition = kPositionNone;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarNone;
+ break;
+
+ case kAction135600432:
+ setup_function53();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(53, Abbot, function53)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getInventory()->setLocationAndProcess(kItem25, kObjectLocation1);
+ getSavePoints()->push(kEntityAbbot, kEntityAnna, kAction158480160);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventLocomotiveAbbotGetSomeRest);
+ getScenes()->processScene();
+ break;
+
+ case 2:
+ getAction()->playAnimation(kEventLocomotiveAbbotShoveling);
+ getScenes()->processScene();
+ break;
+ }
+ break;
+
+ case kAction168646401:
+ if (!getEvent(kEventLocomotiveAbbotGetSomeRest)) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventLocomotiveAbbotGetSomeRest);
+ break;
+ }
+
+ if (!getEvent(kEventLocomotiveAbbotShoveling)) {
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventLocomotiveAbbotShoveling);
+ break;
+ }
+
+ getAction()->playAnimation(kEventLocomotiveAbbotShoveling);
+ getScenes()->processScene();
+ break;
+ }
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/abbot.h b/engines/lastexpress/entities/abbot.h
new file mode 100644
index 0000000000..4637fbd817
--- /dev/null
+++ b/engines/lastexpress/entities/abbot.h
@@ -0,0 +1,225 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_ABBOT_H
+#define LASTEXPRESS_ABBOT_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Abbot : public Entity {
+public:
+ Abbot(LastExpressEngine *engine);
+ ~Abbot() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Draws the entity
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(draw, const char* sequence)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Handles entering/exiting a compartment and updates position/play animation
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment2, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Process callback action when the entity direction is not kDirectionRight
+ */
+ DECLARE_FUNCTION(callbackActionOnDirection)
+
+ /**
+ * Draws the entity along with another one
+ *
+ * @param sequence1 The sequence to draw
+ * @param sequence2 The sequence to draw for the second entity
+ * @param entity The EntityIndex of the second entity
+ */
+ DECLARE_FUNCTION_3(draw2, const char* sequence1, const char* sequence2, EntityIndex entity)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param time The time to add
+ */
+ DECLARE_FUNCTION_1(updateFromTime, uint32 time)
+
+ /**
+ * Updates parameter 2 using ticks value
+ *
+ * @param ticks The number of ticks to add
+ */
+ DECLARE_FUNCTION_1(updateFromTicks, uint32 ticks)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ /**
+ * Call a savepoint (or draw sequence in default case)
+ *
+ * @param sequence1 The sequence to draw in the default case
+ * @param entity The entity
+ * @param action The action
+ * @param sequence2 The sequence name for the savepoint
+ */
+ DECLARE_FUNCTION_4(callSavepoint, const char* sequence1, EntityIndex entity, ActionIndex action, const char* sequence2)
+
+ /**
+ * Updates the position
+ *
+ * @param sequence1 The sequence to draw
+ * @param car The car
+ * @param position The position
+ */
+ DECLARE_FUNCTION_3(updatePosition, const char* sequence1, CarIndex car, Position position)
+
+ /**
+ * Process callback action when somebody is standing in the restaurant or salon.
+ */
+ DECLARE_FUNCTION(callbackActionRestaurantOrSalon)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+ DECLARE_FUNCTION(function19)
+ DECLARE_FUNCTION(function20)
+ DECLARE_FUNCTION(function21)
+ DECLARE_FUNCTION(function22)
+ DECLARE_FUNCTION(function23)
+ DECLARE_FUNCTION(function24)
+ DECLARE_FUNCTION(function25)
+ DECLARE_FUNCTION(function26)
+ DECLARE_FUNCTION(function27)
+ DECLARE_FUNCTION(function28)
+ DECLARE_FUNCTION(function29)
+ DECLARE_FUNCTION(function30)
+ DECLARE_FUNCTION(function31)
+ DECLARE_FUNCTION(function32)
+ DECLARE_FUNCTION(function33)
+ DECLARE_FUNCTION(function34)
+ DECLARE_FUNCTION(function35)
+ DECLARE_FUNCTION(function36)
+ DECLARE_FUNCTION(function37)
+ DECLARE_FUNCTION(function38)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * ???
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(function40, CarIndex car, EntityPosition position)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+ DECLARE_FUNCTION(function42)
+ DECLARE_FUNCTION(function43)
+ DECLARE_FUNCTION(function44)
+ DECLARE_FUNCTION(function45)
+ DECLARE_FUNCTION(function46)
+ DECLARE_FUNCTION(drinkAfterDefuse)
+ DECLARE_FUNCTION(function48)
+ DECLARE_FUNCTION(pickBomb)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+ DECLARE_FUNCTION(function52)
+ DECLARE_FUNCTION(function53)
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_ABBOT_H
diff --git a/engines/lastexpress/entities/alexei.cpp b/engines/lastexpress/entities/alexei.cpp
new file mode 100644
index 0000000000..30e1c4384b
--- /dev/null
+++ b/engines/lastexpress/entities/alexei.cpp
@@ -0,0 +1,1897 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/alexei.h"
+
+#include "lastexpress/game/action.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"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+
+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(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(Alexei, callbackActionRestaurantOrSalon);
+ ADD_CALLBACK_FUNCTION(Alexei, function13);
+ ADD_CALLBACK_FUNCTION(Alexei, function14);
+ ADD_CALLBACK_FUNCTION(Alexei, function15);
+ ADD_CALLBACK_FUNCTION(Alexei, function16);
+ ADD_CALLBACK_FUNCTION(Alexei, chapter1);
+ ADD_CALLBACK_FUNCTION(Alexei, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Alexei, function19);
+ ADD_CALLBACK_FUNCTION(Alexei, function20);
+ ADD_CALLBACK_FUNCTION(Alexei, function21);
+ ADD_CALLBACK_FUNCTION(Alexei, function22);
+ ADD_CALLBACK_FUNCTION(Alexei, function23);
+ ADD_CALLBACK_FUNCTION(Alexei, function24);
+ ADD_CALLBACK_FUNCTION(Alexei, function25);
+ ADD_CALLBACK_FUNCTION(Alexei, function26);
+ ADD_CALLBACK_FUNCTION(Alexei, function27);
+ ADD_CALLBACK_FUNCTION(Alexei, chapter2);
+ ADD_CALLBACK_FUNCTION(Alexei, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Alexei, function30);
+ ADD_CALLBACK_FUNCTION(Alexei, function31);
+ ADD_CALLBACK_FUNCTION(Alexei, chapter3);
+ ADD_CALLBACK_FUNCTION(Alexei, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Alexei, function34);
+ ADD_CALLBACK_FUNCTION(Alexei, function35);
+ ADD_CALLBACK_FUNCTION(Alexei, function36);
+ ADD_CALLBACK_FUNCTION(Alexei, chapter4);
+ ADD_CALLBACK_FUNCTION(Alexei, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Alexei, function39);
+ ADD_CALLBACK_FUNCTION(Alexei, function40);
+ ADD_CALLBACK_FUNCTION(Alexei, function41);
+ ADD_CALLBACK_FUNCTION(Alexei, function42);
+ ADD_CALLBACK_FUNCTION(Alexei, function43);
+ ADD_CALLBACK_FUNCTION(Alexei, function44);
+ ADD_CALLBACK_FUNCTION(Alexei, function45);
+ ADD_CALLBACK_FUNCTION(Alexei, function46);
+ ADD_CALLBACK_FUNCTION(Alexei, function47);
+ ADD_CALLBACK_FUNCTION(Alexei, chapter5);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Alexei, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(2, Alexei, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(3, Alexei, updateFromTicks, uint32)
+ Entity::updateFromTicks(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(4, Alexei, draw)
+ Entity::draw(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SII(5, Alexei, updatePosition, CarIndex, Position)
+ Entity::updatePosition(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(6, Alexei, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(7, Alexei, callbackActionOnDirection)
+ Entity::callbackActionOnDirection(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SIIS(8, Alexei, callSavepoint, EntityIndex, ActionIndex)
+ Entity::callSavepoint(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(9, Alexei, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(10, Alexei, updateEntity, CarIndex, EntityPosition)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExcuseMeCath:
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 18) || getEntities()->isPlayerPosition(kCarRedSleeping, 18)) {
+ getSound()->excuseMe(kEntityAlexei);
+ } else {
+ if (getEvent(kEventAlexeiSalonVassili) || (getEvent(kEventTatianaAskMatchSpeakRussian) && getInventory()->hasItem(kItemPassengerList))) {
+ getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1012" : "CAT1012A");
+ } else {
+ getSound()->excuseMeCath();
+ }
+ }
+ // Stop execution here
+ return;
+
+ case kActionDefault:
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+
+ Entity::updateEntity(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(11, Alexei, draw2)
+ Entity::draw2(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Alexei, callbackActionRestaurantOrSalon)
+ Entity::callbackActionRestaurantOrSalon(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Alexei, function13)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_7500);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityAlexei, kEntityMertens, kAction302614416);
+ getEntities()->drawSequenceLeft(kEntityAlexei, "602DB");
+ getEntities()->enterCompartment(kEntityAlexei, kObjectCompartment2, true);
+
+ getData()->location = kLocationInsideCompartment;
+
+ if (getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, kPosition_7500)) {
+ getAction()->playAnimation(isNight() ? kEventCathTurningNight : kEventCathTurningDay);
+ getSound()->playSound(kEntityPlayer, "BUMP");
+ getScenes()->loadSceneFromObject(kObjectCompartment2, true);
+ }
+ break;
+
+ case 2:
+ getEntities()->exitCompartment(kEntityAlexei, kObjectCompartment2, true);
+ getData()->location = kLocationInsideCompartment;
+ getData()->entityPosition = kPosition_7500;
+ getEntities()->clearSequences(kEntityAlexei);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction135664192:
+ setCallback(2);
+ setup_enterExitCompartment("602Eb", kObjectCompartment2);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Alexei, function14)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_enterExitCompartment("602Fb", kObjectCompartment2);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityAlexei, kEntityMertens, kAction302614416);
+ getEntities()->drawSequenceLeft(kEntityAlexei, "602DB");
+ getEntities()->enterCompartment(kEntityAlexei, kObjectCompartment2, true);
+ }
+ break;
+
+ case kAction135664192:
+ getObjects()->update(kObjectCompartment2, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getEntities()->exitCompartment(kEntityAlexei, kObjectCompartment2, true);
+
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Alexei, function15)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM_CHECK(params->param2, getState()->time, params->param1)
+ if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(3);
+ setup_updatePosition("103D", kCarRestaurant, 52);
+ }
+ }
+ break;
+
+ case kActionDefault:
+ params->param1 = 5 * (3 * rnd(60) + 90);
+
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_updatePosition("103C", kCarRestaurant, 52);
+ break;
+
+ case 2:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->drawSequenceLeft(kEntityAlexei, "103E");
+ break;
+
+ case 3:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->drawSequenceLeft(kEntityAlexei, "103B");
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_IS(16, Alexei, function16, TimeValue)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param7 && params->param1 < getState()->time && !params->param8) {
+ params->param8 = 1;
+
+ getObjects()->update(kObjectCompartment2, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectHandleInsideBathroom, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (params->param5) {
+ UPDATE_PARAM(CURRENT_PARAMS(1, 1), getState()->timeTicks, 75);
+
+ params->param5 = 0;
+ params->param6 = 1;
+
+ getObjects()->update(kObjectCompartment2, kEntityAlexei, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectHandleInsideBathroom, kEntityAlexei, kObjectLocation1, kCursorNormal, kCursorNormal);
+ }
+
+ CURRENT_PARAMS(1, 1) = 0;
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ getObjects()->update(kObjectCompartment2, kEntityAlexei, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectHandleInsideBathroom, kEntityAlexei, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ if (params->param5) {
+ if (savepoint.param.intValue == 18) {
+ setCallback(4);
+ setup_playSound(getSound()->justAMinuteCath());
+ break;
+ }
+
+ if (getInventory()->hasItem(kItemPassengerList)) {
+ setCallback(5);
+ setup_playSound(rnd(2) ? getSound()->wrongDoorCath() : "CAT1503");
+ } else {
+ setCallback(6);
+ setup_playSound(getSound()->wrongDoorCath());
+ }
+ } else {
+ setCallback(savepoint.action == kActionKnock ? 1 : 2);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ }
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityAlexei, (char*)&params->seq);
+ getObjects()->update(kObjectCompartment2, kEntityAlexei, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectHandleInsideBathroom, kEntityAlexei, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionDrawScene:
+ if (params->param6 || params->param5) {
+ getObjects()->update(kObjectCompartment2, kEntityAlexei, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectHandleInsideBathroom, kEntityAlexei, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ params->param5 = 0;
+ params->param6 = 0;
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ setCallback(3);
+ setup_playSound("ALX1134A");
+ break;
+
+ case 3:
+ getObjects()->update(kObjectCompartment2, kEntityAlexei, kObjectLocation1, kCursorTalk, kCursorNormal);
+ getObjects()->update(kObjectHandleInsideBathroom, kEntityAlexei, kObjectLocation1, kCursorTalk, kCursorNormal);
+ params->param5 = 1;
+ break;
+
+ case 4:
+ case 5:
+ case 6:
+ params->param5 = 0;
+ params->param6 = 1;
+ break;
+
+ case 7:
+ setCallback(8);
+ setup_updateFromTicks(300);
+ break;
+
+ case 8:
+ setCallback(9);
+ setup_enterExitCompartment("602Gb", kObjectCompartment2);
+ break;
+
+ case 9:
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityAlexei, kEntityMertens, kAction156567128);
+ getEntities()->drawSequenceLeft(kEntityAlexei, "602Hb");
+ getEntities()->enterCompartment(kEntityAlexei, kObjectCompartment2, true);
+ break;
+
+ case 10:
+ getEntities()->exitCompartment(kEntityAlexei, kObjectCompartment2, true);
+
+ getData()->location = kLocationInsideCompartment;
+ getData()->entityPosition = kPosition_7500;
+
+ getEntities()->drawSequenceLeft(kEntityAlexei, (char *)&params->seq);
+ getObjects()->update(kObjectCompartment2, kEntityAlexei, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectHandleInsideBathroom, kEntityAlexei, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ params->param7 = 0;
+ break;
+ }
+ break;
+
+ case kAction124697504:
+ setCallback(10);
+ setup_enterExitCompartment("602Ib", kObjectCompartment2);
+ break;
+
+ case kAction221617184:
+ params->param7 = 1;
+ getSavePoints()->push(kEntityAlexei, kEntityMertens, kAction100906246);
+
+ setCallback(7);
+ setup_playSound("CON1024");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Alexei, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler)
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartment2, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject10, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ getObjects()->update(kObjectHandleInsideBathroom, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Alexei, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime1089000 && getEntities()->isSomebodyInsideRestaurantOrSalon()) {
+ params->param2 = kItemNone;
+
+ getData()->location = kLocationOutsideCompartment;
+ getData()->inventoryItem = kItemNone;
+
+ getEntities()->updatePositionEnter(kEntityAlexei, kCarRestaurant, 63);
+ getInventory()->setLocationAndProcess(kItem17, kObjectLocation1);
+
+ setCallback(1);
+ setup_callSavepoint("005D", kEntityTables1, kActionDrawTablesWithChairs, "005E");
+ break;
+ }
+
+ if (params->param1) {
+ UPDATE_PARAM(params->param3, getState()->timeTicks, 90);
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 61);
+ } else {
+ params->param3 = 0;
+ }
+ break;
+
+ case kAction1:
+ params->param2 = kItemNone;
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventAlexeiDiner);
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityAlexei, kEntityTables1, kAction136455232);
+ getEntities()->drawSequenceLeft(kEntityAlexei, "005B");
+
+ params->param2 = kItemInvalid;
+ getData()->inventoryItem = kItemInvalid;
+ break;
+
+ case kActionDrawScene:
+ params->param1 = getEntities()->isPlayerPosition(kCarRestaurant, 63) ? 1 : 0;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->updatePositionExit(kEntityAlexei, kCarRestaurant, 63);
+ setup_function19();
+ break;
+
+ case 2:
+ getAction()->playAnimation(getProgress().jacket == kJacketGreen ? kEventAlexeiDiner : kEventAlexeiDinerOriginalJacket);
+ getSavePoints()->push(kEntityAlexei, kEntityTables1, kActionDrawTablesWithChairs, "005E");
+
+ getData()->entityPosition = kPosition_3650;
+ getData()->location = kLocationOutsideCompartment;
+
+ getEntities()->clearSequences(kEntityAlexei);
+ getInventory()->get(kItem17)->location = kObjectLocation1;
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 63);
+
+ setup_function19();
+ break;
+ }
+ break;
+
+ case kAction168046720:
+ getData()->inventoryItem = kItemNone;
+ break;
+
+ case kAction168627977:
+ getData()->inventoryItem = (InventoryItem)LOBYTE(params->param2);
+ break;
+
+ case kAction225182640:
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19 ,Alexei, function19)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_draw("811DS");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarGreenSleeping, kPosition_9460);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 4:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(5);
+ setup_draw("811US");
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_draw("933");
+ break;
+
+ case 6:
+ getEntities()->updatePositionEnter(kEntityAlexei, kCarRestaurant, 63);
+ getScenes()->loadSceneFromItemPosition(kItem17);
+ getSavePoints()->push(kEntityAlexei, kEntityTables1, kAction136455232);
+
+ setCallback(7);
+ setup_callSavepoint("005F", kEntityTables1, kActionDrawTablesWithChairs, "005G");
+ break;
+
+ case 7:
+ getEntities()->updatePositionExit(kEntityAlexei, kCarRestaurant, 63);
+ getSavePoints()->push(kEntityAlexei, kEntityServers1, kAction302996448);
+
+ setCallback(8);
+ setup_draw("934");
+ break;
+
+ case 8:
+ setCallback(9);
+ setup_draw("811DS");
+ break;
+
+ case 9:
+ setCallback(10);
+ setup_function13();
+ break;
+
+ case 10:
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 61))
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
+
+ setCallback(11);
+ setup_function16(kTime1098000, "411");
+ break;
+
+ case 11:
+ setup_function20();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Alexei, function20)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function14();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(4);
+ setup_updatePosition("103A", kCarRestaurant, 52);
+ break;
+
+ case 4:
+ getData()->location = kLocationInsideCompartment;
+ setup_function26();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Alexei, function21)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM_CHECK(params->param2, getState()->time, params->param1)
+ getData()->location = kLocationOutsideCompartment;
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(1);
+ setup_updatePosition("103C", kCarRestaurant, 52);
+ }
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventAlexeiSalonPoem);
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityAlexei, "103B");
+ params->param1 = 225 * (4 * rnd(3) + 4);
+
+ if (!getEvent(kEventAlexeiSalonPoem))
+ getData()->inventoryItem = kItemParchemin;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationInsideCompartment;
+ setup_function22();
+ break;
+
+ case 2:
+ getAction()->playAnimation(kEventAlexeiSalonPoem);
+ getData()->location = kLocationOutsideCompartment;
+
+ getEntities()->drawSequenceRight(kEntityAlexei, "103D");
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 55);
+ getEntities()->updatePositionEnter(kEntityAlexei, kCarRestaurant, 52);
+
+ setCallback(3);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 3:
+ getEntities()->drawSequenceLeft(kEntityAlexei, "103B");
+ getEntities()->updatePositionExit(kEntityAlexei, kCarRestaurant, 52);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Alexei, function22)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM_PROC(params->param2, getState()->time, params->param2)
+ if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
+ getData()->location = kLocationOutsideCompartment;
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(1);
+ setup_updatePosition("103D", kCarRestaurant, 52);
+ break;
+ }
+ UPDATE_PARAM_PROC_END
+
+ if (params->param3 == kTimeInvalid || getState()->time <= kTime1111500)
+ break;
+
+ if (getState()->time > kTime1138500) {
+ params->param3 = kTimeInvalid;
+ } else {
+ if (!getEntities()->isInSalon(kEntityPlayer) || getEntities()->isInSalon(kEntityPlayer) || !params->param3)
+ params->param3 = getState()->time;
+
+ if (params->param3 >= getState()->time)
+ break;
+
+ params->param3 = kTimeInvalid;
+ }
+
+ getData()->inventoryItem = kItemNone;
+
+ setup_function23();
+ break;
+
+ case kAction1:
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventAlexeiSalonPoem);
+ break;
+
+ case kActionDefault:
+ params->param1 = 255 * (4 * rnd(4) + 8);
+ getEntities()->drawSequenceLeft(kEntityAlexei, "103E");
+ if (!getEvent(kEventAlexeiSalonPoem))
+ getData()->inventoryItem = kItemParchemin;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationInsideCompartment;
+ setup_function21();
+ break;
+
+ case 2:
+ getAction()->playAnimation(kEventAlexeiSalonPoem);
+ getData()->inventoryItem = kItemNone;
+ getData()->location = kLocationOutsideCompartment;
+
+ getEntities()->drawSequenceRight(kEntityAlexei, "103D");
+ getEntities()->updatePositionEnter(kEntityAlexei, kCarRestaurant, 52);
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 55);
+
+ setCallback(3);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 3:
+ getEntities()->updatePositionExit(kEntityAlexei, kCarRestaurant, 52);
+ getData()->location = kLocationInsideCompartment;
+
+ setup_function21();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Alexei, function23)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ getData()->inventoryItem = (!getEntities()->isInRestaurant(kEntityAlexei) || getEvent(kEventAlexeiSalonPoem)) ? kItemNone : kItemParchemin;
+ break;
+
+ case kAction1:
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventAlexeiSalonPoem);
+ break;
+
+ case kActionDefault:
+ getData()->location = kLocationInsideCompartment;
+ getSavePoints()->push(kEntityAlexei, kEntityTatiana, kAction124973510);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventAlexeiSalonVassili);
+
+ getData()->location = kLocationOutsideCompartment;
+
+ getEntities()->drawSequenceLeft(kEntityAlexei, "103F");
+ getScenes()->processScene();
+
+ setup_function24();
+ break;
+
+ case 2:
+ getAction()->playAnimation(kEventAlexeiSalonPoem);
+
+ getData()->inventoryItem = kItemNone;
+
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 55);
+ break;
+ }
+ break;
+
+ case kAction157159392:
+ if (getEntities()->isInSalon(kEntityPlayer)) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAlexeiSalonVassili);
+ } else {
+ setup_function24();
+ }
+ break;
+
+ case kAction188784532:
+ setup_function24();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Alexei, function24)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAlexeiSalonCath);
+ break;
+
+ case kActionDefault:
+ if (getEvent(kEventAlexeiSalonVassili))
+ getData()->inventoryItem = kItemInvalid;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventAlexeiSalonCath);
+ getData()->car = kCarRestaurant;
+ getData()->entityPosition = kPosition_9460;
+ getEntities()->clearSequences(kEntityAlexei);
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 55);
+ setup_function25();
+ break;
+
+ case 2:
+ setup_function25();
+ break;
+ }
+ break;
+
+ case kAction135854208:
+ getData()->inventoryItem = kItemNone;
+ setCallback(2);
+ setup_draw("103G");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, Alexei, function25)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function13();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 61))
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
+
+ setCallback(2);
+ setup_function16(kTime1179000, "411");
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function16(kTime1323000, "412");
+ break;
+
+ case 3:
+ setup_function26();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(26, Alexei, function26)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK(kTime1512000, params->param1, setup_function27)
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_7500;
+ getData()->car = kCarGreenSleeping;
+ getData()->location = kLocationInsideCompartment;
+
+ getObjects()->update(kObjectCompartment2, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectHandleInsideBathroom, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject10, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 61))
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 66);
+
+ getEntities()->clearSequences(kEntityAlexei);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(27, Alexei, function27)
+ if (savepoint.action == kActionDefault) {
+ getObjects()->update(kObject10, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 66))
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
+
+ getEntities()->drawSequenceLeft(kEntityAlexei, "412");
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(28, Alexei, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter2Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAlexei);
+
+ getObjects()->update(kObjectCompartment2, kEntityAlexei, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject10, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ getObjects()->update(kObjectHandleInsideBathroom, kEntityAlexei, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ getData()->entityPosition = kPosition_7500;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(29, Alexei, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function16(kTime1791000, "411");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function14();
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 4:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(5);
+ setup_draw("811US");
+ break;
+
+ case 5:
+ getEntities()->updatePositionEnter(kEntityAlexei, kCarRestaurant, 63);
+
+ setCallback(6);
+ setup_callSavepoint("018B", kEntityTables1, kAction136455232, "BOGUS");
+ break;
+
+ case 6:
+ getEntities()->updatePositionExit(kEntityAlexei, kCarRestaurant, 63);
+ getSavePoints()->push(kEntityAlexei, kEntityTatiana, kAction290869168);
+ setup_function30();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(30, Alexei, function30)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartment2, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getData()->car = kCarRestaurant;
+ getData()->location = kLocationInsideCompartment;
+
+ getEntities()->drawSequenceLeft(kEntityAlexei, "018C");
+ getSavePoints()->push(kEntityAlexei, kEntityTables1, kAction136455232);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->updatePositionExit(kEntityAlexei, kCarRestaurant, 63);
+ getSavePoints()->push(kEntityAlexei, kEntityTatiana, kAction156444784);
+ getEntities()->drawSequenceLeft(kEntityAlexei, "018E");
+
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getProgress().field_68 = 1;
+
+ setCallback(2);
+ setup_playSound("TAT2116");
+ break;
+
+ case 2:
+ getSound()->playSound(kEntityAlexei, "TAt2116A");
+ getEntities()->updatePositionEnter(kEntityAlexei, kCarRestaurant, 63);
+
+ setCallback(3);
+ setup_callSavepoint("018F", kEntityTatiana, kAction123857088, "BOGUS");
+ break;
+
+ case 3:
+ getEntities()->updatePositionExit(kEntityAlexei, kCarRestaurant, 63);
+ setup_function31();
+ break;
+ }
+ break;
+
+ case kAction236053296:
+ getEntities()->drawSequenceRight(kEntityAlexei, "018D1");
+ getEntities()->drawSequenceRight(kEntityTatiana, "018D2");
+ getEntities()->updatePositionEnter(kEntityAlexei, kCarRestaurant, 63);
+
+ if (savepoint.param.intValue)
+ getScenes()->loadSceneFromPosition(kCarRestaurant, (Position)savepoint.param.intValue);
+
+ setCallback(1);
+ setup_callbackActionOnDirection();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(31, Alexei, function31)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(kEntityAlexei, "811DS");
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityAlexei);
+
+ setCallback(1);
+ setup_callbackActionOnDirection();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function13();
+ break;
+
+ case 2:
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 61))
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
+
+ setCallback(3);
+ setup_function16(kTimeEnd, "411");
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(32, Alexei, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAlexei);
+
+ getObjects()->update(kObjectCompartment2, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject10, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ getObjects()->update(kObjectHandleInsideBathroom, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(33, Alexei, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function34();
+ break;
+
+ case kAction122288808:
+ getData()->entityPosition = kPosition_9270;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ setCallback(1);
+ setup_function13();
+ break;
+
+ case kAction122358304:
+ getEntities()->drawSequenceLeft(kEntityAlexei, "BLANK");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(34, Alexei, function34)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 61))
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
+
+ setCallback(1);
+ setup_function16(kTime2083500, "411");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function14();
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 4:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(5);
+ setup_updatePosition("103A", kCarRestaurant, 52);
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_function35();
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_function13();
+ break;
+
+ case 7:
+ getObjects()->update(kObject10, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 61))
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 66);
+
+ setCallback(8);
+ setup_function16(kTime2124000, "NONE");
+ break;
+
+ case 8:
+ setCallback(9);
+ setup_function14();
+ break;
+
+ case 9:
+ setCallback(10);
+ setup_function36();
+ break;
+
+ case 10:
+ getObjects()->update(kObject10, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 66))
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
+
+ setCallback(11);
+ setup_function16(kTime16451100, "411");
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(35, Alexei, function35)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isInSalon(kEntityPlayer)) {
+ UPDATE_PARAM_PROC(params->param2, getState()->time, 2700)
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+ UPDATE_PARAM_PROC_END
+ } else {
+ params->param2 = 0;
+ }
+
+ UPDATE_PARAM_PROC(params->param3, getState()->time, params->param1)
+ if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
+ setCallback(3);
+ setup_function15();
+ break;
+ }
+ UPDATE_PARAM_PROC_END
+
+label_callback_3:
+ UPDATE_PARAM(params->param4, getState()->time, 9000);
+
+ setCallback(4);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case kActionDefault:
+ params->param1 = 15 * rnd(120);
+ getEntities()->drawSequenceLeft(kEntityAlexei, "103B");
+ getData()->location = kLocationInsideCompartment;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 4:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback((byte)(getCallback() + 1));
+ setup_updatePosition("124C", kCarRestaurant, 52);
+ break;
+
+ case 2:
+ case 5:
+ CALLBACK_ACTION();
+ break;
+
+ case 3:
+ params->param1 = 15 * rnd(120);
+ params->param3 = 0;
+ goto label_callback_3;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(36, Alexei, function36)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param3 || params->param2)
+ break;
+
+ UPDATE_PARAM(params->param4, getState()->timeTicks, params->param1);
+
+ getEntities()->drawSequenceRight(kEntityAlexei, "124B");
+
+ params->param2 = 1;
+ params->param4 = 0;
+ break;
+
+ case kActionExitCompartment:
+ if (params->param2) {
+ getEntities()->drawSequenceLeft(kEntityAlexei, "124A");
+ params->param1 = 5 * (3 * rnd(15) + 15);
+ params->param2 = 0;
+ }
+ break;
+
+ case kActionDefault:
+ params->param1 = 5 * (3 * rnd(15) + 15);
+
+ setCallback(1);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityAlexei, kEntityAbbot, kAction222609266);
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(3);
+ setup_updatePosition("103A", kCarRestaurant, 52);
+ break;
+
+ case 3:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->drawSequenceLeft(kEntityAlexei, "124A");
+ break;
+
+ case 4:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction122288808:
+ setCallback(4);
+ setup_function13();
+ break;
+
+ case kAction122358304:
+ getEntities()->drawSequenceLeft(kEntityAlexei, "BLANK");
+ params->param3 = 1;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(37, Alexei, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAlexei);
+
+ getObjects()->update(kObjectCompartment2, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject10, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ getObjects()->update(kObjectHandleInsideBathroom, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ getData()->entityPosition = kPosition_7500;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(38, Alexei, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function16(kTime2354400, "411");
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function39();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(39, Alexei, function39)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param2)
+ break;
+
+ if (!params->param4) {
+ params->param3 = getState()->time + 4500;
+ params->param4 = getState()->time + 9000;
+ }
+
+ if (params->param5 != kTimeInvalid && params->param3 < getState()->time) {
+
+ if (params->param4 >= getState()->time) {
+ if (getEntities()->isInGreenCarEntrance(kEntityPlayer) || !params->param5)
+ params->param5 = getState()->time;
+
+ if (params->param5 >= getState()->time)
+ break;
+ }
+
+ params->param4 = kTimeInvalid;
+
+ getEntities()->updatePositionEnter(kEntityAlexei, kCarGreenSleeping, 70);
+ getEntities()->updatePositionEnter(kEntityAlexei, kCarGreenSleeping, 71);
+
+ if (getEntities()->isInGreenCarEntrance(kEntityPlayer)) {
+ getSound()->excuseMe(kEntityAlexei);
+
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 62))
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 72);
+ }
+
+ setup_function40();
+ }
+ break;
+
+ case kActionExitCompartment:
+ if (!params->param2 && !params->param2)
+ getEntities()->drawSequenceLeft(kEntityAlexei, "306F");
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_enterExitCompartment("602FB", kObjectCompartment2);
+ break;
+
+ case kActionDrawScene:
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 62)) {
+ if (params->param1) {
+ if (!params->param2)
+ break;
+ } else if (!params->param2) {
+ getEntities()->drawSequenceRight(kEntityAlexei, "306A");
+ break;
+ }
+
+ setup_function40();
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartment2, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_updateEntity(kCarGreenSleeping, kPosition_540);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityAlexei);
+
+ if (getEntities()->isInGreenCarEntrance(kEntityPlayer)) {
+ getSound()->excuseMe(kEntityAlexei);
+
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 62))
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 72);
+ }
+
+ getEntities()->updatePositionEnter(kEntityAlexei, kCarGreenSleeping, 70);
+ getEntities()->updatePositionEnter(kEntityAlexei, kCarGreenSleeping, 71);
+ break;
+ }
+ break;
+
+ case kAction123536024:
+ params->param2 = 1;
+ break;
+
+ case kAction123712592:
+ getEntities()->clearSequences(kEntityAlexei);
+ params->param1 = 1;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(40, Alexei, function40)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_7500);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceRight(kEntityAlexei, "602Eb");
+ getEntities()->enterCompartment(kEntityAlexei, kObjectCompartment2);
+
+ getData()->location = kLocationInsideCompartment;
+
+ if (getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, kPosition_7500)) {
+ getAction()->playAnimation(isNight() ? kEventCathTurningNight : kEventCathTurningDay);
+ getSound()->playSound(kEntityPlayer, "BUMP");
+ getScenes()->loadSceneFromObject(kObjectCompartment2);
+ }
+
+ setCallback(2);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 2:
+ getEntities()->exitCompartment(kEntityAlexei, kObjectCompartment2);
+ getData()->entityPosition = kPosition_7500;
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityAlexei);
+
+ setup_function41();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(41, Alexei, function41)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 66))
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
+
+ setCallback(1);
+ setup_function16(kTime2403000, "411");
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function42();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(42, Alexei, function42)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function14();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityAlexei, kEntityTatiana, kAction191198209);
+
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_updatePosition("103A", kCarRestaurant, 52);
+ break;
+
+ case 3:
+ getData()->location = kLocationInsideCompartment;
+ setup_function43();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(43, Alexei, function43)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time < kTime1806300 && params->param2 < getState()->time) {
+ if (!params->param2)
+ params->param2 = getState()->time + params->param1;
+
+ if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
+ setCallback(1);
+ setup_function15();
+ break;
+ }
+ }
+
+label_callback_1:
+ if (getState()->time > kTime2457000 && !params->param3) {
+ params->param3 = 1;
+
+ setCallback(2);
+ setup_callbackActionRestaurantOrSalon();
+ }
+ break;
+
+ case kActionDefault:
+ params->param1 = 5 * (3 * rnd(120) + 180);
+ getEntities()->drawSequenceLeft(kEntityAlexei, "103B");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ params->param1 = 5 * (3 * rnd(120) + 180);
+ params->param2 = 0;
+ goto label_callback_1;
+
+ case 2:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(3);
+ setup_updatePosition("124C", kCarRestaurant, 52);
+ break;
+
+ case 3:
+ setup_function44();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(44, Alexei, function44)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime2457000 && !params->param1) {
+ params->param1 = 1;
+
+ getEntities()->updatePositionExit(kEntityAlexei, kCarGreenSleeping, 70);
+ getEntities()->updatePositionExit(kEntityAlexei, kCarGreenSleeping, 71);
+
+ if (getEntities()->isInGreenCarEntrance(kEntityPlayer)) {
+ getSound()->excuseMe(kEntityAlexei);
+
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 62))
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 72);
+
+ setup_function45();
+ }
+ }
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarRedSleeping;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->entityPosition = kPosition_9460;
+
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_540);
+ break;
+
+ case kActionDrawScene:
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 62)) {
+ setCallback(2);
+ setup_draw("306A");
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->clearSequences(kEntityAlexei);
+
+ if (getEntities()->isInGreenCarEntrance(kEntityPlayer)) {
+ getSound()->excuseMe(kEntityAlexei);
+
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 62))
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 72);
+ }
+
+ getEntities()->updatePositionEnter(kEntityAlexei, kCarGreenSleeping, 70);
+ getEntities()->updatePositionEnter(kEntityAlexei, kCarGreenSleeping, 71);
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityAlexei, "306F");
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(45, Alexei, function45)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function13();
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 66))
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
+
+ if (getInventory()->hasItem(kItemBomb)) {
+ setup_function46();
+ } else {
+ setCallback(2);
+ setup_function16(kTimeEnd, "412");
+ }
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(46, Alexei, function46)
+ error("Alexei: callback function 46 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(47, Alexei, function47)
+ if (savepoint.action == kActionDefault) {
+ getEntities()->clearSequences(kEntityAlexei);
+
+ getData()->entityPosition = kPositionNone;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarNone;
+
+ getObjects()->update(kObjectCompartment2, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectHandleInsideBathroom, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(48, Alexei, chapter5)
+ if (savepoint.action == kActionDefault)
+ getEntities()->clearSequences(kEntityAlexei);
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/alexei.h b/engines/lastexpress/entities/alexei.h
new file mode 100644
index 0000000000..dc1a136143
--- /dev/null
+++ b/engines/lastexpress/entities/alexei.h
@@ -0,0 +1,213 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_ALEXEI_H
+#define LASTEXPRESS_ALEXEI_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Alexei : public Entity {
+public:
+ Alexei(LastExpressEngine *engine);
+ ~Alexei() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Updates parameter 2 using ticks value
+ *
+ * @param ticks The number of ticks to add
+ */
+ DECLARE_FUNCTION_1(updateFromTicks, uint32 ticks)
+
+ /**
+ * Draws the entity
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(draw, const char* sequence)
+
+ /**
+ * Updates the position
+ *
+ * @param sequence1 The sequence to draw
+ * @param car The car
+ * @param position The position
+ */
+ DECLARE_FUNCTION_3(updatePosition, const char* sequence1, CarIndex car, Position position)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Process callback action when the entity direction is not kDirectionRight
+ */
+ DECLARE_FUNCTION(callbackActionOnDirection)
+
+ /**
+ * Call a savepoint (or draw sequence in default case)
+ *
+ * @param sequence1 The sequence to draw in the default case
+ * @param entity The entity
+ * @param action The action
+ * @param sequence2 The sequence name for the savepoint
+ */
+ DECLARE_FUNCTION_4(callSavepoint, const char* sequence1, EntityIndex entity, ActionIndex action, const char* sequence2)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ /**
+ * Draws the entity along with another one
+ *
+ * @param savepoint The savepoint
+ * - The sequence to draw
+ * - The sequence to draw for the second entity
+ * - The EntityIndex of the second entity
+ */
+ DECLARE_FUNCTION_NOSETUP(draw2)
+
+ /**
+ * Process callback action when somebody is standing in the restaurant or salon.
+ */
+ DECLARE_FUNCTION(callbackActionRestaurantOrSalon)
+
+ DECLARE_FUNCTION(function13)
+ DECLARE_FUNCTION(function14)
+ DECLARE_FUNCTION(function15)
+
+ /**
+ * ???
+ *
+ * @param timeValue The time value
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_2(function16, TimeValue timeValue, const char* sequence)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+ DECLARE_FUNCTION(function19)
+ DECLARE_FUNCTION(function20)
+ DECLARE_FUNCTION(function21)
+ DECLARE_FUNCTION(function22)
+ DECLARE_FUNCTION(function23)
+ DECLARE_FUNCTION(function24)
+ DECLARE_FUNCTION(function25)
+ DECLARE_FUNCTION(function26)
+ DECLARE_FUNCTION(function27)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+ DECLARE_FUNCTION(function30)
+ DECLARE_FUNCTION(function31)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+ DECLARE_FUNCTION(function34)
+ DECLARE_FUNCTION(function35)
+ DECLARE_FUNCTION(function36)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+ DECLARE_FUNCTION(function39)
+ DECLARE_FUNCTION(function40)
+ DECLARE_FUNCTION(function41)
+ DECLARE_FUNCTION(function42)
+ DECLARE_FUNCTION(function43)
+ DECLARE_FUNCTION(function44)
+ DECLARE_FUNCTION(function45)
+ DECLARE_FUNCTION(function46)
+ DECLARE_FUNCTION(function47)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_ALEXEI_H
diff --git a/engines/lastexpress/entities/alouan.cpp b/engines/lastexpress/entities/alouan.cpp
new file mode 100644
index 0000000000..0a66004a49
--- /dev/null
+++ b/engines/lastexpress/entities/alouan.cpp
@@ -0,0 +1,504 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/alouan.h"
+
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+
+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(Alouan, compartment6);
+ ADD_CALLBACK_FUNCTION(Alouan, compartment8);
+ ADD_CALLBACK_FUNCTION(Alouan, compartment6to8);
+ ADD_CALLBACK_FUNCTION(Alouan, compartment8to6);
+ ADD_CALLBACK_FUNCTION(Alouan, chapter1);
+ ADD_CALLBACK_FUNCTION(Alouan, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Alouan, function12);
+ ADD_CALLBACK_FUNCTION(Alouan, chapter2);
+ ADD_CALLBACK_FUNCTION(Alouan, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Alouan, chapter3);
+ ADD_CALLBACK_FUNCTION(Alouan, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Alouan, chapter4);
+ ADD_CALLBACK_FUNCTION(Alouan, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Alouan, function19);
+ ADD_CALLBACK_FUNCTION(Alouan, chapter5);
+ ADD_CALLBACK_FUNCTION(Alouan, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(Alouan, function22);
+ ADD_CALLBACK_FUNCTION(Alouan, function23);
+ ADD_NULL_FUNCTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Alouan, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(2, Alouan, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(3, Alouan, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(4, Alouan, updateFromTime, uint32)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(5, Alouan, updateEntity, CarIndex, EntityPosition)
+ Entity::updateEntity(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(6, Alouan, compartment6)
+ COMPARTMENT_TO(Alouan, kObjectCompartment6, kPosition_4070, "621Cf", "621Df");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(7, Alouan, compartment8)
+ COMPARTMENT_TO(Alouan, kObjectCompartment8, kPosition_2740, "621Ch", "621Dh");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(8, Alouan, compartment6to8)
+ COMPARTMENT_FROM_TO(Alouan, kObjectCompartment6, kPosition_4070, "621Bf", kObjectCompartment8, kPosition_2740, "621Ah");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(9, Alouan, compartment8to6)
+ COMPARTMENT_FROM_TO(Alouan, kObjectCompartment8, kPosition_2740, "621Bh", kObjectCompartment6, kPosition_4070, "621Af");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(10, Alouan, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Alouan, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+
+ TIME_CHECK_CALLBACK(kTime1096200, params->param1, 1, setup_compartment8to6);
+
+label_callback1:
+ if (getState()->time > kTime1162800 && !params->param2) {
+ params->param2 = 1;
+ getSavePoints()->push(kEntityAlouan, kEntityTrain, kAction191070912, kPosition_4070);
+ getData()->entityPosition = kPosition_4070;
+ }
+
+ if (getState()->time > kTime1179000 && !params->param3) {
+ params->param3 = 1;
+ getSavePoints()->push(kEntityAlouan, kEntityTrain, kAction191070912, kPosition_4840);
+
+ setCallback(2);
+ setup_compartment6to8();
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->entityPosition = kPosition_4840;
+ goto label_callback1;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Alouan, function12)
+ if (savepoint.action == kActionDefault) {
+ getObjects()->update(kObjectCompartment7, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment5, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+
+ getEntities()->clearSequences(kEntityAlouan);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Alouan, chapter2)
+ if (savepoint.action != kActionDefault)
+ return;
+
+ getEntities()->clearSequences(kEntityAlouan);
+
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ setup_chapter2Handler();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Alouan, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param2 == kTimeInvalid)
+ break;
+
+ if (getState()->time <= kTime1777500) {
+ if (!getEntities()->isPlayerInCar(kCarGreenSleeping) || !params->param2)
+ params->param2 = getState()->time + 75;
+
+ if (params->param2 >= getState()->time)
+ break;
+ }
+
+ params->param2 = kTimeInvalid;
+
+ setCallback(params->param1 ? 1 : 2);
+ if (params->param1)
+ setup_compartment8();
+ else
+ setup_compartment6();
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityAlouan, kEntityTrain, kAction191070912, kPosition_4840);
+ params->param1 = 1;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 3:
+ params->param1 = 0;
+ setCallback(4);
+ setup_playSound("Har2011");
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_updateFromTime(900);
+ break;
+
+ case 5:
+ getSavePoints()->push(kEntityAlouan, kEntityFrancois, kAction190219584);
+ break;
+ }
+ break;
+
+ case kAction189489753:
+ setCallback(3);
+ setup_compartment8to6();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Alouan, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAlouan);
+
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Alouan, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CALLBACK(kTimeCitySalzbourg, params->param1, 1, setup_compartment8to6);
+
+label_callback1:
+ if (params->param2 != kTimeInvalid && getState()->time > kTime1989000)
+ TIME_CHECK_CAR(kTime2119500, params->param5, 5, setup_compartment8);
+
+label_callback2:
+ TIME_CHECK_PLAYSOUND(kTime2052000, params->param3, 3, "Har1005");
+
+label_callback3:
+ TIME_CHECK_CALLBACK(kTime2133000, params->param4, 4, setup_compartment6to8);
+
+label_callback4:
+ if (params->param5 != kTimeInvalid && getState()->time > kTime2151000)
+ TIME_CHECK_CAR(kTime2241000, params->param5, 5, setup_compartment8);
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityAlouan, kEntityTrain, kAction191070912, kPosition_4840);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->entityPosition = kPosition_4840;
+ goto label_callback1;
+
+ case 2:
+ goto label_callback2;
+
+ case 3:
+ goto label_callback3;
+
+ case 4:
+ goto label_callback4;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Alouan, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAlouan);
+
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Alouan, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1 != kTimeInvalid)
+ TIME_CHECK_CAR(kTime2443500, params->param1, 1, setup_compartment8);
+
+label_callback1:
+ TIME_CHECK_CALLBACK(kTime2455200, params->param2, 2, setup_compartment8to6);
+
+label_callback2:
+ if (getState()->time > kTime2475000 && !params->param3) {
+ params->param3 = 1;
+ getSavePoints()->push(kEntityAlouan, kEntityTrain, kAction191070912, kPosition_4840);
+
+ setCallback(3);
+ setup_compartment6to8();
+ }
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityAlouan, kEntityTrain, kAction191070912, kPosition_4840);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_callback1;
+
+ case 2:
+ getSavePoints()->push(kEntityAlouan, kEntityTrain, kAction191070912, kPosition_4070);
+ goto label_callback2;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Alouan, function19)
+ if (savepoint.action == kActionDefault) {
+ getObjects()->update(kObjectCompartment7, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment5, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+
+ getEntities()->clearSequences(kEntityAlouan);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Alouan, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAlouan);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Alouan, chapter5Handler)
+ if (savepoint.action == kActionProceedChapter5)
+ setup_function22();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Alouan, function22)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param1, getState()->time, 2700);
+ setup_function23();
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5000;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ break;
+
+ case kActionDrawScene:
+ if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarGreenSleeping))
+ setup_function23();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Alouan, function23)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_4070);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("619AF", kObjectCompartment5);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityAlouan);
+
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+
+ getObjects()->update(kObjectCompartment6, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+ }
+ break;
+
+ case kAction135800432:
+ setup_nullfunction();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_NULL_FUNCTION(24, Alouan)
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/alouan.h b/engines/lastexpress/entities/alouan.h
new file mode 100644
index 0000000000..282117fcea
--- /dev/null
+++ b/engines/lastexpress/entities/alouan.h
@@ -0,0 +1,139 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_ALOUAN_H
+#define LASTEXPRESS_ALOUAN_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Alouan : public Entity {
+public:
+ Alouan(LastExpressEngine *engine);
+ ~Alouan() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param time The time to add
+ */
+ DECLARE_FUNCTION_1(updateFromTime, uint32 time)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ DECLARE_FUNCTION(compartment6)
+ DECLARE_FUNCTION(compartment8)
+ DECLARE_FUNCTION(compartment6to8)
+ DECLARE_FUNCTION(compartment8to6)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+ DECLARE_FUNCTION(function12)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+ DECLARE_FUNCTION(function19)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+ DECLARE_FUNCTION(function22)
+ DECLARE_FUNCTION(function23)
+ DECLARE_NULL_FUNCTION()
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_ALOUAN_H
diff --git a/engines/lastexpress/entities/anna.cpp b/engines/lastexpress/entities/anna.cpp
new file mode 100644
index 0000000000..f81d95754e
--- /dev/null
+++ b/engines/lastexpress/entities/anna.cpp
@@ -0,0 +1,3400 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/anna.h"
+
+#include "lastexpress/game/action.h"
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/fight.h"
+#include "lastexpress/game/inventory.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+
+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(Anna, callbackActionOnDirection);
+ ADD_CALLBACK_FUNCTION(Anna, callSavepoint);
+ ADD_CALLBACK_FUNCTION(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(Anna, function12);
+ ADD_CALLBACK_FUNCTION(Anna, draw2);
+ ADD_CALLBACK_FUNCTION(Anna, updateFromTicks);
+ ADD_CALLBACK_FUNCTION(Anna, function15);
+ ADD_CALLBACK_FUNCTION(Anna, chapter1);
+ ADD_CALLBACK_FUNCTION(Anna, function17);
+ ADD_CALLBACK_FUNCTION(Anna, function18);
+ ADD_CALLBACK_FUNCTION(Anna, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Anna, function20);
+ ADD_CALLBACK_FUNCTION(Anna, function21);
+ ADD_CALLBACK_FUNCTION(Anna, function22);
+ ADD_CALLBACK_FUNCTION(Anna, function23);
+ ADD_CALLBACK_FUNCTION(Anna, function24);
+ ADD_CALLBACK_FUNCTION(Anna, function25);
+ ADD_CALLBACK_FUNCTION(Anna, function26);
+ ADD_CALLBACK_FUNCTION(Anna, function27);
+ ADD_CALLBACK_FUNCTION(Anna, function28);
+ ADD_CALLBACK_FUNCTION(Anna, function29);
+ ADD_CALLBACK_FUNCTION(Anna, function30);
+ ADD_CALLBACK_FUNCTION(Anna, function31);
+ ADD_CALLBACK_FUNCTION(Anna, function32);
+ ADD_CALLBACK_FUNCTION(Anna, function33);
+ ADD_CALLBACK_FUNCTION(Anna, function34);
+ ADD_CALLBACK_FUNCTION(Anna, function35);
+ ADD_CALLBACK_FUNCTION(Anna, function36);
+ ADD_CALLBACK_FUNCTION(Anna, function37);
+ ADD_CALLBACK_FUNCTION(Anna, function38);
+ ADD_CALLBACK_FUNCTION(Anna, function39);
+ ADD_CALLBACK_FUNCTION(Anna, function40);
+ ADD_CALLBACK_FUNCTION(Anna, function41);
+ ADD_CALLBACK_FUNCTION(Anna, chapter2);
+ ADD_CALLBACK_FUNCTION(Anna, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Anna, chapter3);
+ ADD_CALLBACK_FUNCTION(Anna, function45);
+ ADD_CALLBACK_FUNCTION(Anna, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Anna, function47);
+ ADD_CALLBACK_FUNCTION(Anna, function48);
+ ADD_CALLBACK_FUNCTION(Anna, leaveTableWithAugust);
+ ADD_CALLBACK_FUNCTION(Anna, function50);
+ ADD_CALLBACK_FUNCTION(Anna, function51);
+ ADD_CALLBACK_FUNCTION(Anna, function52);
+ ADD_CALLBACK_FUNCTION(Anna, function53);
+ ADD_CALLBACK_FUNCTION(Anna, function54);
+ ADD_CALLBACK_FUNCTION(Anna, function55);
+ ADD_CALLBACK_FUNCTION(Anna, function56);
+ ADD_CALLBACK_FUNCTION(Anna, function57);
+ ADD_CALLBACK_FUNCTION(Anna, function58);
+ ADD_CALLBACK_FUNCTION(Anna, function59);
+ ADD_CALLBACK_FUNCTION(Anna, function60);
+ ADD_CALLBACK_FUNCTION(Anna, function61);
+ ADD_CALLBACK_FUNCTION(Anna, function62);
+ ADD_CALLBACK_FUNCTION(Anna, function63);
+ ADD_CALLBACK_FUNCTION(Anna, baggage);
+ ADD_CALLBACK_FUNCTION(Anna, function65);
+ ADD_CALLBACK_FUNCTION(Anna, chapter4);
+ ADD_CALLBACK_FUNCTION(Anna, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Anna, function68);
+ ADD_CALLBACK_FUNCTION(Anna, function69);
+ ADD_CALLBACK_FUNCTION(Anna, function70);
+ ADD_CALLBACK_FUNCTION(Anna, function71);
+ ADD_CALLBACK_FUNCTION(Anna, function72);
+ ADD_CALLBACK_FUNCTION(Anna, function73);
+ ADD_CALLBACK_FUNCTION(Anna, chapter5);
+ ADD_CALLBACK_FUNCTION(Anna, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(Anna, function76);
+ ADD_CALLBACK_FUNCTION(Anna, function77);
+ ADD_CALLBACK_FUNCTION(Anna, function78);
+ ADD_CALLBACK_FUNCTION(Anna, function79);
+ ADD_CALLBACK_FUNCTION(Anna, function80);
+ ADD_CALLBACK_FUNCTION(Anna, finalSequence);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Anna, reset)
+ Entity::reset(savepoint, true, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(2, Anna, draw)
+ Entity::draw(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SII(3, Anna, updatePosition, CarIndex, Position)
+ Entity::updatePosition(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(4, Anna, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(5, Anna, callbackActionOnDirection)
+ Entity::callbackActionOnDirection(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SIIS(6, Anna, callSavepoint, EntityIndex, ActionIndex)
+ Entity::callSavepoint(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(7, Anna, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(8, Anna, callbackActionRestaurantOrSalon)
+ Entity::callbackActionRestaurantOrSalon(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(9, Anna, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(10, Anna, updateEntity, CarIndex, EntityPosition)
+ if (savepoint.action == kActionExcuseMeCath) {
+ if (getEvent(kEventAugustPresentAnna) || getEvent(kEventAugustPresentAnnaFirstIntroduction) || getProgress().chapter >= kChapter2)
+ getSound()->playSound(kEntityPlayer, "CAT1001");
+ else
+ getSound()->excuseMeCath();
+
+ return;
+ }
+
+ Entity::updateEntity(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(11, Anna, updateFromTime, uint32)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Anna, function12)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param2 && ENTITY_PARAM(0, 1))
+ params->param2 = 1;
+
+ if (params->param6) {
+ UPDATE_PARAM_PROC(params->param7, getState()->timeTicks, 75)
+ getSavePoints()->push(kEntityAnna, kEntityAnna, kActionEndSound);
+
+ params->param6 = 0;
+ params->param7 = 0;
+ UPDATE_PARAM_PROC_END
+ }
+
+ if (params->param4) {
+ UPDATE_PARAM(params->param8, getState()->timeTicks, 75);
+
+ params->param4 = 0;
+ params->param5 = 1;
+
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorHand);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorHand);
+
+ --params->param1;
+
+ getSavePoints()->push(kEntityAnna, kEntityAnna, kActionEndSound);
+ }
+
+ params->param8 = 0;
+ break;
+
+ case kActionEndSound:
+ if (params->param2) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ ++params->param1;
+
+ switch (params->param1) {
+ default:
+ break;
+
+ case 1:
+ getSound()->playSound(kEntityAnna, "ANN2135A");
+ break;
+
+ case 2:
+ getSound()->playSound(kEntityAnna, "ANN2135B");
+ break;
+
+ case 3:
+ getSound()->playSound(kEntityAnna, "ANN2135C");
+ break;
+
+ case 4:
+ getSound()->playSound(kEntityAnna, "ANN2135C");
+ break;
+
+ case 5:
+ getSound()->playSound(kEntityAnna, "ANN2135L");
+ break;
+
+ case 6:
+ getSound()->playSound(kEntityAnna, "ANN2135K");
+ break;
+
+ case 7:
+ getSound()->playSound(kEntityAnna, "ANN2135H");
+ break;
+
+ case 8:
+ getSound()->playSound(kEntityAnna, "ANN2135K");
+ break;
+
+ case 9:
+ getSound()->playSound(kEntityAnna, "ANN2135I");
+ break;
+
+ case 10:
+ getSound()->playSound(kEntityAnna, "ANN2135J");
+ break;
+
+ case 11:
+ getSound()->playSound(kEntityAnna, "ANN2135M");
+ break;
+
+ case 12:
+ getSound()->playSound(kEntityAnna, "ANN2135L");
+ break;
+
+ case 13:
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kActionKnock:
+ if (params->param4) {
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorHand);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorHand);
+
+ if (savepoint.param.intValue == 53) {
+ getSound()->playSound(kEntityPlayer, getSound()->justAMinuteCath());
+ } else if (getInventory()->hasItem(kItemPassengerList)) {
+ if (rnd(2)) {
+ getSound()->playSound(kEntityPlayer, getSound()->wrongDoorCath());
+ } else {
+ getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1506A" : "CAT1506");
+ }
+ } else {
+ getSound()->playSound(kEntityPlayer, getSound()->wrongDoorCath());
+ }
+
+ params->param4 = 0;
+ params->param5 = 0;
+ } else {
+ getSound()->removeFromQueue(kEntityAnna);
+
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(1);
+ setup_playSound("LIB012");
+ }
+ break;
+
+ case kActionOpenDoor:
+ getSound()->removeFromQueue(kEntityAnna);
+ setCallback(3);
+ setup_playSound("LIB013");
+ break;
+
+ case kActionDefault:
+ params->param1 = 1;
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectOutsideAnnaCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ if (getEntities()->isPlayerPosition(kCarRedSleeping, 49))
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 49);
+
+ getEntities()->drawSequenceLeft(kEntityAnna, "418C");
+
+ if (getSound()->isBuffered(kEntityAnna))
+ getSound()->processEntry(kEntityAnna);
+
+ getSound()->playSound(kEntityAnna, "ANN2135A");
+ break;
+
+ case kActionDrawScene:
+ if (params->param5 || params->param4) {
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ params->param4 = 0;
+ params->param5 = 0;
+ }
+
+ if (getEntities()->isPlayerPosition(kCarRedSleeping, 60)) {
+ ++params->param3;
+ if (params->param3 == 2) {
+ setCallback(2);
+ setup_draw("418B");
+ }
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_playSound("Ann1016");
+ break;
+
+ case 2:
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorTalk, kCursorHand);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorTalk, kCursorHand);
+ params->param4 = 1;
+ break;
+
+ case 3:
+ if (!getSound()->isBuffered(kEntityMax)) {
+ setCallback(4);
+ setup_playSound("MAX1120");
+ break;
+ }
+ // Fallback to next case
+
+ case 4:
+ --params->param1;
+ params->param6 = 1;
+ break;
+
+ case 5:
+ getEntities()->drawSequenceLeft(kEntityAnna, "418A");
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SSI(13, Anna, draw2, EntityIndex)
+ Entity::draw2(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(14, Anna, updateFromTicks, uint32)
+ Entity::updateFromTicks(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_IS(15, Anna, function15, TimeValue)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1 < getState()->time && !params->param7) {
+ params->param7 = 1;
+
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (params->param5) {
+ UPDATE_PARAM(params->param8, getState()->timeTicks, 75);
+
+ params->param5 = 0;
+ params->param6 = 1;
+
+ CursorStyle cursor = getEntities()->isInsideCompartment(kEntityMax, kCarRedSleeping, kPosition_4070) ? kCursorHand : kCursorNormal;
+
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorNormal, cursor);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorNormal, cursor);
+ }
+
+ params->param8 = 0;
+ break;
+
+ case kActionOpenDoor:
+ if (getEntities()->isInsideCompartment(kEntityMax, kCarRedSleeping, kPosition_4070)) {
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(1);
+ setup_playSound("LIB013");
+ break;
+ }
+ // Fallback to next action
+
+ case kActionKnock:
+ if (params->param5) {
+ CursorStyle cursor = getEntities()->isInsideCompartment(kEntityMax, kCarRedSleeping, kPosition_4070) ? kCursorHand : kCursorNormal;
+
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorNormal, cursor);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorNormal, cursor);
+
+ if (savepoint.param.intValue == kObject53) {
+ setCallback(6);
+ setup_playSound(getSound()->justAMinuteCath());
+ } else {
+ if (getInventory()->hasItem(kItemPassengerList)) {
+ setCallback(7);
+ setup_playSound(rnd(2) ? getSound()->wrongDoorCath() : (rnd(2) ? "CAT1506" : "CAT1506A"));
+ } else {
+ setCallback(8);
+ setup_playSound(getSound()->wrongDoorCath());
+ }
+ }
+ } else {
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(savepoint.action == kActionKnock ? 3 : 4);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ }
+ break;
+
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getEntities()->drawSequenceLeft(kEntityAnna, (char *)&params->seq);
+ break;
+
+ case kActionDrawScene:
+ if (params->param6 || params->param5) {
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ params->param5 = 0;
+ params->param6 = 0;
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (!getSound()->isBuffered(kEntityMax)) {
+ setCallback(2);
+ setup_playSound("MAX1120");
+ break;
+ }
+ // Fallback to next case
+
+ case 2:
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case 3:
+ case 4:
+ setCallback(5);
+ setup_playSound("ANN1016");
+ break;
+
+ case 5:
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorTalk, kCursorNormal);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorTalk, kCursorNormal);
+ params->param5 = 1;
+ break;
+
+ case 6:
+ case 7:
+ case 8:
+ params->param5 = 0;
+ params->param6 = 1;
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Anna, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getSavePoints()->addData(kEntityAnna, kAction291662081, 0);
+ getSavePoints()->addData(kEntityAnna, kAction238936000, 1);
+
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectOutsideAnnaCompartment, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ getData()->entityPosition = kPosition_8200;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ getData()->clothes = kClothesDefault;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(17, Anna, function17, uint32, uint32)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ getData()->inventoryItem = (params->param3 && getEntities()->isDistanceBetweenEntities(kEntityAnna, kEntityPlayer, 2000)) ? (InventoryItem)LOBYTE(params->param3) : kItemNone;
+
+ if (getEntities()->updateEntity(kEntityAnna, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ getData()->inventoryItem = kItemNone;
+ CALLBACK_ACTION();
+ }
+ break;
+
+ case kAction1:
+ if (savepoint.param.intValue == 8) {
+ getData()->inventoryItem = (InventoryItem)(getData()->inventoryItem & kItemToggleLow);
+ params->param3 &= 0xFFFFFFF7;
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAnnaGiveScarf);
+ } else {
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventGotALight);
+ }
+ break;
+
+ case kActionExcuseMeCath:
+ if (getEvent(kEventAugustPresentAnna) || getEvent(kEventAugustPresentAnnaFirstIntroduction) || getProgress().chapter >= kChapter2)
+ getSound()->playSound(kEntityPlayer, "CAT1001");
+ else
+ getSound()->excuseMeCath();
+ break;
+
+ case kActionExcuseMe:
+ getSound()->excuseMe(kEntityAnna);
+ break;
+
+ case kActionDefault:
+ if (getProgress().jacket == kJacketGreen) {
+ if (!getEvent(kEventGotALight) && !getEvent(kEventGotALightD) && !getEvent(kEventAugustPresentAnna) && !getEvent(kEventAugustPresentAnnaFirstIntroduction))
+ params->param3 = kItemInvalid;
+
+ if (!params->param3 && !getEvent(kEventAnnaGiveScarfAsk) && !getEvent(kEventAnnaGiveScarfDinerAsk) && !getEvent(kEventAnnaGiveScarfSalonAsk))
+ params->param3 |= 8;
+ }
+
+ if (getEntities()->updateEntity(kEntityAnna, (CarIndex)params->param1, (EntityPosition)params->param2))
+ CALLBACK_ACTION();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (getEvent(kEventAnnaGiveScarf)
+ || getEvent(kEventAnnaGiveScarfDiner)
+ || getEvent(kEventAnnaGiveScarfSalon)
+ || getEvent(kEventAnnaGiveScarfMonogram)
+ || getEvent(kEventAnnaGiveScarfDinerMonogram)
+ || getEvent(kEventAnnaGiveScarfSalonMonogram))
+ getAction()->playAnimation(kEventAnnaGiveScarfAsk);
+ else if (getEvent(kEventAugustPresentAnna)
+ || getEvent(kEventAugustPresentAnnaFirstIntroduction))
+ getAction()->playAnimation(kEventAnnaGiveScarfMonogram);
+ else
+ getAction()->playAnimation(kEventAnnaGiveScarf);
+
+ getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + (750 * (getData()->direction == kDirectionUp ? -1 : 1))), getData()->direction == kDirectionUp);
+ break;
+
+ case 2:
+ getAction()->playAnimation(getData()->direction == kDirectionUp ? kEventGotALightD : kEventGotALight);
+ getData()->inventoryItem = (InventoryItem)(getData()->inventoryItem & kItemToggleHigh);
+ params->param3 &= 0xFFFFFF7F;
+
+ if (getProgress().jacket == kJacketGreen && !getEvent(kEventAnnaGiveScarfAsk) && !getEvent(kEventAnnaGiveScarfDinerAsk) && !getEvent(kEventAnnaGiveScarfSalonAsk))
+ params->param3 |= 8;
+
+ getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + (750 * (getData()->direction == kDirectionUp ? -1 : 1))), getData()->direction == kDirectionUp);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(18, Anna, function18, TimeValue)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1 && params->param1 < getState()->time && getEntities()->isSomebodyInsideRestaurantOrSalon()) {
+ getData()->inventoryItem = kItemNone;
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (params->param5 && !params->param4) {
+ UPDATE_PARAM_PROC(params->param6, getState()->time, 900)
+ params->param2 |= kItemScarf;
+ params->param5 = 0;
+ params->param6 = 0;
+ UPDATE_PARAM_PROC_END
+ }
+
+ if (params->param3) {
+ UPDATE_PARAM(params->param7, getState()->timeTicks, 90);
+
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 61);
+ } else {
+ params->param7 = 0;
+ }
+ break;
+
+ case kAction1:
+ setCallback(savepoint.param.intValue == 8 ? 1 : 2);
+ setup_savegame(kSavegameTypeEvent, savepoint.param.intValue == 8 ? kEventAnnaGiveScarf : kEventDinerMindJoin);
+ break;
+
+ case kActionDefault:
+ if (getProgress().jacket == kJacketGreen) {
+ if (!getEvent(kEventDinerMindJoin) && !getEvent(kEventAugustPresentAnna) && !getEvent(kEventAugustPresentAnnaFirstIntroduction))
+ params->param2 |= kItemInvalid;
+
+ if (!params->param2 && !getEvent(kEventAnnaGiveScarfAsk) && !getEvent(kEventAnnaGiveScarfDinerAsk) && !getEvent(kEventAnnaGiveScarfSalonAsk))
+ params->param2 |= 8;
+ }
+
+ getData()->inventoryItem = (InventoryItem)LOBYTE(params->param2);
+ break;
+
+ case kActionDrawScene:
+ params->param3 = getEntities()->isPlayerPosition(kCarRestaurant, 62);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (getEvent(kEventAnnaGiveScarf) || getEvent(kEventAnnaGiveScarfDiner) || getEvent(kEventAnnaGiveScarfSalon)
+ || getEvent(kEventAnnaGiveScarfMonogram) || getEvent(kEventAnnaGiveScarfDinerMonogram) || getEvent(kEventAnnaGiveScarfSalonMonogram)) {
+ getAction()->playAnimation(kEventAnnaGiveScarfDinerAsk);
+ } else {
+ getAction()->playAnimation((getEvent(kEventAugustPresentAnna) || getEvent(kEventAugustPresentAnnaFirstIntroduction)) ? kEventAnnaGiveScarfDinerMonogram : kEventAnnaGiveScarfDiner);
+ params->param5 = 1;
+ }
+
+ params->param2 &= 0xFFFFFFF7;
+ getData()->inventoryItem = (InventoryItem)params->param2;
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 61);
+ break;
+
+ case 2:
+ getAction()->playAnimation(kEventDinerMindJoin);
+
+ params->param2 &= 0xFFFFFFF7;
+
+ if (getProgress().jacket == kJacketGreen
+ && !getEvent(kEventAnnaGiveScarfAsk)
+ && !getEvent(kEventAnnaGiveScarfDinerAsk)
+ && !getEvent(kEventAnnaGiveScarfSalonAsk)) {
+ params->param2 |= 8;
+ }
+
+ getData()->inventoryItem = (InventoryItem)LOBYTE(params->param2);
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 61);
+ break;
+ }
+ break;
+
+ case kAction168046720:
+ getData()->inventoryItem = kItemNone;
+ params->param4 = 1;
+ break;
+
+ case kAction168627977:
+ getData()->inventoryItem = (InventoryItem)LOBYTE(params->param2);
+ params->param4 = 0;
+ break;
+
+ case kAction170016384:
+ case kAction259136835:
+ case kAction268773672:
+ getData()->inventoryItem = kItemNone;
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Anna, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_enterExitCompartment("618Ca", kObjectCompartment1);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->entityPosition = kPosition_8514;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_4070);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_enterExitCompartment("618Af", kObjectCompartmentF);
+ break;
+
+ case 3:
+ getEntities()->clearSequences(kEntityAnna);
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+
+ setup_function20();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Anna, function20)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function15(kTime1093500, "NONE");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("618Bf", kObjectCompartmentF);
+ break;
+
+ case 2:
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityAnna, kEntityMax, kAction71277948);
+ setup_function21();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Anna, function21)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function17(kCarRestaurant, kPosition_850);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 2:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(3);
+ setup_draw("801US");
+ break;
+
+ case 3:
+ getEntities()->drawSequenceRight(kEntityAnna, "001B");
+ if (getEntities()->isInSalon(kEntityPlayer))
+ getEntities()->updateFrame(kEntityAnna);
+
+ setCallback(4);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 4:
+ setup_function22();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Anna, function22)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityAnna, "001A");
+ getSavePoints()->push(kEntityAnna, kEntityPascale, kAction223262556);
+ break;
+
+ case kAction157370960:
+ getData()->location = kLocationInsideCompartment;
+ setup_function23();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Anna, function23)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityAnna, "001D");
+ getSavePoints()->push(kEntityAnna, kEntityServers0, kAction270410280);
+ getSavePoints()->push(kEntityAnna, kEntityTables0, kAction136455232);
+
+ setCallback(1);
+ setup_function18(kTimeNone);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceLeft(kEntityAnna, "001E");
+ setCallback(2);
+ setup_playSound("ANN1048");
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_draw("001F");
+ break;
+
+ case 3:
+ getSavePoints()->push(kEntityAnna, kEntityServers0, kAction203859488);
+ setup_function24();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Anna, function24)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityAnna, "001G");
+
+ setCallback(1);
+ setup_function18(kTimeNone);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceLeft(kEntityAnna, "001H");
+ setCallback(2);
+ setup_playSound("ANN1049");
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityAnna, kEntityServers0, kAction136702400);
+ setup_function25();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, Anna, function25)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityAnna, "001J");
+ getProgress().field_28 = 1;
+
+ setCallback(1);
+ setup_function18(kTimeNone);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 2:
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 3:
+ setup_function26();
+ break;
+ }
+ break;
+
+ case kAction122358304:
+ getEntities()->drawSequenceLeft(kEntityAnna, "BLANK");
+ break;
+
+ case kAction201437056:
+ getEntities()->drawSequenceLeft(kEntityAnna, "001J");
+ setCallback(2);
+ setup_function18(kTime1138500);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(26, Anna, function26)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->location = kLocationOutsideCompartment;
+ getEntities()->updatePositionExit(kEntityAnna, kCarRestaurant, 62);
+
+ setCallback(1);
+ setup_callSavepoint("001L", kEntityTables0, kActionDrawTablesWithChairs, "001H");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->updatePositionExit(kEntityAnna, kCarRestaurant, 62);
+ getSavePoints()->push(kEntityAnna, kEntityServers0, kAction237485916);
+ getEntities()->drawSequenceRight(kEntityAnna, "801DS");
+
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityAnna);
+
+ setCallback(2);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function17(kCarRedSleeping, kPosition_4070);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_enterExitCompartment("618Af", kObjectCompartmentF);
+ break;
+
+ case 4:
+ getEntities()->clearSequences(kEntityAnna);
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+
+ setup_function27();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(27, Anna, function27)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityAnna, kEntityMax, kAction101687594);
+ setCallback(1);
+ setup_function15(kTime1156500, "NONE");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ if (getProgress().field_14 == 29) {
+ params->param1 = getState()->time + 900;
+ setCallback(2);
+ setup_function15((TimeValue)params->param1, "NONE");
+ } else {
+ setCallback(3);
+ setup_enterExitCompartment("618Bf", kObjectCompartmentF);
+ }
+ break;
+
+ case 3:
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityAnna, kEntityMax, kAction71277948);
+ setup_function28();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(28, Anna, function28)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function17(kCarRestaurant, kPosition_850);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 2:
+ getData()->location = kLocationOutsideCompartment;
+ getData()->entityPosition = kPosition_1540;
+ getScenes()->loadSceneFromItemPosition(kItem3);
+
+ setCallback(3);
+ setup_updatePosition("104A", kCarRestaurant, 56);
+ break;
+
+ case 3:
+ getData()->location = kLocationInsideCompartment;
+ setup_function29();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(29, Anna, function29)
+ error("Anna: callback function 29 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(30, Anna, function30)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param3 != kTimeInvalid && getState()->time) {
+ if (getState()->time > kTime1188000) {
+ params->param3 = kTimeInvalid;
+ getSound()->playSound(kEntityAnna, "AUG1004");
+ } else {
+ if (!getEntities()->isInSalon(kEntityPlayer) || !params->param3)
+ params->param3 = getState()->time + 450;
+
+ if (params->param3 < getState()->time) {
+ params->param3 = kTimeInvalid;
+ getSound()->playSound(kEntityAnna, "AUG1004");
+ }
+ }
+ }
+
+ if (params->param2 && params->param4 != kTimeInvalid && getState()->time > kTime1179000) {
+
+ if (getState()->time > kTime1192500) {
+ params->param4 = kTimeInvalid;
+ setup_function30();
+ break;
+ }
+
+ if (!getEntities()->isInSalon(kEntityPlayer) || !params->param4)
+ params->param4 = getState()->time + 150;
+
+ if (params->param4 < getState()->time) {
+ params->param4 = kTimeInvalid;
+ setup_function30();
+ break;
+ }
+ }
+
+ if (params->param1) {
+ UPDATE_PARAM(params->param5, getState()->timeTicks, 90);
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 55);
+ } else {
+ params->param5 = 0;
+ }
+ break;
+
+ case kActionEndSound:
+ params->param2 = 1;
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityAnna, kEntityAugust, kAction122358304);
+ getEntities()->drawSequenceLeft(kEntityAnna, "106B");
+ break;
+
+ case kActionDrawScene:
+ params->param1 = getEntities()->isPlayerPosition(kCarRestaurant, 56);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(31, Anna, function31)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ getSound()->playSound(kEntityAnna, "AUG1005");
+
+ setCallback(2);
+ setup_updateFromTicks(150);
+ break;
+
+ case 2:
+ getEntities()->updatePositionEnter(kEntityAnna, kCarRestaurant, 56);
+
+ setCallback(3);
+ setup_draw2("106C1", "106C2", kEntityAugust);
+ break;
+
+ case 3:
+ getEntities()->updatePositionExit(kEntityAnna, kCarRestaurant, 56);
+ getInventory()->setLocationAndProcess(kItem3, kObjectLocation1);
+ getSavePoints()->push(kEntityAnna, kEntityAugust, kAction159332865);
+
+ setup_function32();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(32, Anna, function32)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function17(kCarRedSleeping, kPosition_4070);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("618Af", kObjectCompartmentF);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityAnna);
+
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+
+ setup_function33();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(33, Anna, function33)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityAnna, kEntityMax, kAction101687594);
+
+ params->param1 = getState()->time + 4500;
+ setCallback(1);
+ setup_function15((TimeValue)params->param1, "NONE");
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getObjects()->updateLocation2(kObjectCompartmentF, kObjectLocation1);
+ setup_function34();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(34, Anna, function34)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1 && getEntities()->isPlayerPosition(kCarRedSleeping, 60)) {
+ UPDATE_PARAM_PROC(params->param2, getState()->time, 150)
+ setCallback(1);
+ setup_draw("419B");
+ break;
+ UPDATE_PARAM_PROC_END
+ }
+
+label_callback_1:
+ TIME_CHECK(kTime1489500, params->param3, setup_function35);
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(savepoint.action == kActionKnock ? 2 : 3);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectOutsideAnnaCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ if (getEntities()->isPlayerPosition(kCarRedSleeping, 78))
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 49);
+
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationOutsideCompartment;
+
+ getEntities()->drawSequenceLeft(kEntityAnna, "419A");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceLeft(kEntityAnna, "419C");
+ params->param1 = 1;
+ goto label_callback_1;
+
+ case 2:
+ case 3:
+ if (!getSound()->isBuffered(kEntityMax)) {
+ setCallback(4);
+ setup_playSound("MAX1120");
+ break;
+ }
+ // Fallback to next case
+
+ case 4:
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(35, Anna, function35)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1)
+ break;
+
+ UPDATE_PARAM(params->param3, getState()->timeTicks, 75);
+
+ switch (params->param2) {
+ default:
+ break;
+
+ case 0:
+ getSound()->playSound(kEntityAnna, "ANN2135E");
+ break;
+
+ case 1:
+ getSound()->playSound(kEntityAnna, "ANN2135F");
+ break;
+
+ case 2:
+ getSound()->playSound(kEntityAnna, "ANN2135G");
+ break;
+
+ case 3:
+ getSound()->playSound(kEntityAnna, "ANN2135D");
+ break;
+ }
+
+ params->param1 = 0;
+ params->param3 = 0;
+ break;
+
+ case kActionEndSound:
+ ++params->param2;
+
+ if (params->param2 > 3)
+ params->param2 = 0;
+
+ params->param1 = 1;
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ if (getSound()->isBuffered(kEntityAnna))
+ getSound()->processEntry(kEntityAnna);
+
+ if (savepoint.action == kActionKnock)
+ getSound()->playSound(kEntityPlayer, "LIB012");
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAnnaVisitToCompartmentGun);
+ break;
+
+ case kActionDefault:
+ getData()->clothes = kClothes1;
+ params->param1 = 1;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventAnnaVisitToCompartmentGun);
+ getSound()->playSound(kEntityPlayer, "LIB015");
+ getData()->location = kLocationOutsideCompartment;
+ getData()->entityPosition = kPosition_4840;
+
+ getEntities()->updateEntity(kEntityAnna, kCarRedSleeping, kPosition_8200);
+ getScenes()->loadSceneFromObject(kObjectCompartmentF, true);
+ getSavePoints()->push(kEntityAnna, kEntityVassili, kAction339669520);
+ getSavePoints()->push(kEntityAnna, kEntityVerges, kAction339669520);
+ getSavePoints()->push(kEntityAnna, kEntityCoudert, kAction339669520);
+ getSavePoints()->push(kEntityAnna, kEntityMax, kAction71277948);
+
+ setup_function36();
+ break;
+
+ case 2:
+ setup_function36();
+ break;
+ }
+ break;
+
+ case kAction226031488:
+ if (getSound()->isBuffered(kEntityAnna))
+ getSound()->processEntry(kEntityAnna);
+
+ getSavePoints()->push(kEntityAnna, kEntityMax, kAction71277948);
+ break;
+
+ case kAction238358920:
+ setCallback(2);
+ setup_enterExitCompartment("608Cf", kObjectCompartmentF);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(36, Anna, function36)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_8200);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(2);
+ setup_enterExitCompartment("608Aa", kObjectCompartmentA);
+ break;
+
+ case 2:
+ getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityAnna);
+
+ setup_function37();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(37, Anna, function37)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_8200;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRedSleeping;
+ break;
+
+ case kAction191477936:
+ setup_function38();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(38, Anna, function38)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_7500;
+
+ setCallback(1);
+ setup_playSound("ANN1010");
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getSound()->playSound(kEntityPlayer, "MUS043");
+ setup_function40();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(39, Anna, function39, CarIndex, EntityPosition)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->updateEntity(kEntityAnna, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ getData()->inventoryItem = kItemNone;
+
+ CALLBACK_ACTION();
+ }
+ break;
+
+ case kAction1:
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAnnaGoodNight);
+ break;
+
+ case kActionExcuseMe:
+ getSound()->playSound(kEntityAnna, "ANN1107A");
+ break;
+
+ case kActionDefault:
+ getData()->inventoryItem = kItemNone;
+ if (!getEvent(kEventAnnaGoodNight) && !getEvent(kEventAnnaGoodNightInverse))
+ getData()->inventoryItem = kItemInvalid;
+
+ if (getEntities()->updateEntity(kEntityAnna, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ getData()->inventoryItem = kItemNone;
+
+ CALLBACK_ACTION();
+ }
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(getData()->direction == kDirectionNone ? kEventAnnaGoodNight : kEventAnnaGoodNightInverse);
+ getData()->inventoryItem = kItemNone;
+
+ getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + (750 * (getData()->direction == kDirectionUp ? -1 : 1))), getData()->direction == kDirectionUp);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(40, Anna, function40)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_enterExitCompartment("608Cb", kObjectCompartmentB);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_function39(kCarRedSleeping, kPosition_4070);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_enterExitCompartment("608Bf", kObjectCompartmentF);
+ break;
+
+ case 3:
+ getEntities()->clearSequences(kEntityAnna);
+ getData()->location = kLocationInsideCompartment;
+
+ setCallback(4);
+ setup_updateFromTime(150);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_enterExitCompartment("608Cf", kObjectCompartmentF);
+ break;
+
+ case 5:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(6);
+ setup_function39(kCarRedSleeping, kPosition_7500);
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_enterExitCompartment("608Bb", kObjectCompartmentB);
+ break;
+
+ case 7:
+ getEntities()->clearSequences(kEntityAnna);
+ getData()->location = kLocationInsideCompartment;
+
+ setCallback(8);
+ setup_updateFromTime(150);
+ break;
+
+ case 8:
+ setCallback(9);
+ setup_enterExitCompartment("608Cb", kObjectCompartmentB);
+ break;
+
+ case 9:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(10);
+ setup_function39(kCarRedSleeping, kPosition_4070);
+ break;
+
+ case 10:
+ setCallback(11);
+ setup_enterExitCompartment("608Bf", kObjectCompartmentF);
+ break;
+
+ case 11:
+ getEntities()->clearSequences(kEntityAnna);
+ getData()->location = kLocationInsideCompartment;
+ getData()->entityPosition = kPosition_4070;
+
+ setup_function41();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(41, Anna, function41)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param2, getState()->time, 2700);
+
+ params->param5++;
+ switch (params->param5) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceLeft(kEntityAnna, "419A");
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityAnna, "419B");
+ break;
+
+ case 3:
+ getEntities()->drawSequenceLeft(kEntityAnna, "419C");
+ params->param1 = 0;
+ break;
+ }
+
+ params->param2 = 0;
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(savepoint.action == kActionKnock ? 1 : 2);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityAnna, kEntityMax, kAction101687594);
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getEntities()->drawSequenceLeft(kEntityAnna, "419C");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ if (!getSound()->isBuffered(kEntityMax)) {
+ setCallback(3);
+ setup_playSound("MAX1120");
+ break;
+ }
+ // Fallback to next case
+
+ case 3:
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(42, Anna, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter2Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAnna);
+
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothes1;
+ getData()->inventoryItem = kItemNone;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(43 ,Anna, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectOutsideAnnaCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(1);
+ setup_function12();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function15(kTime1786500, "418C");
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function12();
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function15(kTime1818000, "418C");
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_function12();
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_function15(kTimeEnd, "418C");
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(44, Anna, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAnna);
+
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothes3;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectOutsideAnnaCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ getObjects()->update(kObject53, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(45, Anna, function45, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_enterExitCompartment("625Bf", kObjectCompartmentF);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityAnna, kEntityCoudert, params->param1 ? kAction185737168 : kAction185671840);
+ getSound()->playSound(kEntityAnna, "Ann3147");
+ getEntities()->drawSequenceLeft(kEntityAnna, "625EF");
+ getEntities()->enterCompartment(kEntityAnna, kObjectCompartmentF, true);
+ break;
+
+ case 2:
+ getEntities()->exitCompartment(kEntityAnna, kObjectCompartmentF, true);
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction157894320:
+ setCallback(2);
+ setup_updateFromTime(75);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(46, Anna, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (getEntities()->isPlayerPosition(kCarRedSleeping, 60))
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 49);
+
+ setCallback(1);
+ setup_function12();
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1 || getCallback() == 2) {
+ if (ENTITY_PARAM(0, 1)) {
+ setup_function47();
+ } else {
+ setCallback(2);
+ setup_function15((TimeValue)(getState()->time + 4500), "418C");
+ }
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(47, Anna, function47)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ setCallback(1);
+ setup_enterExitCompartment("688Bf", kObjectCompartmentF);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityAnna, kEntityMax, kAction71277948);
+
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(4);
+ setup_draw("801VS");
+ break;
+
+ case 4:
+ getSound()->playSound(kEntityAnna, getEvent(kEventAugustLunch) ? "Ann3136" : "Ann3136A", SoundManager::kFlagInvalid, 30);
+ getSavePoints()->push(kEntityAnna, kEntityAugust, kAction122358304);
+
+ setCallback(5);
+ setup_draw2("026B1", "026B2", kEntityAugust);
+ break;
+
+ case 5:
+ getEntities()->drawSequenceLeft(kEntityAugust, "BLANK");
+ setup_function48();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(48, Anna, function48)
+ error("Anna: callback function 48 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(49, Anna, leaveTableWithAugust)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ getSavePoints()->push(kEntityAnna, kEntityTables3, kActionDrawTablesWithChairs, "010M");
+ getEntities()->clearSequences(kEntityAugust);
+
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(kEntityTables3, "026J3");
+ getEntities()->drawSequenceRight(kEntityAugust, "026J2");
+ getEntities()->drawSequenceRight(kEntityAnna, "026J1");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(50, Anna, function50)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_playSound("ann3141");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 2:
+ getData()->location = kLocationOutsideCompartment;
+ setCallback(3);
+ setup_leaveTableWithAugust();
+ break;
+
+ case 3:
+ setup_function51();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(51, Anna, function51)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1) {
+ if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
+ getSound()->playSound(kEntityAnna, "Aug3008");
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_draw2("112E1", "112E2", kEntityAugust);
+ }
+ }
+ break;
+
+ case kActionDefault:
+ getSound()->playSound(kEntityAnna, "Aug3142", SoundManager::kFlagInvalid, 30);
+ getEntities()->updatePositionEnter(kEntityAnna, kCarRestaurant, 57);
+ getEntities()->drawSequenceRight(kEntityAnna, "112A");
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityAnna);
+
+ setCallback(1);
+ setup_callbackActionOnDirection();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->drawSequenceLeft(kEntityAnna, "112B");
+ getEntities()->updatePositionExit(kEntityAnna, kCarRestaurant, 57);
+ getSavePoints()->push(kEntityAnna, kEntityServers1, kAction219377792);
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityAnna, kEntityAugust, kAction122288808);
+
+ setup_function52();
+ break;
+
+ case 3:
+ getEntities()->drawSequenceLeft(kEntityAnna, "112D");
+
+ if (getState()->time >= kTimeEnterAttnangPuchheim) {
+ params->param1 = 1;
+ } else {
+ setCallback(4);
+ setup_playSound("Ann3142A");
+ }
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_updateFromTime(1800);
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_playSound("Aug3007");
+ break;
+
+ case 6:
+ params->param1 = 1;
+ break;
+ }
+ break;
+
+ case kAction101169422:
+ if (getEvent(kEventKronosVisit)) {
+ setCallback(3);
+ setup_updatePosition("112J", kCarRestaurant, 57);
+ break;
+ }
+
+ if (getState()->time >= kTimeEnterAttnangPuchheim) {
+ params->param1 = 1;
+ } else {
+ setCallback(4);
+ setup_playSound("Ann3142A");
+ }
+ break;
+
+ case kAction122288808:
+ getEntities()->drawSequenceLeft(kEntityAnna, "112D");
+ getSavePoints()->push(kEntityAnna, kEntityKronos, kAction157159392);
+ break;
+
+ case kAction122358304:
+ getEntities()->drawSequenceLeft(kEntityAnna, "BLANK");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(52, Anna, function52)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ getEntities()->exitCompartment(kEntityAnna, kObjectCompartmentF);
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+
+ getEntities()->clearSequences(kEntityAnna);
+
+ setup_function53();
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_4070);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getEntities()->drawSequenceRight(kEntityAnna, "688Af");
+ getEntities()->enterCompartment(kEntityAnna, kObjectCompartmentF);
+ getData()->location = kLocationInsideCompartment;
+
+ if (getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_4070) || getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_4455)) {
+ getAction()->playAnimation(isNight() ? kEventCathTurningNight : kEventCathTurningDay);
+ getSound()->playSound(kEntityPlayer, "BUMP");
+ getScenes()->loadSceneFromObject(kObjectCompartmentF);
+ }
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(53, Anna, function53)
+ error("Anna: callback function 53 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(54, Anna, function54)
+ error("Anna: callback function 54 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(55, Anna, function55)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectOutsideAnnaCompartment, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+
+ if (getEntities()->isPlayerPosition(kCarRedSleeping, 78))
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 49);
+
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject53, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getInventory()->setLocationAndProcess(kItemKey, kObjectLocation1);
+
+ setCallback(1);
+ setup_function45(true);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_9270);
+ break;
+
+ case 2:
+ setup_function56();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(56, Anna, function56)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAnna);
+ getData()->entityPosition = kPosition_6000;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarKronos;
+ break;
+
+ case kAction191668032:
+ setup_function57();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(57, Anna, function57)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarGreenSleeping;
+ getData()->entityPosition = kPosition_850;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_5790);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityAnna, kEntityAugust, kAction191668032);
+
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_4070);
+ break;
+
+ case 2:
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getSavePoints()->push(kEntityAnna, kEntityCoudert, kAction205033696);
+ getEntities()->drawSequenceLeft(kEntityAnna, "625Ef");
+ getEntities()->enterCompartment(kEntityAnna, kObjectCompartmentF, true);
+ break;
+
+ case 3:
+ getEntities()->drawSequenceLeft(kEntityAnna, "625Gf");
+ getEntities()->enterCompartment(kEntityAnna, kObjectCompartmentF, true);
+ getSavePoints()->push(kEntityAnna, kEntityAugust, kAction169032608);
+ break;
+
+ case 4:
+ if (getSound()->isBuffered(kEntityAugust)) {
+ setCallback(4);
+ setup_updateFromTime(75);
+ } else {
+ setCallback(5);
+ setup_playSound("Aug3009");
+ }
+ break;
+
+ case 5:
+ getSound()->playSound(kEntityAnna, "Aug3009A");
+
+ setCallback(6);
+ setup_enterExitCompartment("628Bf", kObjectCompartmentF);
+ break;
+
+ case 6:
+ getEntities()->exitCompartment(kEntityAnna, kObjectCompartmentF, true);
+ getSavePoints()->push(kEntityAnna, kEntityAugust, kAction122288808);
+
+ setup_function59();
+ break;
+ }
+ break;
+
+ case kAction123712592:
+ getEntities()->drawSequenceLeft(kEntityAnna, "628Af");
+
+ if (getSound()->isBuffered(kEntityAugust)) {
+ setCallback(4);
+ setup_updateFromTime(75);
+ } else {
+ setCallback(5);
+ setup_playSound("Aug3009");
+ }
+ break;
+
+ case kAction192063264:
+ if (getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_4070)
+ || getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_4455)) {
+ getEntities()->exitCompartment(kEntityAnna, kObjectCompartmentF, true);
+ setup_function58();
+ } else {
+ setCallback(3);
+ setup_enterExitCompartment("625Ff", kObjectCompartmentF);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(58, Anna, function58)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAnnaSearchingCompartment);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventAnnaSearchingCompartment);
+ getEntities()->clearSequences(kEntityAnna);
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 8);
+ getSound()->playSound(kEntityAnna, "lib015");
+ getSavePoints()->push(kEntityAnna, kEntityAugust, kAction122288808);
+ setup_function59();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(59, Anna, function59)
+ error("Anna: callback function 59 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(60, Anna, function60)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityAnna, kEntityMax, kAction122358304);
+ getSound()->playSound(kEntityAnna, rnd(2) ? "Ann3126" : "Ann3127");
+
+ setCallback(1);
+ setup_enterExitCompartment("630Cf", kObjectCompartmentF);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("630Df", kObjectCompartmentF);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityAnna);
+ getSavePoints()->push(kEntityAnna, kEntityCoudert, kAction189026624);
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityAnna);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction156049968:
+ setCallback(3);
+ setup_enterExitCompartment("629EF", kObjectCompartmentF);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(61, Anna, function61)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getState()->timeDelta = 3;
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeIndex, 0);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObject53, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ setCallback(2);
+ setup_function45(false);
+ break;
+
+ case 2:
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ setCallback(3);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 4:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(5);
+ setup_draw("802US");
+ break;
+
+ case 5:
+ getEntities()->drawSequenceRight(kEntityAnna, "802UD");
+ if (getEntities()->isInSalon(kEntityPlayer))
+ getEntities()->updateFrame(kEntityAnna);
+
+ setCallback(6);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 6:
+ getEntities()->clearSequences(kEntityAnna);
+ setup_function62();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(62, Anna, function62)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime2259000 && !params->param2) {
+ params->param2 = 1;
+ getSavePoints()->push(kEntityAnna, kEntityVesna, kAction189299008);
+ setup_function63();
+ }
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarBaggage;
+ getProgress().field_54 = 1;
+ break;
+
+ case kAction235856512:
+ params->param1 = 1;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(63, Anna, function63)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityAnna, kEntityChapters, kAction171843264);
+ break;
+
+ // Game over with Anna killed!
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventAnnaKilled);
+ getLogic()->gameOver(kSavegameTypeTime, kTime2250000, kSceneGameOverAnnaDied, true);
+ }
+ break;
+
+ // Anna will get killed...
+ case kAction272177921:
+ if (getSound()->isBuffered("MUS012"))
+ getSound()->processEntry("MUS012");
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAnnaKilled);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(64, Anna, baggage)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAnna);
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAnnaBaggageArgument);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventAnnaBaggageArgument);
+
+ setCallback(2);
+ setup_savegame(kSavegameTypeTime, (EventIndex)kTimeNone);
+ break;
+
+ case 2:
+ params->param1 = getFight()->setup(kFightAnna);
+
+ if (params->param1)
+ getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, params->param1 == Fight::kFightEndLost);
+ else {
+ getState()->time += 1800;
+
+ setCallback(3);
+ setup_savegame(kSavegameTypeEvent, kEventAnnaBagagePart2);
+ }
+ break;
+
+ case 3:
+ getAction()->playAnimation(kEventAnnaBagagePart2);
+ getScenes()->loadSceneFromPosition(kCarBaggage, 96);
+
+ getProgress().field_54 = 0;
+ getState()->time = kTime2266200;
+
+ setup_function65();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(65, Anna, function65)
+ if (savepoint.action == kActionDefault) {
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothes3;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObjectOutsideAnnaCompartment, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(1);
+ setup_function15(kTimeEnd, "NONE");
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(66, Anna, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAnna);
+
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothes2;
+ getData()->inventoryItem = kItemNone;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(67, Anna, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isPlayerPosition(kCarRedSleeping, 46)) {
+ UPDATE_PARAM_GOTO(params->param4, getState()->timeTicks, 30, label_next);
+
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 8);
+ }
+
+ params->param4 = 0;
+
+label_next:
+ if (params->param1) {
+ UPDATE_PARAM(params->param5, getState()->timeTicks, 75);
+
+ params->param1 = 0;
+ params->param2 = 1;
+
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorNormal, getEntities()->isInsideCompartment(kEntityMax, kCarRedSleeping, kPosition_4070) ? kCursorHand : kCursorNormal);
+ }
+
+ params->param5 = 0;
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+ getData()->location = kLocationInsideCompartment;
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAnnaConversation_34);
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ if (params->param1) {
+ setCallback(5);
+ setup_playSound(getSound()->justAMinuteCath());
+ } else {
+ setCallback(savepoint.action == kActionKnock ? 2 : 3);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ }
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocation2, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectOutsideAnnaCompartment, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getEntities()->drawSequenceLeft(kEntityAnna, "511B");
+ break;
+
+ case kActionDrawScene:
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ params->param1 = 0;
+ params->param2 = 0;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventAnnaConversation_34);
+ getSound()->playSound(kEntityPlayer, "LIB015");
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 8);
+
+ setup_function68();
+ break;
+
+ case 2:
+ case 3:
+ setCallback(4);
+ setup_playSound("ANN1016");
+ break;
+
+ case 4:
+ getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorTalk, kCursorNormal);
+ params->param1 = 1;
+ break;
+
+ case 5:
+ params->param1 = 0;
+ params->param2 = 1;
+ break;
+ }
+ break;
+
+ case kAction191001984:
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getData()->inventoryItem = kItemNone;
+
+ setup_function69();
+ break;
+
+ case kAction219971920:
+ params->param3 = 1;
+ getData()->inventoryItem = kItemInvalid;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(68, Anna, function68)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1) {
+ setCallback(1);
+ setup_function15(kTime2511900, "NONE");
+ }
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+ break;
+
+ case kAction191001984:
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ setup_function69();
+ break;
+
+ case kAction201431954:
+ params->param1 = 1;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(69, Anna, function69)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1) {
+ UPDATE_PARAM(params->param2, getState()->time, 4500);
+
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_9270;
+ getData()->location = kLocationOutsideCompartment;
+
+ setup_function70();
+ break;
+ }
+
+ TIME_CHECK_CALLBACK(kTime2535300, params->param3, 4, setup_callbackActionRestaurantOrSalon);
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case kActionDrawScene:
+ if (params->param1 && getEntities()->isInsideTrainCar(kEntityPlayer, kCarRedSleeping)) {
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_8200;
+ getData()->location = kLocationOutsideCompartment;
+
+ setup_function70();
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 2:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(3);
+ setup_updatePosition("127A", kCarRestaurant, 56);
+ break;
+
+ case 3:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->drawSequenceLeft(kEntityAnna, "127B");
+ getSavePoints()->push(kEntityAnna, kEntityServers1, kAction258136010);
+ break;
+
+ case 4:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(5);
+ setup_updatePosition("127G", kCarRestaurant, 56);
+ break;
+
+ case 5:
+ setup_function70();
+ break;
+ }
+ break;
+
+ case kAction100969180:
+ getEntities()->clearSequences(kEntityAnna);
+ params->param1 = 1;
+
+ case kAction122288808:
+ getEntities()->drawSequenceLeft(kEntityAnna, "127E");
+ getSavePoints()->push(kEntityAnna, kEntityAbbot, kAction203073664);
+ break;
+
+ case kAction122358304:
+ getEntities()->drawSequenceLeft(kEntityAnna, "BLANK");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(70, Anna, function70)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function72(kCarRedSleeping, kPosition_4070);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function71();
+ break;
+
+ case 2:
+ getData()->location = kLocationOutsideCompartment;
+ getEntities()->clearSequences(kEntityAnna);
+ setup_function73();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(71, Anna, function71)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ getEntities()->exitCompartment(kEntityAnna, kObjectCompartmentF);
+ getData()->entityPosition = kPosition_4070;
+
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(kEntityAnna, "625Af");
+
+ if (getEntities()->isPlayerPosition(kCarRedSleeping, 7)
+ || getEntities()->isPlayerPosition(kCarRedSleeping, 28)
+ || getEntities()->isPlayerPosition(kCarRedSleeping, 56))
+ getScenes()->loadScene(getScenes()->processIndex(getState()->scene));
+
+ getEntities()->enterCompartment(kEntityAnna, kObjectCompartmentF);
+
+ getData()->location = kLocationInsideCompartment;
+
+ if (getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_4070)
+ || getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_4455)) {
+ getAction()->playAnimation(isNight() ? kEventCathTurningNight : kEventCathTurningDay);
+ getSound()->playSound(kEntityPlayer, "BUMP");
+ getScenes()->loadSceneFromObject(kObjectCompartmentF, true);
+ }
+ break;
+
+ case kActionDrawScene:
+ if (!getEvent(kEventAnnaTiredKiss)
+ && getEntities()->isDistanceBetweenEntities(kEntityPlayer, kEntityAnna, 2000)
+ && getEntities()->hasValidFrame(kEntityAnna)
+ && getData()->entityPosition < getEntityData(kEntityPlayer)->entityPosition) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAnnaTiredKiss);
+ }
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventAnnaTiredKiss);
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 29);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(72, Anna, function72, CarIndex, EntityPosition)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEvent(kEventAnnaTired) || getEntities()->isWalkingOppositeToPlayer(kEntityAnna))
+ getData()->inventoryItem = kItemNone;
+ else
+ getData()->inventoryItem = kItemInvalid;
+
+ if (getEntities()->updateEntity(kEntityAnna, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ getData()->inventoryItem = kItemNone;
+ CALLBACK_ACTION();
+ }
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAnnaTired);
+ break;
+
+ case kActionDefault:
+ if (getEntities()->updateEntity(kEntityAnna, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ CALLBACK_ACTION();
+ } else if (!getEvent(kEventAnnaTired))
+ getData()->inventoryItem = kItemInvalid;
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventAnnaTired);
+
+ getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + (750 * (getData()->direction == kDirectionUp ? -1 : 1))), getData()->direction == kDirectionUp);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(73, Anna, function73)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param3 == kTimeInvalid || params->param1 >= getState()->time)
+ break;
+
+ if (params->param2 >= getState()->time) {
+ if (!((getEntities()->isPlayerInCar(kCarGreenSleeping) || getEntities()->isPlayerInCar(kCarRedSleeping)) && params->param3))
+ params->param3 = getState()->time;
+
+ if (params->param3 >= getState()->time)
+ break;
+ }
+
+ params->param3 = kTimeInvalid;
+
+ if (!getEntities()->isPlayerInCar(kCarGreenSleeping) && !getEntities()->isPlayerInCar(kCarRedSleeping))
+ getSound()->playSound(kEntityPlayer, "BUMP");
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventTrainHijacked);
+ break;
+
+ case kActionKnock:
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocationNone, kCursorNormal, kCursorNormal);
+
+ setCallback(2);
+ setup_playSound("LIB012");
+ break;
+
+ case kActionOpenDoor:
+ setCallback(4);
+ setup_savegame(kSavegameTypeEvent, kEventAnnaKissTrainHijacked);
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getState()->timeDelta = 1;
+
+ params->param1 = getState()->time + 4500;
+ params->param2 = getState()->time + 9000;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventTrainHijacked);
+ getSavePoints()->push(kEntityAnna, kEntityChapters, kAction139254416);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_playSound("Ann4200");
+ break;
+
+ case 3:
+ getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ break;
+
+ case 4:
+ getAction()->playAnimation(kEventAnnaKissTrainHijacked);
+ getSavePoints()->push(kEntityAnna, kEntityChapters, kAction139254416);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(74, Anna, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAnna);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarBaggageRear;
+ getData()->clothes = kClothes3;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObjectOutsideAnnaCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(75, Anna, chapter5Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ if (getProgress().field_C)
+ getAction()->playAnimation(getEvent(kEventAnnaKissTrainHijacked) ? kEventAnnaBaggageTies2 : kEventAnnaBaggageTies);
+ else
+ getAction()->playAnimation(getEvent(kEventAnnaKissTrainHijacked) ? kEventAnnaBaggageTies3 : kEventAnnaBaggageTies4);
+
+ getScenes()->loadSceneFromPosition(kCarBaggage, 8);
+ setup_function76();
+ }
+ break;
+
+ case kAction272177921:
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAnnaBaggageTies);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(76, Anna, function76)
+ if (savepoint.action == kAction158480160)
+ setup_function77();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(77, Anna, function77)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime3645000 && !params->param2) {
+ params->param2 = 1;
+ getState()->timeDelta = 0;
+ }
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ getSound()->playSound(kEntityPlayer, savepoint.action == kActionKnock ? "LIB012" : "LIB014");
+
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventAnnaDialogGoToJerusalem);
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObject106, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionDrawScene:
+ if (!params->param1 && getEntities()->isInsideTrainCar(kEntityPlayer, kCarBaggage)) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeTime, kTimeNone);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ params->param1 = 1;
+ break;
+
+ case 2:
+ getObjects()->update(kObject106, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getAction()->playAnimation(kEventAnnaDialogGoToJerusalem);
+
+ getState()->time = kTimeCityConstantinople;
+ getState()->timeDelta = 0;
+
+ getSavePoints()->push(kEntityAnna, kEntityTatiana, kAction236060709);
+
+ getScenes()->loadSceneFromPosition(kCarBaggage, 97, 1);
+
+ setCallback(3);
+ setup_savegame(kSavegameTypeTime, kTimeNone);
+ break;
+
+ case 3:
+ setup_function78();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(78, Anna, function78)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDrawScene:
+ if ((getEntities()->isInRestaurant(kEntityPlayer) || getEntities()->isInSalon(kEntityPlayer)) && getInventory()->hasItem(kItemFirebird)) {
+ setup_function80();
+ break;
+ }
+
+ getState()->time = kTimeInvalid2;
+
+ setCallback(getInventory()->get(kItemFirebird)->location == kObjectLocation4 ? 2 : 1);
+ setup_savegame(kSavegameTypeEvent, getInventory()->get(kItemFirebird)->location == kObjectLocation4 ? kEventKronosHostageAnna : kEventKronosHostageAnnaNoFirebird);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventKronosHostageAnnaNoFirebird);
+ getLogic()->gameOver(kSavegameTypeEvent2, kEventAugustUnhookCarsBetrayal, kSceneNone, true);
+ break;
+
+ case 2:
+ getAction()->playAnimation(kEventKronosHostageAnna);
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 61);
+ getSound()->playSound(kEntityAnna, "Mus024", SoundManager::kFlagDefault);
+ setup_function79();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(79, Anna, function79)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionEndSound:
+ getState()->time = kTime5933;
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventKahinaPunch);
+ break;
+
+ case kActionDrawScene:
+ if (getEntities()->isInRestaurant(kEntityPlayer) && getInventory()->hasItem(kItemFirebird)) {
+ setup_function80();
+ break;
+ }
+
+ if (getEntities()->isInSalon(kEntityPlayer) && !getEvent(kEventKahinaPunch)) {
+ getState()->time = kTime5933;
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventKahinaPunch);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (getEntities()->isInSalon(kEntityPlayer))
+ getAction()->playAnimation(kEventKahinaPunchSalon);
+ else if (getEntities()->isInRestaurant(kEntityPlayer))
+ getAction()->playAnimation(kEventKahinaPunchRestaurant);
+ else if (getEntities()->isInKitchen(kEntityPlayer))
+ getAction()->playAnimation(kEventKahinaPunchKitchen);
+ else if (getEntities()->isInBaggageCarEntrance(kEntityPlayer))
+ getAction()->playAnimation(kEventKahinaPunchBaggageCarEntrance);
+ else if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarBaggage))
+ getAction()->playAnimation(kEventKahinaPunchBaggageCar);
+ break;
+
+ case 2:
+ getAction()->playAnimation(kEventKahinaPunchSalon);
+ break;
+ }
+
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneNone, true);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(80, Anna, function80)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param1, getState()->timeTicks, 450);
+
+ getSound()->playSound(kEntityPlayer, "Kro5001", SoundManager::kFlagDefault);
+ break;
+
+ case kActionEndSound:
+ getSound()->playSound(kEntityPlayer, "Kro5002", SoundManager::kFlagDefault);
+ getState()->time = kTime4923000;
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventKronosBringFirebird);
+ break;
+
+ case kActionDefault:
+ getState()->time = kTime4929300;
+
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventKahinaPunch);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (getSound()->isBuffered(kEntityAnna))
+ getSound()->processEntry(kEntityAnna);
+
+ getAction()->playAnimation(kEventKronosBringFirebird);
+ getScenes()->loadSceneFromItem(kItemFirebird);
+ getSound()->playSound(kEntityAnna, "Mus025", SoundManager::kFlagDefault);
+ break;
+
+ case 2:
+ getAction()->playAnimation(kEventKahinaPunch);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneNone, true);
+ break;
+
+ case 3:
+ getProgress().isEggOpen = true;
+
+ if (getSound()->isBuffered(kEntityAnna))
+ getSound()->processEntry(kEntityAnna);
+
+ getAction()->playAnimation(kEventKronosOpenFirebird);
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 3);
+
+ setup_finalSequence();
+ break;
+ }
+ break;
+
+ case kAction205294778:
+ getState()->time = kTime4929300;
+
+ setCallback(3);
+ setup_savegame(kSavegameTypeEvent, kEventKronosOpenFirebird);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(81, Anna, finalSequence)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param1, getState()->timeTicks, 180);
+
+ getSound()->playSound(kEntityTrain, "LIB069");
+ getLogic()->gameOver(kSavegameTypeIndex, 2, kSceneNone, true);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventCathCloseEggNoBackground);
+ getAction()->playAnimation(kEventKronosGiveFirebird);
+
+ if (getInventory()->hasItem(kItemWhistle))
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverTrainExplosion, true);
+ else if (getInventory()->get(kItemWhistle)->location == kObjectLocation1)
+ getLogic()->gameOver(kSavegameTypeEvent2, kEventAnnaDialogGoToJerusalem, kSceneNone, true);
+ else
+ getLogic()->gameOver(kSavegameTypeEvent2, kEventAugustUnhookCarsBetrayal, kSceneGameOverTrainExplosion2, true);
+ break;
+
+ case 2:
+ getInventory()->removeItem(kItemWhistle);
+ getLogic()->playFinalSequence();
+ break;
+ }
+ break;
+
+ case kAction224309120:
+ getProgress().isEggOpen = false;
+ getState()->time = kTimeCityConstantinople;
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventKronosGiveFirebird);
+ break;
+
+ case kActionUseWhistle:
+ getProgress().isEggOpen = false;
+ setGlobalTimer(0);
+ getState()->time = kTimeCityConstantinople;
+
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventFinalSequence);
+ break;
+ }
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/anna.h b/engines/lastexpress/entities/anna.h
new file mode 100644
index 0000000000..4712f4b262
--- /dev/null
+++ b/engines/lastexpress/entities/anna.h
@@ -0,0 +1,252 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_ANNA_H
+#define LASTEXPRESS_ANNA_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Anna : public Entity {
+public:
+ Anna(LastExpressEngine *engine);
+ ~Anna() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Draws the entity
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(draw, const char* sequence)
+
+ /**
+ * Updates the position
+ *
+ * @param sequence1 The sequence to draw
+ * @param car The car
+ * @param position The position
+ */
+ DECLARE_FUNCTION_3(updatePosition, const char* sequence1, CarIndex car, Position position)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Process callback action when the entity direction is not kDirectionRight
+ */
+ DECLARE_FUNCTION(callbackActionOnDirection)
+
+ /**
+ * Call a savepoint (or draw sequence in default case)
+ *
+ * @param sequence1 The sequence to draw in the default case
+ * @param entity The entity
+ * @param action The action
+ * @param sequence2 The sequence name for the savepoint
+ */
+ DECLARE_FUNCTION_4(callSavepoint, const char* sequence1, EntityIndex entity, ActionIndex action, const char* sequence2)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Process callback action when somebody is standing in the restaurant or salon.
+ */
+ DECLARE_FUNCTION(callbackActionRestaurantOrSalon)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param time The time to add
+ */
+ DECLARE_FUNCTION_1(updateFromTime, uint32 time)
+
+ DECLARE_FUNCTION(function12)
+
+ /**
+ * Draws the entity along with another one
+ *
+ * @param sequence1 The sequence to draw
+ * @param sequence2 The sequence to draw for the second entity
+ * @param entity The EntityIndex of the second entity
+ */
+ DECLARE_FUNCTION_3(draw2, const char* sequence1, const char* sequence2, EntityIndex entity)
+
+ /**
+ * Updates parameter 2 using ticks value
+ *
+ * @param ticks The number of ticks to add
+ */
+ DECLARE_FUNCTION_1(updateFromTicks, uint32 ticks)
+
+ DECLARE_FUNCTION_2(function15, TimeValue timeValue, const char *sequence)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ DECLARE_FUNCTION_2(function17, uint32, uint32)
+
+ DECLARE_FUNCTION_1(function18, TimeValue timeValue)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+ DECLARE_FUNCTION(function20)
+ DECLARE_FUNCTION(function21)
+ DECLARE_FUNCTION(function22)
+ DECLARE_FUNCTION(function23)
+ DECLARE_FUNCTION(function24)
+ DECLARE_FUNCTION(function25)
+ DECLARE_FUNCTION(function26)
+ DECLARE_FUNCTION(function27)
+ DECLARE_FUNCTION(function28)
+ DECLARE_FUNCTION(function29)
+ DECLARE_FUNCTION(function30)
+ DECLARE_FUNCTION(function31)
+ DECLARE_FUNCTION(function32)
+ DECLARE_FUNCTION(function33)
+ DECLARE_FUNCTION(function34)
+ DECLARE_FUNCTION(function35)
+ DECLARE_FUNCTION(function36)
+ DECLARE_FUNCTION(function37)
+ DECLARE_FUNCTION(function38)
+ DECLARE_FUNCTION_2(function39, CarIndex car, EntityPosition entityPosition)
+ DECLARE_FUNCTION(function40)
+ DECLARE_FUNCTION(function41)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+ DECLARE_FUNCTION_1(function45, bool useAction1)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+ DECLARE_FUNCTION(function47)
+ DECLARE_FUNCTION(function48)
+ DECLARE_FUNCTION(leaveTableWithAugust)
+ DECLARE_FUNCTION(function50)
+ DECLARE_FUNCTION(function51)
+ DECLARE_FUNCTION(function52)
+ DECLARE_FUNCTION(function53)
+ DECLARE_FUNCTION(function54)
+ DECLARE_FUNCTION(function55)
+ DECLARE_FUNCTION(function56)
+ DECLARE_FUNCTION(function57)
+ DECLARE_FUNCTION(function58)
+ DECLARE_FUNCTION(function59)
+ DECLARE_FUNCTION(function60)
+ DECLARE_FUNCTION(function61)
+ DECLARE_FUNCTION(function62)
+ DECLARE_FUNCTION(function63)
+ DECLARE_FUNCTION(baggage)
+ DECLARE_FUNCTION(function65)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ DECLARE_FUNCTION(function68)
+ DECLARE_FUNCTION(function69)
+ DECLARE_FUNCTION(function70)
+ DECLARE_FUNCTION(function71)
+ DECLARE_FUNCTION_2(function72, CarIndex car, EntityPosition entityPosition)
+ DECLARE_FUNCTION(function73)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+ DECLARE_FUNCTION(function76)
+ DECLARE_FUNCTION(function77)
+ DECLARE_FUNCTION(function78)
+ DECLARE_FUNCTION(function79)
+ DECLARE_FUNCTION(function80)
+ DECLARE_FUNCTION(finalSequence)
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_ANNA_H
diff --git a/engines/lastexpress/entities/august.cpp b/engines/lastexpress/entities/august.cpp
new file mode 100644
index 0000000000..419d716ced
--- /dev/null
+++ b/engines/lastexpress/entities/august.cpp
@@ -0,0 +1,2804 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/august.h"
+
+#include "lastexpress/entities/alexei.h"
+#include "lastexpress/entities/salko.h"
+#include "lastexpress/entities/verges.h"
+
+#include "lastexpress/game/action.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"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+
+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(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(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(August, chapter1);
+ ADD_CALLBACK_FUNCTION(August, function23);
+ ADD_CALLBACK_FUNCTION(August, dinner);
+ ADD_CALLBACK_FUNCTION(August, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(August, function26);
+ ADD_CALLBACK_FUNCTION(August, function27);
+ ADD_CALLBACK_FUNCTION(August, function28);
+ ADD_CALLBACK_FUNCTION(August, function29);
+ ADD_CALLBACK_FUNCTION(August, restaurant);
+ ADD_CALLBACK_FUNCTION(August, function31);
+ ADD_CALLBACK_FUNCTION(August, function32);
+ ADD_CALLBACK_FUNCTION(August, function33);
+ ADD_CALLBACK_FUNCTION(August, function34);
+ ADD_CALLBACK_FUNCTION(August, chapter2);
+ ADD_CALLBACK_FUNCTION(August, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(August, function37);
+ 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(August, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(August, function44);
+ ADD_CALLBACK_FUNCTION(August, function45);
+ ADD_CALLBACK_FUNCTION(August, function46);
+ ADD_CALLBACK_FUNCTION(August, function47);
+ ADD_CALLBACK_FUNCTION(August, function48);
+ ADD_CALLBACK_FUNCTION(August, function49);
+ ADD_CALLBACK_FUNCTION(August, function50);
+ ADD_CALLBACK_FUNCTION(August, function51);
+ ADD_CALLBACK_FUNCTION(August, function52);
+ ADD_CALLBACK_FUNCTION(August, function53);
+ ADD_CALLBACK_FUNCTION(August, function54);
+ ADD_CALLBACK_FUNCTION(August, function55);
+ ADD_CALLBACK_FUNCTION(August, function56);
+ ADD_CALLBACK_FUNCTION(August, chapter4);
+ ADD_CALLBACK_FUNCTION(August, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(August, function59);
+ ADD_CALLBACK_FUNCTION(August, function60);
+ ADD_CALLBACK_FUNCTION(August, function61);
+ ADD_CALLBACK_FUNCTION(August, function62);
+ ADD_CALLBACK_FUNCTION(August, function63);
+ ADD_CALLBACK_FUNCTION(August, function64);
+ ADD_CALLBACK_FUNCTION(August, function65);
+ ADD_CALLBACK_FUNCTION(August, chapter5);
+ ADD_CALLBACK_FUNCTION(August, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(August, function68);
+ ADD_CALLBACK_FUNCTION(August, unhookCars);
+ ADD_NULL_FUNCTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, August, reset)
+ Entity::reset(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(2, August, updateFromTime, uint32)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(3, August, draw)
+ Entity::draw(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SII(4, August, updatePosition, CarIndex, Position)
+ Entity::updatePosition(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(5, August, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(6, August, enterExitCompartment2, ObjectIndex)
+ Entity::enterExitCompartment(savepoint, kPosition_6470, kPosition_6130, kCarGreenSleeping, kObjectCompartment3, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(7, August, enterExitCompartment3, ObjectIndex)
+ if (savepoint.action == kAction4) {
+ getEntities()->exitCompartment(kEntityAugust, (ObjectIndex)params->param4);
+ CALLBACK_ACTION();
+ return;
+ }
+
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(8, August, callbackActionOnDirection)
+ Entity::callbackActionOnDirection(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SIIS(9, August, callSavepoint, EntityIndex, ActionIndex)
+ Entity::callSavepoint(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_IIS(10, August, callSavepointNoDrawing, EntityIndex, ActionIndex)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ if (!params->param6)
+ getSavePoints()->call(kEntityAugust, (EntityIndex)params->param1, (ActionIndex)params->param2, (char *)&params->seq);
+
+ CALLBACK_ACTION();
+ break;
+
+ case kAction10:
+ if (!params->param6) {
+ getSavePoints()->call(kEntityAugust, (EntityIndex)params->param1, (ActionIndex)params->param2, (char *)&params->seq);
+ params->param6 = 1;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SSI(11, August, draw2, EntityIndex)
+ Entity::draw2(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(12, August, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(13, August, playSound16)
+ Entity::playSound(savepoint, false, SoundManager::kFlagDefault);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, August, callbackActionRestaurantOrSalon)
+ Entity::callbackActionRestaurantOrSalon(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(15, August, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(16, August, updateEntity, CarIndex, EntityPosition)
+ if (savepoint.action == kActionExcuseMeCath) {
+ getProgress().eventMetAugust ? getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1002A" : "CAT1002") : getSound()->excuseMeCath();
+ return;
+ }
+
+ Entity::updateEntity(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(17, August, function17, TimeValue)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1 < getState()->time && !params->param2) {
+ params->param2 = 1;
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (getEntities()->isPlayerInCar(kCarGreenSleeping) || getEntities()->isPlayerInCar(kCarRedSleeping)) {
+ if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarGreenSleeping)) {
+ setCallback(2);
+ setup_updateEntity2(kCarGreenSleeping, kPosition_540);
+ } else {
+ setCallback(3);
+ setup_updateEntity2(kCarRedSleeping, kPosition_9460);
+ }
+ }
+ break;
+
+ case kActionDefault:
+ ENTITY_PARAM(0, 1) = 0;
+
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_540);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (ENTITY_PARAM(0, 1)) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ getEntities()->clearSequences(kEntityAugust);
+ break;
+
+ case 2:
+ case 3:
+ if (ENTITY_PARAM(0, 1)) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ getEntities()->clearSequences(kEntityAugust);
+
+ setCallback(4);
+ setup_updateFromTime(450);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_updateEntity2(kCarRedSleeping, kPosition_540);
+ break;
+
+ case 5:
+ if (ENTITY_PARAM(0, 1)) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ getEntities()->clearSequences(kEntityAugust);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(18, August, updateEntity2, CarIndex, EntityPosition)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->updateEntity(_entityIndex, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ CALLBACK_ACTION();
+ } else if (getEntities()->isDistanceBetweenEntities(kEntityAugust, kEntityPlayer, 1000)
+ && !getEntities()->isInGreenCarEntrance(kEntityPlayer)
+ && !getEntities()->isInsideCompartments(kEntityPlayer)
+ && !getEntities()->checkFields10(kEntityPlayer)) {
+
+ if (getData()->car == kCarGreenSleeping || getData()->car == kCarRedSleeping) {
+ ENTITY_PARAM(0, 1) = 1;
+ CALLBACK_ACTION();
+ }
+ }
+ break;
+
+ case kActionDefault:
+ if (getEntities()->updateEntity(_entityIndex, (CarIndex)params->param1, (EntityPosition)params->param2))
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(19, August, function19, bool, bool)
+ error("August: callback function 19 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(20, August, function20, bool)
+ // Expose parameters as ISSI and ignore the default exposed parameters
+ EntityData::EntityParametersISSI *parameters = (EntityData::EntityParametersISSI*)_data->getCurrentParameters();
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ switch (getProgress().chapter) {
+ default:
+ break;
+
+ case kChapter1:
+ strcpy((char *)&parameters->seq1, "626");
+ break;
+
+ case kChapter2:
+ case kChapter3:
+ if (getData()->clothes != kClothes2) {
+ strcpy((char *)&parameters->seq1, "666");
+ break;
+ }
+ // Fallback to next case
+
+ case kChapter4:
+ case kChapter5:
+ strcpy((char *)&parameters->seq1, "696");
+ break;
+ }
+
+ if (params->param1) {
+ strcpy((char *)&parameters->seq2, Common::String::printf("%s%s", (char *)&parameters->seq1, "Gc").c_str());
+
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+ } else {
+ strcpy((char *)&parameters->seq2, Common::String::printf("%s%s", (char *)&parameters->seq1, "Ec").c_str());
+ }
+
+ setCallback(1);
+ setup_enterExitCompartment((char *)&parameters->seq2, kObjectCompartment3);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1: {
+ getData()->location = kLocationOutsideCompartment;
+
+ Common::String sequence2 = Common::String::printf("%s%s", (char *)&parameters->seq2, "Pc");
+ strcpy((char *)&parameters->seq2, (char *)&parameters->seq1);
+
+ getEntities()->drawSequenceLeft(kEntityAugust, sequence2.c_str());
+ getEntities()->enterCompartment(kEntityAugust, kObjectCompartment3, true);
+
+ if (getProgress().chapter != kChapter3 || getState()->time >= kTime1998000) {
+ setCallback(3);
+ setup_playSound("AUG2095");
+ } else {
+ setCallback(2);
+ setup_playSound("AUG2094");
+ }
+ }
+ break;
+
+ case 2:
+ case 3:
+ getSavePoints()->push(kEntityAugust, kEntityMertens, kAction269436673);
+ strcpy((char *)&parameters->seq2, Common::String::printf("%s%s", (char *)&parameters->seq1, "Qc").c_str());
+
+ getEntities()->drawSequenceLeft(kEntityAugust, (char *)&parameters->seq2);
+ break;
+ }
+ break;
+
+ case kAction69239528:
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getEntities()->exitCompartment(kEntityAugust, kObjectCompartment3, true);
+
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(21, August, function21, TimeValue)
+ error("August: callback function 21 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, August, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject11, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ getData()->entityPosition = kPosition_4691;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothesDefault;
+
+ getProgress().eventMetAugust = false;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(23, August, function23, TimeValue)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getProgress().field_14 == 29 || getProgress().field_14 == 3) {
+ if (params->param3) {
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_enterExitCompartment("626Ea", kObjectCompartment1);
+ } else {
+ getEntities()->exitCompartment(kEntityAugust, kObjectCompartment1, true);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ CALLBACK_ACTION();
+ }
+ break;
+ }
+
+ if (!params->param2) {
+
+ if (!CURRENT_PARAMS(1, 3))
+ CURRENT_PARAMS(1, 3) = getState()->timeTicks + 45;
+
+ if (CURRENT_PARAMS(1, 3) >= getState()->timeTicks)
+ break;
+
+ if (!params->param5) {
+ setCallback(8);
+ setup_playSound("AUG1002B");
+ break;
+ }
+
+label_callback_8:
+ UPDATE_PARAM_PROC(CURRENT_PARAMS(1, 4), getState()->timeTicks, 75)
+ getEntities()->exitCompartment(kEntityAugust, kObjectCompartment1, true);
+
+ if (getProgress().eventCorpseMovedFromFloor) {
+ setCallback(9);
+ setup_enterExitCompartment("626Da", kObjectCompartment1);
+ } else if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarGreenSleeping)) {
+ setCallback(10);
+ setup_enterExitCompartment3("626Da", kObjectCompartment1);
+ } else {
+ getScenes()->loadSceneFromPosition(kCarNone, 1);
+ getObjects()->update(kObjectOutsideTylerCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ setCallback(11);
+ setup_savegame(kSavegameTypeEvent, kEventAugustFindCorpse);
+ }
+ break;
+ UPDATE_PARAM_PROC_END
+
+label_callback_9:
+ if (params->param3 && params->param1 < getState()->time && !CURRENT_PARAMS(1, 5)) {
+ CURRENT_PARAMS(1, 5) = 1;
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ setCallback(12);
+ setup_enterExitCompartment("626Ea", kObjectCompartment1);
+ }
+ break;
+ }
+
+ if (!CURRENT_PARAMS(1, 1))
+ CURRENT_PARAMS(1, 1) = getState()->timeTicks + 45;
+
+ if (CURRENT_PARAMS(1, 1) >= getState()->timeTicks)
+ break;
+
+ if (getObjects()->get(kObjectCompartment1).location == kObjectLocation1) {
+ UPDATE_PARAM(CURRENT_PARAMS(1, 2), getState()->timeTicks, 75);
+
+ getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+
+ params->param6++;
+
+ switch (params->param6) {
+ default:
+ break;
+
+ case 1:
+ setCallback(5);
+ setup_playSound("LIB013");
+ return;
+
+ case 2:
+ setCallback(7);
+ setup_playSound("LIB012");
+ return;
+
+ case 3:
+ params->param8++;
+
+ if (params->param8 >= 3) {
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorHandKnock, kCursorHand);
+ CALLBACK_ACTION();
+ break;
+ }
+
+ params->param6 = 0;
+ }
+
+ getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).location, params->param4 ? kCursorNormal : kCursorTalk, kCursorHand);
+ CURRENT_PARAMS(1, 2) = 0;
+ } else {
+
+ if (getProgress().eventCorpseMovedFromFloor && getProgress().jacket != kJacketBlood) {
+ params->param7 = (getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1) ? 8 : 7;
+ getObjects()->update(kObjectOutsideTylerCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(4);
+ setup_savegame(kSavegameTypeEvent, kEventMeetAugustTylerCompartment);
+ } else {
+ getObjects()->update(kObjectOutsideTylerCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(3);
+ setup_savegame(kSavegameTypeEvent, kEventAugustFindCorpse);
+ }
+ }
+ break;
+
+ case kActionKnock:
+ if (params->param3) {
+ getObjects()->update(kObjectCompartment1, kEntityAugust, kObjectLocationNone, kCursorNormal, kCursorNormal);
+
+ setCallback(15);
+ setup_playSound("LIB012");
+ } else if (!params->param4) {
+ getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+
+ setCallback(17);
+ setup_playSound("AUG1002A");
+ }
+ break;
+
+ case kActionOpenDoor:
+ if (getProgress().eventCorpseMovedFromFloor && getProgress().jacket != kJacketBlood) {
+ if (params->param3) {
+ getData()->location = kLocationInsideCompartment;
+
+ params->param7 = (getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1) ? kEventMeetAugustHisCompartmentBed : kEventMeetAugustHisCompartment;
+ } else {
+ params->param7 = (getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1) ? kEventMeetAugustTylerCompartmentBed : kEventMeetAugustTylerCompartment;
+ }
+
+ setCallback(14);
+ setup_savegame(kSavegameTypeEvent, kEventMeetAugustTylerCompartment);
+ } else {
+ getObjects()->update(kObjectOutsideTylerCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(13);
+ setup_savegame(kSavegameTypeEvent, kEventAugustFindCorpse);
+ }
+ break;
+
+ case kActionDefault:
+ if (getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, kPosition_8200)
+ || getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, kPosition_7850)
+ || getEntities()->isOutsideAlexeiWindow()) {
+ getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+
+ if (getEntities()->isOutsideAlexeiWindow())
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
+
+ getSound()->playSound(kEntityPlayer, "LIB012");
+
+ getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).location, kCursorTalk, kCursorHand);
+
+ params->param2 = 1;
+ } else {
+ setCallback(1);
+ setup_enterExitCompartment("626Aa", kObjectCompartment1);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceLeft(kEntityAugust, "626Ba");
+ getEntities()->enterCompartment(kEntityAugust, kObjectCompartment1, true);
+ break;
+
+ case 2:
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ CALLBACK_ACTION();
+ break;
+
+ case 3:
+ getSound()->playSound(kEntityPlayer, "LIB014");
+ getAction()->playAnimation(kEventAugustFindCorpse);
+ if (getEvent(kEventDinerAugustOriginalJacket))
+ getLogic()->gameOver(kSavegameTypeEvent2, kEventDinerAugustOriginalJacket, getProgress().eventCorpseFound ? kSceneGameOverStopPolice : kSceneGameOverPolice, true);
+ else if (getProgress().eventCorpseMovedFromFloor)
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ else
+ getLogic()->gameOver(kSavegameTypeIndex, 1, getProgress().eventCorpseFound ? kSceneGameOverStopPolice : kSceneGameOverPolice, true);
+ break;
+
+ case 4:
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getSound()->playSound(kEntityPlayer, "LIB014");
+ getEntities()->clearSequences(kEntityAugust);
+ getData()->location = kLocationInsideCompartment;
+
+ getAction()->playAnimation((EventIndex)params->param7);
+ getSound()->playSound(kEntityPlayer, "LIB015");
+ getProgress().eventMetAugust = true;
+ getData()->location = kLocationOutsideCompartment;
+
+ getScenes()->loadScene(kScene41);
+
+ CALLBACK_ACTION();
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_playSound16("AUG1002B");
+ break;
+
+ case 6:
+ case 7:
+ getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).location, params->param4 ? kCursorNormal : kCursorTalk, kCursorHand);
+ ENTITY_PARAM(1, 2) = 0;
+ break;
+
+ case 8:
+ params->param5 = 1;
+ goto label_callback_8;
+
+ case 9:
+ params->param3 = 1;
+ getEntities()->clearSequences(kEntityAugust);
+ getData()->location = kLocationInsideCompartment;
+ getObjects()->update(kObjectCompartment1, kEntityAugust, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ goto label_callback_9;
+
+ case 10:
+ getObjects()->update(kObjectOutsideTylerCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ setCallback(11);
+ setup_savegame(kSavegameTypeEvent, kEventAugustFindCorpse);
+ break;
+
+ case 11:
+ getAction()->playAnimation(kEventAugustFindCorpse);
+
+ getLogic()->gameOver(getEvent(kEventDinerAugustOriginalJacket) ? kSavegameTypeEvent2 : kSavegameTypeIndex,
+ getEvent(kEventDinerAugustOriginalJacket) ? kEventDinerAugustOriginalJacket : 1,
+ getProgress().eventCorpseFound ? kSceneGameOverStopPolice : kSceneGameOverPolice,
+ true);
+ break;
+
+ case 12:
+ getData()->location = kLocationOutsideCompartment;
+ CALLBACK_ACTION();
+ break;
+
+ case 13:
+ getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).location == kObjectLocation1 ? "LIB032" : "LIB014");
+ getAction()->playAnimation(kEventAugustFindCorpse);
+
+ if (getEvent(kEventDinerAugustOriginalJacket))
+ getLogic()->gameOver(kSavegameTypeEvent2, kEventDinerAugustOriginalJacket, getProgress().eventCorpseFound ? kSceneGameOverStopPolice : kSceneGameOverPolice, true);
+ else if (getProgress().eventCorpseMovedFromFloor)
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ else
+ getLogic()->gameOver(kSavegameTypeIndex, 1, getProgress().eventCorpseFound ? kSceneGameOverStopPolice : kSceneGameOverPolice, true);
+ break;
+
+ case 14:
+ if (!params->param2)
+ getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).location == kObjectLocation1 ? "LIB032" : "LIB014");
+
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectOutsideTylerCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ getAction()->playAnimation((EventIndex)params->param7);
+ getProgress().eventMetAugust = true;
+ getData()->location = kLocationOutsideCompartment;
+
+ getScenes()->loadScene(kScene41);
+
+ CALLBACK_ACTION();
+ break;
+
+ case 15:
+ setCallback(16);
+ setup_playSound("AUG1128A");
+ break;
+
+ case 16:
+ getObjects()->update(kObjectCompartment1, kEntityAugust, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ break;
+
+ case 17:
+ params->param4 = 1;
+ getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorHand);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, August, dinner)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventDinerAugust);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+
+ getAction()->playAnimation(getEntities()->isInRestaurant(kEntityAlexei) ? kEventDinerAugustAlexeiBackground : kEventDinerAugust);
+ getProgress().eventMetAugust = true;
+
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 61);
+
+ CALLBACK_ACTION();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, August, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1 && getProgress().eventCorpseFound) {
+ getSavePoints()->push(kEntityAugust, kEntityPascale, kAction239072064);
+ params->param1 = 1;
+ }
+
+ if (getState()->time > kTime1080000 && !params->param3) {
+ params->param3 = 1;
+
+ if (!params->param1) {
+ getSavePoints()->push(kEntityAugust, kEntityPascale, kAction239072064);
+ params->param1 = 1;
+ }
+ }
+
+ if (getState()->time > kTime1093500 && getEntities()->isSomebodyInsideRestaurantOrSalon()) {
+ getData()->location = kLocationOutsideCompartment;
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(1);
+ setup_callSavepoint("010J", kEntityTables3, kActionDrawTablesWithChairs, "010K");
+ }
+ break;
+
+ case kAction1:
+ params->param2 = 0;
+ getData()->inventoryItem = kItemNone;
+ getSavePoints()->push(kEntityAugust, kEntityPascale, kAction191604416);
+
+ if (getProgress().jacket == kJacketGreen) {
+ setCallback(3);
+ setup_dinner();
+ } else {
+ setCallback(4);
+ setup_savegame(kSavegameTypeEvent, kEventDinerAugustOriginalJacket);
+ }
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityAugust, kEntityTables3, kAction136455232);
+ getEntities()->drawSequenceLeft(kEntityAugust, "010B");
+
+ if (!getProgress().eventMetAugust)
+ params->param2 = kItemInvalid;
+
+ getData()->inventoryItem = (InventoryItem)params->param2;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityAugust, kEntityServers0, kAction204704037);
+ getEntities()->drawSequenceRight(kEntityAugust, "803DS");
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityAugust);
+
+ setCallback(2);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 2:
+ setup_function26();
+ break;
+
+ case 3:
+ setup_function28();
+ break;
+
+ case 4:
+ getSavePoints()->push(kEntityAugust, kEntityAlexei, kAction225182640);
+ getAction()->playAnimation(kEventDinerAugustOriginalJacket);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocation3, kCursorNormal, kCursorNormal);
+
+ getData()->location = kLocationOutsideCompartment;
+
+ getSavePoints()->push(kEntityAugust, kEntityTables3, kActionDrawTablesWithChairs, "010K");
+ getEntities()->drawSequenceRight(kEntityAugust, "010P");
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 65);
+
+ setCallback(5);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 5:
+ getSavePoints()->push(kEntityAugust, kEntityServers0, kAction204704037);
+ getEntities()->drawSequenceRight(kEntityAugust, "803DS");
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityAugust);
+
+ setCallback(6);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 6:
+ getProgress().field_14 = 2;
+
+ setCallback(7);
+ setup_updateEntity(kCarGreenSleeping, kPosition_8200);
+ break;
+
+ case 7:
+ setCallback(8);
+ setup_function23(kTimeNone);
+ break;
+
+ case 8:
+ getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, true);
+ break;
+ }
+ break;
+
+ case kAction168046720:
+ getData()->inventoryItem = kItemNone;
+ break;
+
+ case kAction168627977:
+ getData()->inventoryItem = (InventoryItem)params->param2;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(26, August, function26)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (getProgress().eventMetAugust || getProgress().field_14) {
+ setCallback(5);
+ setup_updateEntity(kCarGreenSleeping, kPosition_6470);
+ } else {
+ getProgress().field_14 = 2;
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_8200);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function23((TimeValue)(getState()->time + 13500));
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_updateEntity(kCarGreenSleeping, kPosition_6470);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function19(false, false);
+ break;
+
+ case 4:
+ if (getProgress().field_14 == 2)
+ getProgress().field_14 = 0;
+
+ setCallback(7);
+ setup_function21((TimeValue)(getState()->time + 900));
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_function19(false, false);
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_function21((TimeValue)(getState()->time + 900));
+ break;
+
+ case 7:
+ setup_function27();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(27, August, function27)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function20(false);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(4);
+ setup_draw("803US");
+ break;
+
+ case 4:
+ getEntities()->drawSequenceRight(kEntityAugust, "010A");
+ if (getEntities()->isInSalon(kEntityPlayer))
+ getEntities()->updateFrame(kEntityAugust);
+
+ setCallback(5);
+ setup_callSavepointNoDrawing(kEntityTables3, kAction136455232, "BOGUS");
+ break;
+
+ case 5:
+ getData()->location = kLocationInsideCompartment;
+ setup_function28();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(28, August, function28)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+ params->param1 = 0;
+
+ setCallback(3);
+ setup_dinner();
+ break;
+
+ case kActionDefault:
+ if (!getProgress().eventMetAugust && getProgress().jacket == kJacketGreen)
+ params->param1 = kItemInvalid;
+
+ getEntities()->drawSequenceLeft(kEntityAugust, "010B");
+ getSavePoints()->push(kEntityAugust, kEntityServers0, kAction304061224);
+ getData()->inventoryItem = (InventoryItem)params->param1;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityAugust, kEntityServers0, kAction203859488);
+ getData()->inventoryItem = (InventoryItem)params->param1;
+ getEntities()->drawSequenceLeft(kEntityAugust, "010B");
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityAugust, kEntityServers0, kAction136702400);
+ getEntities()->drawSequenceLeft(kEntityAugust, "010B");
+ setup_function29();
+ break;
+ }
+ break;
+
+ case kAction168046720:
+ getData()->inventoryItem = kItemNone;
+ break;
+
+ case kAction168627977:
+ getData()->inventoryItem = (InventoryItem)params->param1;
+ break;
+
+ case kAction170016384:
+ getData()->inventoryItem = kItemNone;
+ getEntities()->drawSequenceLeft(kEntityServers0, "BLANK");
+ getEntities()->drawSequenceLeft(kEntityAugust, "010G");
+
+ setCallback(2);
+ setup_playSound("AUG1053");
+ break;
+
+ case kAction268773672:
+ getData()->inventoryItem = kItemNone;
+ getEntities()->drawSequenceLeft(kEntityAugust, "010D");
+
+ setCallback(1);
+ setup_playSound("AUG1052");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(29, August, function29)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!getProgress().field_28 || (params->param2 && params->param3 == kTimeInvalid))
+ break;
+
+ if (getState()->time < kTime1134000) {
+
+ if (!getEntities()->isInRestaurant(kEntityPlayer)
+ || getSound()->isBuffered("MRB1076") || getSound()->isBuffered("MRB1078") || getSound()->isBuffered("MRB1078A"))
+ params->param3 = getState()->time + 225;
+
+ if (params->param3 > getState()->time)
+ break;
+ }
+
+ params->param3 = kTimeInvalid;
+ getData()->inventoryItem = kItemNone;
+ getProgress().field_28 = 0;
+
+ setup_restaurant();
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+ params->param1 = kItemNone;
+
+ setCallback(1);
+ setup_dinner();
+ break;
+
+ case kActionDefault:
+ if (!getProgress().eventMetAugust && getProgress().jacket == kJacketGreen)
+ params->param1 = kItemInvalid;
+
+ getData()->inventoryItem = (InventoryItem)LOBYTE(params->param1);
+
+ getEntities()->drawSequenceLeft(kEntityAugust, "010H");
+ break;
+
+ case kAction168046720:
+ getData()->inventoryItem = kItemNone;
+ break;
+
+ case kAction168627977:
+ getData()->inventoryItem = (InventoryItem)LOBYTE(params->param1);
+ break;
+
+ case kAction189426612:
+ params->param2 = 1;
+ break;
+
+ case kAction235257824:
+ params->param2 = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(30, August, restaurant)
+ error("August: callback function 30 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(31, August, function31)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_6470);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function19(false, false);
+ break;
+
+ case 2:
+ setCallback(2);
+ setup_function21(kTime1161000);
+ break;
+
+ case 3:
+ case 4:
+ if (getProgress().field_14 == 29) {
+ setCallback(4);
+ setup_function21((TimeValue)(getState()->time + 900));
+ } else {
+ setup_function32();
+ }
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(32, August, function32)
+ error("August: callback function 32 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(33, August, function33)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(getProgress().eventMetAugust ? 1 : 2);
+ setup_function21(getProgress().eventMetAugust ? (TimeValue)(getState()->time + 9000) : kTimeBedTime);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1 || getCallback() == 2)
+ setup_function34();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(34, August, function34)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!getSound()->isBuffered(kEntityAugust) && getProgress().field_18 != 4)
+ getSound()->playSound(kEntityAugust, "AUG1057"); // August snoring
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ getData()->entityPosition = kPosition_6470;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+
+ getEntities()->clearSequences(kEntityAugust);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(35, August, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter2Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAugust);
+
+ getData()->entityPosition = kPosition_3970;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothes1;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject11, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(36, August, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_SAVEPOINT(kTime1755000, params->param2, kEntityAugust, kEntityServers0, kAction252568704);
+
+ if (getState()->time > kTime1773000 && params->param1 && getEntities()->isSomebodyInsideRestaurantOrSalon()) {
+ getData()->inventoryItem = kItemNone;
+ getData()->location = kLocationOutsideCompartment;
+ getEntities()->updatePositionEnter(kEntityAugust, kCarRestaurant, 62);
+
+ setCallback(2);
+ setup_callSavepoint("016C", kEntityTables0, kActionDrawTablesWithChairs, "016D");
+ }
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAugustGoodMorning);
+ break;
+
+ case kActionDefault:
+ if (!getEvent(kEventAugustGoodMorning))
+ getData()->inventoryItem = kItemInvalid;
+
+ getSavePoints()->push(kEntityAugust, kEntityTables0, kAction136455232);
+ getEntities()->drawSequenceLeft(kEntityAugust, "016B");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventAugustGoodMorning);
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 61);
+ break;
+
+ case 2:
+ getEntities()->updatePositionExit(kEntityAugust, kCarRestaurant, 62);
+ getEntities()->drawSequenceRight(kEntityAugust, "803ES");
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityAugust);
+
+ setCallback(3);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 3:
+ getSavePoints()->push(kEntityAugust, kEntityServers0, kAction286534136);
+
+ setCallback(4);
+ setup_updateEntity(kCarGreenSleeping, kPosition_6470);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_function19(true, false);
+ break;
+
+ case 5:
+ setup_function37();
+ break;
+
+ case 6:
+ if (!getEvent(kEventAugustGoodMorning))
+ getData()->inventoryItem = kItemInvalid;
+
+ getSavePoints()->push(kEntityAugust, kEntityServers0, kAction219522616);
+ getEntities()->drawSequenceLeft(kEntityAugust, "016B");
+ params->param1 = 1;
+ break;
+ }
+ break;
+
+ case kAction123712592:
+ getEntities()->drawSequenceLeft(kEntityAugust, "016A");
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(6);
+ setup_playSound("AUG2113");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(37, August, function37)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CALLBACK_1(kTime1791000, params->param2, 5, setup_function20, true);
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocation2, kCursorNormal, kCursorNormal);
+ getEntities()->drawSequenceLeft(kEntityAugust, "506A2");
+ break;
+
+ case kActionDrawScene:
+ if (getState()->time > kTime1786500 && getEntities()->isPlayerPosition(kCarGreenSleeping, 43)) {
+ if (params->param1) {
+ setCallback(2);
+ setup_draw("506C2");
+ } else {
+ params->param1 = 1;
+
+ setCallback(1);
+ setup_draw("506B2");
+ }
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 16);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function20(true);
+ break;
+
+ case 3:
+ case 5:
+ setCallback(getCallback() == 3 ? 4 : 6);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 4:
+ case 6:
+ setup_function38();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(38, August, function38)
+ error("August: callback function 38 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(39, August, function39)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (!ENTITY_PARAM(0, 1))
+ getSound()->playSound(kEntityPlayer, "BUMP");
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAugustArrivalInMunich);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventAugustArrivalInMunich);
+ getSavePoints()->push(kEntityAugust, kEntityChapters, kActionChapter3);
+ getEntities()->clearSequences(kEntityAugust);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(40, August, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAugust);
+
+ getData()->entityPosition = kPosition_6470;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ getData()->clothes = kClothes1;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(41, August, function41, CarIndex, EntityPosition)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param3 && getEntities()->isDistanceBetweenEntities(kEntityAugust, kEntityPlayer, 2000))
+ getData()->inventoryItem = kItemInvalid;
+ else
+ getData()->inventoryItem = kItemNone;
+
+ if (getEntities()->updateEntity(kEntityAugust, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (!getEvent(kEventAugustMerchandise)
+ && getEntities()->isDistanceBetweenEntities(kEntityAugust, kEntityPlayer, 1000)
+ && !getEntities()->isInsideCompartments(kEntityPlayer)
+ && !getEntities()->checkFields10(kEntityPlayer)) {
+ if (getData()->car == kCarGreenSleeping || getData()->car == kCarGreenSleeping) {
+ getAction()->playAnimation(kEventAugustMerchandise);
+
+ getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + (750 * (getData()->direction == kDirectionUp ? -1 : 1))), getData()->direction == kDirectionUp);
+ }
+ }
+ break;
+
+ case kAction1:
+ params->param3 = kItemNone;
+ getData()->inventoryItem = kItemNone;
+
+ getAction()->playAnimation((getData()->entityPosition < getEntityData(kEntityPlayer)->entityPosition) ? kEventAugustTalkGoldDay : kEventAugustTalkGold);
+ getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + (750 * (getData()->direction == kDirectionUp ? -1 : 1))), getData()->direction == kDirectionUp);
+ break;
+
+ case kActionExcuseMeCath:
+ if (getProgress().eventMetAugust)
+ getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1002" : "CAT1002A");
+ else
+ getSound()->excuseMeCath();
+ break;
+
+ case kActionExcuseMe:
+ getSound()->excuseMe(kEntityAugust);
+ break;
+
+ case kActionDefault:
+ if (getEntities()->updateEntity(kEntityAugust, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (getEvent(kEventAugustMerchandise) && !getEvent(kEventAugustTalkGold) && !getEvent(kEventAugustTalkGoldDay))
+ params->param3 = kItemInvalid;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_III(42, August, function42, CarIndex, EntityPosition, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param4 && getEntities()->isDistanceBetweenEntities(kEntityAugust, kEntityPlayer, 2000))
+ getData()->inventoryItem = kItemInvalid;
+ else
+ getData()->inventoryItem = kItemNone;
+
+ if (getEntities()->updateEntity(kEntityAugust, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ getData()->inventoryItem = kItemNone;
+
+ CALLBACK_ACTION();
+ }
+ break;
+
+ case kAction1:
+ params->param4 = 0;
+ getData()->inventoryItem = kItemNone;
+
+ getSound()->playSound(kEntityPlayer, "CAT1002");
+ getSound()->playSound(kEntityAugust, getEvent(kEventAugustBringBriefcase) ? "AUG3103" : "AUG3100", SoundManager::kFlagInvalid, 15);
+ break;
+
+ case kActionExcuseMe:
+ if (!getSound()->isBuffered(kEntityAugust))
+ getSound()->excuseMe(kEntityAugust);
+ break;
+
+ case kActionDefault:
+ if (getEntities()->updateEntity(kEntityAugust, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (params->param3) {
+ params->param4 = 128;
+
+ if (!getEvent(kEventAugustBringBriefcase))
+ params->param4 = 147;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(43, August, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_SAVEPOINT(kTime1953000, params->param2, kEntityAugust, kEntityAnna, kAction291662081);
+
+ // Set as same position as Anna
+ if (params->param1) {
+ getData()->entityPosition = getEntityData(kEntityAnna)->entityPosition;
+ getData()->car = getEntityData(kEntityAnna)->car;
+ }
+
+ if (getState()->time > kTime2016000 && !params->param1) {
+ if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
+ getData()->inventoryItem = kItemNone;
+ setup_function44();
+ }
+ }
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(6);
+ setup_savegame(kSavegameTypeEvent, kEventAugustLunch);
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function20(true);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function41(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(4);
+ setup_draw("803VS");
+ break;
+
+ case 4:
+ getEntities()->drawSequenceRight(kEntityAugust, "010A2");
+
+ if (getEntities()->isInSalon(kEntityPlayer))
+ getEntities()->updateFrame(kEntityAugust);
+
+ setCallback(5);
+ setup_callSavepointNoDrawing(kEntityTables3, kAction136455232, "BOGUS");
+ break;
+
+ case 5:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->drawSequenceLeft(kEntityAugust, "010B2");
+
+ if (!getEvent(kEventAugustLunch))
+ getData()->inventoryItem = kItemInvalid;
+ break;
+
+ case 6:
+ getAction()->playAnimation(kEventAugustLunch);
+ getScenes()->processScene();
+ break;
+ }
+ break;
+
+ case kAction122288808:
+ params->param1 = 0;
+ getData()->inventoryItem = kItemNone;
+ getData()->location = kLocationInsideCompartment;
+
+ getEntities()->drawSequenceLeft(kEntityAugust, "112G");
+ break;
+
+ case kAction122358304:
+ params->param1 = 1;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(44, August, function44)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_updatePosition("122H", kCarRestaurant, 57);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (getEvent(kEventAugustMerchandise)) {
+ setCallback(4);
+ setup_function41(kCarGreenSleeping, kPosition_6470);
+ } else {
+ setCallback(2);
+ setup_function17(kTime2043000);
+ }
+ break;
+
+ case 2:
+ if (!ENTITY_PARAM(0, 1)) {
+ setCallback(4);
+ setup_function41(kCarGreenSleeping, kPosition_6470);
+ } else {
+ setCallback(3);
+ setup_savegame(kSavegameTypeEvent, kEventAugustMerchandise);
+ }
+ break;
+
+ case 3:
+ getAction()->playAnimation(kEventAugustMerchandise);
+ if (getData()->car == kCarGreenSleeping && getEntities()->checkDistanceFromPosition(kEntityAugust, kPosition_6470, 500))
+ getData()->entityPosition = kPosition_5970;
+
+ getEntities()->updateEntity(kEntityAugust, kCarGreenSleeping, kPosition_6470);
+
+ getEntities()->loadSceneFromEntityPosition(getData()->car,
+ (EntityPosition)(getData()->entityPosition + 750 * (getData()->direction == kDirectionUp ? -1 : 1)),
+ getData()->direction == kDirectionUp);
+
+ setCallback(4);
+ setup_function41(kCarGreenSleeping, kPosition_6470);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_function19(true, false);
+ break;
+
+ case 5:
+ setup_function45();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(45, August, function45)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime2061000 && !params->param1) {
+ params->param1 = 1;
+ getData()->inventoryItem = kItemNone;
+
+ setup_function46();
+ }
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+ getSound()->playSound(kEntityPlayer, "CAT1002");
+ getSound()->playSound(kEntityAugust, "AUG3102", SoundManager::kFlagInvalid, 15);
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocation2, kCursorNormal, kCursorNormal);
+ getEntities()->drawSequenceLeft(kEntityAugust, "506A2");
+ getData()->inventoryItem = kItem146; // TODO which item is that?
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(46, August, function46)
+ switch (savepoint.action) {
+ default:
+ TIME_CHECK_CALLBACK(kTime2088000, params->param1, 1, setup_function47);
+ break;
+
+ case kActionNone:
+ break;
+
+ case kActionDrawScene:
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 43)) {
+ setCallback(2);
+ setup_draw("507B2");
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setup_function48();
+ break;
+
+ case 2:
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 43))
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 34);
+
+ getEntities()->clearSequences(kEntityAugust);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(47, August, function47)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function20(true);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function41(kCarGreenSleeping, kPosition_9460);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityAugust);
+ setCallback(3);
+ setup_updateFromTime(2700);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function41(kCarGreenSleeping, kPosition_6470);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_function19(false, false);
+ break;
+
+ case 5:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(48, August, function48)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK(kTimeCityLinz, params->param1, setup_function49);
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ if (!getEvent(kEventAugustTalkCompartmentDoor) && !getEvent(kEventAugustTalkCompartmentDoorBlueRedingote)
+ && !getEvent(kEventAugustBringEgg) && !getEvent(kEventAugustBringBriefcase)) {
+
+ if (savepoint.action == kActionKnock)
+ getSound()->playSound(kEntityPlayer, "LIB012");
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAugustTalkCompartmentDoor);
+ }
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartment3, kEntityAugust, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getData()->clothes = kClothes2;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventAugustTalkCompartmentDoor);
+ getScenes()->processScene();
+
+ setCallback(2);
+ setup_function21(kTimeCityLinz);
+ break;
+
+ case 2:
+ setup_function49();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(49, August, function49)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function20(false);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarKronos, kPosition_9270);
+ break;
+
+ case 2:
+ setup_function50();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(50, August, function50)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getEntities()->clearSequences(kEntityAugust);
+
+ getData()->entityPosition = kPosition_6000;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarKronos;
+ break;
+
+ case kAction191668032:
+ setup_function51();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(51, August, function51)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarGreenSleeping;
+ getData()->entityPosition = kPosition_850;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_function42(kCarGreenSleeping, kPosition_5790, false);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityAugust, kEntityTatiana, kAction191668032);
+
+ setCallback(2);
+ setup_function42(kCarRedSleeping, kPosition_540, true);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityAugust);
+ break;
+
+ case 3:
+ getEntities()->drawSequenceLeft(kEntityAugust, "BLANK");
+ getSavePoints()->push(kEntityAugust, kEntityAnna, kAction123712592);
+ break;
+ }
+ break;
+
+ case kAction122288808:
+ setup_function52();
+ break;
+
+ case kAction122358304:
+ getEntities()->drawSequenceLeft(kEntityAugust, "BLANK");
+ break;
+
+ case kAction169032608:
+ setCallback(3);
+ setup_function42(kCarRedSleeping, kPosition_3820, true);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(52, August, function52)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ if (getInventory()->hasItem(kItemBriefcase)) {
+ getData()->location = kLocationInsideCompartment;
+ if (savepoint.action == kActionKnock)
+ getSound()->playSound(kEntityPlayer, "LIB012");
+
+ setCallback(3);
+ setup_savegame(kSavegameTypeEvent, kEventAugustBringBriefcase);
+ break;
+ }
+
+ if (getInventory()->hasItem(kItemFirebird) && !getEvent(kEventAugustBringEgg)) {
+ setCallback(4);
+ setup_savegame(kSavegameTypeEvent, kEventAugustBringEgg);
+ break;
+ }
+
+ if (!getEvent(kEventAugustTalkCompartmentDoorBlueRedingote) && !getEvent(kEventAugustBringEgg) && !getEvent(kEventAugustBringBriefcase)) {
+ if (savepoint.action == kActionKnock)
+ getSound()->playSound(kEntityPlayer, "LIB012");
+
+ setCallback(5);
+ setup_savegame(kSavegameTypeEvent, kEventAugustBringEgg);
+ break;
+ }
+
+ getObjects()->update(kObjectCompartment3, kEntityAugust, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(savepoint.action == kActionKnock ? 6 : 7);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function42(kCarGreenSleeping, kPosition_6470, true);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function19(false, true);
+ break;
+
+ case 2:
+ getObjects()->update(kObjectCompartment3, kEntityAugust, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getSavePoints()->push(kEntityAugust, kEntityKahina, kAction134611040);
+ break;
+
+ case 3:
+ getAction()->playAnimation(kEventAugustBringBriefcase);
+ getSound()->playSound(kEntityPlayer, "LIB015");
+ RESET_ENTITY_STATE(kEntitySalko, Salko, setup_function17);
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 13);
+
+ setup_function53();
+ break;
+
+ case 4:
+ getAction()->playAnimation(kEventAugustBringEgg);
+ getScenes()->processScene();
+ break;
+
+ case 5:
+ getAction()->playAnimation(kEventAugustTalkCompartmentDoorBlueRedingote);
+ getScenes()->processScene();
+ break;
+
+ case 6:
+ case 7:
+ setCallback(8);
+ setup_playSound("AUG1128F");
+ break;
+
+ case 8:
+ getObjects()->update(kObjectCompartment3, kEntityAugust, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(53, August, function53)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateFromTime(2700);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function20(false);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 3:
+ setup_function54();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(54, August, function54)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param4 || params->param2 || getProgress().field_44)
+ getData()->inventoryItem = kItemNone;
+ else
+ getData()->inventoryItem = kItemInvalid;
+
+ if (!params->param2 && params->param1) {
+ UPDATE_PARAM(params->param5, getState()->time, params->param1);
+
+ getData()->inventoryItem = kItemNone;
+ setup_function55();
+ }
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(3);
+ setup_savegame(kSavegameTypeEvent, kEventAugustTalkCigar);
+ break;
+
+ case kActionExitCompartment:
+ getEntities()->updatePositionExit(kEntityAugust, kCarRestaurant, 57);
+ getEntities()->drawSequenceLeft(kEntityAugust, "105B3");
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case kActionDrawScene:
+ if (!getEntities()->isPlayerPosition(kCarRestaurant, 60) || params->param3) {
+ if (!params->param2 && getEntities()->isPlayerPosition(kCarRestaurant, 57))
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 50);
+ } else if (!params->param2) {
+ getEntities()->updatePositionEnter(kEntityAugust, kCarRestaurant, 57);
+ getEntities()->drawSequenceRight(kEntityAugust, "105C3");
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_updatePosition("105A3", kCarRestaurant, 57);
+ break;
+
+ case 2:
+ getData()->location = kLocationInsideCompartment;
+ getSavePoints()->push(kEntityAugust, kEntityAbbot, kAction123712592);
+ getEntities()->drawSequenceLeft(kEntityAugust, "105B3");
+ params->param4 = 1;
+ break;
+
+ case 3:
+ getAction()->playAnimation(kEventAugustTalkCigar);
+ getEntities()->drawSequenceLeft(kEntityAugust, params->param3 ? "122B" : "105B3");
+ getScenes()->processScene();
+
+ params->param1 = 9000;
+ params->param4 = 0;
+ break;
+ }
+ break;
+
+ case kAction122288808:
+ getEntities()->drawSequenceLeft(kEntityAugust, "122B");
+ params->param2 = 0;
+
+ if (getEvent(kEventAugustTalkCigar))
+ params->param1 = 9000;
+ break;
+
+ case kAction122358304:
+ getEntities()->drawSequenceLeft(kEntityAugust, "BLANK");
+ params->param2 = 1;
+ params->param3 = 1;
+ break;
+
+ case kAction136196244:
+ params->param2 = 1;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(55, August, function55)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_updatePosition("105D3", kCarRestaurant, 57);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_updateEntity(kCarGreenSleeping, kPosition_6470);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function19(true, false);
+ break;
+
+ case 4:
+ setup_function56();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(56, August, function56)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocation2, kCursorNormal, kCursorNormal);
+ getEntities()->drawSequenceLeft(kEntityAugust, "507A3");
+ break;
+
+ case kActionDrawScene:
+ if (!params->param1 && getEntities()->isPlayerPosition(kCarGreenSleeping, 43)) {
+ setCallback(1);
+ setup_draw("507B3");
+ }
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ params->param1 = 1;
+ getEntities()->drawSequenceLeft(kEntityAugust, "507A3");
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(57, August, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAugust);
+
+ getData()->entityPosition = kPosition_6470;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ getData()->clothes = kClothes2;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocation2, kCursorNormal, kCursorNormal);
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(58, August, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function20(false);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(4);
+ setup_draw("803WS");
+ break;
+
+ case 4:
+ getEntities()->drawSequenceRight(kEntityAugust, "010A3");
+ if (getEntities()->isInSalon(kEntityPlayer))
+ getEntities()->updateFrame(kEntityAugust);
+
+ setCallback(5);
+ setup_callSavepointNoDrawing(kEntityTables3, kAction136455232, "BOGUS");
+ break;
+
+ case 5:
+ getData()->location = kLocationInsideCompartment;
+ setup_function59();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(59, August, function59)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityAugust, "010B3");
+ getSavePoints()->push(kEntityAugust, kEntityPascale, kAction190605184);
+ break;
+
+ case kAction122358304:
+ getEntities()->drawSequenceLeft(kEntityAugust, "BLANK");
+ break;
+
+ case kAction123793792:
+ setup_function60();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(60, August, function60)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone: {
+ bool pushSavepoint = false;
+ if (!params->param2) {
+ pushSavepoint = true;
+ params->param2 = getState()->time + 450;
+ }
+
+ if (params->param2 < getState()->time) {
+ pushSavepoint = true;
+ params->param2 = kTimeInvalid;
+ }
+
+ if (pushSavepoint)
+ getSavePoints()->push(kEntityAugust, kEntityServers0, kAction207330561);
+
+ if (!params->param1)
+ break;
+
+ UPDATE_PARAM(params->param3, getState()->time, 9000);
+
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ }
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityAugust, "010B3");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_callSavepoint("010J3", kEntityTables3, kActionDrawTablesWithChairs, "010M");
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityAugust, kEntityServers0, kAction286403504);
+ setup_function61();
+ break;
+ }
+ break;
+
+ case kAction122288808:
+ getEntities()->drawSequenceLeft(kEntityAugust, "010B3");
+ break;
+
+ case kAction122358304:
+ getEntities()->drawSequenceLeft(kEntityAugust, "BLANK");
+ break;
+
+ case kAction201964801:
+ getEntities()->drawSequenceLeft(kEntityAugust, "010H3");
+ params->param1 = 1;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(61, August, function61)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->location = kLocationOutsideCompartment;
+ getEntities()->drawSequenceRight(kEntityAugust, "803FS");
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityAugust);
+
+ setCallback(1);
+ setup_callbackActionOnDirection();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarGreenSleeping, kPosition_6470);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function19(false, false);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function21((TimeValue)(getState()->time + 4500));
+ break;
+
+ case 4:
+ setup_function62();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(62, August, function62)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param1, getState()->time, 900);
+
+ getSound()->playSound(kEntityAugust, "Aug4003A");
+
+ setCallback(5);
+ setup_updatePosition("122C", kCarRestaurant, 57);
+ break;
+
+ case kActionDefault:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_enterExitCompartment("696Ec", kObjectCompartment3);
+ break;
+
+ case kActionDrawScene:
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 57))
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 50);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(4);
+ setup_updatePosition("122A", kCarRestaurant, 57);
+ break;
+
+ case 4:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->drawSequenceLeft(kEntityAugust, "122B");
+ break;
+
+ case 5:
+ getEntities()->drawSequenceLeft(kEntityAugust, "122B");
+ getSavePoints()->push(kEntityAugust, kEntityServers1, kAction291721418);
+ break;
+ }
+ break;
+
+ case kAction122358304:
+ getEntities()->drawSequenceLeft(kEntityAugust, "BLANK");
+ break;
+
+ case kAction125826561:
+ setup_function63();
+ break;
+
+ case kAction134486752:
+ getEntities()->drawSequenceLeft(kEntityAugust, "122B");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(63, August, function63)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM_PROC(params->param3, getState()->time, 1800)
+ getData()->inventoryItem = kItemInvalid;
+ UPDATE_PARAM_PROC_END
+
+ if (getState()->time > kTime2488500 && !params->param4) {
+ params->param4 = 1;
+ getData()->inventoryItem = kItemNone;
+ setup_function64();
+ break;
+ }
+
+ UPDATE_PARAM(params->param5, getState()->timeTicks, params->param1);
+
+ params->param2 = (params->param6 < 1 ? 1 : 0);
+
+ getEntities()->drawSequenceLeft(kEntityAugust, params->param2 ? "122H" : "122F");
+
+ params->param1 = 5 * (3 * rnd(20) + 15);
+ params->param5 = 0;
+ break;
+
+ case kAction1:
+ if (getEntities()->isInSalon(kEntityAlexei))
+ RESET_ENTITY_STATE(kEntityAlexei, Alexei, setup_function44);
+
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAugustDrink);
+ break;
+
+ case kActionDefault:
+ params->param1 = 5 * (3 * rnd(20) + 15);
+ getEntities()->drawSequenceLeft(kEntityAugust, "122F");
+ break;
+
+ case kActionDrawScene:
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 57))
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 50);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventAugustDrink);
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 55);
+
+ setup_function64();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(64, August, function64)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1)
+ params->param1 = getState()->time + 1800;
+
+ if (params->param1 >= getState()->time)
+ break;
+
+ if (getState()->time > kTime2430000 && getEntities()->isSomebodyInsideRestaurantOrSalon()) {
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_updatePosition("122J", kCarRestaurant, 57);
+ }
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityAugust, "122H");
+ break;
+
+ case kActionDrawScene:
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 57))
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 50);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarGreenSleeping, kPosition_6470);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_enterExitCompartment2("696Dc", kObjectCompartment3);
+ break;
+
+ case 3:
+ getEntities()->clearSequences(kEntityAugust);
+ setup_function65();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(65, August, function65)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionEndSound:
+ getSound()->playSound(kEntityAugust, "AUG1057"); // August snoring
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_6470;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+
+ getEntities()->clearSequences(kEntityAugust);
+
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ if (!getSound()->isBuffered(kEntityAugust))
+ getSound()->playSound(kEntityAugust, "AUG1057"); // August snoring
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(66, August, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityAugust);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothes2;
+ getData()->inventoryItem = kItemNone;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(67, August, chapter5Handler)
+ if (savepoint.action == kActionProceedChapter5)
+ setup_function68();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(68, August, function68)
+ error("August: callback function 68 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(69, August, unhookCars)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ getSavePoints()->pushAll(kEntityAugust, kAction135800432);
+ setup_nullfunction();
+ break;
+
+ case kActionDefault:
+ getSound()->processEntries();
+ if (getSound()->isBuffered("ARRIVE"))
+ getSound()->removeFromQueue("ARRIVE");
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventAugustUnhookCarsBetrayal);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(getProgress().field_C ? kEventAugustUnhookCarsBetrayal : kEventAugustUnhookCars);
+ getEntities()->clearSequences(kEntityAugust);
+ getSound()->resetState();
+ getSound()->playSound(kEntityPlayer, "MUS050");
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 85, 1);
+ getSavePoints()->pushAll(kEntityAugust, kActionProceedChapter5);
+
+ RESET_ENTITY_STATE(kEntityVerges, Verges, setup_function42)
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_NULL_FUNCTION(70, August)
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/august.h b/engines/lastexpress/entities/august.h
new file mode 100644
index 0000000000..e684fc0361
--- /dev/null
+++ b/engines/lastexpress/entities/august.h
@@ -0,0 +1,275 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_AUGUST_H
+#define LASTEXPRESS_AUGUST_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class August : public Entity {
+public:
+ August(LastExpressEngine *engine);
+ ~August() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param time The time to add
+ */
+ DECLARE_FUNCTION_1(updateFromTime, uint32 time)
+
+ /**
+ * Draws the entity
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(draw, const char* sequence)
+
+ /**
+ * Updates the position
+ *
+ * @param sequence1 The sequence to draw
+ * @param car The car
+ * @param position The position
+ */
+ DECLARE_FUNCTION_3(updatePosition, const char* sequence1, CarIndex car, Position position)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Handles entering/exiting a compartment and updates position/play animation
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment2, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment3, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Process callback action when the entity direction is not kDirectionRight
+ */
+ DECLARE_FUNCTION(callbackActionOnDirection)
+
+ /**
+ * Call a savepoint (or draw sequence in default case)
+ *
+ * @param sequence1 The sequence to draw in the default case
+ * @param entity The entity
+ * @param action The action
+ * @param sequence2 The sequence name for the savepoint
+ */
+ DECLARE_FUNCTION_4(callSavepoint, const char* sequence1, EntityIndex entity, ActionIndex action, const char* sequence2)
+
+ /**
+ * Call a savepoint
+ *
+ * @param param1 The entity
+ * @param param2 The action
+ * @param seq The sequence name for the savepoint
+ */
+ DECLARE_FUNCTION_3(callSavepointNoDrawing, EntityIndex entity, ActionIndex action, const char* sequence)
+
+ /**
+ * Draws the entity along with another one
+ *
+ * @param sequence1 The sequence to draw
+ * @param sequence2 The sequence to draw for the second entity
+ * @param entity The EntityIndex of the second entity
+ */
+ DECLARE_FUNCTION_3(draw2, const char* sequence1, const char* sequence2, EntityIndex entity)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound16, const char* filename)
+
+ /**
+ * Process callback action when somebody is standing in the restaurant or salon.
+ */
+ DECLARE_FUNCTION(callbackActionRestaurantOrSalon)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ DECLARE_FUNCTION_1(function17, TimeValue timeValue)
+
+ /**
+ * Updates the entity
+ *
+ * @param param1 The car
+ * @param param2 The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity2, CarIndex car, EntityPosition entityPosition)
+
+ DECLARE_FUNCTION_2(function19, bool, bool)
+
+ DECLARE_FUNCTION_1(function20, bool)
+ DECLARE_FUNCTION_1(function21, TimeValue timeValue)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ DECLARE_FUNCTION_1(function23, TimeValue timeValue)
+ DECLARE_FUNCTION(dinner)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function26)
+ DECLARE_FUNCTION(function27)
+ DECLARE_FUNCTION(function28)
+ DECLARE_FUNCTION(function29)
+ DECLARE_FUNCTION(restaurant)
+ DECLARE_FUNCTION(function31)
+ DECLARE_FUNCTION(function32)
+ DECLARE_FUNCTION(function33)
+ DECLARE_FUNCTION(function34)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+
+ DECLARE_FUNCTION(function37)
+ DECLARE_FUNCTION(function38)
+ DECLARE_FUNCTION(function39)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ DECLARE_FUNCTION_2(function41, CarIndex car, EntityPosition entityPosition)
+ DECLARE_FUNCTION_3(function42, CarIndex car, EntityPosition entityPosition, bool)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ DECLARE_FUNCTION(function44)
+ DECLARE_FUNCTION(function45)
+ DECLARE_FUNCTION(function46)
+ DECLARE_FUNCTION(function47)
+ DECLARE_FUNCTION(function48)
+ DECLARE_FUNCTION(function49)
+ DECLARE_FUNCTION(function50)
+ DECLARE_FUNCTION(function51)
+ DECLARE_FUNCTION(function52)
+ DECLARE_FUNCTION(function53)
+ DECLARE_FUNCTION(function54)
+ DECLARE_FUNCTION(function55)
+ DECLARE_FUNCTION(function56)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ DECLARE_FUNCTION(function59)
+ DECLARE_FUNCTION(function60)
+ DECLARE_FUNCTION(function61)
+ DECLARE_FUNCTION(function62)
+ DECLARE_FUNCTION(function63)
+ DECLARE_FUNCTION(function64)
+ DECLARE_FUNCTION(function65)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_FUNCTION(function68)
+ DECLARE_FUNCTION(unhookCars)
+
+ DECLARE_NULL_FUNCTION()
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_AUGUST_H
diff --git a/engines/lastexpress/entities/boutarel.cpp b/engines/lastexpress/entities/boutarel.cpp
new file mode 100644
index 0000000000..411456c5c8
--- /dev/null
+++ b/engines/lastexpress/entities/boutarel.cpp
@@ -0,0 +1,1260 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/boutarel.h"
+
+#include "lastexpress/game/action.h"
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/inventory.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+
+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(Boutarel, callbackActionOnDirection);
+ ADD_CALLBACK_FUNCTION(Boutarel, callbackActionRestaurantOrSalon);
+ ADD_CALLBACK_FUNCTION(Boutarel, updateEntity);
+ ADD_CALLBACK_FUNCTION(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(Boutarel, chapter1);
+ ADD_CALLBACK_FUNCTION(Boutarel, function20);
+ ADD_CALLBACK_FUNCTION(Boutarel, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Boutarel, function22);
+ ADD_CALLBACK_FUNCTION(Boutarel, chapter2);
+ ADD_CALLBACK_FUNCTION(Boutarel, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Boutarel, function25);
+ ADD_CALLBACK_FUNCTION(Boutarel, chapter3);
+ ADD_CALLBACK_FUNCTION(Boutarel, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Boutarel, function28);
+ ADD_CALLBACK_FUNCTION(Boutarel, function29);
+ ADD_CALLBACK_FUNCTION(Boutarel, function30);
+ ADD_CALLBACK_FUNCTION(Boutarel, chapter4);
+ ADD_CALLBACK_FUNCTION(Boutarel, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Boutarel, function33);
+ ADD_CALLBACK_FUNCTION(Boutarel, function34);
+ ADD_CALLBACK_FUNCTION(Boutarel, function35);
+ ADD_CALLBACK_FUNCTION(Boutarel, chapter5);
+ ADD_CALLBACK_FUNCTION(Boutarel, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(Boutarel, function38);
+ ADD_NULL_FUNCTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Boutarel, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(2, Boutarel, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(3, Boutarel, draw)
+ Entity::draw(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(4, Boutarel, updateFromTime, uint32)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SII(5, Boutarel, updatePosition, CarIndex, Position)
+ Entity::updatePosition(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(6, Boutarel, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(7, Boutarel, enterExitCompartment2, ObjectIndex)
+ Entity::enterExitCompartment(savepoint, kPosition_6470, kPosition_6130, kCarRedSleeping, kObjectCompartmentC, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(8, Boutarel, callbackActionOnDirection)
+ Entity::callbackActionOnDirection(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(9, Boutarel, callbackActionRestaurantOrSalon)
+ Entity::callbackActionRestaurantOrSalon(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(10, Boutarel, updateEntity, CarIndex, EntityPosition)
+ if (savepoint.action == kActionExcuseMeCath) {
+
+ if (getInventory()->hasItem(kItemPassengerList) && getState()->time > kTime1089000)
+ getSound()->playSound(kEntityPlayer, "CAT1022");
+ else
+ getSound()->excuseMeCath();
+
+ return;
+ }
+
+ Entity::updateEntity(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(11, Boutarel, function11, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (ENTITY_PARAM(0, 1) && ENTITY_PARAM(0, 2)) {
+ ENTITY_PARAM(0, 2) = 0;
+ ENTITY_PARAM(0, 1) = 0;
+
+ setCallback(5);
+ setup_callbackActionRestaurantOrSalon();
+ }
+ break;
+
+ case kActionDefault:
+ if (params->param1) {
+ if (getProgress().chapter == kChapter4) {
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ setCallback(1);
+ setup_enterExitCompartment("607Hc", kObjectCompartmentC);
+ } else {
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(2);
+ setup_enterExitCompartment("607Dc", kObjectCompartmentC);
+ }
+ } else {
+ setCallback(3);
+ setup_enterExitCompartment("607Bc", kObjectCompartmentC);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 2:
+ case 3:
+ if (getCallback() == 2)
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ else
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ // Fallback to next case
+
+ case 1:
+ getObjects()->update(kObject50, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityBoutarel, kEntityFrancois, kAction101107728);
+
+ setCallback(4);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 4:
+ getEntities()->clearSequences(kEntityBoutarel);
+ break;
+
+ case 5:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(6);
+ setup_draw("812US");
+ break;
+
+ case 6:
+ switch (getProgress().chapter) {
+ default:
+ break;
+
+ case kChapter1:
+ getSound()->playSound(kEntityBoutarel, "MRB1075", SoundManager::kFlagInvalid, 60);
+ break;
+
+ case kChapter3:
+ getSound()->playSound(kEntityBoutarel, "MRB3101");
+ break;
+ }
+
+ setCallback(7);
+ setup_enterTableWithMmeBoutarel();
+ break;
+
+ case 7:
+ getData()->location = kLocationInsideCompartment;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Boutarel, enterTableWithMmeBoutarel)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ getEntities()->clearSequences(kEntityMmeBoutarel);
+ getSavePoints()->push(kEntityBoutarel, kEntityTables2, kAction136455232);
+ getData()->location = kLocationInsideCompartment;
+
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(kEntityTables2, "008A3");
+ getEntities()->drawSequenceRight(kEntityMmeBoutarel, "008A2");
+ getEntities()->drawSequenceRight(kEntityBoutarel, "008A1");
+
+ if (getEntities()->isInSalon(kEntityPlayer)) {
+ getEntities()->updateFrame(kEntityBoutarel);
+ getEntityData(kEntityMmeBoutarel)->location = getData()->location;
+ getEntityData(kEntityTables2)->location = getData()->location;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Boutarel, leaveTableWithMmeBoutarel)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ getSavePoints()->push(kEntityBoutarel, kEntityTables2, kActionDrawTablesWithChairs, "008F");
+ getEntities()->clearSequences(kEntityMmeBoutarel);
+
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(kEntityTables2, "008E3");
+ getEntities()->drawSequenceRight(kEntityMmeBoutarel, "008E2");
+ getEntities()->drawSequenceRight(kEntityBoutarel, "008E1");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(14, Boutarel, function14, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ getSound()->playSound(kEntityBoutarel, "MRB1079");
+
+ setCallback(2);
+ setup_leaveTableWithMmeBoutarel();
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityBoutarel, kEntityServers1, kAction326144276);
+ getEntities()->drawSequenceRight(kEntityBoutarel, "812DS");
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityBoutarel);
+
+ setCallback(3);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 3:
+ getEntityData(kEntityFrancois)->entityPosition = kPosition_540;
+ getEntityData(kEntityMmeBoutarel)->entityPosition = kPosition_540;
+ getData()->entityPosition = kPosition_540;
+
+ getEntityData(kEntityFrancois)->location = kLocationOutsideCompartment;
+ getEntityData(kEntityMmeBoutarel)->location = kLocationOutsideCompartment;
+
+ getEntities()->clearSequences(kEntityBoutarel);
+ getSavePoints()->push(kEntityBoutarel, kEntityMmeBoutarel, kAction100901266);
+
+ setCallback(4);
+ setup_updateFromTime(450);
+ break;
+
+ case 4:
+ getSavePoints()->push(kEntityBoutarel, kEntityFrancois, kAction100901266);
+
+ setCallback(5);
+ setup_updateFromTime(450);
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_updateEntity(kCarRedSleeping, kPosition_6470);
+ break;
+
+ case 6:
+ setCallback(params->param1 ? 7: 8);
+ setup_enterExitCompartment2(params->param1 ? "607Gc" : "607Ac", kObjectCompartmentC);
+ break;
+
+ case 7:
+ case 8:
+ getEntities()->clearSequences(kEntityBoutarel);
+ getData()->location = kLocationInsideCompartment;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_IS(15, Boutarel, function15, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (params->param1)
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(params->param1 ? 1 : 2);
+ setup_enterExitCompartment(params->param1 ? "607Dc" : "607Bc", kObjectCompartmentC);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getObjects()->update(kObject50, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ setCallback(3);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject50, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ setCallback(3);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 4:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(5);
+ setup_updatePosition(params->seq, kCarRestaurant, 52);
+ break;
+
+ case 5:
+ getData()->location = kLocationInsideCompartment;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Parameters:
+// bool
+// const char *
+IMPLEMENT_FUNCTION_IS(16, Boutarel, function16, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_updatePosition((const char *)&params->seq, kCarRestaurant, 52);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_updateEntity(kCarRedSleeping, kPosition_6470);
+ break;
+
+ case 3:
+ setCallback(params->param1 ? 4 : 5);
+ setup_enterExitCompartment2(params->param1 ? "607Gc" : "607Ac", kObjectCompartmentC);
+ break;
+
+ case 4:
+ case 5:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityBoutarel);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_IS(17, Boutarel, function17, TimeValue)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CALLBACK_ACTION(params->param1, params->param6);
+
+ if (params->param5) {
+ UPDATE_PARAM(params->param7, getState()->timeTicks, 90)
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 51);
+ } else {
+ params->param7 = 0;
+ }
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityBoutarel, (char *)&params->seq);
+ break;
+
+ case kActionDrawScene:
+ params->param5 = (getEntities()->isPlayerPosition(kCarRestaurant, 52) ? 1 : 0);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(18, Boutarel, function18, TimeValue)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1 < getState()->time && !params->param4) {
+ params->param4 = 1;
+
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject50, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (params->param2) {
+ UPDATE_PARAM(params->param5, getState()->timeTicks, 75);
+
+ params->param2 = 0;
+ params->param3 = 1;
+
+ getObjects()->update(kObjectCompartmentC, kEntityBoutarel, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject50, kEntityBoutarel, kObjectLocation1, kCursorNormal, kCursorNormal);
+ }
+
+ params->param5 = 0;
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ getObjects()->update(kObjectCompartmentC, kEntityBoutarel, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject50, kEntityBoutarel, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ if (params->param2) {
+ if (savepoint.param.intValue == 50) {
+ setCallback(4);
+ setup_playSound(getSound()->justAMinuteCath());
+ } else if (getInventory()->hasItem(kItemPassengerList)) {
+ setCallback(5);
+ setup_playSound(rnd(2) ? "CAT1511" : getSound()->wrongDoorCath());
+ } else {
+ setCallback(6);
+ setup_playSound(getSound()->wrongDoorCath());
+ }
+ } else {
+ setCallback(savepoint.action == kActionKnock ? 1 : 2);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ }
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentC, kEntityBoutarel, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject50, kEntityBoutarel, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionDrawScene:
+ if (params->param3 || params->param2) {
+ getObjects()->update(kObjectCompartmentC, kEntityBoutarel, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject50, kEntityBoutarel, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ params->param2 = 0;
+ params->param3 = 0;
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ setCallback(3);
+ setup_playSound(rnd(2) ? "MRB1001" : "MRB1001A");
+ break;
+
+ case 3:
+ getObjects()->update(kObjectCompartmentC, kEntityBoutarel, kObjectLocation1, kCursorTalk, kCursorNormal);
+ getObjects()->update(kObject50, kEntityBoutarel, kObjectLocation1, kCursorTalk, kCursorNormal);
+
+ params->param2 = 1;
+ break;
+
+ case 4:
+ case 5:
+ case 6:
+ params->param2 = 0;
+ params->param3 = 1;
+ break;
+
+ case 7:
+ getSavePoints()->push(kEntityBoutarel, kEntityCoudert, kAction123199584);
+ break;
+
+ }
+ break;
+
+ case kAction122865568:
+ getSavePoints()->push(kEntityBoutarel, kEntityCoudert, kAction88652208);
+ break;
+
+ case kAction221683008:
+ setCallback(7);
+ setup_playSound("MRB1001");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Boutarel, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getSavePoints()->addData(kEntityBoutarel, kAction203520448, 0);
+ getSavePoints()->addData(kEntityBoutarel, kAction237889408, 1);
+
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject50, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject42, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ getData()->entityPosition = kPosition_1750;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Boutarel, function20)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1)
+ break;
+
+ if (!params->param2) {
+ UPDATE_PARAM_PROC(params->param3, getState()->time, 4500)
+ setCallback(3);
+ setup_playSound("MRB1078A");
+ break;
+ UPDATE_PARAM_PROC_END
+ }
+
+ TIME_CHECK_CALLBACK_1(kTime1138500, params->param4, 4, setup_function14, false);
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function11(false);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceLeft(kEntityBoutarel, "008B");
+
+ setCallback(2);
+ setup_playSound("MRB1076");
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityBoutarel, kEntityServers1, kAction256200848);
+ break;
+
+ case 3:
+ TIME_CHECK_CALLBACK_1(kTime1138500, params->param4, 4, setup_function14, false);
+ break;
+
+ case 4:
+ getSavePoints()->push(kEntityBoutarel, kEntityCooks, kAction224849280);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction134466544:
+ params->param2 = 0;
+ break;
+
+ case kAction135854206:
+ params->param2 = 1;
+ break;
+
+ case kAction168717392:
+ params->param1 = 1;
+ getEntities()->drawSequenceLeft(kEntityBoutarel, "008D");
+
+ if (!params->param2) {
+ setCallback(5);
+ setup_playSound("MRB1078");
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Boutarel, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function17(kTime1071000, "101A");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function16(false, "101B");
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function18(kTime1102500);
+ break;
+
+ case 3:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject50, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ if (getEntities()->isPlayerPosition(kCarRedSleeping, 54) || getEntities()->isPlayerPosition(kCarRedSleeping, 44))
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 10);
+
+ getEntities()->updatePositionExit(kEntityBoutarel, kCarRedSleeping, 54);
+ getEntities()->updatePositionExit(kEntityBoutarel, kCarRedSleeping, 44);
+
+ setCallback(4);
+ setup_playSound("MRB1074");
+ break;
+
+ case 4:
+ getEntities()->updatePositionExit(kEntityBoutarel, kCarRedSleeping, 54);
+ getEntities()->updatePositionExit(kEntityBoutarel, kCarRedSleeping, 44);
+
+ setCallback(5);
+ setup_function20();
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_function18(kTimeEnterChalons);
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_function15(false, "102A");
+ break;
+
+ case 7:
+ setCallback(8);
+ setup_function17(kTime1183500, "102B");
+ break;
+
+ case 8:
+ setCallback(9);
+ setup_function16(false, "102C");
+ break;
+
+ case 9:
+ setCallback(10);
+ setup_function18(kTime1215000);
+ break;
+
+ case 10:
+ setup_function22();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Boutarel, function22)
+ if (savepoint.action == kActionDefault) {
+ getData()->entityPosition = kPosition_6470;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject50, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ getEntities()->clearSequences(kEntityBoutarel);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Boutarel, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter2Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityBoutarel);
+
+ getData()->entityPosition = kPosition_4689;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject50, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Boutarel, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CALLBACK_1(kTime1759500, params->param2, 1, setup_function14, false);
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityBoutarel, "008D");
+ break;
+
+ case kActionDrawScene:
+ if (getEntities()->isInRestaurant(kEntityPlayer) && !params->param1) {
+ getSound()->playSound(kEntityBoutarel, "MRB2001");
+ params->param1 = 1;
+ }
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function25();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, Boutarel, function25)
+ if (savepoint.action == kActionDefault) {
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getEntities()->drawSequenceLeft(kEntityBoutarel, "510");
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(26, Boutarel, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityBoutarel);
+
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getObjects()->update(kObject50, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(27, Boutarel, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getEntities()->drawSequenceLeft(kEntityBoutarel, "510");
+ break;
+
+ case kAction122288808:
+ setup_function28();
+ break;
+
+ case kAction122358304:
+ getEntities()->drawSequenceLeft(kEntityBoutarel, "BLANK");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(28, Boutarel, function28)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function11(true);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function29();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(29, Boutarel, function29)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM_PROC(params->param2, getState()->time, 450)
+ getSavePoints()->push(kEntityBoutarel, kEntityServers1, kAction256200848);
+ UPDATE_PARAM_PROC_END
+
+ if (!params->param1)
+ break;
+
+ if (getEntities()->isInRestaurant(kEntityAnna)
+ && getEntities()->isInRestaurant(kEntityAugust)
+ && !getSound()->isBuffered(kEntityBoutarel)
+ && params->param3 != kTimeInvalid) {
+
+ if (getState()->time <= kTime1998000)
+ if (!getEntities()->isInRestaurant(kEntityPlayer) || !params->param3)
+ params->param3 = getState()->time + 450;
+
+ if (params->param3 < getState()->time || getState()->time > kTime1998000) {
+ params->param3 = kTimeInvalid;
+
+ setCallback(1);
+ setup_playSound("MRB3102");
+ break;
+ }
+ }
+
+ TIME_CHECK_CALLBACK_1(kTime2002500, params->param4, 1, setup_function14, true);
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityBoutarel, "008B");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ TIME_CHECK_CALLBACK_1(kTime2002500, params->param4, 1, setup_function14, true);
+ break;
+
+ case 2:
+ setup_function30();
+ break;
+ }
+ break;
+
+ case kAction122288808:
+ getEntities()->drawSequenceLeft(kEntityBoutarel, "008D");
+ params->param1 = 1;
+ break;
+
+ case kAction122358304:
+ getEntities()->drawSequenceLeft(kEntityBoutarel, "BLANK");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(30, Boutarel, function30)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getEntities()->drawSequenceLeft(kEntityBoutarel, "510");
+ break;
+
+ case kAction122288808:
+ getEntities()->drawSequenceLeft(kEntityBoutarel, "510");
+ break;
+
+ case kAction122358304:
+ getEntities()->drawSequenceLeft(kEntityBoutarel, "BLANK");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(31, Boutarel, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityBoutarel);
+
+ getData()->entityPosition = kPosition_6470;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getObjects()->update(kObject50, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(32, Boutarel, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK(kTime2367000, params->param1, setup_function33);
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getEntities()->drawSequenceLeft(kEntityBoutarel, "510");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(33, Boutarel, function33)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1)
+ TIME_CHECK_CALLBACK_1(kTime2389500, params->param2, 3, setup_function14, false);
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function11(true);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceLeft(kEntityBoutarel, "008B");
+
+ setCallback(2);
+ setup_updateFromTime(450);
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityBoutarel, kEntityServers1, kAction256200848);
+ break;
+
+ case 3:
+ setup_function34();
+ break;
+ }
+ break;
+
+ case kAction122288808:
+ params->param1 = 1;
+ getEntities()->drawSequenceLeft(kEntityBoutarel, "008D");
+ break;
+
+ case kAction122358304:
+ getEntities()->drawSequenceLeft(kEntityBoutarel, "BLANK");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(34, Boutarel, function34)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK(kTime2470500, params->param1, setup_function35);
+
+ if (getState()->time > kTime2457000 && getEvent(kEventAugustDrink)) {
+ getSavePoints()->push(kEntityBoutarel, kEntityAbbot, kAction159003408);
+
+ setCallback(1);
+ setup_function15(false, "102A");
+ }
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityBoutarel, kEntityAbbot, kAction101687594);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function17(kTime2479500, "102B");
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function16(false, "102C");
+ break;
+
+ case 3:
+ case 7:
+ setup_function35();
+ break;
+
+ case 4:
+ case 8:
+ if (getState()->time >= kTime2470500) {
+ setup_function35();
+ break;
+ }
+
+ if (getEvent(kEventAugustDrink)) {
+ setCallback(5);
+ setup_function15(false, "102A");
+ } else {
+ setCallback(8);
+ setup_function18((TimeValue)(getState()->time + 900));
+ }
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_function17(kTime2479500, "102B");
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_function16(false, "102C");
+ break;
+
+ case 9:
+ getSavePoints()->push(kEntityBoutarel, kEntityCoudert, kAction123199584);
+ break;
+ }
+ break;
+
+ case kAction122865568:
+ getSavePoints()->push(kEntityBoutarel, kEntityCoudert, kAction88652208);
+ break;
+
+ case kAction125039808:
+ setCallback(4);
+ setup_function18(kTime2457000);
+ break;
+
+ case kAction221683008:
+ setCallback(9);
+ setup_playSound("Mrb1001");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(35, Boutarel, function35)
+ if (savepoint.action == kActionDefault) {
+ getData()->entityPosition = kPosition_6470;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getEntities()->clearSequences(kEntityBoutarel);
+
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject50, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(36, Boutarel, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityBoutarel);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(37, Boutarel, chapter5Handler)
+ if (savepoint.action == kActionProceedChapter5)
+ setup_function38();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(38, Boutarel, function38)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ break;
+
+ case kAction135800432:
+ setup_nullfunction();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_NULL_FUNCTION(39, Boutarel)
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/boutarel.h b/engines/lastexpress/entities/boutarel.h
new file mode 100644
index 0000000000..22f8e62b62
--- /dev/null
+++ b/engines/lastexpress/entities/boutarel.h
@@ -0,0 +1,188 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_BOUTAREL_H
+#define LASTEXPRESS_BOUTAREL_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Boutarel : public Entity {
+public:
+ Boutarel(LastExpressEngine *engine);
+ ~Boutarel() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Draws the entity
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(draw, const char* sequence)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param time The time to add
+ */
+ DECLARE_FUNCTION_1(updateFromTime, uint32 time)
+
+ /**
+ * Updates the position
+ *
+ * @param sequence1 The sequence to draw
+ * @param car The car
+ * @param position The position
+ */
+ DECLARE_FUNCTION_3(updatePosition, const char* sequence1, CarIndex car, Position position)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Handles entering/exiting a compartment and updates position/play animation
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment2, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Process callback action when the entity direction is not kDirectionRight
+ */
+ DECLARE_FUNCTION(callbackActionOnDirection)
+
+ /**
+ * Process callback action when somebody is standing in the restaurant or salon.
+ */
+ DECLARE_FUNCTION(callbackActionRestaurantOrSalon)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ DECLARE_FUNCTION_1(function11, bool)
+ DECLARE_FUNCTION(enterTableWithMmeBoutarel)
+ DECLARE_FUNCTION(leaveTableWithMmeBoutarel)
+ DECLARE_FUNCTION_1(function14, bool)
+ DECLARE_FUNCTION_2(function15, bool, const char *sequence)
+ DECLARE_FUNCTION_2(function16, bool, const char *sequence)
+ DECLARE_FUNCTION_2(function17, TimeValue timeValue, const char *sequence)
+ DECLARE_FUNCTION_1(function18, TimeValue timeValue)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+ DECLARE_FUNCTION(function20)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function22)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+
+ DECLARE_FUNCTION(function25)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ DECLARE_FUNCTION(function28)
+ DECLARE_FUNCTION(function29)
+ DECLARE_FUNCTION(function30)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ DECLARE_FUNCTION(function33)
+ DECLARE_FUNCTION(function34)
+ DECLARE_FUNCTION(function35)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_FUNCTION(function38)
+ DECLARE_NULL_FUNCTION()
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_BOUTAREL_H
diff --git a/engines/lastexpress/entities/chapters.cpp b/engines/lastexpress/entities/chapters.cpp
new file mode 100644
index 0000000000..1bf3ee3f71
--- /dev/null
+++ b/engines/lastexpress/entities/chapters.cpp
@@ -0,0 +1,1810 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/chapters.h"
+
+#include "lastexpress/entities/abbot.h"
+#include "lastexpress/entities/alexei.h"
+#include "lastexpress/entities/alouan.h"
+#include "lastexpress/entities/anna.h"
+#include "lastexpress/entities/august.h"
+#include "lastexpress/entities/boutarel.h"
+#include "lastexpress/entities/coudert.h"
+#include "lastexpress/entities/cooks.h"
+#include "lastexpress/entities/francois.h"
+#include "lastexpress/entities/gendarmes.h"
+#include "lastexpress/entities/hadija.h"
+#include "lastexpress/entities/ivo.h"
+#include "lastexpress/entities/kahina.h"
+#include "lastexpress/entities/kronos.h"
+#include "lastexpress/entities/mahmud.h"
+#include "lastexpress/entities/max.h"
+#include "lastexpress/entities/mertens.h"
+#include "lastexpress/entities/milos.h"
+#include "lastexpress/entities/mmeboutarel.h"
+#include "lastexpress/entities/pascale.h"
+#include "lastexpress/entities/rebecca.h"
+#include "lastexpress/entities/salko.h"
+#include "lastexpress/entities/servers0.h"
+#include "lastexpress/entities/servers1.h"
+#include "lastexpress/entities/sophie.h"
+#include "lastexpress/entities/tatiana.h"
+#include "lastexpress/entities/vassili.h"
+#include "lastexpress/entities/verges.h"
+#include "lastexpress/entities/vesna.h"
+#include "lastexpress/entities/yasmin.h"
+
+#include "lastexpress/game/action.h"
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/inventory.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/menu.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/resource.h"
+
+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(Chapters, chapter1);
+ ADD_CALLBACK_FUNCTION(Chapters, resetMainEntities);
+ ADD_CALLBACK_FUNCTION(Chapters, chapter1End);
+ ADD_CALLBACK_FUNCTION(Chapters, chapter1Init);
+ ADD_CALLBACK_FUNCTION(Chapters, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Chapters, chapter1Next);
+ ADD_CALLBACK_FUNCTION(Chapters, chapter2);
+ ADD_CALLBACK_FUNCTION(Chapters, chapter2Init);
+ ADD_CALLBACK_FUNCTION(Chapters, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Chapters, chapter3);
+ ADD_CALLBACK_FUNCTION(Chapters, chapter3Init);
+ ADD_CALLBACK_FUNCTION(Chapters, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Chapters, viennaEvents);
+ ADD_CALLBACK_FUNCTION(Chapters, chapter4);
+ 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);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(1, Chapters, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(2, Chapters, enterStation, CityIndex)
+ enterExitStation(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(3, Chapters, exitStation)
+ enterExitStation(savepoint, false);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(4, Chapters, chapter1)
+ if (savepoint.action == kActionDefault) {
+ getSavePoints()->addData(kEntityChapters, kAction171843264, 0);
+ setup_chapter1Init();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(5, Chapters, resetMainEntities)
+ if (savepoint.action != kActionDefault)
+ return;
+
+ RESET_ENTITY_STATE(kEntityAbbot, Abbot, setup_reset);
+ RESET_ENTITY_STATE(kEntityAlexei, Alexei, setup_reset);
+ RESET_ENTITY_STATE(kEntityAlouan, Alouan, setup_reset);
+ RESET_ENTITY_STATE(kEntityAnna, Anna, setup_reset);
+ RESET_ENTITY_STATE(kEntityAugust, August, setup_reset);
+ RESET_ENTITY_STATE(kEntityMertens, Mertens, setup_reset);
+ RESET_ENTITY_STATE(kEntityCoudert, Coudert, setup_reset);
+ RESET_ENTITY_STATE(kEntityFrancois, Francois, setup_reset);
+ RESET_ENTITY_STATE(kEntityHadija, Hadija, setup_reset);
+ RESET_ENTITY_STATE(kEntityIvo, Ivo, setup_reset);
+ RESET_ENTITY_STATE(kEntityKahina, Kahina, setup_reset);
+ RESET_ENTITY_STATE(kEntityMmeBoutarel, MmeBoutarel, setup_reset);
+ RESET_ENTITY_STATE(kEntityMahmud, Mahmud, setup_reset);
+ RESET_ENTITY_STATE(kEntityMax, Max, setup_reset);
+ RESET_ENTITY_STATE(kEntityMilos, Milos, setup_reset);
+ RESET_ENTITY_STATE(kEntityBoutarel, Boutarel, setup_reset);
+ RESET_ENTITY_STATE(kEntityGendarmes, Gendarmes, setup_reset);
+ RESET_ENTITY_STATE(kEntityRebecca, Rebecca, setup_reset);
+ RESET_ENTITY_STATE(kEntitySalko, Salko, setup_reset);
+ RESET_ENTITY_STATE(kEntitySophie, Sophie, setup_reset);
+ RESET_ENTITY_STATE(kEntityTatiana, Tatiana, setup_reset);
+ RESET_ENTITY_STATE(kEntityVerges, Verges, setup_reset);
+ RESET_ENTITY_STATE(kEntityVassili, Vassili, setup_reset);
+ RESET_ENTITY_STATE(kEntityVesna, Vesna, setup_reset);
+ RESET_ENTITY_STATE(kEntityYasmin, Yasmin, setup_reset);
+
+ CALLBACK_ACTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(6,Chapters, chapter1End)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionEndSound:
+ getSound()->playSound(kEntityChapters, "MUS0009", SoundManager::kFlagDefault);
+ break;
+
+ case kActionKnock:
+ if (!getSound()->isBuffered("LIB012", true))
+ getSound()->playSound(kEntityPlayer, "LIB012");
+ break;
+
+ case kActionOpenDoor:
+ if (params->param1) {
+ getEntities()->clearSequences(kEntityChapters);
+ getSound()->processEntry(kEntityChapters);
+ getSound()->playSound(kEntityPlayer, "LIB014");
+ getSound()->resetState();
+
+ ENTITY_PARAM(0, 4) = 7;
+
+ getSound()->playSteam(kCityPolice);
+
+ getAction()->playAnimation(kEventCathDream);
+
+ getState()->timeDelta = 3;
+ getProgress().field_18 = 1;
+ getProgress().field_84 = 0;
+
+ getObjects()->update(kObject63, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ getScenes()->loadScene(kScene41);
+
+ CALLBACK_ACTION();
+ } else {
+ getSound()->playSound(kEntityPlayer, "LIB014");
+ getSound()->playSound(kEntityPlayer, "LIB015", SoundManager::kFlagDefault, 15);
+
+ if (!getSound()->isBuffered(kEntityChapters))
+ getSound()->playSound(kEntityChapters, "MUS009", SoundManager::kFlagDefault);
+
+ getScenes()->loadSceneFromPosition(kCarLocomotive, 38);
+
+ getObjects()->update(kObject63, kEntityChapters, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ params->param1 = 1;
+ }
+ break;
+
+ case kActionDefault:
+ RESET_ENTITY_STATE(kEntityPascale, Pascale, setup_function19);
+ RESET_ENTITY_STATE(kEntityServers0, Servers0, setup_function22);
+ RESET_ENTITY_STATE(kEntityServers1, Servers1, setup_function16);
+ RESET_ENTITY_STATE(kEntityCooks, Cooks, setup_function7);
+
+ RESET_ENTITY_STATE(kEntityMertens, Mertens, setup_function42);
+ RESET_ENTITY_STATE(kEntityCoudert, Coudert, setup_chapter1Handler);
+ RESET_ENTITY_STATE(kEntityVerges, Verges, setup_chapter1Handler);
+
+ getSavePoints()->push(kEntityChapters, kEntityMertens, kAction201431954);
+ getSavePoints()->push(kEntityChapters, kEntityCoudert, kAction201431954);
+ getSavePoints()->push(kEntityChapters, kEntityVerges, kAction201431954);
+
+ RESET_ENTITY_STATE(kEntityKronos, Kronos, setup_function10);
+ RESET_ENTITY_STATE(kEntityKahina, Kahina, setup_function13);
+ RESET_ENTITY_STATE(kEntityAnna, Anna, setup_function34);
+ RESET_ENTITY_STATE(kEntityAugust, August, setup_function34);
+ RESET_ENTITY_STATE(kEntityTatiana, Tatiana, setup_function24);
+ RESET_ENTITY_STATE(kEntityVassili, Vassili, setup_function7);
+ RESET_ENTITY_STATE(kEntityAlexei, Alexei, setup_function26);
+ RESET_ENTITY_STATE(kEntityMilos, Milos, setup_function18);
+ RESET_ENTITY_STATE(kEntityVesna, Vesna, setup_function15);
+ RESET_ENTITY_STATE(kEntityIvo, Ivo, setup_function17);
+ RESET_ENTITY_STATE(kEntitySalko, Salko, setup_function11);
+ RESET_ENTITY_STATE(kEntityFrancois, Francois, setup_function20);
+ RESET_ENTITY_STATE(kEntityMmeBoutarel, MmeBoutarel, setup_function16);
+ RESET_ENTITY_STATE(kEntityBoutarel, Boutarel, setup_function22);
+ RESET_ENTITY_STATE(kEntityRebecca, Rebecca, setup_function27);
+ RESET_ENTITY_STATE(kEntitySophie, Sophie, setup_function5);
+ RESET_ENTITY_STATE(kEntityMahmud, Mahmud, setup_resetChapter);
+ RESET_ENTITY_STATE(kEntityYasmin, Yasmin, setup_function10);
+ RESET_ENTITY_STATE(kEntityHadija, Hadija, setup_function12);
+ RESET_ENTITY_STATE(kEntityHadija, Alouan, setup_function12);
+
+ if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
+ getSound()->removeFromQueue(kEntityChapters);
+
+ ENTITY_PARAM(0, 2) = 0;
+ ENTITY_PARAM(0, 3) = 0;
+ }
+
+ getSound()->processEntries();
+
+ if (getSound()->isBuffered("CON1505"))
+ getSound()->processEntry("CON1505");
+
+ if (getSound()->isBuffered("AUG1057"))
+ getSound()->processEntry("AUG1057");
+
+ if (getSound()->isBuffered("ZFX1005"))
+ getSound()->processEntry("ZFX1005");
+
+ if (getSound()->isBuffered("ZFX1006"))
+ getSound()->processEntry("ZFX1006");
+
+ if (getSound()->isBuffered("ZFX1007"))
+ getSound()->processEntry("ZFX1007");
+
+ if (getSound()->isBuffered("ZFX1007A"))
+ getSound()->processEntry("ZFX1007A");
+
+ if (getSound()->isBuffered("ZFX1007B"))
+ getSound()->processEntry("ZFX1007B");
+
+
+ getSound()->playSound(kEntityPlayer, "MUS008", SoundManager::kFlagDefault);
+ getInventory()->unselectItem();
+
+ // FIXME add event pump ?
+ while (getSound()->isBuffered("MUS008"))
+ getSound()->updateQueue();
+
+ getProgress().field_84 = true;
+
+ getScenes()->loadSceneFromPosition(kCarLocomotive, 75);
+ getInventory()->show();
+
+ getState()->time = kTime1492200;
+ getProgress().field_18 = 4;
+ getState()->timeDelta = 0;
+
+ getObjects()->update(kObject63, kEntityChapters, kObjectLocationNone, kCursorNormal, kCursorHand);
+ getSavePoints()->push(kEntityChapters, kEntityTrain, kActionTrainStopRunning);
+
+ getProgress().isTrainRunning = false;
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeTime, kTimeNone);
+ break;
+
+ case kAction225358684:
+ params->param2++;
+
+ if (params->param2 >= 3) {
+
+ if (!getSound()->isBuffered("LIB031", true))
+ getSound()->playSound(kEntityPlayer, "LIB031");
+
+ if (params->param2 == 3) {
+ getData()->car = kCarGreenSleeping;
+ getEntities()->drawSequenceLeft(kEntityChapters, "JUGL");
+ }
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(7, Chapters, chapter1Init)
+ if (savepoint.action != kActionDefault)
+ return;
+
+ getProgress().chapter = kChapter1;
+ getSound()->resetState();
+
+ getState()->time = kTimeChapter1;
+ getState()->timeDelta = 0;
+ getProgress().isTrainRunning = true;
+ getProgress().portrait = kPortraitOriginal;
+ getProgress().field_18 = 1;
+
+ // Setup inventory & items location
+ getInventory()->addItem(kItemTelegram);
+ getInventory()->addItem(kItemArticle);
+
+ getInventory()->setLocationAndProcess(kItemScarf, kObjectLocation1);
+ getInventory()->setLocationAndProcess(kItemParchemin, kObjectLocation1);
+ getInventory()->setLocationAndProcess(kItemGreenJacket, kObjectLocation1);
+ getInventory()->setLocationAndProcess(kItemCorpse, kObjectLocation1);
+ getInventory()->setLocationAndProcess(kItemPassengerList, kObjectLocation1);
+ getInventory()->setLocationAndProcess(kItem5, kObjectLocation1);
+ getInventory()->setLocationAndProcess(kItem7, kObjectLocation1);
+ getInventory()->setLocationAndProcess(kItem3, kObjectLocation1);
+ getInventory()->setLocationAndProcess(kItemMatch, kObjectLocation1);
+ getInventory()->setLocationAndProcess(kItem22, kObjectLocation1);
+ getInventory()->setLocationAndProcess(kItemPaper, kObjectLocation1);
+
+ getProgress().field_7C = 1;
+
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectOutsideTylerCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ for (uint i = kObjectCompartment1; i <= kObjectCompartment8; i++) {
+ getObjects()->updateLocation2((ObjectIndex)i, kObjectLocation2);
+ }
+
+ for (uint i = kObjectCompartmentA; i <= kObjectCompartmentH; i++) {
+ getObjects()->updateLocation2((ObjectIndex)i, kObjectLocation2);
+ }
+
+ params->param1 = 40;
+
+ getObjects()->updateLocation2(kObject25, kObjectLocation1);
+ getObjects()->updateLocation2(kObjectTrainTimeTable, kObjectLocation1);
+ getObjects()->updateLocation2(kObject98, kObjectLocation1);
+ getObjects()->updateLocation2(kObjectRestaurantCar, kObjectLocation1);
+
+ getObjects()->update(kObject25, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
+ getObjects()->update(kObjectTrainTimeTable, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
+ getObjects()->update(kObjectRedSleepingCar, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
+ getObjects()->update(kObject28, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
+ getObjects()->update(kObject56, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
+ getObjects()->update(kObject54, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
+ getObjects()->update(kObjectRestaurantCar, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
+ getObjects()->update(kObject59, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
+ getObjects()->update(kObject66, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
+ getObjects()->update(kObject64, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
+ 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(kObject101, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ setup_chapter1Handler();
+}
+
+//////////////////////////////////////////////////////////////////////////
+#define PLAY_STEAM() { \
+ getSound()->resetState(); \
+ getSound()->playSteam((CityIndex)ENTITY_PARAM(0, 4)); \
+ ENTITY_PARAM(0, 2) = 0; \
+ }
+
+IMPLEMENT_FUNCTION(8, Chapters, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!getProgress().isTrainRunning || getState()->time >= kTime1458000)
+ goto label_processStations;
+
+ UPDATE_PARAM_PROC(params->param6, getState()->timeTicks, params->param2)
+ // Play sound FX
+ getSound()->playLocomotiveSound();
+
+ params->param2 = 225 * (4 * rnd(5) + 20);
+ params->param6 = 0;
+ UPDATE_PARAM_PROC_END
+
+label_processStations:
+ // Process stations
+ TIME_CHECK_SAVEGAME(kTime1039500, params->param7, 1, kSavegameTypeTime, kTimeNone);
+
+label_enter_epernay:
+ // Entering Epernay station
+ TIME_CHECK_ENTERSTATION(kTimeEnterEpernay, params->param8, 1, "Epernay", kCityEpernay);
+
+label_exit_epernay:
+ // Exiting Epernay station
+ TIME_CHECK_EXITSTATION_2(kTimeExitEpernay, CURRENT_PARAMS(1, 1), params->param4, 3, "Epernay");
+
+label_epernay_police:
+ TIME_CHECK_EXITSTATION_0(params->param5, ENTITY_PARAM(0, 2), 4, "Unschedu");
+
+label_enter_chalons:
+ if (getState()->time > kTimeEnterChalons && !CURRENT_PARAMS(1, 2)) {
+ CURRENT_PARAMS(1, 2) = 1;
+ getProgress().field_18 = 2;
+ }
+
+ // Skip to callback 18 checks
+ if (params->param1)
+ goto label_exit_strasbourg;
+
+ // Entering Chalons station
+ TIME_CHECK_ENTERSTATION(kTimeEnterChalons, CURRENT_PARAMS(1, 3), 5, "Chalons", kCityChalons);
+
+label_exit_chalons:
+ // Exiting Chalons station
+ TIME_CHECK_EXITSTATION(kTimeExitChalons, CURRENT_PARAMS(1, 4), 6, "Chalons");
+
+label_enter_barleduc:
+ // Entering Bar-Le-Duc station
+ TIME_CHECK_ENTERSTATION(kTimeCityBarLeDuc, CURRENT_PARAMS(1, 5), 7, "BarLeDuc", kCityBarleduc);
+
+label_exit_barleduc:
+ // Exiting Bar-Le-Duc station
+ TIME_CHECK_EXITSTATION(kTimeExitBarLeDuc, CURRENT_PARAMS(1, 6), 8, "BarLeDuc");
+
+label_enter_nancy:
+ if (getState()->time > kTime1260000 && !CURRENT_PARAMS(1, 7)) {
+ CURRENT_PARAMS(1, 7) = 1;
+ getState()->timeDelta = 1;
+ }
+
+ // Entering Nancy station
+ TIME_CHECK_ENTERSTATION(kTimeCityNancy, CURRENT_PARAMS(1, 8), 9, "Nancy", kCityNancy);
+
+label_exit_nancy:
+ // Exiting Nancy station
+ TIME_CHECK_EXITSTATION(kTimeExitNancy, CURRENT_PARAMS(2, 1), 10, "Nancy");
+
+label_enter_luneville:
+ // Entering Luneville station
+ TIME_CHECK_ENTERSTATION(kTimeCityLuneville, CURRENT_PARAMS(2, 2), 11, "Luneville", kCityLuneville);
+
+label_exit_luneville:
+ // Exiting Luneville station
+ TIME_CHECK_EXITSTATION(kTimeExitLuneville, CURRENT_PARAMS(2, 3), 12, "Luneville");
+
+label_enter_avricourt:
+ // Entering Avricourt station
+ TIME_CHECK_ENTERSTATION(kTimeCityAvricourt, CURRENT_PARAMS(2, 4), 13, "Avricourt", kCityAvricourt);
+
+label_exit_avricourt:
+ // Exiting Avricourt station
+ TIME_CHECK_EXITSTATION(kTimeExitAvricourt, CURRENT_PARAMS(2, 5), 14, "Avricourt");
+
+label_enter_deutschavricourt:
+ // Entering Deutsch-Avricourt station
+ TIME_CHECK_ENTERSTATION(kTimeCityDeutschAvricourt, CURRENT_PARAMS(2, 6), 15, "DeutschA", kCityDeutschAvricourt);
+
+label_exit_deutschavricourt:
+ // Exiting Avricourt station
+ TIME_CHECK_EXITSTATION(kTimeExitDeutschAvricourt, CURRENT_PARAMS(2, 7), 16, "DeutschA");
+
+label_enter_strasbourg:
+ TIME_CHECK_SAVEGAME(kTimeCityStrasbourg, CURRENT_PARAMS(2, 8), 17, kSavegameTypeTime, kTimeNone);
+
+label_exit_strasbourg:
+ // Exiting Strasbourg station
+ TIME_CHECK_EXITSTATION(kTimeExitStrasbourg, CURRENT_PARAMS(3, 1), 19, "Strasbou");
+
+label_enter_badenoos:
+ // Entering Baden Oos station
+ TIME_CHECK_ENTERSTATION(kTimeCityBadenOos, CURRENT_PARAMS(3, 2), 20, "BadenOos", kCityBadenOos);
+
+label_exit_badenoos:
+ // Exiting Baden Oos station
+ TIME_CHECK_EXITSTATION(kTimeExitBadenOos, CURRENT_PARAMS(3, 3), 21, "BadenOos");
+
+label_chapter1_next:
+ if (getState()->time > kTimeChapter1End3 && ! CURRENT_PARAMS(3, 4)) {
+ CURRENT_PARAMS(3, 4) = 1;
+ setup_chapter1Next();
+ }
+ break;
+
+ case kActionEndSound:
+ if (ENTITY_PARAM(0, 2)) {
+
+ getSavePoints()->push(kEntityChapters, kEntityTrain, kActionTrainStopRunning);
+
+ if (getEntityData(kEntityPlayer)->location != kLocationOutsideTrain) {
+ PLAY_STEAM();
+ break;
+ }
+
+ if (getEntities()->isOutsideAlexeiWindow()) {
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
+ PLAY_STEAM();
+ break;
+ }
+
+ if (getEntities()->isOutsideAnnaWindow()) {
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 49);
+ PLAY_STEAM();
+ break;
+ }
+
+ CarIndex car = getEntityData(kEntityPlayer)->car;
+ if (car < kCarRedSleeping || car > kCarCoalTender) {
+ if (car < kCarBaggageRear || car > kCarGreenSleeping) {
+ PLAY_STEAM();
+ break;
+ }
+
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 98)) {
+ getSound()->playSound(kEntityPlayer, "LIB015");
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 71);
+ PLAY_STEAM();
+ break;
+ }
+
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 82);
+ PLAY_STEAM();
+ break;
+ }
+
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 82);
+ PLAY_STEAM();
+ break;
+ }
+
+ if (ENTITY_PARAM(0, 3)) {
+ getSound()->resetState();
+ ENTITY_PARAM(0, 3) = 0;
+
+ if (params->param4) {
+ getSavePoints()->push(kEntityChapters, getProgress().field_24 ? kEntityVerges : kEntityMertens, getProgress().field_24 ? kAction168187490 : kAction224122407);
+ params->param4 = 0;
+ }
+ }
+ break;
+
+ case kActionDefault:
+ params->param2 = 225 * (4 * rnd(5) + 20);
+ break;
+
+ case kActionDrawScene:
+ if (!params->param3) {
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 1)) {
+ getState()->time = kTimeChapter1;
+ getState()->timeDelta = 3;
+ params->param3 = 1;
+ }
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_enter_epernay;
+
+ case 2:
+ goto label_exit_epernay;
+
+ case 3:
+ goto label_epernay_police;
+
+ case 4:
+ params->param5 = 0;
+ goto label_enter_chalons;
+
+ case 5:
+ goto label_exit_chalons;
+
+ case 6:
+ goto label_enter_barleduc;
+
+ case 7:
+ goto label_exit_barleduc;
+
+ case 8:
+ goto label_enter_nancy;
+
+ case 9:
+ goto label_exit_nancy;
+
+ case 10:
+ goto label_enter_luneville;
+
+ case 11:
+ goto label_exit_luneville;
+
+ case 12:
+ goto label_enter_avricourt;
+
+ case 13:
+ goto label_exit_avricourt;
+
+ case 14:
+ goto label_enter_deutschavricourt;
+
+ case 15:
+ goto label_exit_deutschavricourt;
+
+ case 16:
+ getState()->time = kTimeEnterStrasbourg;
+ goto label_enter_strasbourg;
+
+ case 17:
+ getProgress().field_18 = 1;
+ setCallback(18);
+ setup_enterStation("Strasbou", kCityStrasbourg);
+ break;
+
+ case 18:
+ goto label_exit_strasbourg;
+
+ case 19:
+ getState()->timeDelta = 1;
+ goto label_enter_badenoos;
+
+ case 20:
+ goto label_exit_badenoos;
+
+ case 21:
+ goto label_chapter1_next;
+
+ case 22:
+ params->param5 = 1;
+ break;
+
+ case 23:
+ params->param1 = 1;
+ break;
+ }
+ break;
+
+ case kAction169629818:
+ setCallback(22);
+ setup_enterStation("Unschedu", kCityPolice);
+ break;
+
+ case kActionEndChapter:
+ getProgress().field_18 = 3;
+
+ if (getState()->time >= kTimeChapter1End) {
+ setup_chapter1Next();
+ } else {
+ setCallback(23);
+ setup_chapter1End();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(9, Chapters, chapter1Next)
+ if (savepoint.action == kActionDefault) {
+ // Reset sound cache
+ if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
+ getSound()->removeFromQueue(kEntityChapters);
+ ENTITY_PARAM(0, 2) = 0;
+ ENTITY_PARAM(0, 3) = 0;
+ }
+
+ getSound()->playSound(kEntityPlayer, "MUS008", SoundManager::kFlagDefault);
+ getInventory()->unselectItem();
+
+ while (getSound()->isBuffered("MUS008"))
+ getSound()->updateQueue();
+
+ setup_chapter2();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(10, Chapters, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ // Setup for chapter 2 in case it hasn't been done before
+ if (getProgress().chapter != kChapter2) {
+ getProgress().chapter = kChapter2;
+ getEntities()->setupChapter(kChapter2);
+ }
+
+ // Set game time & delta
+ getState()->time = kTimeChapter2;
+ getState()->timeDelta = 5;
+
+ // Save game
+ setCallback(1);
+ setup_savegame(kSavegameTypeTime, kTimeNone);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ if (!_engine->getResourceManager()->loadArchive(kArchiveCd2)) {
+ getMenu()->show(false, kSavegameTypeIndex, 0);
+ return;
+ }
+
+ // Load scene data
+ getScenes()->loadSceneDataFile(kArchiveCd2);
+ setup_chapter2Init();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Chapters, chapter2Init)
+ if (savepoint.action != kActionDefault)
+ return;
+
+ getProgress().eventCorpseMovedFromFloor = true;
+ getProgress().field_18 = 1;
+ getProgress().isTrainRunning = true;
+ getProgress().eventCorpseFound = true;
+
+ // Switch to green jacket/portrait
+ getProgress().jacket = kJacketGreen;
+ getProgress().portrait = kPortraitGreen;
+
+ // Setup inventory & items location
+ getInventory()->addItem(kItemGreenJacket);
+
+ getObjects()->update(kObjectHandleOutsideLeft, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHand);
+ getObjects()->update(kObjectHandleOutsideRight, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHand);
+
+ getInventory()->setLocationAndProcess(kItemBeetle, kObjectLocation3);
+ getInventory()->setLocationAndProcess(kItem3, kObjectLocation1);
+
+ for (uint i = 1; i < 9; i++) {
+ getObjects()->updateLocation2((ObjectIndex)i, kObjectLocation2);
+ }
+
+ for (uint i = 33; i < 40; i++) {
+ getObjects()->updateLocation2((ObjectIndex)i, kObjectLocation2);
+ }
+
+ params->param1 = 40;
+
+ getSavePoints()->push(kEntityChapters, kEntityTables0, kActionDrawTablesWithChairs);
+ getSavePoints()->push(kEntityChapters, kEntityTables1, kActionDrawTablesWithChairs);
+ getSavePoints()->push(kEntityChapters, kEntityTables2, kActionDrawTablesWithChairs);
+ getSavePoints()->push(kEntityChapters, kEntityTables3, kActionDrawTablesWithChairs);
+ getSavePoints()->push(kEntityChapters, kEntityTables4, kActionDrawTablesWithChairs);
+
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectOutsideTylerCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ // Reset sound cache
+ if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
+ getSound()->removeFromQueue(kEntityChapters);
+ ENTITY_PARAM(0, 2) = 0;
+ ENTITY_PARAM(0, 3) = 0;
+ }
+
+ getAction()->playAnimation(kEventTrainPassing);
+
+ if (getInventory()->hasItem(kItemScarf))
+ getScenes()->loadScene(kScene41);
+ else
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 79);
+
+ setup_chapter2Handler();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Chapters, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!getProgress().isTrainRunning)
+ break;
+
+ UPDATE_PARAM(params->param2, getState()->timeTicks, params->param1);
+
+ getSound()->playLocomotiveSound();
+
+ params->param1 = 225 * (4 * rnd(5) + 20);
+ params->param2 = 0;
+ break;
+
+ case kActionDefault:
+ params->param1 = 225 * (4 * rnd(5) + 20);
+ break;
+
+ case kActionChapter3:
+ setup_chapter3();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Chapters, chapter3)
+ if (savepoint.action == kActionDefault) {
+ // Setup for chapter 3 in case it hasn't been done before
+ if (getProgress().chapter != kChapter3) {
+ getProgress().chapter = kChapter3;
+ getEntities()->setupChapter(kChapter3);
+ }
+
+ // Set game time & delta
+ getState()->time = kTimeChapter3;
+ getState()->timeDelta = 5;
+
+ setup_chapter3Init();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Chapters, chapter3Init)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityChapters, kEntityTables0, kActionDrawTablesWithChairs);
+ getSavePoints()->push(kEntityChapters, kEntityTables1, kActionDrawTablesWithChairs);
+ getSavePoints()->push(kEntityChapters, kEntityTables2, kActionDrawTablesWithChairs);
+ getSavePoints()->push(kEntityChapters, kEntityTables3, kActionDrawTablesWithChairs);
+ getSavePoints()->push(kEntityChapters, kEntityTables4, kActionDrawTablesWithChairs);
+ getSavePoints()->push(kEntityChapters, kEntityTables5, kActionDrawTablesWithChairs);
+
+ getProgress().isTrainRunning = true;
+
+ getObjects()->update(kObjectHandleOutsideLeft, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHand);
+ getObjects()->update(kObjectHandleOutsideRight, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHand);
+ getInventory()->setLocationAndProcess(kItemBriefcase, kObjectLocation1);
+ getInventory()->setLocationAndProcess(kItem3, kObjectLocation1);
+ getObjects()->updateLocation2(kObjectCompartment1, kObjectLocation2);
+ getObjects()->update(kObject107, kEntityPlayer, kObjectLocation3, kCursorKeepValue, kCursorKeepValue);
+
+ if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
+ getSound()->removeFromQueue(kEntityChapters);
+ ENTITY_PARAM(0, 2) = 0;
+ ENTITY_PARAM(0, 3) = 0;
+ }
+
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 60);
+ getInventory()->show();
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeTime, kTimeNone);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_chapter3Handler();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Chapters, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getProgress().isTrainRunning) {
+ UPDATE_PARAM_PROC(params->param4, getState()->timeTicks, params->param1)
+ getSound()->playLocomotiveSound();
+
+ params->param1 = 225 * (4 * rnd(5) + 20);
+ params->param4 = 0;
+ UPDATE_PARAM_PROC_END
+ }
+
+ UPDATE_PARAM_PROC(params->param5, getState()->timeTicks, params->param2)
+ switch (rnd(2)) {
+ default:
+ break;
+
+ case 0:
+ getSound()->playSound(kEntityPlayer, "ZFX1008", (SoundManager::FlagType)(rnd(15) + 2));
+ break;
+
+ case 1:
+ getSound()->playSound(kEntityPlayer, "ZFX1009", (SoundManager::FlagType)(rnd(15) + 2));
+ break;
+ }
+
+ params->param2 = 225 * (4 * rnd(6) + 8);
+ params->param5 = 0;
+ UPDATE_PARAM_PROC_END
+
+ TIME_CHECK_ENTERSTATION(kTimeEnterSalzbourg, params->param6, 1, "Salzburg", kCitySalzbourg);
+
+label_callback_1:
+ TIME_CHECK_EXITSTATION(kTimeExitSalzbourg, params->param7, 2, "Salzburg");
+
+label_callback_2:
+ TIME_CHECK_ENTERSTATION(kTimeEnterAttnangPuchheim, params->param8, 3, "Attnang", kCityAttnangPuchheim);
+
+label_callback_3:
+ TIME_CHECK_EXITSTATION(kTimeExitAttnangPuchheim, CURRENT_PARAMS(1, 1), 4, "Attnang");
+
+label_callback_4:
+ TIME_CHECK_ENTERSTATION(kTimeEnterWels, CURRENT_PARAMS(1, 2), 5, "Wels", kCityWels);
+
+label_callback_5:
+ TIME_CHECK_EXITSTATION(kTimeEnterWels, CURRENT_PARAMS(1, 3), 6, "Wels");
+
+label_callback_6:
+ TIME_CHECK_ENTERSTATION(kTimeEnterLinz, CURRENT_PARAMS(1, 4), 7, "Linz", kCityLinz);
+
+label_callback_7:
+ TIME_CHECK_EXITSTATION(kTimeCityLinz, CURRENT_PARAMS(1, 5), 8, "Linz");
+
+label_callback_8:
+ if (getState()->time > kTime2187000 && !CURRENT_PARAMS(1, 6)) {
+ CURRENT_PARAMS(1, 6) = 1;
+ getState()->timeDelta = 5;
+ }
+
+ TIME_CHECK_ENTERSTATION(kTimeCityVienna, CURRENT_PARAMS(1, 7), 9, "Vienna", kCityVienna);
+ break;
+
+ case kActionEndSound:
+ if (ENTITY_PARAM(0, 2)) {
+ getSavePoints()->push(kEntityChapters, kEntityTrain, kActionTrainStopRunning);
+
+ if (getEntityData(kEntityPlayer)->location == kLocationOutsideTrain) {
+
+ if (getEntities()->isOutsideAlexeiWindow()) {
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
+ } else if (getEntities()->isOutsideAnnaWindow()) {
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 49);
+ } else {
+ CarIndex car = getEntityData(kEntityPlayer)->car;
+
+ if (car < kCarRedSleeping || car > kCarCoalTender) {
+ if (car >= kCarBaggageRear && car <= kCarGreenSleeping) {
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 98)) {
+ getSound()->playSound(kEntityPlayer, "LIB015");
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 71);
+ } else {
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 82);
+ }
+ }
+ } else {
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 82);
+ }
+ }
+ }
+
+ getSound()->resetState();
+ getSound()->playSteam((CityIndex)ENTITY_PARAM(0, 4));
+
+ ENTITY_PARAM(0, 2) = 0;
+ if (params->param1)
+ setup_viennaEvents();
+
+ break;
+ }
+
+ if (ENTITY_PARAM(0, 3)) {
+ getSound()->resetState();
+ ENTITY_PARAM(0, 3) = 0;
+ }
+ break;
+
+ case kActionDefault:
+ params->param1 = 225 * (4 * rnd(5) + 20);
+ params->param2 = 225 * (4 * rnd(6) + 8);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_callback_1;
+
+ case 2:
+ goto label_callback_2;
+
+ case 3:
+ goto label_callback_3;
+
+ case 4:
+ goto label_callback_4;
+
+ case 5:
+ goto label_callback_5;
+
+ case 6:
+ goto label_callback_6;
+
+ case 7:
+ goto label_callback_7;
+
+ case 8:
+ goto label_callback_8;
+
+ case 9:
+ params->param3 = 1;
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Chapters, viennaEvents)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventViennaAugustUnloadGuns);
+ if (getEvent(kEventConcertLeaveWithBriefcase))
+ getLogic()->gameOver(kSavegameTypeTime, kTime2187000, kSceneNone, true);
+ else if (getEvent(kEventCathJumpDownCeiling))
+ getLogic()->gameOver(kSavegameTypeEvent, kEventCathJumpDownCeiling, kSceneNone, true);
+ else
+ getLogic()->gameOver(kSavegameTypeTime, kTime2155500, kSceneNone, true);
+ break;
+
+ case 2:
+ getAction()->playAnimation(kEventViennaKronosFirebird);
+ 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);
+ } else {
+ if (getProgress().field_C0) {
+ if (getEvent(kEventKronosReturnBriefcase))
+ getLogic()->gameOver(kSavegameTypeTime, getProgress().field_C0, kSceneGameOverVienna2, true);
+ else
+ getLogic()->gameOver(kSavegameTypeTime, kTime2155500, kSceneGameOverVienna2, true);
+ } else {
+ if (getEvent(kEventKronosReturnBriefcase))
+ getLogic()->gameOver(kSavegameTypeEvent, kEventKronosReturnBriefcase, kSceneGameOverVienna, true);
+ else
+ getLogic()->gameOver(kSavegameTypeTime, kTime2155500, kSceneGameOverVienna, true);
+ }
+ }
+ break;
+
+ case 3:
+ getAction()->playAnimation(kEventVergesAnnaDead);
+ getLogic()->gameOver(kSavegameTypeTime, kTime2250000, kSceneGameOverAnnaDied, true);
+ break;
+
+ case 4:
+ getAction()->playAnimation(kEventViennaContinueGame);
+ setup_chapter4();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Chapters, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ // Setup for chapter 4 in case it hasn't been done before
+ if (getProgress().chapter != kChapter4) {
+ getProgress().chapter = kChapter4;
+ getEntities()->setupChapter(kChapter4);
+ }
+
+ // Set game time & delta
+ getState()->time = kTimeChapter4;
+ getState()->timeDelta = 5;
+
+ // Save game
+ setCallback(1);
+ setup_savegame(kSavegameTypeTime, kTimeNone);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ if (!_engine->getResourceManager()->loadArchive(kArchiveCd3)) {
+ getMenu()->show(false, kSavegameTypeIndex, 0);
+ return;
+ }
+
+ // Load scene data
+ getScenes()->loadSceneDataFile(kArchiveCd3);
+ setup_chapter4Init();
+ }
+ break;
+
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Chapters, chapter4Init)
+ if (savepoint.action != kActionDefault)
+ return;
+
+ getSound()->processEntries();
+ getSound()->resetState();
+
+ getProgress().isTrainRunning = true;
+
+ getObjects()->update(kObjectHandleOutsideLeft, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHand);
+ getObjects()->update(kObjectHandleOutsideRight, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHand);
+
+ getSavePoints()->push(kEntityChapters, kEntityTrain, kActionTrainStartRunning);
+ getSavePoints()->push(kEntityChapters, kEntityTables0, kActionDrawTablesWithChairs);
+ getSavePoints()->push(kEntityChapters, kEntityTables1, kActionDrawTablesWithChairs);
+ getSavePoints()->push(kEntityChapters, kEntityTables2, kActionDrawTablesWithChairs);
+ getSavePoints()->push(kEntityChapters, kEntityTables3, kActionDrawTablesWithChairs);
+ getSavePoints()->push(kEntityChapters, kEntityTables4, kActionDrawTablesWithChairs);
+ getSavePoints()->push(kEntityChapters, kEntityTables5, kActionDrawTablesWithChairs);
+
+ getScenes()->loadSceneFromItemPosition(kItem3);
+
+ getInventory()->setLocationAndProcess(kItemBomb, kObjectLocation1);
+
+ if (getInventory()->get(kItemBeetle)->location == kObjectLocation3)
+ getScenes()->loadSceneFromItemPosition(kItemBeetle);
+
+ getObjects()->updateLocation2(kObject25, kObjectLocation2);
+ getObjects()->update(kObject107, kEntityPlayer, kObjectLocation3, kCursorKeepValue, kCursorKeepValue);
+
+ if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
+ getSound()->removeFromQueue(kEntityChapters);
+ ENTITY_PARAM(0, 2) = 0;
+ ENTITY_PARAM(0, 3) = 0;
+ }
+
+ if (getInventory()->hasItem(kItemFirebird))
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 76);
+ else
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 69);
+
+ getInventory()->show();
+ setup_chapter4Handler();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Chapters, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getProgress().isTrainRunning) {
+ UPDATE_PARAM_PROC(params->param6, getState()->timeTicks, params->param4);
+ getSound()->playLocomotiveSound();
+
+ params->param4 = 225 * (4 * rnd(5) + 20);
+ params->param6 = 0;
+ UPDATE_PARAM_PROC_END
+ }
+
+ UPDATE_PARAM_PROC(params->param7, getState()->timeTicks, params->param5)
+ switch (rnd(2)) {
+ default:
+ break;
+
+ case 0:
+ getSound()->playSound(kEntityPlayer, "ZFX1008", (SoundManager::FlagType)(rnd(15) + 2));
+ break;
+
+ case 1:
+ getSound()->playSound(kEntityPlayer, "ZFX1009", (SoundManager::FlagType)(rnd(15) + 2));
+ break;
+ }
+
+ params->param5 = 225 * (4 * rnd(6) + 8);
+ params->param7 = 0;
+ UPDATE_PARAM_PROC_END
+
+ TIME_CHECK_ENTERSTATION(kTimeEnterPoszony, params->param8, 1, "Pozsony", kCityPoszony);
+
+label_exitPozsony:
+ TIME_CHECK_EXITSTATION(kTimeExitPoszony, CURRENT_PARAMS(1, 1), 2, "Pozsony");
+
+label_enterGalanta:
+ if (getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1) {
+ if (getState()->time > kTime2403000 && !CURRENT_PARAMS(1, 2)) {
+ CURRENT_PARAMS(1, 2) = 1;
+ getProgress().field_18 = 2;
+ }
+ }
+
+ if (params->param1)
+ goto label_callback_4;
+
+ TIME_CHECK_ENTERSTATION(kTimeEnterGalanta, CURRENT_PARAMS(1, 3), 3, "Galanta", kCityGalanta);
+
+label_exitGalanta:
+ TIME_CHECK_EXITSTATION(kTimeExitGalanta, CURRENT_PARAMS(1, 4), 4, "Galanta");
+
+label_callback_4:
+ if (getState()->time > kTime2470500 && !CURRENT_PARAMS(1, 5)) {
+ CURRENT_PARAMS(1, 5) = 1;
+
+ if (getProgress().field_18 == 2)
+ getState()->timeDelta = 1;
+ }
+
+ if (getState()->time > kTime2506500 && !CURRENT_PARAMS(1, 6)) {
+ CURRENT_PARAMS(1, 6) = 1;
+
+ if (getProgress().field_18 == 2)
+ getProgress().field_18 = 1;
+ }
+
+ if (getState()->time > kTime2520000 && !CURRENT_PARAMS(1, 7)) {
+ CURRENT_PARAMS(1, 7) = 1;
+
+ if (!params->param2 && !params->param3) {
+ setCallback(5);
+ setup_savegame(kSavegameTypeEvent, kEventTrainExplosionBridge);
+ }
+ }
+ break;
+
+ case kActionEndSound:
+ if (ENTITY_PARAM(0, 2)) {
+
+ getSavePoints()->push(kEntityChapters, kEntityTrain, kActionTrainStopRunning);
+
+ if (getEntityData(kEntityPlayer)->location != kLocationOutsideTrain) {
+ PLAY_STEAM();
+ break;
+ }
+
+ if (getEntities()->isOutsideAlexeiWindow()) {
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
+ PLAY_STEAM();
+ break;
+ }
+
+ if (getEntities()->isOutsideAnnaWindow()) {
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 49);
+ PLAY_STEAM();
+ break;
+ }
+
+ CarIndex car = getEntityData(kEntityPlayer)->car;
+ if (car < kCarRedSleeping || car > kCarCoalTender) {
+ if (car < kCarBaggageRear || car > kCarGreenSleeping) {
+ PLAY_STEAM();
+ break;
+ }
+
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 98)) {
+ getSound()->playSound(kEntityPlayer, "LIB015");
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 71);
+ PLAY_STEAM();
+ break;
+ }
+
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 82);
+ PLAY_STEAM();
+ break;
+ }
+
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 82);
+ PLAY_STEAM();
+ break;
+ }
+
+ if (ENTITY_PARAM(0, 3)) {
+ getSound()->resetState();
+ ENTITY_PARAM(0, 3) = 0;
+ } else if (!params->param2 && !params->param3) {
+ getSound()->playSound(kEntityChapters, "ZFX1001");
+ }
+ break;
+
+ case kActionExitCompartment:
+ getEntities()->clearSequences(kEntityChapters);
+
+ setCallback(11);
+ setup_savegame(kSavegameTypeTime, kTimeNone);
+ break;
+
+ case kActionDefault:
+ params->param4 = 225 * (4 * rnd(5) + 20);
+ params->param5 = 225 * (4 * rnd(6) + 8);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_exitPozsony;
+
+ case 2:
+ goto label_enterGalanta;
+
+ case 3:
+ goto label_exitGalanta;
+
+ case 4:
+ goto label_callback_4;
+
+ case 5:
+ if (getSound()->isBuffered(kEntityChapters))
+ getSound()->removeFromQueue(kEntityChapters);
+
+ getAction()->playAnimation(kEventTrainExplosionBridge);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneNone, true);
+ break;
+
+ case 6:
+ getSound()->processEntries();
+ getAction()->playAnimation(kEventTylerCastleDream);
+ getSound()->resetState();
+
+ getProgress().field_18 = 1;
+
+ getScenes()->loadScene(kScene41);
+ getSavePoints()->push(kEntityChapters, kEntityTatiana, kAction169360385);
+
+ getState()->timeDelta = 1;
+ getState()->time = kTime2511900;
+
+ getInventory()->setLocationAndProcess(kItem2, kObjectLocation1);
+ getScenes()->loadSceneFromItemPosition(kItem22);
+
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_1500;
+ getData()->location = kLocationInsideCompartment;
+
+ getSound()->playSound(kEntityChapters, "ZFX1001");
+ break;
+
+ case 7:
+ getAction()->playAnimation(kEventTrainExplosionBridge);
+ getLogic()->gameOver(kSavegameTypeTime, kTime2430000, kSceneNone, true);
+ break;
+
+ case 8:
+ getSound()->playSound(kEntityPlayer, "MUS022");
+
+ if (getState()->time < kTime2517300)
+ getState()->time = kTime2517300;
+ break;
+
+ case 9:
+ getAction()->playAnimation(kEventCathDefusingBomb);
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 73);
+ break;
+
+ case 10:
+ getAction()->playAnimation(kEventDefuseBomb);
+ RESET_ENTITY_STATE(kEntityAbbot, Abbot, setup_function48);
+ getSavePoints()->push(kEntityChapters, kEntityAnna, kAction191001984);
+ getSavePoints()->push(kEntityChapters, kEntityCoudert, kAction191001984);
+ getScenes()->loadSceneFromItemPosition(kItem2);
+
+ getInventory()->get(kItem2)->location = kObjectLocationNone;
+ params->param2 = 1;
+
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 2);
+ break;
+
+ case 11:
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 74);
+ getSound()->playSound(kEntityTrain, "ZFX4001", SoundManager::kFlagDefault);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneNone, true);
+ break;
+ }
+ break;
+
+ case kActionChapter5:
+ setup_chapter5();
+ break;
+
+ case kAction156435676:
+ getSavePoints()->push(kEntityChapters, kEntityTatiana, kAction169360385);
+ getSavePoints()->push(kEntityChapters, kEntityCoudert, kAction201431954);
+ getSavePoints()->push(kEntityChapters, kEntityVerges, kAction201431954);
+
+ getState()->timeDelta = 1;
+ getState()->time = kTime2511900;
+
+ getInventory()->setLocationAndProcess(kItem2, kObjectLocation1);
+
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_1500;
+ getData()->location = kLocationInsideCompartment;
+
+ getSound()->playSound(kEntityChapters, "ZFX1001");
+ break;
+
+ case kAction158610240:
+ setCallback(8);
+ setup_savegame(kSavegameTypeTime, kTimeNone);
+ break;
+
+ case kAction169300225:
+ if (getState()->time < kTime2519100)
+ getState()->time = kTime2519100;
+
+ params->param3 = 1;
+
+ getEntities()->drawSequenceRight(kEntityChapters, "BOMB");
+ break;
+
+ case kAction190346110:
+ getProgress().field_18 = 3;
+
+ params->param1 = 1;
+
+ if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
+ getSound()->removeFromQueue(kEntityChapters);
+
+ ENTITY_PARAM(0, 2) = 0;
+ ENTITY_PARAM(0, 3) = 0;
+ }
+
+ getSound()->playSound(kEntityPlayer, "MUS008", SoundManager::kFlagDefault);
+ getInventory()->unselectItem();
+
+ while (getSound()->isBuffered("MUS008"))
+ getSound()->updateQueue();
+
+ if (getInventory()->hasItem(kItemBomb)) {
+ RESET_ENTITY_STATE(kEntityAlexei, Alexei, setup_function47);
+ RESET_ENTITY_STATE(kEntityAnna, Anna, setup_function68);
+ RESET_ENTITY_STATE(kEntityAugust, August, setup_function65);
+ RESET_ENTITY_STATE(kEntityMertens, Mertens, setup_function48);
+ RESET_ENTITY_STATE(kEntityCoudert, Coudert, setup_function53);
+ RESET_ENTITY_STATE(kEntityServers0, Servers0, setup_chapter4Handler);
+ RESET_ENTITY_STATE(kEntityServers1, Servers1, setup_chapter4Handler);
+ RESET_ENTITY_STATE(kEntityPascale, Pascale, setup_chapter4Handler);
+ RESET_ENTITY_STATE(kEntityVerges, Verges, setup_chapter4Handler);
+ RESET_ENTITY_STATE(kEntityTatiana, Tatiana, setup_function49);
+ RESET_ENTITY_STATE(kEntityAbbot, Abbot, setup_function44);
+ RESET_ENTITY_STATE(kEntityMilos, Milos, setup_function32);
+ RESET_ENTITY_STATE(kEntityVesna, Vesna, setup_function27);
+ RESET_ENTITY_STATE(kEntityIvo, Ivo, setup_function29);
+ RESET_ENTITY_STATE(kEntitySalko, Salko, setup_function22);
+ RESET_ENTITY_STATE(kEntityMmeBoutarel, MmeBoutarel, setup_function25);
+ RESET_ENTITY_STATE(kEntityBoutarel, Boutarel, setup_function35);
+ RESET_ENTITY_STATE(kEntityRebecca, Rebecca, setup_function45);
+ RESET_ENTITY_STATE(kEntitySophie, Sophie, setup_function9);
+ RESET_ENTITY_STATE(kEntityYasmin, Yasmin, setup_function17);
+ RESET_ENTITY_STATE(kEntityHadija, Hadija, setup_function19);
+ RESET_ENTITY_STATE(kEntityAlouan, Alouan, setup_function19);
+ RESET_ENTITY_STATE(kEntityMax, Max, setup_chapter4Handler);
+ getSavePoints()->push(kEntityChapters, kEntityAnna, kAction201431954);
+ getSavePoints()->push(kEntityChapters, kEntityMertens, kAction201431954);
+ getSavePoints()->push(kEntityChapters, kEntityCoudert, kAction201431954);
+ getSavePoints()->push(kEntityChapters, kEntityServers0, kAction201431954);
+ getSavePoints()->push(kEntityChapters, kEntityServers1, kAction201431954);
+ getSavePoints()->push(kEntityChapters, kEntityPascale, kAction201431954);
+ getSavePoints()->push(kEntityChapters, kEntityVerges, kAction201431954);
+
+ setCallback(6);
+ setup_savegame(kSavegameTypeEvent, kEventTylerCastleDream);
+ } else {
+ getState()->time = kTime2520000;
+
+ setCallback(7);
+ setup_savegame(kSavegameTypeEvent, kEventTrainExplosionBridge);
+ }
+ break;
+
+ case kAction191001984:
+ getState()->time = kTime2520000;
+
+ if (getSound()->isBuffered(kEntityChapters))
+ getSound()->removeFromQueue(kEntityChapters);
+
+ getEntities()->clearSequences(kEntityChapters);
+ getInventory()->removeItem(kItemTelegram);
+
+ getState()->timeDelta = 5;
+
+ setCallback(10);
+ setup_savegame(kSavegameTypeEvent, kEventDefuseBomb);
+ break;
+
+ case kAction201959744:
+ if (getSound()->isBuffered(kEntityChapters))
+ getSound()->removeFromQueue(kEntityChapters);
+
+ getSound()->playSound(kEntityTrain, "ZFX4001", SoundManager::kFlagDefault);
+
+ getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, true);
+ break;
+
+ case kAction225367984:
+ setCallback(9);
+ setup_savegame(kSavegameTypeEvent, kEventCathDefusingBomb);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Chapters, chapter5)
+ if (savepoint.action == kActionDefault) {
+ // Setup for chapter 5 in case it hasn't been done before
+ if (getProgress().chapter != kChapter5) {
+ getProgress().chapter = kChapter5;
+ getEntities()->setupChapter(kChapter5);
+ }
+
+ // Set game time & delta
+ getState()->time = kTimeChapter5;
+ getState()->timeDelta = 2;
+
+ setup_chapter5Init();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Chapters, chapter5Init)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityTables0);
+ getEntities()->clearSequences(kEntityTables1);
+ getEntities()->clearSequences(kEntityTables2);
+ getEntities()->clearSequences(kEntityTables3);
+ getEntities()->clearSequences(kEntityTables4);
+ getEntities()->clearSequences(kEntityTables5);
+
+ getProgress().isTrainRunning = true;
+
+ getObjects()->update(kObjectHandleOutsideLeft, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHand);
+ getObjects()->update(kObjectHandleOutsideRight, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment2, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment4, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment5, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment6, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment7, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment8, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartmentE, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartmentG, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartmentH, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectHandleBathroom, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectHandleInsideBathroom, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectKitchen, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject20, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject21, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject22, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject48, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject49, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject50, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject51, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject52, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectHandleOutsideLeft, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectHandleOutsideRight, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ getProgress().field_18 = 1;
+ getProgress().field_84 = 1;
+ getProgress().portrait = kCursorPortraitYellow;
+
+ getInventory()->unselectItem();
+
+ getInventory()->removeItem(kItemKey);
+ getInventory()->removeItem(kItemBomb);
+ getInventory()->removeItem(kItemMatch);
+
+ if (getInventory()->hasItem(kItemFirebird)) {
+ getInventory()->removeItem(kItemFirebird);
+ getInventory()->setLocationAndProcess(kItemFirebird, kObjectLocation3);
+
+ if (getInventory()->hasItem(kItemWhistle)) {
+ getInventory()->removeItem(kItemWhistle);
+ getInventory()->setLocationAndProcess(kItemWhistle, kObjectLocation3);
+ }
+ }
+
+ getObjects()->update(kObject93, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getObjects()->update(kObject94, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ getObjects()->update(kObject101, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ getObjects()->updateLocation2(kObject98, kObjectLocation2);
+ getObjects()->updateLocation2(kObjectRestaurantCar, kObjectLocation2);
+
+ if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
+ getSound()->removeFromQueue(kEntityChapters);
+ ENTITY_PARAM(0, 2) = 0;
+ ENTITY_PARAM(0, 3) = 0;
+ }
+
+ getScenes()->loadSceneFromPosition(kCarBaggageRear, 95);
+ getInventory()->show();
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeTime, kTimeNone);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_chapter5Handler();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Chapters, chapter5Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime2907000 && !params->param2) {
+ params->param2 = 1;
+
+ if (!getProgress().isNightTime) {
+ getSound()->playSound(kEntityChapters, "ARRIVE", SoundManager::kFlag8);
+ getSound()->processEntries();
+ }
+ }
+
+ if (getState()->time > kTimeTrainStopped2 && !params->param3) {
+ params->param3 = 1;
+
+ if (!getEvent(kEventLocomotiveMilos) && !getEvent(kEventLocomotiveMilosNight)) {
+ getSound()->playSound(kEntityChapters, "ARRIVE", SoundManager::kFlag8);
+ getSound()->processEntries();
+ }
+ }
+ break;
+
+ case kActionEndSound:
+ if (getState()->time <= kTimeTrainStopped2) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventTrainStopped);
+ } else {
+ getLogic()->gameOver(kSavegameTypeTime, kTimeTrainStopped2, kSceneGameOverTrainStopped, true);
+ }
+ break;
+
+ case kActionDefault:
+ params->param1 = 225 * (4 * rnd(10) + 20);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventTrainStopped);
+ getLogic()->gameOver(kSavegameTypeTime, kTimeTrainStopped, kSceneGameOverTrainStopped, true);
+ }
+ break;
+
+ case kAction135800432:
+ getProgress().isNightTime = true;
+ getState()->time = kTime2916000;
+
+ if (getSound()->isBuffered(kEntityChapters))
+ getSound()->removeFromQueue(kEntityChapters);
+ break;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// Private functions
+//////////////////////////////////////////////////////////////////////////
+void Chapters::enterExitStation(const SavePoint &savepoint, bool isEnteringStation) {
+ if (savepoint.action == kActionDefault) {
+ if (!ENTITY_PARAM(0, 2) && !ENTITY_PARAM(0, 3)) {
+ enterExitHelper(isEnteringStation);
+ return;
+ }
+
+ getSound()->removeFromQueue(kEntityChapters);
+
+ if (!ENTITY_PARAM(0, 2)) {
+ if (ENTITY_PARAM(0, 3))
+ ENTITY_PARAM(0, 3) = 0;
+
+ enterExitHelper(isEnteringStation);
+ return;
+ }
+
+ getSavePoints()->push(kEntityChapters, kEntityTrain, kActionTrainStopRunning);
+
+ if (getEntityData(kEntityPlayer)->location != kLocationOutsideTrain) {
+ ENTITY_PARAM(0, 2) = 0;
+ enterExitHelper(isEnteringStation);
+ return;
+ }
+
+ // Green sleeping car
+ if (getEntities()->isOutsideAlexeiWindow()) {
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
+ ENTITY_PARAM(0, 2) = 0;
+ enterExitHelper(isEnteringStation);
+ return;
+ }
+
+ // Red sleeping car
+ if (getEntities()->isOutsideAnnaWindow()) {
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 49);
+ ENTITY_PARAM(0, 2) = 0;
+ enterExitHelper(isEnteringStation);
+ return;
+ }
+
+ // Other cars
+ if (getEntityData(kEntityPlayer)->car < kCarRedSleeping || getEntityData(kEntityPlayer)->car > kCarCoalTender) {
+
+ if (getEntityData(kEntityPlayer)->car < kCarBaggageRear || getEntityData(kEntityPlayer)->car > kCarGreenSleeping) {
+ ENTITY_PARAM(0, 2) = 0;
+ enterExitHelper(isEnteringStation);
+ return;
+ }
+
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 98)) {
+ getSound()->playSound(kEntityPlayer, "LIB015");
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 71);
+ ENTITY_PARAM(0, 2) = 0;
+ enterExitHelper(isEnteringStation);
+ return;
+ }
+
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 82);
+ ENTITY_PARAM(0, 2) = 0;
+ enterExitHelper(isEnteringStation);
+ return;
+ }
+
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 82);
+ ENTITY_PARAM(0, 2) = 0;
+ enterExitHelper(isEnteringStation);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void Chapters::enterExitHelper(bool isEnteringStation) {
+ EXPOSE_PARAMS(EntityData::EntityParametersSIIS);
+
+ getSound()->playSound(kEntityChapters, isEnteringStation ? "ARRIVE" : "DEPART", SoundManager::kFlag8);
+ getSound()->processEntries();
+
+ getObjects()->update(kObjectHandleOutsideLeft, kEntityPlayer, kObjectLocation1, kCursorNormal, isEnteringStation ? kCursorNormal : kCursorHand);
+ getObjects()->update(kObjectHandleOutsideRight, kEntityPlayer, kObjectLocation1, kCursorNormal, isEnteringStation ? kCursorNormal : kCursorHand);
+
+ getProgress().isTrainRunning = isEnteringStation ? false : true;
+
+ if (isEnteringStation) {
+ ENTITY_PARAM(0, 2) = 1;
+ ENTITY_PARAM(0, 4) = params->param4;
+ } else {
+ getSavePoints()->push(kEntityChapters, kEntityTrain, kActionTrainStartRunning);
+ ENTITY_PARAM(0, 3) = 1;
+ }
+
+ CALLBACK_ACTION();
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/chapters.h b/engines/lastexpress/entities/chapters.h
new file mode 100644
index 0000000000..845fe8b727
--- /dev/null
+++ b/engines/lastexpress/entities/chapters.h
@@ -0,0 +1,166 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_CHAPTERS_H
+#define LASTEXPRESS_CHAPTERS_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Chapters : public Entity {
+public:
+ Chapters(LastExpressEngine *engine);
+ ~Chapters() {};
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ /**
+ * Exit a train station
+ *
+ * @param stationName The name of the train station
+ * @param index The index of the train station
+ */
+ DECLARE_FUNCTION_2(enterStation, const char *stationName, CityIndex index)
+
+ /**
+ * Exit a train station
+ *
+ * @param stationName The name of the train station
+ */
+ DECLARE_FUNCTION_1(exitStation, const char *stationName)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Reset main entities
+ */
+ DECLARE_FUNCTION(resetMainEntities)
+
+ /**
+ * Handle end of Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1End)
+
+ /**
+ * Init Chapter 1 data
+ */
+ DECLARE_FUNCTION(chapter1Init)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ /**
+ * Handle switching to Chapter 2 after the end of Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1Next)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Init Chapter 2 data
+ */
+ DECLARE_FUNCTION(chapter2Init)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Init Chapter 3 data
+ */
+ DECLARE_FUNCTION(chapter3Init)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ /**
+ * Handle Vienna events
+ */
+ DECLARE_FUNCTION(viennaEvents)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Init Chapter 4 data
+ */
+ DECLARE_FUNCTION(chapter4Init)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Init Chapter 5 data
+ */
+ DECLARE_FUNCTION(chapter5Init)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+private:
+ void enterExitStation(const SavePoint &savepoint, bool isEnteringStation);
+ void enterExitHelper(bool isEnteringStation);
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_CHAPTERS_H
diff --git a/engines/lastexpress/entities/cooks.cpp b/engines/lastexpress/entities/cooks.cpp
new file mode 100644
index 0000000000..2bc787b495
--- /dev/null
+++ b/engines/lastexpress/entities/cooks.cpp
@@ -0,0 +1,571 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/cooks.h"
+
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+
+namespace LastExpress {
+
+Cooks::Cooks(LastExpressEngine *engine) : Entity(engine, kEntityCooks) {
+ ADD_CALLBACK_FUNCTION(Cooks, draw);
+ ADD_CALLBACK_FUNCTION(Cooks, playSound);
+ ADD_CALLBACK_FUNCTION(Cooks, function3);
+ ADD_CALLBACK_FUNCTION(Cooks, function4);
+ ADD_CALLBACK_FUNCTION(Cooks, chapter1);
+ ADD_CALLBACK_FUNCTION(Cooks, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Cooks, function7);
+ ADD_CALLBACK_FUNCTION(Cooks, chapter2);
+ ADD_CALLBACK_FUNCTION(Cooks, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Cooks, chapter3);
+ ADD_CALLBACK_FUNCTION(Cooks, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Cooks, chapter4);
+ ADD_CALLBACK_FUNCTION(Cooks, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Cooks, chapter5);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(1, Cooks, draw)
+ Entity::draw(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(2, Cooks, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(3, Cooks, function3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityCooks, "308A");
+ getEntities()->updatePositionEnter(kEntityCooks, kCarRestaurant, 75);
+ getEntities()->updatePositionEnter(kEntityCooks, kCarRestaurant, 78);
+
+ switch (getProgress().chapter) {
+ default:
+ getSound()->playSound(kEntityCooks, "KIT1011");
+ setCallback(3);
+ setup_draw("308B");
+ break;
+
+ case kChapter1:
+ setCallback(1);
+ setup_playSound("KIT1010");
+ break;
+
+ case kChapter3:
+ setCallback(2);
+ setup_playSound("KIT1012");
+ break;
+ }
+ break;
+
+ case kActionDrawScene:
+ if (!getEntities()->isInKitchen(kEntityPlayer)) {
+ getEntities()->clearSequences(kEntityCooks);
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 46)) {
+ getEntities()->drawSequenceLeft(kEntityCooks, "308D");
+
+ if (!getSound()->isBuffered(kEntityCooks)) {
+ if (params->param1) {
+ if (!getEntities()->hasValidFrame(kEntityCooks)) {
+ getSound()->playSound(kEntityCooks, "LIB015");
+ getEntities()->clearSequences(kEntityCooks);
+ CALLBACK_ACTION();
+ }
+ break;
+ }
+
+ // Kitchen apprentice getting a lesson :D
+ getSound()->playSound(kEntityCooks, "KIT1011A");
+ params->param1 = 1;
+ }
+ }
+
+ if (params->param1 && !getEntities()->hasValidFrame(kEntityCooks)) {
+ getSound()->playSound(kEntityCooks, "LIB015");
+ getEntities()->clearSequences(kEntityCooks);
+ CALLBACK_ACTION();
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ getSound()->playSound(kEntityCooks, "KIT1011");
+ setCallback(3);
+ setup_draw("308B");
+ break;
+
+ case 3:
+ getEntities()->drawSequenceLeft(kEntityCooks, "308C");
+ getEntities()->updatePositionExit(kEntityCooks, kCarRestaurant, 75);
+ getEntities()->updatePositionExit(kEntityCooks, kCarRestaurant, 78);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(4, Cooks, function4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityCooks, "308A");
+ getEntities()->updatePositionEnter(kEntityCooks, kCarRestaurant, 75);
+ getEntities()->updatePositionEnter(kEntityCooks, kCarRestaurant, 78);
+
+ switch (getProgress().chapter) {
+ default:
+ break;
+
+ case kChapter1:
+ setCallback(2);
+ setup_playSound("ZFX1011");
+ break;
+
+ case kChapter3:
+ setCallback(2);
+ setup_playSound("ZFX1011");
+ break;
+ }
+
+ getSound()->playSound(kEntityCooks, "KIT1011");
+ setCallback(3);
+ setup_draw("308B");
+ break;
+
+ case kActionDrawScene:
+ if (!getEntities()->isInKitchen(kEntityPlayer)) {
+ getEntities()->clearSequences(kEntityCooks);
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 80)) {
+ getEntities()->drawSequenceLeft(kEntityCooks, "308D");
+
+ if (!getSound()->isBuffered(kEntityCooks)) {
+ if (params->param1) {
+ if (!getEntities()->hasValidFrame(kEntityCooks)) {
+ getSound()->playSound(kEntityCooks, "LIB015");
+ getEntities()->clearSequences(kEntityCooks);
+ CALLBACK_ACTION();
+ }
+ break;
+ }
+
+ // Kitchen apprentice getting a lesson :D
+ getSound()->playSound(kEntityCooks, "KIT1011A");
+ params->param1 = 1;
+ }
+ }
+
+ if (params->param1 && !getEntities()->hasValidFrame(kEntityCooks)) {
+ getSound()->playSound(kEntityCooks, "LIB015");
+ getEntities()->clearSequences(kEntityCooks);
+ CALLBACK_ACTION();
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ getSound()->playSound(kEntityCooks, "KIT1011");
+ setCallback(3);
+ setup_draw("308B");
+ break;
+
+ case 3:
+ getEntities()->drawSequenceLeft(kEntityCooks, "308C");
+ getEntities()->updatePositionExit(kEntityCooks, kCarRestaurant, 75);
+ getEntities()->updatePositionEnter(kEntityCooks, kCarRestaurant, 78);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(5, Cooks, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+
+ getProgress().field_4C = 0;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(6, Cooks, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param4, getState()->time, params->param2);
+
+ // Broken plate sound
+ getSound()->playSound(kEntityPlayer, "LIB122", getSound()->getSoundFlag(kEntityCooks));
+ params->param2 = 225 * (4 * rnd(30) + 120);
+ params->param4 = 0;
+ break;
+
+ case kActionDefault:
+ params->param1 = 1;
+ params->param2 = 225 * (4 * rnd(30) + 120);
+ break;
+
+ case kActionDrawScene:
+ if (!getEntities()->isInKitchen(kEntityPlayer))
+ break;
+
+ if (params->param1) {
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 73)) {
+ setCallback(1);
+ setup_function3();
+ }
+ } else {
+ if (params->param3) {
+ setCallback(2);
+ setup_playSound("ZFX1011");
+ } else {
+ setCallback(3);
+ setup_playSound("ZFX1012");
+ }
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ params->param1 = 0;
+ break;
+
+ case 2:
+ case 3:
+ params->param3 = !params->param3;
+ break;
+ }
+ break;
+
+ case kAction101632192:
+ setup_function7();
+ break;
+
+ case kAction224849280:
+ getProgress().field_4C = 1;
+ params->param1 = 1;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(7, Cooks, function7)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ // Snoring...
+ setCallback(1);
+ setup_playSound("WAT1200");
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_3650;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+
+ getEntities()->clearSequences(kEntityCooks);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(8, Cooks, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter2Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityCooks);
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+
+ getProgress().field_4C = 1;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(9, Cooks, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param3, getState()->time, params->param1);
+
+ // Broken plate sound
+ getSound()->playSound(kEntityPlayer, "LIB122", getSound()->getSoundFlag(kEntityCooks));
+ params->param1 = 225 * (4 * rnd(30) + 120);
+ params->param3 = 0;
+ break;
+
+ case kActionDefault:
+ params->param1 = 225 * (4 * rnd(30) + 120);
+ break;
+
+ case kActionDrawScene:
+ if (params->param2) {
+ setCallback(1);
+ setup_playSound("ZFX1011");
+ } else {
+ setCallback(2);
+ setup_playSound("ZFX1012");
+ }
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1 || getCallback() == 2)
+ params->param2 = !params->param2;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(10, Cooks, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityCooks);
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+
+ getProgress().field_4C = 0;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Cooks, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM_PROC(params->param4, getState()->time, params->param2)
+ // Broken plate sound
+ getSound()->playSound(kEntityPlayer, "LIB122", getSound()->getSoundFlag(kEntityCooks));
+ params->param2 = 225 * (4 * rnd(30) + 120);
+ params->param4 = 0;
+ UPDATE_PARAM_PROC_END
+
+ if (getState()->time > kTime2079000 && !params->param5) {
+ params->param1 = 0;
+ params->param5 = 1;
+ }
+ break;
+
+ case kActionDefault:
+ params->param1 = 1;
+ params->param2 = 225 * (4 * rnd(30) + 120);
+ break;
+
+ case kActionDrawScene:
+ if (!getEntities()->isInKitchen(kEntityPlayer))
+ break;
+
+ if (params->param1) {
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 80)) {
+ setCallback(1);
+ setup_function4();
+ }
+ } else {
+ if (params->param3) {
+ setCallback(2);
+ setup_playSound("ZFX1011");
+ } else {
+ setCallback(3);
+ setup_playSound("ZFX1012");
+ }
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ params->param1 = 0;
+ break;
+
+ case 2:
+ case 3:
+ params->param3 = !params->param3;
+ break;
+ }
+ break;
+
+ case kAction236976550:
+ getProgress().field_4C = 1;
+ break;
+
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Cooks, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityCooks);
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+
+ getProgress().field_4C = 1;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Cooks, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param3, getState()->time, params->param1)
+
+ // Broken plate sound
+ getSound()->playSound(kEntityPlayer, "LIB122", getSound()->getSoundFlag(kEntityCooks));
+ params->param1 = 225 * (4 * rnd(30) + 120);
+ params->param3 = 0;
+ break;
+
+ case kActionDefault:
+ params->param1 = 225 * (4 * rnd(30) + 120);
+ break;
+
+ case kActionDrawScene:
+ if (!getEntities()->isInKitchen(kEntityPlayer))
+ break;
+
+ // Kitchen background sound
+ if (params->param2) {
+ setCallback(1);
+ setup_playSound("ZFX1011");
+ } else {
+ setCallback(2);
+ setup_playSound("ZFX1012");
+ }
+ break;
+
+
+ case kActionCallback:
+ // Play the next part of background sound
+ if (getCallback() == 1 || getCallback() == 2) {
+ params->param2 = !params->param2;
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Cooks, chapter5)
+ if (savepoint.action == kActionDefault)
+ getEntities()->clearSequences(kEntityCooks);
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/cooks.h b/engines/lastexpress/entities/cooks.h
new file mode 100644
index 0000000000..7f1a70fb8a
--- /dev/null
+++ b/engines/lastexpress/entities/cooks.h
@@ -0,0 +1,109 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_COOKS_H
+#define LASTEXPRESS_COOKS_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Cooks : public Entity {
+public:
+ Cooks(LastExpressEngine *engine);
+ ~Cooks() {};
+
+ /**
+ * Draws the entity
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(draw, const char* sequence)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ DECLARE_FUNCTION(function3)
+
+ DECLARE_FUNCTION(function4)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function7)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_COOKS_H
diff --git a/engines/lastexpress/entities/coudert.cpp b/engines/lastexpress/entities/coudert.cpp
new file mode 100644
index 0000000000..6249ea5487
--- /dev/null
+++ b/engines/lastexpress/entities/coudert.cpp
@@ -0,0 +1,3611 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/coudert.h"
+
+#include "lastexpress/game/action.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"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+
+namespace LastExpress {
+
+#define SAVEGAME_BLOOD_JACKET() \
+ if (getProgress().jacket == kJacketBlood \
+ && getEntities()->isDistanceBetweenEntities(kEntityCoudert, kEntityPlayer, 1000) \
+ && !getEntities()->isInsideCompartments(kEntityPlayer) \
+ && !getEntities()->checkFields10(kEntityPlayer)) { \
+ setCallback(1); \
+ setup_savegame(kSavegameTypeEvent, kEventMertensBloodJacket); \
+ }
+
+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(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(Coudert, function16);
+ ADD_CALLBACK_FUNCTION(Coudert, function17);
+ ADD_CALLBACK_FUNCTION(Coudert, function18);
+ ADD_CALLBACK_FUNCTION(Coudert, function19);
+ ADD_CALLBACK_FUNCTION(Coudert, function20);
+ ADD_CALLBACK_FUNCTION(Coudert, function21);
+ ADD_CALLBACK_FUNCTION(Coudert, function22);
+ ADD_CALLBACK_FUNCTION(Coudert, function23);
+ ADD_CALLBACK_FUNCTION(Coudert, visitCompartmentF);
+ ADD_CALLBACK_FUNCTION(Coudert, function25);
+ ADD_CALLBACK_FUNCTION(Coudert, function26);
+ 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(Coudert, function32);
+ ADD_CALLBACK_FUNCTION(Coudert, function33);
+ ADD_CALLBACK_FUNCTION(Coudert, function34);
+ ADD_CALLBACK_FUNCTION(Coudert, function35);
+ ADD_CALLBACK_FUNCTION(Coudert, chapter1);
+ ADD_CALLBACK_FUNCTION(Coudert, function37);
+ ADD_CALLBACK_FUNCTION(Coudert, function38);
+ ADD_CALLBACK_FUNCTION(Coudert, function39);
+ ADD_CALLBACK_FUNCTION(Coudert, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Coudert, function41);
+ ADD_CALLBACK_FUNCTION(Coudert, chapter2);
+ ADD_CALLBACK_FUNCTION(Coudert, function43);
+ ADD_CALLBACK_FUNCTION(Coudert, chapter3);
+ ADD_CALLBACK_FUNCTION(Coudert, function45);
+ ADD_CALLBACK_FUNCTION(Coudert, function46);
+ ADD_CALLBACK_FUNCTION(Coudert, function47);
+ ADD_CALLBACK_FUNCTION(Coudert, function48);
+ ADD_CALLBACK_FUNCTION(Coudert, function49);
+ ADD_CALLBACK_FUNCTION(Coudert, function50);
+ ADD_CALLBACK_FUNCTION(Coudert, function51);
+ ADD_CALLBACK_FUNCTION(Coudert, chapter4);
+ ADD_CALLBACK_FUNCTION(Coudert, function53);
+ ADD_CALLBACK_FUNCTION(Coudert, function54);
+ ADD_CALLBACK_FUNCTION(Coudert, function55);
+ ADD_CALLBACK_FUNCTION(Coudert, function56);
+ ADD_CALLBACK_FUNCTION(Coudert, chapter5);
+ ADD_CALLBACK_FUNCTION(Coudert, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(Coudert, function59);
+ ADD_CALLBACK_FUNCTION(Coudert, function60);
+ ADD_CALLBACK_FUNCTION(Coudert, function61);
+ ADD_CALLBACK_FUNCTION(Coudert, function62);
+ ADD_NULL_FUNCTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Coudert, reset)
+ Entity::reset(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(2, Coudert, bloodJacket)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ SAVEGAME_BLOOD_JACKET();
+ break;
+
+ case kActionExitCompartment:
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(kEntityCoudert, (char *)&params->seq1);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventCoudertBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(3, Coudert, enterExitCompartment, ObjectIndex)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ SAVEGAME_BLOOD_JACKET();
+ return;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventCoudertBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ }
+ return;
+ }
+
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(4, Coudert, callbackActionOnDirection)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getData()->direction != kDirectionRight) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ SAVEGAME_BLOOD_JACKET();
+ break;
+
+ case kActionExitCompartment:
+ CALLBACK_ACTION();
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventCoudertBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SIII(5, Coudert, enterExitCompartment2, ObjectIndex, EntityPosition, EntityPosition)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ SAVEGAME_BLOOD_JACKET();
+ return;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventCoudertBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ }
+ return;
+ }
+
+ Entity::enterExitCompartment(savepoint, (EntityPosition)params->param5, (EntityPosition)params->param6, kCarRedSleeping, (ObjectIndex)params->param4, false);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(6, Coudert, playSound)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ SAVEGAME_BLOOD_JACKET();
+ break;
+
+ case kActionEndSound:
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getSound()->playSound(kEntityCoudert, (char *)&params->seq1);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventCoudertBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(7, Coudert, playSound16)
+ EXPOSE_PARAMS(EntityData::EntityParametersSIIS);
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ SAVEGAME_BLOOD_JACKET();
+ break;
+
+ case kActionEndSound:
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getSound()->playSound(kEntityCoudert, (char *)&params->seq1, SoundManager::kFlagDefault);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventCoudertBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(8, Coudert, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(9, Coudert, updateEntity, CarIndex, EntityPosition)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param3 && getEntities()->isDistanceBetweenEntities(kEntityCoudert, kEntityPlayer, 2000))
+ getData()->inventoryItem = kItemInvalid;
+ else
+ getData()->inventoryItem = kItemNone;
+
+ if (getProgress().jacket != kJacketBlood
+ || !getEntities()->isDistanceBetweenEntities(kEntityCoudert, kEntityPlayer, 1000)
+ || getEntities()->isInsideCompartments(kEntityPlayer)
+ || getEntities()->checkFields10(kEntityPlayer)) {
+ if (getEntities()->updateEntity(kEntityCoudert, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ getData()->inventoryItem = kItemNone;
+
+ CALLBACK_ACTION();
+ }
+ break;
+ }
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventMertensBloodJacket);
+ break;
+
+ case kAction1:
+ params->param3 = 0;
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventCoudertAskTylerCompartment);
+ break;
+
+ case kActionExcuseMeCath:
+ if (getData()->clothes == kClothes1)
+ getSound()->playSound(kEntityPlayer, "ZFX1003", getSound()->getSoundFlag(kEntityCoudert));
+ else if (!getSound()->isBuffered(kEntityCoudert))
+ getSound()->playSound(kEntityPlayer, "JAC1112", getSound()->getSoundFlag(kEntityCoudert));
+ break;
+
+ case kActionExcuseMe:
+ if (getData()->clothes == kClothes1)
+ getSound()->playSound(kEntityPlayer, "ZFX1003", getSound()->getSoundFlag(kEntityCoudert));
+ else
+ getSound()->excuseMe(kEntityCoudert);
+ break;
+
+ case kActionDefault:
+ if (!getProgress().eventCorpseFound && !getEvent(kEventCoudertAskTylerCompartment))
+ params->param3 = kItemInvalid;
+
+ if (getEntities()->updateEntity(kEntityCoudert, (CarIndex)params->param1, (EntityPosition)params->param2))
+ CALLBACK_ACTION();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventCoudertBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ break;
+
+ case 2:
+ getAction()->playAnimation(kEventCoudertAskTylerCompartment);
+
+ if (getData()->direction != kDirectionUp)
+ getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + 750));
+ else
+ getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition - 750), true);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(10, Coudert, updateFromTime, uint32)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ SAVEGAME_BLOOD_JACKET();
+
+ UPDATE_PARAM(params->param2, getState()->time, params->param1);
+
+ CALLBACK_ACTION();
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventCoudertBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(11, Coudert, updateFromTicks, uint32)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ SAVEGAME_BLOOD_JACKET();
+
+ UPDATE_PARAM(params->param2, getState()->timeTicks, params->param1);
+
+ CALLBACK_ACTION();
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventCoudertBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Parameters
+// - EntityIndex
+IMPLEMENT_FUNCTION_I(12, Coudert, excuseMe, EntityIndex)
+ if (savepoint.action != kActionDefault)
+ return;
+
+ if (getSound()->isBuffered(kEntityCoudert)) {
+ CALLBACK_ACTION();
+ return;
+ }
+
+ if (isNight()) {
+ if (Entities::isFemale((EntityIndex)params->param1)) {
+ getSound()->playSound(kEntityCoudert, Entities::isMarried((EntityIndex)params->param1) ? "JAC1112C" : "JAC1112F");
+ } else {
+ if (!params->param1 && getProgress().field_18 == 2) {
+ switch (rnd(4)) {
+ default:
+ break;
+
+ case 0:
+ getSound()->playSound(kEntityCoudert, "JAC1013");
+ break;
+
+ case 1:
+ getSound()->playSound(kEntityCoudert, "JAC1013A");
+ break;
+
+ case 2:
+ getSound()->playSound(kEntityCoudert, "JAC1113");
+ break;
+
+ case 3:
+ getSound()->playSound(kEntityCoudert, "JAC1113A");
+ break;
+ }
+ } else {
+ getSound()->playSound(kEntityCoudert, "JAC1112D");
+ }
+ }
+ } else {
+ if (Entities::isFemale((EntityIndex)params->param1))
+ getSound()->playSound(kEntityCoudert, Entities::isMarried((EntityIndex)params->param1) ? "JAC1112B" : "JAC1112G");
+ else
+ getSound()->playSound(kEntityCoudert, "JAC1112E");
+ }
+
+ CALLBACK_ACTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(13, Coudert, function13, bool, EntityIndex)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ SAVEGAME_BLOOD_JACKET();
+
+ if (!params->param2 && !params->param3) {
+
+ if (!params->param4) {
+ params->param4 = getState()->timeTicks + 75;
+
+ if (!params->param4) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(4);
+ setup_function19(true);
+ break;
+ }
+ }
+
+ if (params->param4 < getState()->timeTicks) {
+ params->param4 = kTimeInvalid;
+
+ getData()->inventoryItem = kItemNone;
+ setCallback(4);
+ setup_function19(true);
+ break;
+ }
+ }
+
+ UPDATE_PARAM(params->param5, getState()->timeTicks, 225);
+
+ getData()->inventoryItem = kItemNone;
+ setCallback(5);
+ setup_function19(true);
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(9);
+ setup_savegame(kSavegameTypeEvent, kEventCoudertAskTylerCompartment);
+ break;
+
+ case kAction11:
+ ++params->param3;
+
+ setCallback(8);
+ setup_excuseMe(savepoint.entity2);
+ break;
+
+ case kActionDefault:
+ if (params->param2)
+ params->param3 = 1;
+
+ setCallback(1);
+ setup_excuseMe((EntityIndex)params->param2);
+ break;
+
+ case kAction16:
+ --params->param3;
+
+ if (params->param2 && !params->param3) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(7);
+ setup_function19(true);
+ }
+ break;
+
+ case kActionDrawScene:
+ if (!params->param3) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(6);
+ setup_function19(true);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function17(true);
+ break;
+
+ case 2:
+ if (getProgress().chapter == kChapter1 && !getProgress().eventCorpseFound && !getEvent(kEventCoudertAskTylerCompartment))
+ getData()->inventoryItem = kItemInvalid;
+
+ getEntities()->drawSequenceLeft(kEntityCoudert, params->param1 ? "667I" : "667H");
+ break;
+
+ case 3:
+ getAction()->playAnimation(kEventCoudertBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ // BUG: the original game continues executing code here
+ break;
+
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ CALLBACK_ACTION();
+ break;
+
+ case 9:
+ getAction()->playAnimation(kEventCoudertAskTylerCompartment);
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 25);
+ break;
+ }
+ break;
+
+ case kAction201439712:
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627K");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(14, Coudert, function14, EntityIndex)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ SAVEGAME_BLOOD_JACKET();
+ break;
+
+ case kActionDefault:
+ if (ENTITY_PARAM(2, 1)) {
+ ENTITY_PARAM(2, 1) = 0;
+
+ setCallback(3);
+ setup_updateEntity(kCarRedSleeping, kPosition_1500);
+ } else {
+ setCallback(1);
+ setup_updateFromTime(15);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityCoudert, (EntityIndex)params->param1, kAction202558662);
+
+ setCallback(2);
+ setup_function17(false);
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityCoudert, (EntityIndex)params->param1, kAction155853632);
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627K");
+ break;
+
+ case 3:
+ getSavePoints()->push(kEntityCoudert, (EntityIndex)params->param1, kAction202558662);
+ getSavePoints()->push(kEntityCoudert, (EntityIndex)params->param1, kAction155853632);
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627K");
+ getScenes()->loadSceneFromItemPosition(kItem5);
+ break;
+
+ case 4:
+ getAction()->playAnimation(kEventCoudertBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ break;
+
+ case 5:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction125499160:
+ switch (params->param1) {
+ default:
+ break;
+
+ case kEntityVerges:
+ ENTITY_PARAM(0, 3) = 0;
+ break;
+
+ case kEntityMmeBoutarel:
+ ENTITY_PARAM(0, 4) = 0;
+ break;
+
+ case kEntityMertens:
+ ENTITY_PARAM(0, 5) = 0;
+ break;
+ }
+
+ setCallback(5);
+ setup_function19(false);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(15, Coudert, function15, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ ENTITY_PARAM(0, 8) = 0;
+ ENTITY_PARAM(1, 1) = 0;
+
+ setCallback(1);
+ setup_function16();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_7500);
+ break;
+
+ case 2:
+ if (params->param1)
+ getSound()->playSound(kEntityCoudert, "Tat3163");
+ else
+ getSound()->playSound(kEntityCoudert, (getProgress().chapter != kChapter3 || getState()->time > kTime1449000) ? "Tat3162A" : "Tat3161A");
+
+ setCallback(3);
+ setup_enterExitCompartment("627Xb", kObjectCompartmentB);
+ break;
+
+ case 3:
+ getSavePoints()->push(kEntityCoudert, kEntityTatiana, kAction69239528);
+ getData()->entityPosition = kPosition_7250;
+
+ setCallback(4);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_function18();
+ break;
+
+ case 5:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Coudert, function16)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (ENTITY_PARAM(2, 1)) {
+ ENTITY_PARAM(2, 1) = 0;
+ getInventory()->setLocationAndProcess(kItem5, kObjectLocation1);
+
+ CALLBACK_ACTION();
+ break;
+ }
+
+ setCallback(ENTITY_PARAM(0, 2) ? 1 : 2);
+ setup_bloodJacket(ENTITY_PARAM(0, 2) ? "627C" : "627F");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ getInventory()->setLocationAndProcess(kItem5, kObjectLocation1);
+ if (!getEntities()->isPlayerPosition(kCarRedSleeping, 2))
+ getData()->entityPosition = kPosition_2088;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(17, Coudert, function17, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getScenes()->loadSceneFromItemPosition(kItem5);
+
+ if (ENTITY_PARAM(2, 1)) {
+ ENTITY_PARAM(2, 1) = 0;
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (params->param1) {
+ setCallback(1);
+ setup_bloodJacket("627H");
+ break;
+ }
+
+ if (params->param2) {
+ setCallback(2);
+ setup_bloodJacket("627C");
+ break;
+ }
+
+ setCallback(3);
+ setup_bloodJacket("627F");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ case 3:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Coudert, function18)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (ENTITY_PARAM(0, 6) || ENTITY_PARAM(0, 8)
+ || ENTITY_PARAM(1, 1) || ENTITY_PARAM(1, 2) || ENTITY_PARAM(1, 3) || ENTITY_PARAM(1, 5) || ENTITY_PARAM(1, 6) || ENTITY_PARAM(1, 7) || ENTITY_PARAM(1, 8)
+ || ENTITY_PARAM(2, 4) || ENTITY_PARAM(2, 6)) {
+ getInventory()->setLocationAndProcess(kItem5, kObjectLocation1);
+
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_540);
+ break;
+ }
+
+ if (ENTITY_PARAM(0, 3) || ENTITY_PARAM(0, 5) || ENTITY_PARAM(0, 4)) {
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627K");
+ getScenes()->loadSceneFromItemPosition(kItem5);
+
+ CALLBACK_ACTION();
+ break;
+ }
+
+ getEntities()->drawSequenceRight(kEntityCoudert, ENTITY_PARAM(0, 2) ? "627A" : "627D");
+ getScenes()->loadSceneFromItemPosition(kItem5);
+
+ if (getEntities()->isPlayerPosition(kCarRedSleeping, 68)) {
+ if (!getSound()->isBuffered(kEntityCoudert))
+ getSound()->playSound(kEntityCoudert, "JAC1111");
+
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 25);
+ }
+
+ setCallback(3);
+ setup_callbackActionOnDirection();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->clearSequences(kEntityCoudert);
+ ENTITY_PARAM(2, 1) = 1;
+
+ setCallback(2);
+ setup_updateFromTime(75);
+ break;
+
+ case 2:
+ CALLBACK_ACTION();
+ break;
+
+ case 3:
+ getEntities()->drawSequenceLeft(kEntityCoudert, ENTITY_PARAM(0, 2) ? "627B" : "627E");
+ ENTITY_PARAM(0, 1) = 0;
+ getSavePoints()->push(kEntityCoudert, kEntityCoudert, kActionDrawScene);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(19, Coudert, function19, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (ENTITY_PARAM(0, 6) || ENTITY_PARAM(0, 8)
+ || ENTITY_PARAM(1, 1) || ENTITY_PARAM(1, 2) || ENTITY_PARAM(1, 3) || ENTITY_PARAM(1, 5) || ENTITY_PARAM(1, 6) || ENTITY_PARAM(1, 7) || ENTITY_PARAM(1, 8)
+ || ENTITY_PARAM(2, 4) || ENTITY_PARAM(2, 6)) {
+ getInventory()->setLocationAndProcess(kItem5, kObjectLocation1);
+ ENTITY_PARAM(2, 1) = 1;
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (ENTITY_PARAM(0, 3) || ENTITY_PARAM(0, 5) || ENTITY_PARAM(0, 4)) {
+ getScenes()->loadSceneFromItemPosition(kItem5);
+ ENTITY_PARAM(2, 1) = 1;
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (params->param1)
+ getEntities()->drawSequenceRight(kEntityCoudert, "697H");
+ else
+ getEntities()->drawSequenceRight(kEntityCoudert, ENTITY_PARAM(0, 2) ? "627A" : "627D");
+
+ getScenes()->loadSceneFromItemPosition(kItem5);
+
+ setCallback(1);
+ setup_callbackActionOnDirection();
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getEntities()->drawSequenceLeft(kEntityCoudert, ENTITY_PARAM(0, 2) ? "627B" : "627E");
+ ENTITY_PARAM(0, 1) = 0;
+
+ CALLBACK_ACTION();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(20, Coudert, function20, ObjectIndex, ObjectIndex)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM_PROC(CURRENT_PARAMS(1, 3), getState()->time, 300)
+ getSound()->playSound(kEntityPlayer, "ZFX1004", getSound()->getSoundFlag(kEntityCoudert));
+ UPDATE_PARAM_PROC_END
+
+ UPDATE_PARAM(CURRENT_PARAMS(1, 4), getState()->time, 900);
+
+ getObjects()->updateLocation2((ObjectIndex)params->param1, kObjectLocation1);
+
+ if (params->param4 != kObjectLocation2)
+ getObjects()->update((ObjectIndex)params->param1, (EntityIndex)params->param3, (ObjectLocation)params->param4, (CursorStyle)params->param5, (CursorStyle)params->param6);
+
+ if (params->param2)
+ getObjects()->update((ObjectIndex)params->param2, (EntityIndex)params->param7, (ObjectLocation)params->param8, (CursorStyle)CURRENT_PARAMS(1, 1), (CursorStyle)CURRENT_PARAMS(1, 2));
+
+ CALLBACK_ACTION();
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ getObjects()->update((ObjectIndex)params->param1, kEntityCoudert, kObjectLocation1, kCursorNormal, kCursorNormal);
+ if (params->param2)
+ getObjects()->update((ObjectIndex)params->param2, kEntityCoudert, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(savepoint.action == kActionKnock ? 1 : 2);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ break;
+
+ case kActionDefault:
+ params->param3 = getObjects()->get((ObjectIndex)params->param1).entity;
+ params->param4 = getObjects()->get((ObjectIndex)params->param1).location;
+ params->param5 = getObjects()->get((ObjectIndex)params->param1).cursor;
+ params->param6 = getObjects()->get((ObjectIndex)params->param1).cursor2;
+
+ if (params->param2) {
+ params->param7 = getObjects()->get((ObjectIndex)params->param2).entity;
+ params->param8 = getObjects()->get((ObjectIndex)params->param2).location;
+ CURRENT_PARAMS(1, 1) = getObjects()->get((ObjectIndex)params->param2).cursor;
+ CURRENT_PARAMS(1, 2) = getObjects()->get((ObjectIndex)params->param2).cursor2;
+
+ getObjects()->update((ObjectIndex)params->param2, kEntityCoudert, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ }
+
+ if (params->param4 != kObjectLocation2)
+ getObjects()->update((ObjectIndex)params->param1, kEntityCoudert, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ if (params->param1 == kObjectCompartmentA || params->param1 == kObjectCompartmentC
+ || params->param1 == kObjectCompartmentG || params->param1 == kObjectCompartmentH) {
+ setCallback(3);
+ setup_playSound("Jac1001B");
+ } else {
+ setCallback(4);
+ setup_playSound("Jac1001A");
+ }
+ break;
+
+ case 3:
+ case 4:
+ getObjects()->update((ObjectIndex)params->param1, kEntityCoudert, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ if (params->param2)
+ getObjects()->update((ObjectIndex)params->param2, kEntityCoudert, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Coudert, function21)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1) {
+ UPDATE_PARAM(params->param2, getState()->timeTicks, 75);
+
+ setCallback(3);
+ setup_enterExitCompartment("627Zh", kObjectCompartmentH);
+ }
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_2740);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("627Vh", kObjectCompartmentH);
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityCoudert, kEntityIvo, kAction221683008);
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627Wh");
+ getEntities()->enterCompartment(kEntityCoudert, kObjectCompartmentH, true);
+ break;
+
+ case 3:
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentH, true);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityCoudert);
+
+ setCallback(4);
+ setup_function20(kObjectCompartmentH, kObjectNone);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_enterExitCompartment("697Ah", kObjectCompartmentH);
+ break;
+
+ case 5:
+ getData()->location = kLocationOutsideCompartment;
+
+ CALLBACK_ACTION();
+ break;
+
+ case 6:
+ getSavePoints()->push(kEntityCoudert, kEntityIvo, kAction122865568);
+ break;
+
+ case 7:
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentH, true);
+ getObjects()->update(kObjectCompartmentH, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityCoudert);
+
+ setCallback(8);
+ setup_function20(kObjectCompartmentH, kObjectNone);
+ break;
+
+ case 8:
+ getSound()->playSound(kEntityCoudert, "JAC1013A");
+ getObjects()->update(kObjectCompartmentH, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(9);
+ setup_enterExitCompartment("667Uh", kObjectCompartmentH);
+ break;
+
+ case 9:
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityCoudert, kEntityIvo, kAction123852928);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction88652208:
+ setCallback(7);
+ setup_enterExitCompartment("667Th", kObjectCompartmentH);
+ break;
+
+ case kAction123199584:
+ params->param1 = 1;
+
+ setCallback(6);
+ setup_playSound("JAC1012");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Coudert, function22)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1) {
+ UPDATE_PARAM(params->param2, getState()->timeTicks, 75);
+
+ setCallback(3);
+ setup_enterExitCompartment("627Rg", kObjectCompartmentG);
+ }
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_3050);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("627Mg", kObjectCompartmentG);
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityCoudert, kEntityMilos, kAction221683008);
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627Ng");
+ getEntities()->enterCompartment(kEntityCoudert, kObjectCompartmentG, true);
+ break;
+
+ case 3:
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentG, true);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityCoudert);
+
+ setCallback(4);
+ setup_function20(kObjectCompartmentG, kObjectNone);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_enterExitCompartment("627Sg", kObjectCompartmentG);
+ break;
+
+ case 5:
+ getData()->location = kLocationOutsideCompartment;
+
+ CALLBACK_ACTION();
+ break;
+
+ case 6:
+ getSavePoints()->push(kEntityCoudert, kEntityMilos, kAction122865568);
+ break;
+
+ case 7:
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentG, true);
+ getObjects()->update(kObjectCompartmentG, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityCoudert);
+
+ setCallback(8);
+ setup_function20(kObjectCompartmentG, kObjectNone);
+ break;
+
+ case 8:
+ getSound()->playSound(kEntityCoudert, "JAC1013A");
+ getObjects()->update(kObjectCompartmentG, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(9);
+ setup_enterExitCompartment("627Ug", kObjectCompartmentG);
+ break;
+
+ case 9:
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityCoudert, kEntityMilos, kAction123852928);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction88652208:
+ setCallback(7);
+ setup_enterExitCompartment("627Tg", kObjectCompartmentG);
+ break;
+
+ case kAction123199584:
+ params->param1 = 1;
+
+ setCallback(6);
+ setup_playSound("JAC1030");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Coudert, function23)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_4070);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("627Vf", kObjectCompartmentF);
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627Wf");
+ getEntities()->enterCompartment(kEntityCoudert, kObjectCompartmentF, true);
+ getSavePoints()->push(kEntityCoudert, kEntityMax, kAction158007856);
+
+ setCallback(3);
+ setup_updateFromTime(150);
+ break;
+
+ case 3:
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentF, true);
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Coudert, visitCompartmentF)
+ visitCompartment(savepoint, kPosition_4070, "627Vf", kObjectCompartmentF, "627Wf", "627Zf", kPosition_4455, kObject53, "697Af");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, Coudert, function25)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_4840);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("627Me", kObjectCompartmentE);
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627Ne");
+ getEntities()->enterCompartment(kEntityCoudert, kObjectCompartmentE, true);
+
+ setCallback(3);
+ setup_updateFromTime(45);
+ break;
+
+ case 3:
+ getSavePoints()->push(kEntityCoudert, kEntityRebecca, kAction254915200);
+
+ setCallback(4);
+ setup_updateFromTime(450);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_enterExitCompartment2("627Re", kObjectCompartmentE, kPosition_4840, kPosition_4455);
+ break;
+
+ case 5:
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentE, true);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityCoudert);
+
+ setCallback(6);
+ setup_function20(kObjectCompartmentE, kObject52);
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_enterExitCompartment("627Se", kObjectCompartmentE);
+ break;
+
+ case 7:
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityCoudert, kEntityRebecca, kAction123852928);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(26, Coudert, function26)
+ error("Coudert: callback function 26 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(27, Coudert, function27)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1) {
+ UPDATE_PARAM(params->param2, getState()->timeTicks, 75);
+
+ setCallback(3);
+ setup_enterExitCompartment2("627Rc", kObjectCompartmentC, kPosition_6470, kPosition_6130);
+ }
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_6470);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("627Mc", kObjectCompartmentC);
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityCoudert, kEntityBoutarel, kAction221683008);
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627Nc");
+ getEntities()->enterCompartment(kEntityCoudert, kObjectCompartmentC, true);
+ break;
+
+ case 3:
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentC, true);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityCoudert);
+
+ setCallback(4);
+ setup_function20(kObjectCompartmentC, kObject50);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_enterExitCompartment("627Sc", kObjectCompartmentC);
+ break;
+
+ case 5:
+ getData()->location = kLocationOutsideCompartment;
+ CALLBACK_ACTION();
+ break;
+
+ case 6:
+ getSavePoints()->push(kEntityCoudert, kEntityBoutarel, kAction122865568);
+ break;
+
+ case 7:
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentC, true);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityCoudert);
+
+ setCallback(8);
+ setup_function20(kObjectCompartmentC, kObject50);
+ break;
+
+ case 8:
+ getSound()->playSound(kEntityCoudert, "JAC1013");
+
+ setCallback(9);
+ setup_enterExitCompartment("627Uc", kObjectCompartmentC);
+ break;
+
+ case 9:
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityCoudert, kEntityBoutarel, kAction123852928);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction88652208:
+ setCallback(7);
+ setup_enterExitCompartment2("627Rc", kObjectCompartmentC, kPosition_6470, kPosition_6130);
+ break;
+
+ case kAction123199584:
+ params->param1 = 1;
+
+ setCallback(6);
+ setup_playSound("JAC1012");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(28, Coudert, visitCompartmentB)
+ visitCompartment(savepoint, kPosition_7500, "627Vb", kObjectCompartmentB, "627Wb", "627Zb", kPosition_7850, kObject49, "697Ab");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(29, Coudert, visitCompartmentA)
+ visitCompartment(savepoint, kPosition_8200, "627Ma", kObjectCompartmentA, "627Na", "627Ra", kPosition_7850, kObject48, "627Sa");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(30, Coudert, function30, ObjectIndex)
+ // Expose parameters as IIIIIS and ignore the default exposed parameters
+ EntityData::EntityParametersI5S *parameters = (EntityData::EntityParametersI5S*)_data->getCurrentParameters();
+ EntityData::EntityParametersSIIS *parameters1 = (EntityData::EntityParametersSIIS*)_data->getCurrentParameters(1);
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ switch (parameters->param1) {
+ default:
+ CALLBACK_ACTION();
+ // Stop processing here
+ return;
+
+ case kObjectCompartmentA:
+ parameters->param2 = kPosition_8200;
+ parameters->param3 = kPosition_7850;
+ strcpy((char *)&parameters->seq, "627Ma");
+ strcpy((char *)&parameters1->seq1, "627Na");
+ break;
+
+ case kObjectCompartmentB:
+ parameters->param2 = kPosition_7500;
+ parameters->param3 = kPosition_7850;
+ parameters->param4 = true;
+ strcpy((char *)&parameters->seq, "627Vb");
+ strcpy((char *)&parameters1->seq1, "627Wb");
+ break;
+
+ case kObjectCompartmentC:
+ parameters->param2 = kPosition_6470;
+ parameters->param3 = kPosition_6130;
+ strcpy((char *)&parameters->seq, "627Mc");
+ strcpy((char *)&parameters1->seq1, "627Nc");
+ break;
+
+ case kObjectCompartmentD:
+ parameters->param2 = kPosition_5790;
+ parameters->param3 = kPosition_6130;
+ parameters->param4 = true;
+ strcpy((char *)&parameters->seq, "627Vd");
+ strcpy((char *)&parameters1->seq1, "627Wd");
+ break;
+
+ case kObjectCompartmentE:
+ parameters->param2 = kPosition_4840;
+ parameters->param3 = kPosition_4455;
+ parameters->param4 = true;
+ strcpy((char *)&parameters->seq, "627Me");
+ strcpy((char *)&parameters1->seq1, "627Ne");
+ break;
+
+ case kObjectCompartmentF:
+ parameters->param2 = kPosition_4070;
+ parameters->param3 = kPosition_4455;
+ parameters->param4 = true;
+ strcpy((char *)&parameters->seq, "627Vf");
+ strcpy((char *)&parameters1->seq1, "627Wf");
+ break;
+ }
+
+ setCallback(1);
+ setup_function16();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, (EntityPosition)parameters->param2);
+ break;
+
+ case 2:
+ if (getEntities()->checkFields19(kEntityPlayer, kCarRedSleeping, (EntityPosition)parameters->param3)
+ || ((parameters->param1 == kObjectCompartmentE || parameters->param1 == kObjectCompartmentF) && getEntities()->isOutsideAnnaWindow())) {
+ getObjects()->update((ObjectIndex)parameters->param1, kEntityPlayer, getObjects()->get((ObjectIndex)parameters->param1).location, kCursorNormal, kCursorNormal);
+ parameters->param5 = true;
+ }
+
+ setCallback(3);
+ setup_enterExitCompartment((char *)&parameters->seq, (ObjectIndex)parameters->param1);
+ break;
+
+ case 3:
+ getEntities()->drawSequenceLeft(kEntityCoudert, (char *)&parameters1->seq1);
+ getEntities()->enterCompartment(kEntityCoudert, (ObjectIndex)parameters->param1, true);
+
+ setCallback(4);
+ setup_playSound(parameters->param4 ? "JAC3020" : "JAC3021");
+ break;
+
+ case 4:
+ if (parameters->param5)
+ getObjects()->update((ObjectIndex)parameters->param1, kEntityPlayer, getObjects()->get((ObjectIndex)parameters->param1).location, kCursorHandKnock, kCursorHand);
+
+ getEntities()->exitCompartment(kEntityCoudert, (ObjectIndex)parameters->param1, true);
+
+ setCallback(5);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_function18();
+ break;
+
+ case 6:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(31, Coudert, function31, uint32)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionEndSound:
+ setCallback(3);
+ setup_function19(true);
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_bloodJacket("627G");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (getSound()->isBuffered(kEntityCoudert)) {
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627K");
+ } else {
+ setCallback(2);
+ setup_function19(true);
+ }
+ break;
+
+ case 2:
+ case 3:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(32, Coudert, function32)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function16();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_9460);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityCoudert);
+ setCallback(3);
+ setup_updateFromTime(900);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_function18();
+ break;
+
+ case 5:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(33, Coudert, function33)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (ENTITY_PARAM(0, 3) || ENTITY_PARAM(0, 4) || ENTITY_PARAM(0, 5) || ENTITY_PARAM(0, 6) || ENTITY_PARAM(0, 7)
+ || ENTITY_PARAM(1, 2) || ENTITY_PARAM(1, 7)
+ || ENTITY_PARAM(2, 2)) {
+ ENTITY_PARAM(2, 6) = 1;
+
+ if (ENTITY_PARAM(0, 3) || ENTITY_PARAM(0, 4) || ENTITY_PARAM(0, 5)) {
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_1500);
+ } else {
+ setCallback(5);
+ setup_updateEntity(kCarRedSleeping, kPosition_540);
+ }
+ } else {
+ CALLBACK_ACTION();
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ ENTITY_PARAM(2, 1) = 1;
+ if (ENTITY_PARAM(0, 3)) {
+ setCallback(2);
+ setup_function14(kEntityVerges);
+ break;
+ }
+ // Fallback to next case
+
+ case 2:
+ if (ENTITY_PARAM(0, 5)) {
+ setCallback(3);
+ setup_function14(kEntityMertens);
+ break;
+ }
+ // Fallback to next case
+
+ case 3:
+ if (ENTITY_PARAM(0, 4)) {
+ setCallback(4);
+ setup_function14(kEntityMmeBoutarel);
+ break;
+ }
+ // Fallback to next case
+
+ case 4:
+ ENTITY_PARAM(2, 6) = 0;
+
+ CALLBACK_ACTION();
+ break;
+
+ case 5:
+ getEntities()->clearSequences(kEntityCoudert);
+
+ setCallback(6);
+ setup_updateFromTime(75);
+ break;
+
+ case 6:
+ if (ENTITY_PARAM(0, 6) || ENTITY_PARAM(0, 7)) {
+ setCallback(7);
+ setup_function37();
+ break;
+ }
+ // Fallback to next case
+
+ case 7:
+ if (ENTITY_PARAM(2, 2)) {
+ setCallback(8);
+ setup_function39();
+ break;
+ }
+ // Fallback to next case
+
+ case 8:
+ if (ENTITY_PARAM(1, 2)) {
+ setCallback(9);
+ setup_function55();
+ break;
+ }
+ // Fallback to next case
+
+ case 9:
+ if (ENTITY_PARAM(1, 7)) {
+ setCallback(10);
+ setup_function34(false);
+ break;
+ }
+ // Fallback to next case
+
+ case 10:
+ ENTITY_PARAM(2, 6) = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(34, Coudert, function34, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function16();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_4070);
+ break;
+
+ case 2:
+ if (!params->param1) {
+ getSound()->playSound(kEntityCoudert, "Ann3124");
+
+ ENTITY_PARAM(1, 7) = 0;
+ ENTITY_PARAM(1, 4) = 0;
+
+ setCallback(7);
+ setup_function35((bool)params->param1);
+ } else {
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627Vf");
+ getEntities()->enterCompartment(kEntityCoudert, kObjectCompartmentF, true);
+
+ setCallback(3);
+ setup_playSound("LIB012");
+ }
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_playSound("Jac1001");
+ break;
+
+ case 4:
+ getSound()->playSound(kEntityCoudert, "Ann3125");
+
+ setCallback(5);
+ setup_enterExitCompartment("629Bf", kObjectCompartmentF);
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_enterExitCompartment("629Ff", kObjectCompartmentF);
+ break;
+
+ case 6:
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentF, true);
+
+ ENTITY_PARAM(1, 7) = 0;
+ ENTITY_PARAM(1, 4) = 0;
+
+ setCallback(7);
+ setup_function35((bool)params->param1);
+ break;
+
+ case 7:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(35, Coudert, function35, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarBaggage)) {
+ getAction()->playAnimation(kEventCoudertBaggageCar);
+ getSound()->playSound(kEntityPlayer, "BUMP");
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 65);
+ }
+
+ UPDATE_PARAM(params->param2, getState()->time, 2700);
+
+ getSavePoints()->push(kEntityCoudert, kEntityMax, kActionMaxFreeFromCage);
+
+ getData()->clothes = kClothesDefault;
+
+ setCallback(3);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case kActionDefault:
+ if (params->param1)
+ getSavePoints()->push(kEntityCoudert, kEntityAnna, kAction156049968);
+
+ getSavePoints()->push(kEntityCoudert, kEntityMax, kAction122358304);
+
+ getData()->clothes = kClothes1;
+ getData()->entityPosition = kPosition_4370;
+
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_8200);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (!getSound()->isBuffered(kEntityCoudert))
+ getSound()->playSound(kEntityCoudert, "Ann3124");
+
+ if (params->param1)
+ getSavePoints()->push(kEntityCoudert, kEntityAnna, kAction123733488);
+
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_9460);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityCoudert);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function18();
+ break;
+
+ case 4:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(36, Coudert, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CALLBACK(kTimeChapter1, params->param1, 1, setup_chapter1Handler)
+ break;
+
+ case kActionDefault:
+ getSavePoints()->addData(kEntityCoudert, kAction292048641, 7);
+ getSavePoints()->addData(kEntityCoudert, kAction326348944, 8);
+ getSavePoints()->addData(kEntityCoudert, kAction171394341, 2);
+ getSavePoints()->addData(kEntityCoudert, kAction154005632, 4);
+ getSavePoints()->addData(kEntityCoudert, kAction169557824, 3);
+ getSavePoints()->addData(kEntityCoudert, kAction226031488, 5);
+ getSavePoints()->addData(kEntityCoudert, kAction339669520, 6);
+ getSavePoints()->addData(kEntityCoudert, kAction189750912, 10);
+ getSavePoints()->addData(kEntityCoudert, kAction185737168, 12);
+ getSavePoints()->addData(kEntityCoudert, kAction185671840, 13);
+ getSavePoints()->addData(kEntityCoudert, kAction205033696, 15);
+ getSavePoints()->addData(kEntityCoudert, kAction157026693, 14);
+ getSavePoints()->addData(kEntityCoudert, kAction189026624, 11);
+ getSavePoints()->addData(kEntityCoudert, kAction168254872, 17);
+ getSavePoints()->addData(kEntityCoudert, kAction201431954, 18);
+ getSavePoints()->addData(kEntityCoudert, kAction188570113, 19);
+
+ ENTITY_PARAM(0, 1) = 0;
+ ENTITY_PARAM(0, 2) = 1;
+
+ getData()->entityPosition = kPosition_1500;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getObjects()->updateLocation2(kObject111, kObjectLocation1);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_chapter1Handler();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(37, Coudert, function37)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (getSound()->isBuffered(kEntityCoudert))
+ getSound()->processEntry(kEntityCoudert);
+
+ if (ENTITY_PARAM(0, 7)) {
+ getData()->entityPosition = kPosition_8200;
+
+ setCallback(4);
+ setup_enterExitCompartment2("698Ha", kObjectCompartmentA, kPosition_8200, kPosition_7850);
+ } else {
+ setCallback(1);
+ setup_function16();
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_5790);
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityCoudert, kEntityAnna, kAction238358920);
+ setCallback(3);
+ setup_updateEntity(kCarRedSleeping, kPosition_8200);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_enterExitCompartment2("698Ha", kObjectCompartmentA, kPosition_8200, kPosition_7850);
+ break;
+
+ case 4:
+ getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityCoudert);
+ setup_function38();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(38, Coudert, function38)
+switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_8200;
+ getData()->location = kLocationInsideCompartment;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ ENTITY_PARAM(0, 6) = 0;
+ ENTITY_PARAM(0, 7) = 0;
+
+ setCallback(2);
+ setup_function18();
+ break;
+
+ case 2:
+ setup_chapter1Handler();
+ break;
+ }
+ break;
+
+ case kAction191477936:
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationOutsideCompartment;
+ getObjects()->update(kObjectCompartment4, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(39, Coudert, function39)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_playSound("LIB070");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function16();
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_updateEntity(kCarRedSleeping, kPosition_5790);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_enterExitCompartment("627Vd", kObjectCompartmentD);
+ break;
+
+ case 4:
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627Wd");
+ getEntities()->enterCompartment(kEntityCoudert, kObjectCompartmentD, true);
+
+ setCallback(5);
+ setup_playSound("MME1151A");
+ break;
+
+ case 5:
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentD, true);
+
+ setCallback(6);
+ setup_enterExitCompartment("627Zd", kObjectCompartmentD);
+ break;
+
+ case 6:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityCoudert);
+
+ setCallback(7);
+ setup_playSound("MME1151");
+ break;
+
+ case 7:
+ setCallback(8);
+ setup_enterExitCompartment("MME1151", kObjectCompartmentD);
+ break;
+
+ case 8:
+ getSavePoints()->push(kEntityCoudert, kEntityMmeBoutarel, kAction223068211);
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(9);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case 9:
+ setCallback(10);
+ setup_function18();
+ break;
+
+ case 10:
+ getSavePoints()->push(kEntityCoudert, kEntityVerges, kAction167854368);
+ ENTITY_PARAM(2, 2) = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(40, Coudert, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (ENTITY_PARAM(2, 3)) {
+ ENTITY_PARAM(0, 1) = 1;
+ ENTITY_PARAM(0, 3) = 0;
+ ENTITY_PARAM(0, 4) = 0;
+ ENTITY_PARAM(0, 5) = 0;
+ ENTITY_PARAM(0, 8) = 0;
+
+ ENTITY_PARAM(1, 1) = 0;
+
+ ENTITY_PARAM(2, 1) = 0;
+ ENTITY_PARAM(2, 2) = 0;
+
+ getEntities()->drawSequenceLeft(kEntityCoudert, "697F");
+
+ params->param1 = 1;
+ params->param2 = 1;
+
+ ENTITY_PARAM(2, 3) = 0;
+ }
+
+ getData()->inventoryItem = (getProgress().eventCorpseFound || getEvent(kEventCoudertAskTylerCompartment)) ? kItemNone : kItemInvalid;
+
+ if (ENTITY_PARAM(0, 8)) {
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(4);
+ setup_function15(true);
+ break;
+ }
+
+label_callback_4:
+ if (ENTITY_PARAM(1, 1)) {
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(5);
+ setup_function15(false);
+ break;
+ }
+
+label_callback_5:
+ if (ENTITY_PARAM(0, 6) || ENTITY_PARAM(0, 7)) {
+ getData()->inventoryItem = kItemNone;
+ setup_function37();
+ break;
+ }
+
+ if (ENTITY_PARAM(0, 3)) {
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(6);
+ setup_function14(kEntityVerges);
+ break;
+ }
+
+label_callback_6:
+ if (ENTITY_PARAM(0, 5)) {
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(7);
+ setup_function14(kEntityMertens);
+ break;
+ }
+
+label_callback_7:
+ if (ENTITY_PARAM(0, 4)) {
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(8);
+ setup_function14(kEntityMmeBoutarel);
+ break;
+ }
+
+label_callback_8:
+ if (ENTITY_PARAM(2, 2)) {
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(9);
+ setup_function39();
+ break;
+ }
+
+label_callback_9:
+ if (ENTITY_PARAM(0, 1) && !getSound()->isBuffered(kEntityCoudert))
+ getSound()->playSound(kEntityCoudert, rnd(2) ? "JAC1065" : "JAC1065A");
+
+ if (getState()->time > kTime1107000 && !ENTITY_PARAM(0, 1) && !getEvent(kEventVassiliSeizure)) {
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(10);
+ setup_function41();
+ break;
+ }
+
+label_callback_10:
+ if (getState()->time > kTime1189800 && !ENTITY_PARAM(0, 1) && !ENTITY_PARAM(2, 1)) {
+ UPDATE_PARAM_PROC(params->param3, getState()->time, 2700);
+ ENTITY_PARAM(0, 2) = 1;
+ ENTITY_PARAM(0, 1) = 1;
+
+ getEntities()->drawSequenceLeft(kEntityCoudert, "697F");
+
+ params->param3 = 0;
+ UPDATE_PARAM_PROC_END
+ }
+
+ if (!ENTITY_PARAM(0, 2))
+ break;
+
+ TIME_CHECK_OBJECT(kTime1107000, params->param4, kObject111, kObjectLocation2);
+ TIME_CHECK_OBJECT(kTime1161000, params->param5, kObject111, kObjectLocation3);
+ TIME_CHECK_OBJECT(kTime1206000, params->param6, kObject111, kObjectLocation4);
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(11);
+ setup_savegame(kSavegameTypeEvent, kEventCoudertAskTylerCompartment);
+ break;
+
+ case kAction11:
+ if (!ENTITY_PARAM(0, 1) && !ENTITY_PARAM(2, 1)) {
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(13);
+ setup_function13((bool)savepoint.param.intValue, savepoint.entity2);
+ }
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_1500;
+ getData()->location = kLocationOutsideCompartment;
+
+ getScenes()->loadSceneFromItemPosition(kItem5);
+ break;
+
+ case kActionDrawScene:
+ if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1)) {
+
+ if (!getEntities()->isPlayerPosition(kCarRedSleeping, 1) && !getEntities()->isPlayerPosition(kCarRedSleeping, 23))
+ break;
+
+ if (getProgress().jacket == kJacketBlood) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventCoudertBloodJacket);
+ } else {
+ setCallback(getEntities()->isPlayerPosition(kCarRedSleeping, 1) ? 2 : 3);
+ setup_function13(true, kEntityPlayer);
+ }
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventCoudertBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ break;
+
+ case 4:
+ goto label_callback_4;
+
+ case 5:
+ goto label_callback_5;
+
+ case 6:
+ goto label_callback_6;
+
+ case 7:
+ goto label_callback_7;
+
+ case 8:
+ goto label_callback_8;
+
+ case 9:
+ goto label_callback_9;
+
+ case 10:
+ params->param1 = 1;
+ goto label_callback_10;
+
+ case 11:
+ getAction()->playAnimation(kEventCoudertAskTylerCompartment);
+ getEntities()->drawSequenceRight(kEntityCoudert, ENTITY_PARAM(0, 2) ? "627A" : "627D");
+ getScenes()->loadSceneFromItemPosition(kItem5);
+
+ ENTITY_PARAM(0, 1) = 0;
+
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 25);
+
+ setCallback(12);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 12:
+ getEntities()->drawSequenceLeft(kEntityCoudert, ENTITY_PARAM(0, 2) ? "627B" : "627E");
+ break;
+
+ case 14:
+ setCallback(15);
+ setup_function18();
+ break;
+ }
+ break;
+
+ case kAction168253822:
+ if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1)) {
+ getData()->inventoryItem = kItemNone;
+ getSound()->playSound(kEntityCoudert, "JAC1120");
+
+ setCallback(14);
+ setup_bloodJacket("697D");
+ }
+ break;
+
+ case kAction225358684:
+ if (!ENTITY_PARAM(0, 1)) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(16);
+ setup_function30((ObjectIndex)savepoint.param.intValue);
+ }
+ break;
+
+ case kAction225932896:
+ if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1))
+ getSavePoints()->push(kEntityCoudert, kEntityFrancois, kAction205346192);
+ break;
+
+ case kAction305159806:
+ if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1)) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(17);
+ setup_function31(savepoint.param.intValue);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(41, Coudert, function41)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function16();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_visitCompartmentA();
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function33();
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_visitCompartmentB();
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_function33();
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_function27();
+ break;
+
+ case 6:
+ getSavePoints()->push(kEntityCoudert, kEntityRebecca, kAction285528346);
+
+ setCallback(7);
+ setup_function33();
+ break;
+
+ case 7:
+ setCallback(8);
+ setup_function26();
+ break;
+
+ case 8:
+ setCallback(9);
+ setup_function33();
+ break;
+
+ case 9:
+ setCallback(10);
+ setup_function25();
+ break;
+
+ case 10:
+ setCallback(11);
+ setup_function33();
+ break;
+
+ case 11:
+ setCallback(12);
+ setup_function23();
+ break;
+
+ case 12:
+ setCallback(13);
+ setup_function33();
+ break;
+
+ case 13:
+ setCallback(14);
+ setup_function22();
+ break;
+
+ case 14:
+ setCallback(15);
+ setup_function33();
+ break;
+
+ case 15:
+ setCallback(16);
+ setup_function21();
+ break;
+
+ case 16:
+ setCallback(17);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case 17:
+ setCallback(18);
+ setup_function18();
+ break;
+
+ case 18:
+ getSavePoints()->push(kEntityCoudert, kEntityMilos, kAction208228224);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(42, Coudert, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setCallback(1);
+ setup_function18();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityCoudert);
+
+ getData()->entityPosition = kPosition_1500;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->inventoryItem = kItemNone;
+
+ 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, 8) = 0;
+
+ ENTITY_PARAM(1, 1) = 0;
+ ENTITY_PARAM(1, 2) = 0;
+ ENTITY_PARAM(1, 3) = 0;
+ ENTITY_PARAM(1, 5) = 0;
+ ENTITY_PARAM(1, 6) = 0;
+ ENTITY_PARAM(1, 7) = 0;
+ ENTITY_PARAM(1, 8) = 0;
+
+ ENTITY_PARAM(2, 4) = 0;
+
+ getObjects()->updateLocation2(kObject111, kObjectLocation5);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function43();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(43, Coudert, function43)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (ENTITY_PARAM(0, 8)) {
+ setCallback(1);
+ setup_function15(true);
+ break;
+ }
+
+label_callback1:
+ if (!ENTITY_PARAM(1, 1)) {
+ setCallback(2);
+ setup_function15(false);
+ break;
+ }
+
+label_callback2:
+ if (ENTITY_PARAM(0, 3)) {
+ setCallback(3);
+ setup_function14(kEntityVerges);
+ }
+ break;
+
+ case kAction11:
+ if (!ENTITY_PARAM(2, 1)) {
+ setCallback(4);
+ setup_function13((bool)savepoint.param.intValue, savepoint.entity2);
+ }
+ break;
+
+ case kActionDrawScene:
+ if (ENTITY_PARAM(2, 1))
+ break;
+
+ if (getEntities()->isPlayerPosition(kCarRedSleeping, 1)) {
+ setCallback(5);
+ setup_function13(true, kEntityPlayer);
+
+ } else if (getEntities()->isPlayerPosition(kCarRedSleeping, 23)) {
+ setCallback(6);
+ setup_function13(false, kEntityPlayer);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_callback1;
+
+ case 2:
+ goto label_callback2;
+
+ case 7:
+ setCallback(8);
+ setup_function18();
+ break;
+ }
+ break;
+
+ case kAction225358684:
+ if (!ENTITY_PARAM(0, 1)) {
+ setCallback(9);
+ setup_function30((ObjectIndex)savepoint.param.intValue);
+ }
+ break;
+
+ case kAction226078300:
+ if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1)) {
+ getSound()->playSound(kEntityCoudert, "JAC2020");
+
+ setCallback(7);
+ setup_bloodJacket("697D");
+ }
+ break;
+
+ case kAction305159806:
+ if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1)) {
+ setCallback(10);
+ setup_function31(savepoint.param.intValue);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(44, Coudert, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setCallback(1);
+ setup_function18();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityCoudert);
+
+ getData()->entityPosition = kPosition_1500;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ ENTITY_PARAM(0, 2) = 0;
+ ENTITY_PARAM(0, 3) = 0;
+ ENTITY_PARAM(0, 4) = 0;
+ ENTITY_PARAM(0, 5) = 0;
+ ENTITY_PARAM(0, 8) = 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;
+ ENTITY_PARAM(1, 8) = 0;
+
+ ENTITY_PARAM(2, 4) = 0;
+ ENTITY_PARAM(2, 5) = 0;
+
+ getObjects()->updateLocation2(kObject111, kObjectLocation6);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function45();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(45, Coudert, function45)
+ error("Coudert: callback function 45 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(46, Coudert, function46)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function16();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_4070);
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627Vf");
+ getEntities()->enterCompartment(kEntityCoudert, kObjectCompartmentF, true);
+ getSavePoints()->push(kEntityCoudert, kEntityAnna, kAction253868128);
+
+ setCallback(3);
+ setup_playSound("LIB012");
+ break;
+
+ case 3:
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627Wf");
+
+ setCallback(4);
+ setup_playSound("Ann1016A");
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_playSound("Ann4150");
+ break;
+
+ case 5:
+ getSound()->playSound(kEntityCoudert, "Ann3121");
+
+ setCallback(6);
+ setup_enterExitCompartment("629Bf", kObjectCompartmentF);
+ break;
+
+ case 6:
+ getEntities()->drawSequenceLeft(kEntityCoudert, "629Cf");
+ getEntities()->enterCompartment(kEntityCoudert, kObjectCompartmentF, true);
+ // Fallback to next case
+
+ case 7:
+ if (getSound()->isBuffered(kEntityCoudert)) {
+ setCallback(7);
+ setup_updateFromTime(75);
+ } else {
+ setCallback(8);
+ setup_playSound("Ann3122");
+ }
+ break;
+
+ case 8:
+ getSound()->playSound(kEntityCoudert, "Ann3123");
+
+ setCallback(9);
+ setup_updateFromTicks(75);
+ break;
+
+ case 9:
+ setCallback(10);
+ setup_enterExitCompartment("629Ff", kObjectCompartmentF);
+ break;
+
+ case 10:
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentF, true);
+ ENTITY_PARAM(1, 3) = 0;
+
+ setCallback(11);
+ setup_function35(true);
+ break;
+
+ case 11:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(47, Coudert, function47, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function16();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_4070);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_enterExitCompartment("627Xf", kObjectCompartmentF);
+ break;
+
+ case 3:
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627Wf");
+ getEntities()->enterCompartment(kEntityCoudert, kObjectCompartmentF);
+ // Fallback to next case
+
+ case 4:
+ if (getSound()->isBuffered(kEntityCoudert)) {
+ setCallback(4);
+ setup_updateFromTime(225);
+ } else {
+ setCallback(5);
+ setup_playSound(params->param1 ? "Ann3149" : "Ann3147a");
+ }
+ break;
+
+ case 5:
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentF, true);
+ getSavePoints()->push(kEntityCoudert, kEntityAnna, kAction157894320);
+
+ setCallback(6);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case 6:
+ ENTITY_PARAM(1, 5) = 0;
+ ENTITY_PARAM(1, 6) = 0;
+
+ setCallback(7);
+ setup_function18();
+ break;
+
+ case 7:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(48, Coudert, function48)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function16();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSound()->playSound(kEntityCoudert, "Ann3148A");
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_4070);
+ break;
+
+ case 2:
+ getSound()->playSound(kEntityCoudert, rnd(2) ? "Ann3148B" : "Ann3148");
+ setCallback(3);
+ setup_enterExitCompartment("627Xf", kObjectCompartmentF);
+ break;
+
+ case 3:
+ getSavePoints()->push(kEntityCoudert, kEntityAnna, kAction192063264);
+ setCallback(4);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case 4:
+ ENTITY_PARAM(1, 8) = 0;
+ setCallback(5);
+ setup_function18();
+ break;
+
+ case 5:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(49, Coudert, function49)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function16();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_7500);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_enterExitCompartment("627Vb", kObjectCompartmentB);
+ break;
+
+ case 3:
+ if (getEntities()->isInsideCompartment(kEntityTatiana, kCarRedSleeping, kPosition_7500)) {
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627Wb");
+
+ setCallback(4);
+ setup_playSound("Jac3006");
+ } else {
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627Wb");
+ getEntities()->enterCompartment(kEntityCoudert, kObjectCompartmentB, true);
+
+ setCallback(8);
+ setup_playSound("LIB012");
+ }
+ break;
+
+ case 4:
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentB, true);
+
+ setCallback(5);
+ setup_enterExitCompartment("627Zb", kObjectCompartmentB);
+ break;
+
+ case 5:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityCoudert);
+
+ setCallback(6);
+ setup_playSound("Jac3006A");
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_enterExitCompartment("697Ab", kObjectCompartmentB);
+ break;
+
+ case 7:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(10);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case 8:
+ setCallback(9);
+ setup_updateFromTime(150);
+ break;
+
+ case 9:
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentB, true);
+
+ setCallback(10);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case 10:
+ getSavePoints()->push(kEntityCoudert, kEntityMmeBoutarel, kAction242526416);
+ ENTITY_PARAM(2, 4) = 0;
+ ENTITY_PARAM(2, 5) = 1;
+
+ setCallback(11);
+ setup_function18();
+ break;
+
+ case 11:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(50, Coudert, function50)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function16();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_4840);
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627Me");
+ getEntities()->enterCompartment(kEntityCoudert, kObjectCompartmentE, true);
+
+ setCallback(3);
+ setup_playSound("LIB012");
+ break;
+
+ case 3:
+ if (!getEntities()->isInsideCompartment(kEntityRebecca, kCarRedSleeping, kPosition_4840)) {
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentE, true);
+
+ setCallback(8);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ } else {
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627Ne");
+
+ setCallback(4);
+ setup_playSound("Jac3005");
+ }
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_enterExitCompartment("627Re", kObjectCompartmentE);
+ break;
+
+ case 5:
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentE, true);
+
+ getData()->location = kLocationInsideCompartment;
+
+ getEntities()->clearSequences(kEntityCoudert);
+
+ setCallback(6);
+ setup_playSound("Jac3005A");
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_enterExitCompartment("627Se", kObjectCompartmentE);
+ break;
+
+ case 7:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(8);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case 8:
+ ENTITY_PARAM(2, 5) = 0;
+
+ setCallback(9);
+ setup_function18();
+ break;
+
+ case 9:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(51, Coudert, function51)
+ error("Coudert: callback function 51 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(52, Coudert, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setCallback(1);
+ setup_function18();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityCoudert);
+
+ getData()->entityPosition = kPosition_1500;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ 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, 8) = 0;
+
+ ENTITY_PARAM(1, 1) = 0;
+ ENTITY_PARAM(1, 3) = 0;
+ ENTITY_PARAM(1, 5) = 0;
+ ENTITY_PARAM(1, 6) = 0;
+ ENTITY_PARAM(1, 7) = 0;
+ ENTITY_PARAM(1, 8) = 0;
+
+ ENTITY_PARAM(2, 3) = 0;
+ ENTITY_PARAM(2, 4) = 0;
+
+ getObjects()->updateLocation2(kObject111, kObjectLocation10);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ ENTITY_PARAM(1, 2) = 1;
+ setup_function53();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(53, Coudert, function53)
+ error("Coudert: callback function 53 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(54, Coudert, function54)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (getEntities()->hasValidFrame(kEntityCoudert)) {
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_540);
+ } else {
+ getData()->car = kCarLocomotive;
+ getData()->entityPosition = kPosition_540;
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->clearSequences(kEntityCoudert);
+ getData()->car = kCarLocomotive;
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function18();
+ break;
+
+ case 3:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction191001984:
+ getData()->car = kCarRedSleeping;
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_1500);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(55, Coudert, function55)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_playSound("LIB070");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function16();
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_updateEntity(kCarRedSleeping, kPosition_4070);
+ break;
+
+ case 3:
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627Wf");
+ getEntities()->enterCompartment(kEntityCoudert, kObjectCompartmentF, true);
+
+ setCallback(4);
+ setup_playSound("Ann4150A");
+ break;
+
+ case 4:
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentF, true);
+ getSavePoints()->push(kEntityCoudert, kEntityAnna, kAction219971920);
+ getSavePoints()->push(kEntityCoudert, kEntityPascale, kAction101824388);
+
+ setCallback(5);
+ setup_updateEntity(kCarRedSleeping, kPosition_9460);
+ break;
+
+ case 5:
+ getEntities()->clearSequences(kEntityCoudert);
+ getSavePoints()->push(kEntityCoudert, kEntityPascale, kAction136059947);
+ break;
+
+ case 6:
+ ENTITY_PARAM(1, 2) = 0;
+
+ setCallback(7);
+ setup_function18();
+ break;
+
+ case 7:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction123712592:
+ setCallback(6);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(56, Coudert, function56)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function16();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function21();
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function33();
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function22();
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_function33();
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_visitCompartmentF();
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_function33();
+ break;
+
+ case 7:
+ setCallback(8);
+ setup_function25();
+ break;
+
+ case 8:
+ setCallback(9);
+ setup_function33();
+ break;
+
+ case 9:
+ setCallback(10);
+ setup_function26();
+ break;
+
+ case 10:
+ setCallback(11);
+ setup_function33();
+ break;
+
+ case 11:
+ setCallback(12);
+ setup_function27();
+ break;
+
+ case 12:
+ setCallback(13);
+ setup_function33();
+ break;
+
+ case 13:
+ setCallback(14);
+ setup_visitCompartmentB();
+ break;
+
+ case 14:
+ setCallback(15);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case 15:
+ setCallback(16);
+ setup_function18();
+ break;
+
+ case 16:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(57, Coudert, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityCoudert);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(58, Coudert, chapter5Handler)
+ if (savepoint.action == kActionProceedChapter5)
+ setup_function59();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(59, Coudert, function59)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_7500;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getSound()->playSound(kEntityCoudert, "Jac5010"); // Situation is under control, please remain in your compartment
+
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627K");
+ setup_function60();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(60, Coudert, function60)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function61();
+ break;
+
+ case kAction155991520:
+ setCallback(1);
+ setup_updateFromTime(225);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(61, Coudert, function61)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_2088;
+
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_4840);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("627Me", kObjectCompartmentE);
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityCoudert, "627Ne");
+ getEntities()->enterCompartment(kEntityCoudert, kObjectCompartmentE, true);
+
+ setCallback(3);
+ setup_updateFromTime(75);
+ break;
+
+ case 3:
+ getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentE, true);
+
+ setCallback(4);
+ setup_enterExitCompartment("627Re", kObjectCompartmentE);
+ break;
+
+ case 4:
+ getData()->location = kLocationInsideCompartment;
+
+ getEntities()->clearSequences(kEntityCoudert);
+ getObjects()->update(kObjectCompartmentE, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ setCallback(5);
+ setup_playSound("Reb5010");
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_enterExitCompartment("627Se", kObjectCompartmentE);
+ break;
+
+ case 6:
+ getSavePoints()->push(kEntityCoudert, kEntityRebecca, kAction155604840);
+
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(7);
+ setup_updateEntity(kCarRedSleeping, kPosition_2740);
+ break;
+
+ case 7:
+ setCallback(8);
+ setup_enterExitCompartment("627Zh", kObjectCompartmentH);
+ break;
+
+ case 8:
+ getData()->location = kLocationInsideCompartment;
+
+ getEntities()->clearSequences(kEntityCoudert);
+ getSavePoints()->push(kEntityCoudert, kEntityPascale, kAction169750080);
+
+ setup_function62();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(62, Coudert, function62)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1) {
+ UPDATE_PARAM(params->param4, getState()->timeTicks, 75);
+
+ params->param1 = 0;
+ params->param2 = 1;
+
+ getObjects()->update(kObjectCompartmentH, kEntityCoudert, kObjectLocation1, kCursorNormal, kCursorNormal);
+ }
+
+ params->param4 = 0;
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ if (params->param1) {
+ getObjects()->update(kObjectCompartmentH, kEntityCoudert, kObjectLocation1, kCursorNormal, kCursorNormal);
+ params->param1 = 0;
+
+ setCallback(1);
+ setup_playSound(getSound()->justCheckingCath());
+ } else {
+ setCallback(savepoint.action == kActionKnock ? 2 : 3);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ }
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentH, kEntityCoudert, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionDrawScene:
+ if (params->param1 || params->param2) {
+ params->param1 = 0;
+ params->param2 = 0;
+ params->param3 = 0;
+
+ getObjects()->update(kObjectCompartmentH, kEntityCoudert, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartmentH, kEntityCoudert, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case 2:
+ case 3:
+ ++params->param3;
+
+ if (params->param3 == 1 || params->param2) {
+ getObjects()->update(kObjectCompartmentH, kEntityCoudert, kObjectLocation1, kCursorNormal, kCursorNormal);
+ setCallback(params->param3 == 1 ? 4 : 5);
+ setup_playSound(params->param3 == 1 ? "Jac5002" : "Jac5002A");
+ }
+ break;
+
+ case 4:
+ params->param1 = 1;
+ getObjects()->update(kObjectCompartmentH, kEntityCoudert, kObjectLocation1, kCursorTalk, kCursorNormal);
+ break;
+
+ case 5:
+ params->param2 = 1;
+ break;
+ }
+ break;
+
+ case kAction135800432:
+ setup_nullfunction();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_NULL_FUNCTION(63, Coudert)
+
+
+//////////////////////////////////////////////////////////////////////////
+// Private functions
+//////////////////////////////////////////////////////////////////////////
+void Coudert::visitCompartment(const SavePoint &savepoint, EntityPosition position, const char* seq1, ObjectIndex compartment, const char* seq2, const char* seq3, EntityPosition sittingPosition, ObjectIndex object, const char* seq4) {
+ EXPOSE_PARAMS(EntityData::EntityParametersIIII)
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, position);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment(seq1, compartment);
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityCoudert, seq2);
+ getEntities()->enterCompartment(kEntityCoudert, compartment, true);
+
+ setCallback(3);
+ setup_updateFromTime(150);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_enterExitCompartment2(seq3, compartment, position, sittingPosition);
+ break;
+
+ case 4:
+ getEntities()->exitCompartment(kEntityCoudert, compartment, true);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityCoudert);
+
+ setCallback(5);
+ setup_function20(compartment, object);
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_enterExitCompartment(seq4, compartment);
+ break;
+
+ case 6:
+ getData()->location = kLocationOutsideCompartment;
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/coudert.h b/engines/lastexpress/entities/coudert.h
new file mode 100644
index 0000000000..e86e519385
--- /dev/null
+++ b/engines/lastexpress/entities/coudert.h
@@ -0,0 +1,229 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_COUDERT_H
+#define LASTEXPRESS_COUDERT_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Coudert : public Entity {
+public:
+ Coudert(LastExpressEngine *engine);
+ ~Coudert() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Handle meeting Coudert with the blooded jacket
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(bloodJacket, const char *sequence)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Process callback action when the entity direction is not kDirectionRight
+ */
+ DECLARE_FUNCTION(callbackActionOnDirection)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ * @param entityPosition1 The entity position 1
+ * @param entityPosition2 The entity position 2
+ */
+ DECLARE_FUNCTION_4(enterExitCompartment2, const char* sequence, ObjectIndex compartment, EntityPosition entityPosition1, EntityPosition entityPosition2)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Plays sound
+ *
+ * @param savepoint The savepoint
+ * - the sound filename
+ */
+ DECLARE_FUNCTION_NOSETUP(playSound16)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param time The time to add
+ */
+ DECLARE_FUNCTION_1(updateFromTime, uint32 time)
+
+ /**
+ * Updates parameter 2 using ticks value
+ *
+ * @param ticks The number of ticks to add
+ */
+ DECLARE_FUNCTION_1(updateFromTicks, uint32 ticks)
+
+ DECLARE_FUNCTION_1(excuseMe, EntityIndex entity)
+ DECLARE_FUNCTION_2(function13, bool, EntityIndex entity)
+ DECLARE_FUNCTION_1(function14, EntityIndex entity)
+ DECLARE_FUNCTION_1(function15, bool)
+ DECLARE_FUNCTION(function16)
+ DECLARE_FUNCTION_1(function17, bool)
+ DECLARE_FUNCTION(function18)
+ DECLARE_FUNCTION_1(function19, bool)
+
+ /**
+ * ???
+ *
+ * @param object1 The first object index
+ * @param object2 The second object index
+ */
+ DECLARE_FUNCTION_2(function20, ObjectIndex object1, ObjectIndex object2)
+
+ DECLARE_FUNCTION(function21)
+ DECLARE_FUNCTION(function22)
+ DECLARE_FUNCTION(function23)
+ DECLARE_FUNCTION(visitCompartmentF)
+ DECLARE_FUNCTION(function25)
+ DECLARE_FUNCTION(function26)
+ DECLARE_FUNCTION(function27)
+ DECLARE_FUNCTION(visitCompartmentB)
+ DECLARE_FUNCTION(visitCompartmentA)
+
+ /**
+ * ???
+ *
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_1(function30, ObjectIndex compartment)
+
+ DECLARE_FUNCTION_1(function31, uint32)
+ DECLARE_FUNCTION(function32)
+ DECLARE_FUNCTION(function33)
+ DECLARE_FUNCTION_1(function34, bool)
+ DECLARE_FUNCTION_1(function35, bool)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+ DECLARE_FUNCTION(function37)
+ DECLARE_FUNCTION(function38)
+ DECLARE_FUNCTION(function39)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function41)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ DECLARE_FUNCTION(function43)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ DECLARE_FUNCTION(function45)
+ DECLARE_FUNCTION(function46)
+ DECLARE_FUNCTION_1(function47, bool)
+ DECLARE_FUNCTION(function48)
+ DECLARE_FUNCTION(function49)
+ DECLARE_FUNCTION(function50)
+ DECLARE_FUNCTION(function51)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ DECLARE_FUNCTION(function53)
+ DECLARE_FUNCTION(function54)
+ DECLARE_FUNCTION(function55)
+ DECLARE_FUNCTION(function56)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_FUNCTION(function59)
+ DECLARE_FUNCTION(function60)
+ DECLARE_FUNCTION(function61)
+ DECLARE_FUNCTION(function62)
+
+ DECLARE_NULL_FUNCTION()
+
+private:
+ void visitCompartment(const SavePoint &savepoint, EntityPosition position, const char* seq1, ObjectIndex compartment, const char* seq2, const char* seq3, EntityPosition sittingPosition, ObjectIndex object, const char* seq4);
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_COUDERT_H
diff --git a/engines/lastexpress/entities/entity.cpp b/engines/lastexpress/entities/entity.cpp
new file mode 100644
index 0000000000..8400c38737
--- /dev/null
+++ b/engines/lastexpress/entities/entity.cpp
@@ -0,0 +1,434 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/entity.h"
+
+#include "lastexpress/entities/entity_intern.h"
+
+#include "lastexpress/game/action.h"
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/state.h"
+#include "lastexpress/game/savegame.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+
+namespace LastExpress {
+
+//////////////////////////////////////////////////////////////////////////
+// EntityData
+//////////////////////////////////////////////////////////////////////////
+EntityData::EntityParameters *EntityData::getParameters(uint callback, byte index) const {
+ if (callback >= 9)
+ error("EntityData::getParameters: invalid callback value (was: %d, max: 9)", callback);
+
+ if (index >= 4)
+ error("EntityData::getParameters: invalid index value (was: %d, max: 4)", index);
+
+ return _parameters[callback].parameters[index];
+}
+
+int EntityData::getCallback(uint callback) const {
+ if (callback >= 16)
+ error("EntityData::getParameters: invalid callback value (was: %d, max: 16)", callback);
+
+ return _data.callbacks[callback];
+}
+
+void EntityData::setCallback(uint callback, byte index) {
+ if (callback >= 16)
+ error("EntityData::getParameters: invalid callback value (was: %d, max: 16)", callback);
+
+ _data.callbacks[callback] = index;
+}
+
+void EntityData::updateParameters(uint32 index) const {
+ if (index < 8)
+ getParameters(8, 0)->update(index);
+ else if (index < 16)
+ getParameters(8, 1)->update(index - 8);
+ else if (index < 24)
+ getParameters(8, 2)->update(index - 16);
+ else if (index < 32)
+ getParameters(8, 3)->update(index - 24);
+ else
+ error("EntityData::updateParameters: invalid param index to update (was:%d, max:32)!", index);
+}
+
+void EntityData::saveLoadWithSerializer(Common::Serializer &) {
+ error("EntityData::saveLoadWithSerializer: not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Entity
+//////////////////////////////////////////////////////////////////////////
+Entity::Entity(LastExpressEngine *engine, EntityIndex index) : _engine(engine), _entityIndex(index) {
+ _data = new EntityData();
+
+ // Add first empty entry to callbacks array
+ _callbacks.push_back(NULL);
+}
+
+Entity::~Entity() {
+ for (uint i = 0; i < _callbacks.size(); i++)
+ delete _callbacks[i];
+
+ delete _data;
+
+ // Zero-out passed pointers
+ _engine = NULL;
+}
+
+void Entity::setup(ChapterIndex index) {
+ switch(index) {
+ case kChapterAll:
+ getSavePoints()->setCallback(_entityIndex, _callbacks[_data->getCurrentCallback()]);
+ break;
+
+ case kChapter1:
+ setup_chapter1();
+ break;
+
+ case kChapter2:
+ setup_chapter2();
+ break;
+
+ case kChapter3:
+ setup_chapter3();
+ break;
+
+ case kChapter4:
+ setup_chapter4();
+ break;
+
+ case kChapter5:
+ setup_chapter5();
+ break;
+
+ default:
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Shared functions
+//////////////////////////////////////////////////////////////////////////
+
+void Entity::reset(const SavePoint &savepoint, bool resetClothes, bool resetItem) {
+ EXPOSE_PARAMS(EntityData::EntityParametersIIII)
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kAction1:
+ if (resetClothes) {
+ // Select next available clothes
+ getData()->clothes = (ClothesIndex)(getData()->clothes + 1);
+ if (getData()->clothes > kClothes3)
+ getData()->clothes = kClothesDefault;
+ }
+ break;
+
+ case kActionNone:
+ if (getEntities()->updateEntity(_entityIndex, kCarGreenSleeping, (EntityPosition)params->param1))
+ params->param1 = (params->param1 == 10000) ? 0 : 10000;
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPositionNone;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarGreenSleeping;
+
+ if (resetItem)
+ getData()->inventoryItem = kItemInvalid;
+
+ params->param1 = 10000;
+ break;
+ }
+}
+
+void Entity::savegame(const SavePoint &savepoint) {
+ EXPOSE_PARAMS(EntityData::EntityParametersIIII)
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getSaveLoad()->saveGame((SavegameType)params->param1, _entityIndex, (EventIndex)params->param2);
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+void Entity::playSound(const SavePoint &savepoint, bool resetItem, SoundManager::FlagType flag) {
+ EXPOSE_PARAMS(EntityData::EntityParametersSIIS)
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionEndSound:
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ if (resetItem)
+ getData()->inventoryItem = kItemNone;
+
+ getSound()->playSound(_entityIndex, (char *)&params->seq1, flag);
+ break;
+ }
+}
+
+void Entity::draw(const SavePoint &savepoint, bool handleExcuseMe) {
+ EXPOSE_PARAMS(EntityData::EntityParametersSIIS)
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ CALLBACK_ACTION();
+ break;
+
+ case kActionExcuseMeCath:
+ if (handleExcuseMe && !params->param4) {
+ getSound()->excuseMe(_entityIndex);
+ params->param4 = 1;
+ }
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(_entityIndex, (char *)&params->seq1);
+ break;
+ }
+}
+
+void Entity::draw2(const SavePoint &savepoint) {
+ EXPOSE_PARAMS(EntityData::EntityParametersSSII)
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(_entityIndex, (char *)&params->seq1);
+ getEntities()->drawSequenceRight((EntityIndex)params->param7, (char *)&params->seq2);
+ break;
+ }
+}
+
+void Entity::updateFromTicks(const SavePoint &savepoint) {
+ EXPOSE_PARAMS(EntityData::EntityParametersIIII)
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param2, getState()->timeTicks, params->param1)
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+void Entity::updateFromTime(const SavePoint &savepoint) {
+ EXPOSE_PARAMS(EntityData::EntityParametersIIII)
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param2, getState()->time, params->param1)
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+void Entity::callbackActionOnDirection(const SavePoint &savepoint) {
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ if (getData()->direction != kDirectionRight)
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+void Entity::callbackActionRestaurantOrSalon(const SavePoint &savepoint) {
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ case kActionDefault:
+ if (getEntities()->isSomebodyInsideRestaurantOrSalon())
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+void Entity::updateEntity(const SavePoint &savepoint, bool handleExcuseMe) {
+ EXPOSE_PARAMS(EntityData::EntityParametersIIII)
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExcuseMeCath:
+ if (handleExcuseMe)
+ getSound()->excuseMeCath();
+ break;
+
+ case kActionExcuseMe:
+ if (handleExcuseMe)
+ getSound()->excuseMe(_entityIndex);
+ break;
+
+ case kActionNone:
+ case kActionDefault:
+ if (getEntities()->updateEntity(_entityIndex, (CarIndex)params->param1, (EntityPosition)params->param2))
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+void Entity::callSavepoint(const SavePoint &savepoint, bool handleExcuseMe) {
+ EXPOSE_PARAMS(EntityData::EntityParametersSIIS)
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ if (!CURRENT_PARAMS(1, 1))
+ getSavePoints()->call(_entityIndex, (EntityIndex)params->param4, (ActionIndex)params->param5, (char *)&params->seq2);
+ CALLBACK_ACTION();
+ break;
+
+ case kActionExcuseMeCath:
+ if (handleExcuseMe && !CURRENT_PARAMS(1, 2)) {
+ getSound()->excuseMe(_entityIndex);
+ CURRENT_PARAMS(1, 2) = 1;
+ }
+ break;
+
+ case kAction10:
+ if (!CURRENT_PARAMS(1, 1)) {
+ getSavePoints()->call(_entityIndex, (EntityIndex)params->param4, (ActionIndex)params->param5, (char *)&params->seq2);
+ CURRENT_PARAMS(1, 1) = 1;
+ }
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(_entityIndex, (char *)&params->seq1);
+ break;
+ }
+}
+
+void Entity::enterExitCompartment(const SavePoint &savepoint, EntityPosition position1, EntityPosition position2, CarIndex car, ObjectIndex compartment, bool alternate, bool updateLocation) {
+ EXPOSE_PARAMS(EntityData::EntityParametersSIIS)
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ getEntities()->exitCompartment(_entityIndex, (ObjectIndex)params->param4);
+ if (position1)
+ getData()->entityPosition = position1;
+
+ if (updateLocation)
+ getData()->location = kLocationInsideCompartment;
+
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(_entityIndex, (char *)&params->seq1);
+ getEntities()->enterCompartment(_entityIndex, (ObjectIndex)params->param4);
+
+ if (position1) {
+ getData()->location = kLocationInsideCompartment;
+
+ if (getEntities()->isInsideCompartment(kEntityPlayer, car, position1) || getEntities()->isInsideCompartment(kEntityPlayer, car, position2)) {
+ getAction()->playAnimation(isNight() ? kEventCathTurningNight : kEventCathTurningDay);
+ getSound()->playSound(kEntityPlayer, "BUMP");
+ getScenes()->loadSceneFromObject(compartment, alternate);
+ }
+ }
+ break;
+ }
+}
+
+void Entity::updatePosition(const SavePoint &savepoint, bool handleExcuseMe) {
+ EXPOSE_PARAMS(EntityData::EntityParametersSIII)
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ getEntities()->updatePositionExit(_entityIndex, (CarIndex)params->param4, (Position)params->param5);
+ CALLBACK_ACTION();
+ break;
+
+ case kActionExcuseMeCath:
+ if (handleExcuseMe && !params->param6) {
+ getSound()->excuseMe(_entityIndex);
+ params->param6 = 1;
+ }
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(_entityIndex, (char *)&params->seq);
+ getEntities()->updatePositionEnter(_entityIndex, (CarIndex)params->param4, (Position)params->param5);
+ break;
+ }
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/entity.h b/engines/lastexpress/entities/entity.h
new file mode 100644
index 0000000000..b0a1ab68ea
--- /dev/null
+++ b/engines/lastexpress/entities/entity.h
@@ -0,0 +1,681 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_ENTITY_H
+#define LASTEXPRESS_ENTITY_H
+
+#include "lastexpress/shared.h"
+
+#include "lastexpress/game/sound.h"
+
+#include "common/array.h"
+#include "common/func.h"
+#include "common/serializer.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+class Sequence;
+class SequenceFrame;
+struct SavePoint;
+
+class EntityData : Common::Serializable {
+public:
+
+ struct EntityParameters {
+ virtual ~EntityParameters() {}
+ virtual Common::String toString() = 0;
+
+ virtual void update(uint32 index) = 0;
+ };
+
+ struct EntityParametersIIII : EntityParameters {
+ uint param1;
+ uint param2;
+ uint param3;
+ uint param4;
+ uint param5;
+ uint param6;
+ uint param7;
+ uint param8;
+
+ EntityParametersIIII() {
+ param1 = 0;
+ param2 = 0;
+ param3 = 0;
+ param4 = 0;
+ param5 = 0;
+ param6 = 0;
+ param7 = 0;
+ param8 = 0;
+ }
+
+ bool hasNonNullParameter() {
+ return param1 || param2 || param3 || param4 || param5 || param6 || param7 || param8;
+ }
+
+ Common::String toString() {
+ return Common::String::printf("IIII: %d %d %d %d %d %d %d %d\n", param1, param2, param3, param4, param5, param6, param7, param8);
+ }
+
+ void update(uint32 index) {
+ switch (index) {
+ default:
+ error("EntityParametersIIII::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;
+ case 5: param6 = 1; break;
+ case 6: param7 = 1; break;
+ case 7: param8 = 1; break;
+ }
+ }
+ };
+
+ struct EntityParametersSIII : EntityParameters {
+ char seq[12];
+ uint param4;
+ uint param5;
+ uint param6;
+ uint param7;
+ uint param8;
+
+ EntityParametersSIII() {
+ memset(&seq, 0, 12);
+ param4 = 0;
+ param5 = 0;
+ param6 = 0;
+ param7 = 0;
+ param8 = 0;
+ }
+
+ Common::String toString() {
+ return Common::String::printf("SIII: %s %d %d %d %d %d\n", seq, param4, param5, param6, param7, param8);
+ }
+
+ void update(uint32 index) {
+ switch (index) {
+ default:
+ error("EntityParametersSIII::update: invalid index (was: %d)", index);
+
+ case 3: param4 = 1; break;
+ case 4: param5 = 1; break;
+ case 5: param6 = 1; break;
+ case 6: param7 = 1; break;
+ case 7: param8 = 1; break;
+ }
+ }
+ };
+
+ struct EntityParametersSIIS : EntityParameters {
+ char seq1[12];
+ uint param4;
+ uint param5;
+ char seq2[12];
+
+ EntityParametersSIIS() {
+ memset(&seq1, 0, 12);
+ param4 = 0;
+ param5 = 0;
+ memset(&seq2, 0, 12);
+ }
+
+ Common::String toString() {
+ return Common::String::printf("SIIS: %s %d %d %s\n", seq1, param4, param5, seq2);
+ }
+
+ void update(uint32 index) {
+ switch (index) {
+ default:
+ error("EntityParametersSIIS::update: invalid index (was: %d)", index);
+
+ case 3: param4 = 1; break;
+ case 4: param5 = 1; break;
+ }
+ }
+ };
+
+ struct EntityParametersISSI : EntityParameters {
+ uint param1;
+ char seq1[12];
+ char seq2[12];
+ uint param8;
+
+ EntityParametersISSI() {
+ param1 = 0;
+ memset(&seq1, 0, 12);
+ memset(&seq2, 0, 12);
+ param8 = 0;
+ }
+
+ Common::String toString() {
+ return Common::String::printf("ISSI: %d %s %s %d\n", param1, seq1, seq2, param8);
+ }
+
+ void update(uint32 index) {
+ switch (index) {
+ default:
+ error("EntityParametersISSI::update: invalid index (was: %d)", index);
+
+ case 0: param1 = 1; break;
+ case 7: param8 = 1; break;
+ }
+ }
+ };
+
+ struct EntityParametersISII : EntityParameters {
+ uint param1;
+ char seq[12];
+ uint param5;
+ uint param6;
+ uint param7;
+ uint param8;
+
+ EntityParametersISII() {
+ param1 = 0;
+ memset(&seq, 0, 12);
+ param5 = 0;
+ param6 = 0;
+ param7 = 0;
+ param8 = 0;
+ }
+
+ Common::String toString() {
+ return Common::String::printf("ISII: %d %s %d %d %d %d\n", param1, seq, param5, param6, param7, param8);
+ }
+
+ void update(uint32 index) {
+ switch (index) {
+ default:
+ error("EntityParametersISII::update: invalid index (was: %d)", index);
+
+ case 0: param1 = 1; break;
+ case 4: param5 = 1; break;
+ case 5: param6 = 1; break;
+ case 6: param7 = 1; break;
+ case 7: param8 = 1; break;
+ }
+ }
+ };
+
+ struct EntityParametersSSII : EntityParameters {
+ char seq1[12];
+ char seq2[12];
+ uint param7;
+ uint param8;
+
+ EntityParametersSSII() {
+ memset(&seq1, 0, 12);
+ memset(&seq2, 0, 12);
+ param7 = 0;
+ param8 = 0;
+ }
+
+ Common::String toString() {
+ return Common::String::printf("SSII: %s %s %d %d\n", seq1, seq2, param7, param8);
+ }
+
+ void update(uint32 index) {
+ switch (index) {
+ default:
+ error("EntityParametersSSII::update: invalid index (was: %d)", index);
+
+ case 6: param7 = 1; break;
+ case 7: param8 = 1; break;
+ }
+ }
+ };
+
+ struct EntityParametersIISS : EntityParameters {
+ uint param1;
+ uint param2;
+ char seq1[12];
+ char seq2[12];
+
+ EntityParametersIISS() {
+ param1 = 0;
+ param2 = 0;
+ memset(&seq1, 0, 12);
+ memset(&seq2, 0, 12);
+ }
+
+ Common::String toString() {
+ return Common::String::printf("IISS: %d %d %s %s\n", param1, param2, seq1, seq2);
+ }
+
+ void update(uint32 index) {
+ switch (index) {
+ default:
+ error("EntityParametersIISS::update: invalid index (was: %d)", index);
+
+ case 0: param1 = 1; break;
+ case 1: param2 = 1; break;
+ }
+ }
+ };
+
+ struct EntityParametersIISI : EntityParameters {
+ uint param1;
+ uint param2;
+ char seq[12];
+ uint param6;
+ uint param7;
+ uint param8;
+
+ EntityParametersIISI() {
+ param1 = 0;
+ param2 = 0;
+ memset(&seq, 0, 12);
+ param6 = 0;
+ param7 = 0;
+ param8 = 0;
+ }
+
+ Common::String toString() {
+ return Common::String::printf("IISI: %d %d %s %d %d %d\n", param1, param2, seq, param6, param7, param8);
+ }
+
+ void update(uint32 index) {
+ switch (index) {
+ default:
+ error("EntityParametersIISI::update: invalid index (was: %d)", index);
+
+ case 0: param1 = 1; break;
+ case 1: param2 = 1; break;
+ case 5: param6 = 1; break;
+ case 6: param7 = 1; break;
+ case 7: param8 = 1; break;
+ }
+ }
+ };
+
+ struct EntityParametersIIIS : EntityParameters {
+ uint param1;
+ uint param2;
+ uint param3;
+ char seq[12];
+ uint param7;
+ uint param8;
+
+ EntityParametersIIIS() {
+ param1 = 0;
+ param2 = 0;
+ param3 = 0;
+ memset(&seq, 0, 12);
+ param7 = 0;
+ param8 = 0;
+ }
+
+ Common::String toString() {
+ return Common::String::printf("IIIS: %d %d %d %s %d %d\n", param1, param2, param3, seq, param7, param8);
+ }
+
+ void update(uint32 index) {
+ switch (index) {
+ default:
+ error("EntityParametersIIIS::update: invalid index (was: %d)", index);
+
+ case 0: param1 = 1; break;
+ case 1: param2 = 1; break;
+ case 2: param3 = 1; break;
+ case 6: param7 = 1; break;
+ case 7: param8 = 1; break;
+ }
+ }
+ };
+
+ struct EntityParametersI5S : EntityParameters {
+ uint param1;
+ uint param2;
+ uint param3;
+ uint param4;
+ uint param5;
+ char seq[12];
+
+ EntityParametersI5S() {
+ param1 = 0;
+ param2 = 0;
+ param3 = 0;
+ param4 = 0;
+ param5 = 0;
+ memset(&seq, 0, 12);
+ }
+ };
+
+ struct EntityCallParameters {
+ EntityParameters* parameters[4];
+
+ EntityCallParameters() {
+ // We default to int parameters
+ create<EntityParametersIIII>();
+ }
+
+ ~EntityCallParameters() {
+ clear();
+ }
+
+ template <class parameter>
+ void create() {
+ for (int i = 0; i < 4; i++)
+ parameters[i] = new parameter();
+ }
+
+ void clear() {
+ for (int i = 0; i < 4; i++) {
+ if (parameters[i])
+ delete parameters[i];
+ parameters[i] = NULL;
+ }
+ }
+ };
+
+ struct EntityCallData {
+ byte callbacks[16];
+ byte currentCall;
+ EntityPosition entityPosition; // word
+ Location location; // word
+ CarIndex car; // word
+ byte field_497;
+ EntityIndex entity; // byte
+ InventoryItem inventoryItem; // byte
+ EntityDirection direction; // byte
+ int16 field_49B;
+ int16 currentFrame;
+ int16 currentFrame2;
+ int16 field_4A1;
+ int16 field_4A3;
+ ClothesIndex clothes; // byte
+ Position position;
+ CarIndex car2; // byte
+ bool doProcessEntity; // byte
+ bool field_4A9; // byte
+ bool field_4AA; // byte
+ EntityDirection directionSwitch;
+ Common::String sequenceName; // char[13]
+ Common::String sequenceName2; // char[13]
+ Common::String sequenceNamePrefix; // char[7]
+ Common::String sequenceNameCopy; // char[13]
+ SequenceFrame *frame;
+ SequenceFrame *frame1;
+ Sequence *sequence;
+ Sequence *sequence2;
+ Sequence *sequence3;
+
+ /**
+ * Default constructor.
+ */
+ EntityCallData() {
+ memset(&callbacks, 0, 16 * sizeof(byte));
+ currentCall = 0;
+ entityPosition = kPositionNone;
+ location = kLocationOutsideCompartment;
+ car = kCarNone;
+ field_497 = 0;
+ entity = kEntityPlayer;
+ inventoryItem = kItemNone;
+ direction = kDirectionNone;
+ field_49B = 0;
+ currentFrame = 0;
+ currentFrame2 = 0;
+ field_4A1 = 0;
+ field_4A3 = 30;
+ clothes = kClothesDefault;
+ position = 0;
+ car2 = kCarNone;
+ doProcessEntity = false;
+ field_4A9 = false;
+ field_4AA = false;
+ directionSwitch = kDirectionNone;
+ frame = NULL;
+ frame1 = NULL;
+ sequence = NULL;
+ sequence2 = NULL;
+ sequence3 = NULL;
+ }
+
+ /**
+ * Convert this object into a string representation.
+ *
+ * @return A string representation of this object.
+ */
+ Common::String toString() {
+ Common::String str = "";
+
+ str += Common::String::printf("Entity position: %d - Location: %d - Car: %d\n", entityPosition, location, car);
+ str += Common::String::printf("Entity: %d - Item: %d - Direction: %d\n", entity, inventoryItem, direction);
+ str += Common::String::printf("Clothes: %d - Position: %d - Direction switch: %d\n", clothes, position, directionSwitch);
+ str += "\n";
+ str += Common::String::printf("field_497: %02d - field_49B: %i - field_4A1: %i\n", field_497, field_49B, field_4A1);
+ str += Common::String::printf("field_4A9: %02d - field_4AA: %i - Car 2: %d\n", field_4A9, field_4AA, car2);
+ str += "\n";
+ str += "Sequence: " + sequenceName + " - Sequence 2: " + sequenceName2 + "\n";
+ str += "Sequence prefix: " + sequenceNamePrefix + " - Sequence copy: " + sequenceNameCopy + "\n";
+ str += Common::String::printf("Current frame: %i - Current frame 2: %i - Process entity: %d\n", currentFrame, currentFrame2, doProcessEntity);
+ str += "\n";
+ str += Common::String::printf("Current call: %d\n", currentCall);
+ str += Common::String::printf("Functions: %d %d %d %d %d %d %d %d\n", callbacks[0], callbacks[1], callbacks[2], callbacks[3], callbacks[4], callbacks[5], callbacks[6], callbacks[7]);
+ str += Common::String::printf("Callbacks: %d %d %d %d %d %d %d %d\n", callbacks[8], callbacks[9], callbacks[10], callbacks[11], callbacks[12], callbacks[13], callbacks[14], callbacks[15]);
+
+ return str;
+ }
+ };
+
+ EntityData() {}
+
+ template <class parameter>
+ void resetCurrentParameters() {
+ _parameters[_data.currentCall].clear();
+ _parameters[_data.currentCall].create<parameter>();
+ }
+
+ EntityCallData *getCallData() { return &_data; }
+
+ EntityParameters *getParameters(uint callback, byte index) const;
+ EntityParameters *getCurrentParameters(byte index = 0) { return getParameters(_data.currentCall, index); }
+
+ int getCallback(uint callback) const;
+ int getCurrentCallback() { return getCallback(_data.currentCall); }
+ void setCallback(uint callback, byte index);
+ void setCurrentCallback(uint index) { setCallback(_data.currentCall, index); }
+
+ void updateParameters(uint32 index) const;
+
+ // Serializable
+ void saveLoadWithSerializer(Common::Serializer &ser);
+
+private:
+
+ EntityCallData _data;
+ EntityCallParameters _parameters[9];
+};
+
+class Entity : Common::Serializable {
+public:
+
+ typedef Common::Functor1<const SavePoint&, void> Callback;
+
+ Entity(LastExpressEngine *engine, EntityIndex index);
+ virtual ~Entity();
+
+ // Accessors
+ EntityData *getParamData() { return _data; }
+ EntityData::EntityCallData *getData() { return _data->getCallData(); }
+
+ // Callbacks
+ int getCallback() { return _data->getCallback(_data->getCallData()->currentCall + 8); }
+ void setCallback(byte index) { _data->setCallback(_data->getCallData()->currentCall + 8, index); getData()->currentCall++; }
+
+ // Setup
+ void setup(ChapterIndex index);
+
+ virtual void setup_chapter1() = 0;
+ virtual void setup_chapter2() = 0;
+ virtual void setup_chapter3() = 0;
+ virtual void setup_chapter4() = 0;
+ virtual void setup_chapter5() = 0;
+
+ // Serializable
+ void saveLoadWithSerializer(Common::Serializer &ser) { _data->saveLoadWithSerializer(ser); }
+
+ void nullfunction(const SavePoint &savepoint) {}
+
+protected:
+ LastExpressEngine* _engine;
+
+ EntityIndex _entityIndex;
+ EntityData *_data;
+ Common::Array<Callback *> _callbacks;
+
+ /**
+ * Saves the game
+ *
+ * @param savepoint The savepoint
+ * - SavegameType
+ * - EventIndex
+ */
+ void savegame(const SavePoint &savepoint);
+
+ /**
+ * Play sound
+ *
+ * @param savepoint The savepoint
+ * - Sound filename
+ * @param resetItem true to reset item.
+ * @param flag sound flag
+ */
+ void playSound(const SavePoint &savepoint, bool resetItem = false, SoundManager::FlagType flag = SoundManager::kFlagInvalid);
+
+ /**
+ * Draws the entity
+ *
+ * @param savepoint The savepoint
+ * - Sequence
+ * - ExcuseMe flag
+ * @param handleExcuseMe true to handle excuseMeCath action
+ */
+ void draw(const SavePoint &savepoint, bool handleExcuseMe = false);
+
+ /**
+ * Draws the entity along with another one
+ *
+ * @param savepoint The savepoint.
+ * - Sequence 1
+ * - Sequence 2
+ * - EntityIndex
+ */
+ void draw2(const SavePoint &savepoint);
+
+ /**
+ * Updates parameter 2 using ticks value
+ *
+ * @param savepoint The savepoint
+ * - Number of ticks to add
+ */
+ void updateFromTicks(const SavePoint &savepoint);
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param savepoint The savepoint.
+ * - Time to add
+ */
+ void updateFromTime(const SavePoint &savepoint);
+
+ /**
+ * Resets an entity
+ *
+ * @param savepoint The savepoint.
+ * @param resetClothes true to reset clothes.
+ * @param resetItem true to reset inventoryItem to kItemInvalid
+ */
+ void reset(const SavePoint &savepoint, bool resetClothes = false, bool resetItem = false);
+
+ /**
+ * Process callback action when the entity direction is not kDirectionRight
+ *
+ * @param savepoint The savepoint.
+ */
+ void callbackActionOnDirection(const SavePoint &savepoint);
+
+ /**
+ * Process callback action when somebody is standing in the restaurant or salon.
+ *
+ * @param savepoint The savepoint.
+ */
+ void callbackActionRestaurantOrSalon(const SavePoint &savepoint);
+
+ /**
+ * Updates the entity
+ *
+ * @param savepoint The savepoint.
+ * - CarIndex
+ * - EntityPosition
+ * @param handleExcuseMe true to handle the kActionExcuseMe/kActionExcuseMeCath actions.
+ */
+ void updateEntity(const SavePoint &savepoint, bool handleExcuseMe = false);
+
+ /**
+ * Call a specific savepoint (or draw sequence in default case)
+ *
+ * @param savepoint The savepoint.
+ * - Sequence to draw in default case
+ * - EntityIndex
+ * - ActionIndex
+ * - Sequence for the savepoint
+ * @param handleExcuseMe true to handle excuse me.
+ */
+ void callSavepoint(const SavePoint &savepoint, bool handleExcuseMe = false);
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param savepoint The savepoint.
+ * @param position1 The first position.
+ * @param position2 The second position.
+ * @param car The car.
+ * @param compartment The compartment.
+ * @param alternate true to use the alternate version of SceneManager::loadSceneFromObject()
+ */
+ void enterExitCompartment(const SavePoint &savepoint, EntityPosition position1 = kPositionNone, EntityPosition position2 = kPositionNone, CarIndex car = kCarNone, ObjectIndex compartment = kObjectNone, bool alternate = false, bool updateLocation = false);
+
+ /**
+ * Updates the position
+ *
+ * @param savepoint The savepoint
+ * - Sequence name
+ * - CarIndex
+ * - Position
+ * @param handleExcuseMe true to handle excuseMe actions
+ */
+ void updatePosition(const SavePoint &savepoint, bool handleExcuseMe = false);
+};
+
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_ENTITY_H
diff --git a/engines/lastexpress/entities/entity39.cpp b/engines/lastexpress/entities/entity39.cpp
new file mode 100644
index 0000000000..6d139094c7
--- /dev/null
+++ b/engines/lastexpress/entities/entity39.cpp
@@ -0,0 +1,103 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/entity39.h"
+
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+
+namespace LastExpress {
+
+Entity39::Entity39(LastExpressEngine *engine) : Entity(engine, kEntity39) {
+ ADD_CALLBACK_FUNCTION(Entity39, chapter1);
+ ADD_CALLBACK_FUNCTION(Entity39, chapter2);
+ ADD_CALLBACK_FUNCTION(Entity39, chapter3);
+ ADD_CALLBACK_FUNCTION(Entity39, chapter4);
+ ADD_CALLBACK_FUNCTION(Entity39, chapter5);
+ ADD_CALLBACK_FUNCTION(Entity39, process);
+
+ memset(&_sequence, 0, 12);
+ _counter = 0;
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Entity39, chapter1)
+ if (savepoint.action == kActionDefault)
+ setup_process();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(2, Entity39, chapter2)
+ if (savepoint.action == kActionDefault)
+ setup_process();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(3, Entity39, chapter3)
+ if (savepoint.action == kActionDefault)
+ setup_process();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(4, Entity39, chapter4)
+ if (savepoint.action == kActionDefault)
+ setup_process();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(5, Entity39, chapter5)
+ if (savepoint.action == kActionDefault)
+ setup_process();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(6, Entity39, process)
+// TODO: _sequence & counter do not seem to be touched anywhere else in the code :(
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ getEntities()->drawSequenceRight(kEntity39, (char *)&_sequence);
+ break;
+
+ case kActionNone:
+ getData()->car = getEntityData(kEntityPlayer)->car;
+
+ if (*_sequence && !_counter) {
+ _counter++;
+ getEntities()->drawSequenceRight(kEntity39, (char *)&_sequence);
+ }
+ break;
+ }
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/entity39.h b/engines/lastexpress/entities/entity39.h
new file mode 100644
index 0000000000..652dbd139e
--- /dev/null
+++ b/engines/lastexpress/entities/entity39.h
@@ -0,0 +1,78 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_ENTITY39_H
+#define LASTEXPRESS_ENTITY39_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Entity39 : public Entity {
+public:
+ Entity39(LastExpressEngine *engine);
+ ~Entity39() {};
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Process function
+ */
+ DECLARE_FUNCTION(process)
+
+private:
+ char _sequence[12];
+ int _counter;
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_##define##_H
diff --git a/engines/lastexpress/entities/entity_intern.h b/engines/lastexpress/entities/entity_intern.h
new file mode 100644
index 0000000000..6442f76b3c
--- /dev/null
+++ b/engines/lastexpress/entities/entity_intern.h
@@ -0,0 +1,577 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_ENTITY_INTERN_H
+#define LASTEXPRESS_ENTITY_INTERN_H
+
+namespace LastExpress {
+
+#define LOBYTE(w) ((unsigned char)(((unsigned long)(w)) & 0xff))
+
+//////////////////////////////////////////////////////////////////////////
+// Callbacks
+#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_NULL_FUNCTION() \
+ _callbacks.push_back(new ENTITY_CALLBACK(Entity, nullfunction, this));
+
+//////////////////////////////////////////////////////////////////////////
+// Declaration
+//////////////////////////////////////////////////////////////////////////
+
+#define DECLARE_FUNCTION(name) \
+ void setup_##name(); \
+ void name(const SavePoint &savepoint);
+
+#define DECLARE_FUNCTION_1(name, param1) \
+ void setup_##name(param1); \
+ void name(const SavePoint &savepoint);
+
+#define DECLARE_FUNCTION_2(name, param1, param2) \
+ void setup_##name(param1, param2); \
+ void name(const SavePoint &savepoint);
+
+#define DECLARE_FUNCTION_3(name, param1, param2, param3) \
+ void setup_##name(param1, param2, param3); \
+ void name(const SavePoint &savepoint);
+
+#define DECLARE_FUNCTION_4(name, param1, param2, param3, param4) \
+ void setup_##name(param1, param2, param3, param4); \
+ void name(const SavePoint &savepoint);
+
+#define DECLARE_FUNCTION_NOSETUP(name) \
+ void name(const SavePoint &savepoint);
+
+#define DECLARE_NULL_FUNCTION() \
+ void setup_nullfunction();
+
+//////////////////////////////////////////////////////////////////////////
+// Setup
+//////////////////////////////////////////////////////////////////////////
+
+#define IMPLEMENT_SETUP(class, callback_class, name, index) \
+void class::setup_##name() { \
+ BEGIN_SETUP(callback_class, name, index, EntityData::EntityParametersIIII) \
+ debugC(6, kLastExpressDebugLogic, "Entity: " #class "::setup_" #name "()"); \
+ END_SETUP() \
+}
+
+#define BEGIN_SETUP(class, name, index, type) \
+ _engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, new ENTITY_CALLBACK(class, name, this)); \
+ _data->setCurrentCallback(index); \
+ _data->resetCurrentParameters<type>();
+
+#define END_SETUP() \
+ _engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
+
+
+//////////////////////////////////////////////////////////////////////////
+// Implementation
+//////////////////////////////////////////////////////////////////////////
+
+// Expose parameters and check validity
+#define EXPOSE_PARAMS(type) \
+ type *params = (type*)_data->getCurrentParameters(); \
+ if (!params) \
+ error("Trying to call an entity function with invalid parameters!"); \
+
+
+// function signature without setup (we keep the index for consistency but never use it)
+#define IMPLEMENT_FUNCTION_NOSETUP(index, class, name) \
+ void class::name(const SavePoint &savepoint) { \
+ debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(index=" #index ")");
+
+// simple setup with no parameters
+#define IMPLEMENT_FUNCTION(index, class, name) \
+ IMPLEMENT_SETUP(class, class, name, index) \
+ void class::name(const SavePoint &savepoint) { \
+ EXPOSE_PARAMS(EntityData::EntityParametersIIII) \
+ debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "() - action: %s", ACTION_NAME(savepoint.action));
+
+// nullfunction call
+#define IMPLEMENT_NULL_FUNCTION(index, class) \
+ IMPLEMENT_SETUP(class, Entity, nullfunction, index)
+
+// setup with one uint parameter
+#define IMPLEMENT_FUNCTION_I(index, class, name, paramType) \
+ void class::setup_##name(paramType param1) { \
+ BEGIN_SETUP(class, name, index, EntityData::EntityParametersIIII) \
+ EntityData::EntityParametersIIII *params = (EntityData::EntityParametersIIII*)_data->getCurrentParameters(); \
+ params->param1 = (unsigned int)param1; \
+ END_SETUP() \
+ } \
+ void class::name(const SavePoint &savepoint) { \
+ EXPOSE_PARAMS(EntityData::EntityParametersIIII) \
+ debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%d) - action: %s", params->param1, ACTION_NAME(savepoint.action));
+
+// setup with two uint parameters
+#define IMPLEMENT_FUNCTION_II(index, class, name, paramType1, paramType2) \
+ void class::setup_##name(paramType1 param1, paramType2 param2) { \
+ BEGIN_SETUP(class, name, index, EntityData::EntityParametersIIII) \
+ EntityData::EntityParametersIIII *params = (EntityData::EntityParametersIIII*)_data->getCurrentParameters(); \
+ params->param1 = param1; \
+ params->param2 = param2; \
+ END_SETUP() \
+ } \
+ void class::name(const SavePoint &savepoint) { \
+ EXPOSE_PARAMS(EntityData::EntityParametersIIII) \
+ debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%d, %d) - action: %s", params->param1, params->param2, ACTION_NAME(savepoint.action));
+
+// 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) { \
+ BEGIN_SETUP(class, name, index, EntityData::EntityParametersIIII) \
+ EntityData::EntityParametersIIII *params = (EntityData::EntityParametersIIII*)_data->getCurrentParameters(); \
+ params->param1 = param1; \
+ params->param2 = param2; \
+ params->param3 = param3; \
+ END_SETUP() \
+ } \
+ void class::name(const SavePoint &savepoint) { \
+ EXPOSE_PARAMS(EntityData::EntityParametersIIII) \
+ debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%d, %d, %d) - action: %s", params->param1, params->param2, params->param3, ACTION_NAME(savepoint.action));
+
+// setup with on char* parameter
+#define IMPLEMENT_FUNCTION_S(index, class, name) \
+ void class::setup_##name(const char* seq1) { \
+ BEGIN_SETUP(class, name, index, EntityData::EntityParametersSIIS) \
+ EntityData::EntityParametersSIIS *params = (EntityData::EntityParametersSIIS*)_data->getCurrentParameters(); \
+ strncpy((char *)&params->seq1, seq1, 12); \
+ END_SETUP() \
+ } \
+ void class::name(const SavePoint &savepoint) { \
+ EXPOSE_PARAMS(EntityData::EntityParametersSIIS) \
+ debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%s) - action: %s", (char *)&params->seq1, ACTION_NAME(savepoint.action));
+
+// setup with on char* parameter and one uint
+#define IMPLEMENT_FUNCTION_SI(index, class, name, paramType2) \
+ void class::setup_##name(const char* seq1, paramType2 param4) { \
+ BEGIN_SETUP(class, name, index, EntityData::EntityParametersSIIS) \
+ EntityData::EntityParametersSIIS *params = (EntityData::EntityParametersSIIS*)_data->getCurrentParameters(); \
+ strncpy((char *)&params->seq1, seq1, 12); \
+ params->param4 = param4; \
+ END_SETUP() \
+ } \
+ void class::name(const SavePoint &savepoint) { \
+ EXPOSE_PARAMS(EntityData::EntityParametersSIIS) \
+ debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%s, %d) - action: %s", (char *)&params->seq1, params->param4, ACTION_NAME(savepoint.action));
+
+// setup with on 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) { \
+ BEGIN_SETUP(class, name, index, EntityData::EntityParametersSIIS) \
+ EntityData::EntityParametersSIIS *params = (EntityData::EntityParametersSIIS*)_data->getCurrentParameters(); \
+ strncpy((char *)&params->seq1, seq1, 12); \
+ params->param4 = param4; \
+ params->param5 = param5; \
+ END_SETUP() \
+ } \
+ 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));
+
+// setup with on 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) { \
+ BEGIN_SETUP(class, name, index, EntityData::EntityParametersSIII) \
+ EntityData::EntityParametersSIII *params = (EntityData::EntityParametersSIII*)_data->getCurrentParameters(); \
+ strncpy((char *)&params->seq, seq, 12); \
+ params->param4 = param4; \
+ params->param5 = param5; \
+ params->param6 = param6; \
+ END_SETUP() \
+ } \
+ void class::name(const SavePoint &savepoint) { \
+ EXPOSE_PARAMS(EntityData::EntityParametersSIII) \
+ debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%s, %d, %d, %d) - action: %s", (char *)&params->seq, params->param4, params->param5, params->param6, ACTION_NAME(savepoint.action));
+
+#define IMPLEMENT_FUNCTION_SIIS(index, class, name, paramType2, paramType3) \
+ void class::setup_##name(const char* seq1, paramType2 param4, paramType3 param5, const char* seq2) { \
+ BEGIN_SETUP(class, name, index, EntityData::EntityParametersSIIS) \
+ EntityData::EntityParametersSIIS *params = (EntityData::EntityParametersSIIS*)_data->getCurrentParameters(); \
+ strncpy((char *)&params->seq1, seq1, 12); \
+ params->param4 = param4; \
+ params->param5 = param5; \
+ strncpy((char *)&params->seq2, seq2, 12); \
+ END_SETUP() \
+ } \
+ void class::name(const SavePoint &savepoint) { \
+ EXPOSE_PARAMS(EntityData::EntityParametersSIIS) \
+ debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%s, %d, %d, %s) - action: %s", (char *)&params->seq1, params->param4, params->param5, (char *)&params->seq2, ACTION_NAME(savepoint.action));
+
+#define IMPLEMENT_FUNCTION_SS(index, class, name) \
+ void class::setup_##name(const char* seq1, const char* seq2) { \
+ BEGIN_SETUP(class, name, index, EntityData::EntityParametersSSII) \
+ EntityData::EntityParametersSSII *params = (EntityData::EntityParametersSSII*)_data->getCurrentParameters(); \
+ strncpy((char *)&params->seq1, seq1, 12); \
+ strncpy((char *)&params->seq2, seq2, 12); \
+ END_SETUP() \
+ } \
+ void class::name(const SavePoint &savepoint) { \
+ EXPOSE_PARAMS(EntityData::EntityParametersSSII) \
+ debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%s, %s) - action: %s", (char *)&params->seq1, (char *)&params->seq2, ACTION_NAME(savepoint.action));
+
+#define IMPLEMENT_FUNCTION_SSI(index, class, name, paramType3) \
+ void class::setup_##name(const char* seq1, const char* seq2, paramType3 param7) { \
+ BEGIN_SETUP(class, name, index, EntityData::EntityParametersSSII) \
+ EntityData::EntityParametersSSII *params = (EntityData::EntityParametersSSII*)_data->getCurrentParameters(); \
+ strncpy((char *)&params->seq1, seq1, 12); \
+ strncpy((char *)&params->seq2, seq2, 12); \
+ params->param7 = param7; \
+ END_SETUP() \
+ } \
+ void class::name(const SavePoint &savepoint) { \
+ EXPOSE_PARAMS(EntityData::EntityParametersSSII) \
+ debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%s, %s, %d) - action: %s", (char *)&params->seq1, (char *)&params->seq2, params->param7, ACTION_NAME(savepoint.action));
+
+#define IMPLEMENT_FUNCTION_IS(index, class, name, paramType) \
+ void class::setup_##name(paramType param1, const char* seq) { \
+ BEGIN_SETUP(class, name, index, EntityData::EntityParametersISII) \
+ EntityData::EntityParametersISII *params = (EntityData::EntityParametersISII*)_data->getCurrentParameters(); \
+ params->param1 = (unsigned int)param1; \
+ strncpy((char *)&params->seq, seq, 12); \
+ END_SETUP() \
+ } \
+ void class::name(const SavePoint &savepoint) { \
+ EXPOSE_PARAMS(EntityData::EntityParametersISII) \
+ debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%d, %s) - action: %s", params->param1, (char *)&params->seq, ACTION_NAME(savepoint.action));
+
+#define IMPLEMENT_FUNCTION_ISS(index, class, name, paramType) \
+ void class::setup_##name(paramType param1, const char* seq1, const char* seq2) { \
+ BEGIN_SETUP(class, name, index, EntityData::EntityParametersISSI) \
+ EntityData::EntityParametersISSI *params = (EntityData::EntityParametersISSI*)_data->getCurrentParameters(); \
+ params->param1 = param1; \
+ strncpy((char *)&params->seq1, seq1, 12); \
+ strncpy((char *)&params->seq2, seq2, 12); \
+ END_SETUP() \
+ } \
+ void class::name(const SavePoint &savepoint) { \
+ EXPOSE_PARAMS(EntityData::EntityParametersISSI) \
+ debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%d, %s, %s) - action: %s", params->param1, (char *)&params->seq1, (char *)&params->seq2, ACTION_NAME(savepoint.action));
+
+#define IMPLEMENT_FUNCTION_IIS(index, class, name, paramType1, paramType2) \
+ void class::setup_##name(paramType1 param1, paramType2 param2, const char* seq) { \
+ BEGIN_SETUP(class, name, index, EntityData::EntityParametersIISI) \
+ EntityData::EntityParametersIISI *params = (EntityData::EntityParametersIISI*)_data->getCurrentParameters(); \
+ params->param1 = param1; \
+ params->param2 = param2; \
+ strncpy((char *)&params->seq, seq, 12); \
+ END_SETUP() \
+ } \
+ void class::name(const SavePoint &savepoint) { \
+ EXPOSE_PARAMS(EntityData::EntityParametersIISI) \
+ debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%d, %d, %s) - action: %s", params->param1, params->param2, (char *)&params->seq, ACTION_NAME(savepoint.action));
+
+#define IMPLEMENT_FUNCTION_IISS(index, class, name, paramType1, paramType2) \
+ void class::setup_##name(paramType1 param1, paramType2 param2, const char* seq1, const char* seq2) { \
+ BEGIN_SETUP(class, name, index, EntityData::EntityParametersIISS) \
+ EntityData::EntityParametersIISS *params = (EntityData::EntityParametersIISS*)_data->getCurrentParameters(); \
+ params->param1 = param1; \
+ params->param2 = param2; \
+ strncpy((char *)&params->seq1, seq1, 12); \
+ strncpy((char *)&params->seq2, seq2, 12); \
+ END_SETUP() \
+ } \
+ void class::name(const SavePoint &savepoint) { \
+ EXPOSE_PARAMS(EntityData::EntityParametersIISS) \
+ debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%d, %d, %s, %s) - action: %s", params->param1, params->param2, (char *)&params->seq1, (char *)&params->seq2, ACTION_NAME(savepoint.action));
+
+
+//////////////////////////////////////////////////////////////////////////
+// Misc
+//////////////////////////////////////////////////////////////////////////
+#define RESET_ENTITY_STATE(entity, class, function) \
+ getEntities()->resetState(entity); \
+ ((class*)getEntities()->get(entity))->function();
+
+//////////////////////////////////////////////////////////////////////////
+// Parameters macros (for default IIII parameters)
+//////////////////////////////////////////////////////////////////////////
+#define CURRENT_PARAMS(index, id) \
+ ((EntityData::EntityParametersIIII*)_data->getCurrentParameters(index))->param##id
+
+#define ENTITY_PARAM(index, id) \
+ ((EntityData::EntityParametersIIII*)_data->getParameters(8, index))->param##id
+
+//////////////////////////////////////////////////////////////////////////
+// Time check macros
+//////////////////////////////////////////////////////////////////////////
+#define TIME_CHECK_CHAPTER1(function) \
+ TIME_CHECK(kTimeChapter1, params->param1, function)
+
+#define TIME_CHECK(timeValue, parameter, function) \
+ if (getState()->time > timeValue && !parameter) { \
+ parameter = 1; \
+ function(); \
+ break; \
+ }
+
+#define TIME_CHECK_SAVEPOINT(timeValue, parameter, entity1, entity2, action) \
+ if (getState()->time > timeValue && !parameter) { \
+ parameter = 1; \
+ getSavePoints()->push(entity1, entity2, action); \
+ }
+
+#define TIME_CHECK_CALLBACK(timeValue, parameter, callback, function) \
+ if (getState()->time > timeValue && !parameter) { \
+ parameter = 1; \
+ setCallback(callback); \
+ function(); \
+ break; \
+ }
+
+#define TIME_CHECK_CALLBACK_1(timeValue, parameter, callback, function, param1) \
+ if (getState()->time > timeValue && !parameter) { \
+ parameter = 1; \
+ setCallback(callback); \
+ function(param1); \
+ break; \
+ }
+
+#define TIME_CHECK_CALLBACK_2(timeValue, parameter, callback, function, param1, param2) \
+ if (getState()->time > timeValue && !parameter) { \
+ parameter = 1; \
+ setCallback(callback); \
+ function(param1, param2); \
+ break; \
+ }
+
+#define TIME_CHECK_CALLBACK_3(timeValue, parameter, callback, function, param1, param2, param3) \
+ if (getState()->time > timeValue && !parameter) { \
+ parameter = 1; \
+ setCallback(callback); \
+ function(param1, param2, param3); \
+ break; \
+ }
+
+#define TIME_CHECK_CALLBACK_INVENTORY(timeValue, parameter, callback, function) \
+ if (getState()->time > timeValue && !parameter) { \
+ parameter = 1; \
+ getData()->inventoryItem = kItemNone; \
+ setCallback(callback); \
+ function(); \
+ break; \
+ }
+
+#define TIME_CHECK_CALLBACK_ACTION(timeValue, parameter) \
+ if (getState()->time > timeValue && !parameter) { \
+ parameter = 1; \
+ CALLBACK_ACTION(); \
+ break; \
+ }
+
+#define TIME_CHECK_SAVEGAME(timeValue, parameter, callback, type, event) \
+ if (getState()->time > timeValue && !parameter) { \
+ parameter = 1; \
+ setCallback(callback); \
+ setup_savegame(type, event); \
+ break; \
+ }
+
+#define TIME_CHECK_ENTERSTATION(timeValue, parameter, callback, name, param2) \
+ if (getState()->time > timeValue && !parameter) { \
+ parameter = 1; \
+ setCallback(callback); \
+ setup_enterStation(name, param2); \
+ break; \
+ }
+
+#define TIME_CHECK_EXITSTATION(timeValue, parameter, callback, name) \
+ if (getState()->time > timeValue && !parameter) { \
+ parameter = 1; \
+ setCallback(callback); \
+ setup_exitStation(name); \
+ break; \
+ }
+
+#define TIME_CHECK_EXITSTATION_2(timeValue, parameter1, parameter2, callback, name) \
+ if (getState()->time > timeValue && !parameter1) { \
+ parameter1 = 1; \
+ parameter2 = 1; \
+ setCallback(callback); \
+ setup_exitStation(name); \
+ break; \
+ }
+
+#define TIME_CHECK_EXITSTATION_0(parameter1, parameter2, callback, name) \
+ if (parameter1 && !parameter2) { \
+ setCallback(callback); \
+ setup_exitStation(name); \
+ break; \
+ }
+
+#define TIME_CHECK_PLAYSOUND(timeValue, parameter, callback, sound) \
+ if (getState()->time > timeValue && !parameter) { \
+ parameter = 1; \
+ setCallback(callback); \
+ setup_playSound(sound); \
+ break; \
+ }
+
+#define TIME_CHECK_PLAYSOUND_UPDATEPOSITION(timeValue, parameter, callback, sound, position) \
+ if (getState()->time > timeValue && !parameter) { \
+ parameter = 1; \
+ getData()->entityPosition = position; \
+ setCallback(callback); \
+ setup_playSound(sound); \
+ break; \
+ }
+
+#define TIME_CHECK_OBJECT(timeValue, parameter, object, location) \
+ if (getState()->time > timeValue && !parameter) { \
+ parameter = 1; \
+ getObjects()->updateLocation2(object, location); \
+ }
+
+#define TIME_CHECK_POSITION(timeValue, parameter, position) \
+ if (getState()->time > timeValue && !parameter) { \
+ parameter = 1; \
+ getData()->entityPosition = position; \
+ }
+
+#define TIME_CHECK_CAR(timeValue, parameter, callback, function) {\
+ if ((getState()->time <= timeValue && !getEntities()->isPlayerInCar(kCarGreenSleeping)) || !parameter) \
+ parameter = getState()->time + 75; \
+ if (getState()->time > timeValue || parameter < getState()->time) { \
+ parameter = kTimeInvalid; \
+ setCallback(callback); \
+ function(); \
+ break; \
+ } \
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Callback action
+//////////////////////////////////////////////////////////////////////////
+#define CALLBACK_ACTION() { \
+ if (getData()->currentCall == 0) \
+ error("CALLBACK_ACTION: currentCall is already 0, cannot proceed!"); \
+ getData()->currentCall--; \
+ getSavePoints()->setCallback(_entityIndex, _callbacks[_data->getCurrentCallback()]); \
+ getSavePoints()->call(_entityIndex, _entityIndex, kActionCallback); \
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// Param update
+//////////////////////////////////////////////////////////////////////////
+#define UPDATE_PARAM(parameter, type, value) { \
+ if (!parameter) \
+ parameter = type + value; \
+ if (parameter >= type) \
+ break; \
+ parameter = kTimeInvalid; \
+}
+
+// Todo: replace with UPDATE_PARAM_PROC as appropriate
+#define UPDATE_PARAM_GOTO(parameter, type, value, label) { \
+ if (!parameter) \
+ parameter = type + value; \
+ if (parameter >= type) \
+ goto label; \
+ parameter = kTimeInvalid; \
+}
+
+// Updating parameter with code inside the check
+#define UPDATE_PARAM_PROC(parameter, type, value) \
+ if (!parameter) \
+ parameter = type + value; \
+ if (parameter < type) { \
+ parameter = kTimeInvalid;
+
+#define UPDATE_PARAM_PROC_END }
+
+// Updating parameter with an added check (and code inside the check)
+#define UPDATE_PARAM_CHECK(parameter, type, value) \
+ if (!parameter || parameter < type) { \
+ if (!parameter) \
+ parameter = type + value;
+
+//////////////////////////////////////////////////////////////////////////
+// Compartments
+//////////////////////////////////////////////////////////////////////////
+// Go from one compartment to another (or the same one if no optional args are passed
+#define COMPARTMENT_TO(class, compartmentFrom, positionFrom, sequenceFrom, sequenceTo) \
+ switch (savepoint.action) { \
+ default: \
+ break; \
+ case kActionDefault: \
+ getData()->entityPosition = positionFrom; \
+ setCallback(1); \
+ setup_enterExitCompartment(sequenceFrom, compartmentFrom); \
+ break; \
+ case kActionCallback: \
+ switch (getCallback()) { \
+ default: \
+ break; \
+ case 1: \
+ setCallback(2); \
+ setup_enterExitCompartment(sequenceTo, compartmentFrom); \
+ break; \
+ case 2: \
+ getData()->entityPosition = positionFrom; \
+ getEntities()->clearSequences(_entityIndex); \
+ CALLBACK_ACTION(); \
+ } \
+ break; \
+ }
+
+#define COMPARTMENT_FROM_TO(class, compartmentFrom, positionFrom, sequenceFrom, compartmentTo, positionTo, sequenceTo) \
+ switch (savepoint.action) { \
+ default: \
+ break; \
+ case kActionDefault: \
+ getData()->entityPosition = positionFrom; \
+ getData()->location = kLocationOutsideCompartment; \
+ setCallback(1); \
+ setup_enterExitCompartment(sequenceFrom, compartmentFrom); \
+ break; \
+ case kActionCallback: \
+ switch (getCallback()) { \
+ default: \
+ break; \
+ case 1: \
+ setCallback(2); \
+ setup_updateEntity(kCarGreenSleeping, positionTo); \
+ break; \
+ case 2: \
+ setCallback(3); \
+ setup_enterExitCompartment(sequenceTo, compartmentTo); \
+ break; \
+ case 3: \
+ getData()->location = kLocationInsideCompartment; \
+ getEntities()->clearSequences(_entityIndex); \
+ CALLBACK_ACTION(); \
+ break; \
+ } \
+ break; \
+ }
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_ENTITY_INTERN_H
diff --git a/engines/lastexpress/entities/francois.cpp b/engines/lastexpress/entities/francois.cpp
new file mode 100644
index 0000000000..fd1237f8a3
--- /dev/null
+++ b/engines/lastexpress/entities/francois.cpp
@@ -0,0 +1,1043 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/francois.h"
+
+#include "lastexpress/game/action.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"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+
+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, updateEntity);
+ ADD_CALLBACK_FUNCTION(Francois, function9);
+ ADD_CALLBACK_FUNCTION(Francois, function10);
+ ADD_CALLBACK_FUNCTION(Francois, function11);
+ ADD_CALLBACK_FUNCTION(Francois, function12);
+ ADD_CALLBACK_FUNCTION(Francois, function13);
+ ADD_CALLBACK_FUNCTION(Francois, function14);
+ ADD_CALLBACK_FUNCTION(Francois, function15);
+ ADD_CALLBACK_FUNCTION(Francois, function16);
+ ADD_CALLBACK_FUNCTION(Francois, chapter1);
+ ADD_CALLBACK_FUNCTION(Francois, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Francois, function19);
+ ADD_CALLBACK_FUNCTION(Francois, function20);
+ ADD_CALLBACK_FUNCTION(Francois, chapter2);
+ ADD_CALLBACK_FUNCTION(Francois, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Francois, function23);
+ ADD_CALLBACK_FUNCTION(Francois, chapter3);
+ ADD_CALLBACK_FUNCTION(Francois, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Francois, chapter4);
+ ADD_CALLBACK_FUNCTION(Francois, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Francois, chapter5);
+ ADD_CALLBACK_FUNCTION(Francois, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(Francois, function30);
+ ADD_NULL_FUNCTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Francois, reset)
+ Entity::reset(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(2, Francois, updateFromTime, uint32)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(3, Francois, draw)
+ Entity::draw(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(4, Francois, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(5, Francois, enterExitCompartment2, ObjectIndex)
+ Entity::enterExitCompartment(savepoint, kPosition_5790, kPosition_6130, kCarRedSleeping, kObjectCompartmentD, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(6, Francois, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(7, Francois, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(8, Francois, updateEntity, CarIndex, EntityPosition)
+ error("Francois: callback function 8 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(9, Francois, function9)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (getObjects()->get(kObjectCompartmentD).location == kObjectLocation2) {
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ getSavePoints()->push(kEntityFrancois, kEntityMmeBoutarel, kAction134289824);
+ setCallback(1);
+ setup_enterExitCompartment("605Cd", kObjectCompartmentD);
+ } else {
+ setCallback(2);
+ setup_enterExitCompartment("605Ed", kObjectCompartmentD);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ break;
+
+ case 2:
+ getData()->location = kLocationOutsideCompartment;
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(10, Francois, function10)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (getObjects()->get(kObjectCompartmentD).location == kObjectLocation2) {
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ setCallback(1);
+ setup_enterExitCompartment("605Bd", kObjectCompartmentD);
+ } else {
+ setCallback(2);
+ setup_enterExitCompartment("605Dd", kObjectCompartmentD);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getSavePoints()->push(kEntityFrancois, kEntityMmeBoutarel, kAction102484312);
+ break;
+
+ case 2:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityFrancois);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(11, Francois, function11, TimeValue)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!getSound()->isBuffered(kEntityFrancois)) {
+
+ UPDATE_PARAM_PROC(CURRENT_PARAMS(1, 1), getState()->timeTicks, params->param6)
+ switch (rnd(7)) {
+ default:
+ break;
+
+ case 0:
+ getSound()->playSound(kEntityFrancois, "Fra1002A");
+ break;
+
+ case 1:
+ getSound()->playSound(kEntityFrancois, "Fra1002B");
+ break;
+
+ case 2:
+ getSound()->playSound(kEntityFrancois, "Fra1002C");
+ break;
+
+ case 3:
+ getSound()->playSound(kEntityFrancois, "Fra1002D");
+ break;
+
+ case 4:
+ getSound()->playSound(kEntityFrancois, "Fra1002E");
+ break;
+
+ case 5:
+ case 6:
+ getSound()->playSound(kEntityFrancois, "Fra1002F");
+ break;
+ }
+
+ params->param6 = 15 * rnd(7);
+ CURRENT_PARAMS(1, 1) = 0;
+ UPDATE_PARAM_PROC_END
+ }
+
+ if (!getEntities()->hasValidFrame(kEntityFrancois) || !getEntities()->isWalkingOppositeToPlayer(kEntityFrancois))
+ getData()->inventoryItem = kItemNone;
+
+ if (getEntities()->updateEntity(kEntityFrancois, (CarIndex)params->param2, (EntityPosition)params->param3)) {
+ params->param5 = 0;
+
+ if (params->param3 == kPosition_540) {
+ params->param2 = (getProgress().chapter == kChapter1) ? kCarRedSleeping : kCarGreenSleeping;
+ params->param3 = kPosition_9460;
+ } else {
+ params->param2 = kCarGreenSleeping;
+ params->param3 = kPosition_540;
+ params->param7 = 0;
+ params->param8 = 0;
+
+ getSavePoints()->push(kEntityFrancois, kEntityCoudert, kAction225932896);
+ getSavePoints()->push(kEntityFrancois, kEntityMertens, kAction225932896);
+ }
+ }
+
+ if (getEntities()->checkDistanceFromPosition(kEntityFrancois, kPosition_2000, 500) && getData()->direction == kDirectionDown) {
+
+ if (getEntities()->isInsideTrainCar(kEntityFrancois, kCarRedSleeping) && params->param8) {
+ setCallback(2);
+ setup_draw("605A");
+ break;
+ }
+
+ if (getEntities()->isInsideTrainCar(kEntityFrancois, kCarGreenSleeping) && params->param7) {
+ setCallback(3);
+ setup_draw("605A");
+ break;
+ }
+ }
+
+label_callback:
+ if (getProgress().chapter == kChapter1) {
+
+ if (getEntities()->isInsideTrainCar(kEntityFrancois, kCarRedSleeping)
+ && (getEntities()->hasValidFrame(kEntityFrancois) || params->param1 < getState()->time || params->param4)
+ && !params->param5
+ && getData()->entityPosition < getEntityData(kEntityMmeBoutarel)->entityPosition) {
+
+ if (getData()->direction == kDirectionDown) {
+ getSavePoints()->push(kEntityFrancois, kEntityMmeBoutarel, kAction202221040);
+ params->param4 = 1;
+ params->param5 = 1;
+ } else if (params->param4 && getEntities()->isDistanceBetweenEntities(kEntityFrancois, kEntityMmeBoutarel, 1000)) {
+ getSavePoints()->push(kEntityFrancois, kEntityMmeBoutarel, kAction168986720);
+ params->param5 = 1;
+ }
+ }
+ } else if (params->param1 < getState()->time) {
+ getData()->clothes = kClothesDefault;
+ getData()->field_4A3 = 30;
+ getData()->inventoryItem = kItemNone;
+
+ if (getSound()->isBuffered(kEntityFrancois))
+ getSound()->processEntry(kEntityFrancois);
+
+ setCallback(4);
+ setup_updateEntity(kCarRedSleeping, kPosition_5790);
+ }
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+
+ if (getSound()->isBuffered(kEntityFrancois))
+ getSound()->processEntry(kEntityFrancois);
+
+ setCallback(6);
+ setup_savegame(kSavegameTypeEvent, kEventFrancoisWhistle);
+ break;
+
+ case kActionExcuseMeCath:
+ if (getProgress().jacket == kJacketGreen
+ && !getEvent(kEventFrancoisWhistle)
+ && !getEvent(kEventFrancoisWhistleD)
+ && !getEvent(kEventFrancoisWhistleNight)
+ && !getEvent(kEventFrancoisWhistleNightD))
+ getData()->inventoryItem = kItemInvalid;
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function9();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->clothes = kClothes1;
+ getData()->field_4A3 = 100;
+ getData()->inventoryItem = kItemNone;
+
+ params->param2 = kCarGreenSleeping;
+ params->param3 = kPosition_540;
+
+ getEntities()->updateEntity(kEntityFrancois, kCarGreenSleeping, kPosition_540);
+
+ params->param6 = 15 * rnd(7);
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityFrancois, kEntityCoudert, kAction168253822);
+ // Fallback to next case
+
+ case 3:
+ params->param2 = kCarRedSleeping;
+ params->param3 = kPosition_9460;
+ params->param5 = 0;
+
+ getData()->entityPosition = kPosition_2088;
+
+ getEntities()->updateEntity(kEntityFrancois, kCarRedSleeping, kPosition_9460);
+ goto label_callback;
+
+ case 4:
+ setCallback(5);
+ setup_function10();
+ break;
+
+ case 5:
+ CALLBACK_ACTION();
+ break;
+
+ case 6:
+ if (getProgress().jacket == kJacketGreen) {
+ if (isNight())
+ getAction()->playAnimation(getData()->entityPosition <= getEntityData(kEntityPlayer)->entityPosition ? kEventFrancoisWhistleNightD : kEventFrancoisWhistleNight);
+ else
+ getAction()->playAnimation(getData()->entityPosition <= getEntityData(kEntityPlayer)->entityPosition ? kEventFrancoisWhistleD : kEventFrancoisWhistleD);
+ }
+ getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + 750 * (getData()->direction == kDirectionUp ? -1 : 1)), getData()->direction == kDirectionUp);
+ break;
+ }
+ break;
+
+ case kAction102752636:
+ getEntities()->clearSequences(kEntityFrancois);
+ getData()->location = kLocationInsideCompartment;
+ getData()->entityPosition = kPosition_5790;
+ getData()->clothes = kClothesDefault;
+ getData()->field_4A3 = 30;
+ getData()->inventoryItem = kItemNone;
+
+ CALLBACK_ACTION();
+ break;
+
+ case kAction205346192:
+ if (savepoint.entity2 == kEntityCoudert)
+ params->param8 = 1;
+ else if (savepoint.entity2 == kEntityMertens)
+ params->param7 = 1;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Francois, function12)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function9();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_9460);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_updateFromTime(675);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_updateEntity(kCarRedSleeping, kPosition_540);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_updateFromTime(675);
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_updateEntity(kCarRedSleeping, kPosition_5790);
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_function10();
+ break;
+
+ case 7:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Francois, function13)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function9();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_540);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_updateEntity(kCarGreenSleeping, kPosition_4070);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_enterExitCompartment("605Df", kObjectCompartment6);
+ break;
+
+ case 4:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityFrancois);
+
+ setCallback(5);
+ setup_playSound("Har2010");
+ break;
+
+ case 5:
+ getSavePoints()->push(kEntityFrancois, kEntityAlouan, kAction189489753);
+ break;
+
+ case 6:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(7);
+ setup_updateEntity(kCarGreenSleeping, kPosition_4840);
+ break;
+
+ case 7:
+ if (getInventory()->hasItem(kItemWhistle) || getInventory()->get(kItemWhistle)->location == kObjectLocation3) {
+ setCallback(10);
+ setup_updateEntity(kCarGreenSleeping, kPosition_5790);
+ break;
+ }
+
+ getEntities()->drawSequenceLeft(kEntityFrancois, "605He");
+ break;
+
+ case 8:
+ setCallback(9);
+ setup_updateFromTime(450);
+ break;
+
+ case 9:
+ getEntities()->exitCompartment(kEntityFrancois, kObjectCompartmentE, true);
+
+ setCallback(10);
+ setup_updateEntity(kCarGreenSleeping, kPosition_5790);
+ break;
+
+ case 10:
+ setCallback(11);
+ setup_function10();
+ break;
+
+ case 11:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction190219584:
+ setCallback(6);
+ setup_enterExitCompartment("605Ef", kObjectCompartment6);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_IIS(14, Francois, function14, ObjectIndex, EntityPosition)
+ error("Francois: callback function 14 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Francois, function15)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function9();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (getData()->entityPosition >= getEntityData(kEntityPlayer)->entityPosition) {
+ setCallback(3);
+ setup_updateEntity(kCarRedSleeping, kPosition_540);
+ } else {
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_9460);
+ }
+ break;
+
+ case 2:
+ case 3:
+ setCallback(4);
+ setup_updateFromTime(450);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_updateEntity(kCarRedSleeping, kPosition_5790);
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_function10();
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_updateFromTime(900);
+ break;
+
+ case 7:
+ if (!getEntities()->isInsideCompartment(kEntityMmeBoutarel, kCarRedSleeping, kPosition_5790)) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ setCallback(8);
+ setup_playSound("Fra2012");
+ break;
+
+ case 8:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Francois, function16)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ getData()->entityPosition = getEntityData(kEntityBoutarel)->entityPosition;
+ getData()->location = getEntityData(kEntityBoutarel)->location;
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorNormal);
+
+ setCallback(1);
+ setup_enterExitCompartment("605Cd", kObjectCompartmentD);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ getData()->entityPosition = kPosition_5890;
+
+ getSavePoints()->push(kEntityFrancois, kEntityMmeBoutarel, kAction101107728);
+
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityFrancois);
+ getSavePoints()->push(kEntityFrancois, kEntityBoutarel, kAction237889408);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_enterExitCompartment("605Id", kObjectCompartmentD);
+ break;
+
+ case 4:
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getSavePoints()->push(kEntityFrancois, kEntityMmeBoutarel, kAction100957716);
+
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction100901266:
+ setCallback(3);
+ setup_updateEntity(kCarRedSleeping, kPosition_5790);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Francois, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Francois, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CALLBACK_1(kTimeParisEpernay, params->param1, 1, setup_function11, kTime1093500);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function19();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Francois, function19)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CALLBACK(kTime1161000, params->param1, 2, setup_function12);
+ break;
+
+ case kAction101107728:
+ setCallback(1);
+ setup_function16();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Francois, function20)
+ if (savepoint.action == kActionDefault) {
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getEntities()->clearSequences(kEntityFrancois);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21 ,Francois, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter2Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityFrancois);
+
+ getData()->entityPosition = kPosition_4689;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Francois, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("605Id", kObjectCompartmentD);
+ break;
+
+ case 2:
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getSavePoints()->push(kEntityFrancois, kEntityMmeBoutarel, kAction100957716);
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityFrancois);
+ setup_function23();
+ break;
+ }
+ break;
+
+ case kAction100901266:
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_5790);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Francois, function23)
+ error("Francois: callback function 23 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Francois, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityFrancois);
+
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, Francois, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEvent(kEventFrancoisShowBeetle) || getEvent(kEventFrancoisShowBeetleD))
+ if (!getEvent(kEventFrancoisTradeWhistle) && !getEvent(kEventFrancoisTradeWhistleD))
+ ENTITY_PARAM(0, 1) = 1;
+
+ if (params->param2 && getEntities()->isInsideCompartment(kEntityMmeBoutarel, kCarRedSleeping, kPosition_5790) && !params->param1) {
+
+ if (ENTITY_PARAM(0, 1) && getEntities()->isPlayerInCar(kCarRedSleeping)) {
+ setCallback(2);
+ setup_function15();
+ break;
+ }
+
+label_callback_2:
+ TIME_CHECK_CALLBACK(kTime2025000, params->param3, 3, setup_function12);
+
+label_callback_3:
+ TIME_CHECK_CALLBACK(kTime2052000, params->param4, 4, setup_function12);
+
+label_callback_4:
+ TIME_CHECK_CALLBACK(kTime2079000, params->param5, 5, setup_function12);
+
+label_callback_5:
+ TIME_CHECK_CALLBACK(kTime2092500, params->param6, 6, setup_function12);
+
+label_callback_6:
+ TIME_CHECK_CALLBACK(kTime2173500, params->param7, 7, setup_function12);
+
+label_callback_7:
+ TIME_CHECK_CALLBACK(kTime2182500, params->param8, 8, setup_function12);
+
+label_callback_8:
+ TIME_CHECK_CALLBACK(kTime2241000, CURRENT_PARAMS(1, 1), 9, setup_function12);
+
+label_callback_9:
+ if (!getInventory()->hasItem(kItemWhistle) && getInventory()->get(kItemWhistle)->location != kObjectLocation3) {
+ TIME_CHECK_CALLBACK_1(kTime2011500, CURRENT_PARAMS(1, 2), 10, setup_function11, kTime2016000);
+
+label_callback_10:
+ TIME_CHECK_CALLBACK_1(kTime2115000, CURRENT_PARAMS(1, 3), 11, setup_function11, kTime2119500);
+ }
+
+label_callback_11:
+ if (getInventory()->get(kItemWhistle)->location == kObjectLocation3) {
+ if (getState()->time <= kTimeEnd)
+ if (!getEntities()->isDistanceBetweenEntities(kEntityFrancois, kEntityPlayer, 2000) || !params->param4)
+ params->param4 = getState()->time + 75;
+
+ if (params->param4 < getState()->time || getState()->time > kTimeEnd) {
+ params->param4 = kTimeInvalid;
+
+ setCallback(12);
+ setup_playSound("Fra2010");
+ break;
+ }
+
+label_callback_12:
+ TIME_CHECK_CALLBACK_3(kTime2040300, CURRENT_PARAMS(1, 5), 13, setup_function14, kObjectCompartmentE, kPosition_4840, "e");
+
+label_callback_13:
+ TIME_CHECK_CALLBACK_3(kTime2040300, CURRENT_PARAMS(1, 6), 14, setup_function14, kObjectCompartmentF, kPosition_4070, "f");
+
+label_callback_14:
+ TIME_CHECK_CALLBACK_3(kTime2040300, CURRENT_PARAMS(1, 7), 15, setup_function14, kObjectCompartmentB, kPosition_7500, "b");
+ }
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ params->param2 = 1;
+ break;
+
+ case 2:
+ goto label_callback_2;
+
+ case 3:
+ goto label_callback_3;
+
+ case 4:
+ goto label_callback_4;
+
+ case 5:
+ goto label_callback_5;
+
+ case 6:
+ goto label_callback_6;
+
+ case 7:
+ goto label_callback_7;
+
+ case 8:
+ goto label_callback_8;
+
+ case 9:
+ goto label_callback_9;
+
+ case 10:
+ goto label_callback_10;
+
+ case 11:
+ goto label_callback_11;
+
+ case 12:
+ getProgress().field_9C = 1;
+ goto label_callback_12;
+
+ case 13:
+ goto label_callback_13;
+
+ case 14:
+ goto label_callback_14;
+ }
+ break;
+
+ case kAction101107728:
+ setCallback(1);
+ setup_function16();
+ break;
+
+ case kAction189872836:
+ params->param1 = 1;
+ break;
+ case kAction190390860:
+ params->param1 = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(26, Francois, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityFrancois);
+
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(27, Francois, chapter4Handler)
+ if (savepoint.action == kAction101107728) {
+ setCallback(1);
+ setup_function16();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(28, Francois, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityFrancois);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(29, Francois, chapter5Handler)
+ if (savepoint.action == kActionProceedChapter5) {
+ if (!getInventory()->hasItem(kItemWhistle)
+ && getInventory()->get(kItemWhistle)->location != kObjectLocation3)
+ getInventory()->setLocationAndProcess(kItemWhistle, kObjectLocation1);
+
+ setup_function30();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(30, Francois, function30)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+
+ case kAction135800432:
+ setup_nullfunction();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_NULL_FUNCTION(31, Francois)
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/francois.h b/engines/lastexpress/entities/francois.h
new file mode 100644
index 0000000000..894a60bc5b
--- /dev/null
+++ b/engines/lastexpress/entities/francois.h
@@ -0,0 +1,170 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_FRANCOIS_H
+#define LASTEXPRESS_FRANCOIS_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Francois : public Entity {
+public:
+ Francois(LastExpressEngine *engine);
+ ~Francois() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param time The time to add
+ */
+ DECLARE_FUNCTION_1(updateFromTime, uint32 time)
+
+ /**
+ * Draws the entity
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(draw, const char* sequence)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Handles entering/exiting a compartment and updates position/play animation
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment2, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ DECLARE_FUNCTION(function9)
+ DECLARE_FUNCTION(function10)
+ DECLARE_FUNCTION_1(function11, TimeValue timeValue)
+ DECLARE_FUNCTION(function12)
+ DECLARE_FUNCTION(function13)
+ DECLARE_FUNCTION_3(function14, ObjectIndex compartment, EntityPosition entityPosition, const char *str)
+ DECLARE_FUNCTION(function15)
+ DECLARE_FUNCTION(function16)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function19)
+ DECLARE_FUNCTION(function20)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+
+ DECLARE_FUNCTION(function23)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_FUNCTION(function30)
+
+ DECLARE_NULL_FUNCTION()
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_FRANCOIS_H
diff --git a/engines/lastexpress/entities/gendarmes.cpp b/engines/lastexpress/entities/gendarmes.cpp
new file mode 100644
index 0000000000..3af85ffdb9
--- /dev/null
+++ b/engines/lastexpress/entities/gendarmes.cpp
@@ -0,0 +1,491 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/gendarmes.h"
+
+#include "lastexpress/game/action.h"
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+namespace LastExpress {
+
+Gendarmes::Gendarmes(LastExpressEngine *engine) : Entity(engine, kEntityGendarmes) {
+ ADD_CALLBACK_FUNCTION(Gendarmes, reset);
+ ADD_CALLBACK_FUNCTION(Gendarmes, chapter1);
+ ADD_CALLBACK_FUNCTION(Gendarmes, arrestDraw);
+ ADD_CALLBACK_FUNCTION(Gendarmes, arrestPlaysound);
+ ADD_CALLBACK_FUNCTION(Gendarmes, arrestPlaysound16);
+ ADD_CALLBACK_FUNCTION(Gendarmes, arrestCallback);
+ ADD_CALLBACK_FUNCTION(Gendarmes, savegame);
+ ADD_CALLBACK_FUNCTION(Gendarmes, arrestUpdateEntity);
+ ADD_CALLBACK_FUNCTION(Gendarmes, function9);
+ ADD_CALLBACK_FUNCTION(Gendarmes, function10);
+ ADD_CALLBACK_FUNCTION(Gendarmes, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Gendarmes, function12);
+ ADD_CALLBACK_FUNCTION(Gendarmes, function13);
+ ADD_CALLBACK_FUNCTION(Gendarmes, chapter2);
+ ADD_CALLBACK_FUNCTION(Gendarmes, chapter3);
+ ADD_CALLBACK_FUNCTION(Gendarmes, chapter4);
+ ADD_CALLBACK_FUNCTION(Gendarmes, chapter5);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Gendarmes, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(2, Gendarmes, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(3, Gendarmes, arrestDraw)
+ arrest(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(4, Gendarmes, arrestPlaysound)
+ arrest(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(5, Gendarmes, arrestPlaysound16)
+ arrest(savepoint, true, SoundManager::kFlagDefault);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(6, Gendarmes, arrestCallback, TimeValue)
+ arrest(savepoint, true, SoundManager::kFlagInvalid, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(7, Gendarmes, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(8, Gendarmes, arrestUpdateEntity, CarIndex, EntityPosition)
+ arrest(savepoint, true, SoundManager::kFlagInvalid, false, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_IISS(9, Gendarmes, function9, CarIndex, EntityPosition)
+ error("Gendarmes: callback function 9 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_III(10, Gendarmes, function10, CarIndex, EntityPosition, ObjectIndex)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param5 || getState()->timeTicks > (uint32)params->param5) {
+ if (!params->param5)
+ params->param5 = getState()->timeTicks + 75;
+
+ if (!getEntities()->isOutsideAlexeiWindow() && getObjects()->get((ObjectIndex)params->param3).location != kObjectLocation1) {
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventGendarmesArrestation);
+ break;
+ }
+ }
+
+ if (!params->param6)
+ params->param6 = getState()->timeTicks + 150;
+
+ if (params->param6 == 0 || getState()->timeTicks > (uint32)params->param6) {
+ params->param6 = kTimeInvalid;
+
+ getSound()->playSound(kEntityGendarmes, "POL1046A", SoundManager::kFlagDefault);
+ }
+
+ UPDATE_PARAM(params->param7, getState()->timeTicks, 300);
+
+ if (!params->param4 && getEntities()->isOutsideAlexeiWindow()) {
+ getObjects()->update((ObjectIndex)params->param3, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ CALLBACK_ACTION();
+ } else {
+ if (getEntities()->isOutsideAlexeiWindow())
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
+
+ getSound()->playSound(kEntityGendarmes, "LIB017", SoundManager::kFlagDefault);
+
+ setCallback(getProgress().jacket == kJacketBlood ? 3 : 4);
+ setup_savegame(kSavegameTypeEvent, getProgress().jacket == kJacketBlood ? kEventMertensBloodJacket : kEventGendarmesArrestation);
+ }
+ break;
+
+ case kActionKnock:
+ getObjects()->update((ObjectIndex)params->param3, kEntityGendarmes, getObjects()->get((ObjectIndex)params->param3).location, kCursorNormal, kCursorNormal);
+
+ setCallback(5);
+ setup_arrestPlaysound16("POL1046B");
+ break;
+
+ case kActionOpenDoor:
+ setCallback(6);
+ setup_savegame(kSavegameTypeEvent, kEventGendarmesArrestation);
+ break;
+
+ case kActionDefault:
+ getObjects()->update((ObjectIndex)params->param3, kEntityGendarmes, getObjects()->get((ObjectIndex)params->param3).location, kCursorNormal, kCursorNormal);
+
+ setCallback(1);
+ setup_arrestPlaysound16("POL1046");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update((ObjectIndex)params->param3, kEntityGendarmes, getObjects()->get((ObjectIndex)params->param3).location, kCursorTalk, kCursorNormal);
+ break;
+
+ case 2:
+ getSound()->playSound(kEntityGendarmes, "LIB014", SoundManager::kFlagDefault);
+ getAction()->playAnimation(kEventGendarmesArrestation);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverPolice1, true);
+ break;
+
+ case 3:
+ getAction()->playAnimation((params->param1 < kCarRedSleeping) ? kEventMertensBloodJacket : kEventCoudertBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+
+ getObjects()->update((ObjectIndex)params->param3, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ CALLBACK_ACTION();
+ break;
+
+ case 4:
+ getAction()->playAnimation(kEventGendarmesArrestation);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverPolice1, true);
+
+ getObjects()->update((ObjectIndex)params->param3, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ CALLBACK_ACTION();
+ break;
+
+ case 5:
+ getObjects()->update((ObjectIndex)params->param3, kEntityGendarmes, getObjects()->get((ObjectIndex)params->param3).location, kCursorNormal, kCursorHand);
+ break;
+
+ case 6:
+ getSound()->playSound(kEntityGendarmes, "LIB014", SoundManager::kFlagDefault);
+ getAction()->playAnimation(kEventGendarmesArrestation);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverPolice1, true);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Gendarmes, chapter1Handler)
+ if (savepoint.action == kAction169499649) {
+ getSavePoints()->push(kEntityGendarmes, kEntityMertens, kAction190082817);
+ setup_function12();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Gendarmes, function12)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_540;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarGreenSleeping;
+
+ getProgress().field_14 = 29;
+
+ setCallback(1);
+ setup_arrestUpdateEntity(kCarGreenSleeping, kPosition_5540);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function9(kCarGreenSleeping, kPosition_5790, "d", "A");
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_arrestUpdateEntity(kCarGreenSleeping, kPosition_6220);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function9(kCarGreenSleeping, kPosition_6470, "c", "B");
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_arrestUpdateEntity(kCarGreenSleeping, kPosition_7250);
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_function9(kCarGreenSleeping, kPosition_7500, "b", "C");
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_arrestUpdateEntity(kCarGreenSleeping, kPosition_7950);
+ break;
+
+ case 7:
+ setCallback(8);
+ setup_function9(kCarGreenSleeping, kPosition_8200, "a", "NODIALOG");
+ break;
+
+ case 8:
+ setCallback(9);
+ setup_arrestUpdateEntity(kCarGreenSleeping, kPosition_9460);
+ break;
+
+ case 9:
+ if (getEntityData(kEntityPlayer)->car == kCarGreenSleeping) {
+ getProgress().field_14 = 0;
+ getEntities()->clearSequences(kEntityGendarmes);
+ getSavePoints()->push(kEntityGendarmes, kEntityVerges, kAction168710784);
+ setup_function13();
+ break;
+ }
+
+ setCallback(10);
+ setup_arrestUpdateEntity(kCarRedSleeping, kPosition_2490);
+ break;
+
+ case 10:
+ setCallback(11);
+ setup_function9(kCarRedSleeping, kPosition_2740, "h", "NODIALOG");
+ break;
+
+ case 11:
+ setCallback(12);
+ setup_arrestUpdateEntity(kCarRedSleeping, kPosition_3820);
+ break;
+
+ case 12:
+ setCallback(13);
+ setup_function9(kCarRedSleeping, kPosition_4070, "f", "E");
+ break;
+
+ case 13:
+ setCallback(14);
+ setup_arrestUpdateEntity(kCarRedSleeping, kPosition_4590);
+ break;
+
+ case 14:
+ setCallback(15);
+ setup_function9(kCarRedSleeping, kPosition_4840, "e", "F");
+ break;
+
+ case 15:
+ setCallback(16);
+ setup_arrestUpdateEntity(kCarRedSleeping, kPosition_5540);
+ break;
+
+ case 16:
+ setCallback(17);
+ setup_function9(kCarRedSleeping, kPosition_5790, "d", "G");
+ break;
+
+ case 17:
+ setCallback(18);
+ setup_arrestUpdateEntity(kCarRedSleeping, kPosition_6220);
+ break;
+
+ case 18:
+ setCallback(19);
+ setup_function9(kCarRedSleeping, kPosition_6470, "c", "H");
+ break;
+
+ case 19:
+ setCallback(20);
+ setup_arrestUpdateEntity(kCarRedSleeping, kPosition_7250);
+ break;
+
+ case 20:
+ setCallback(21);
+ setup_function9(kCarRedSleeping, kPosition_7500, "b", "J");
+ break;
+
+ case 21:
+ setCallback(22);
+ setup_arrestUpdateEntity(kCarRedSleeping, kPosition_7950);
+ break;
+
+ case 22:
+ setCallback(23);
+ setup_function9(kCarRedSleeping, kPosition_8200, "a", "NODIALOG");
+ break;
+
+ case 23:
+ setCallback(24);
+ setup_arrestUpdateEntity(kCarRedSleeping, kPosition_9460);
+ break;
+
+ case 24:
+ getProgress().field_14 = 0;
+ getEntities()->clearSequences(kEntityGendarmes);
+ getSavePoints()->push(kEntityGendarmes, kEntityVerges, kAction168710784);
+ setup_function13();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Gendarmes, function13)
+ if (savepoint.action == kActionDefault)
+ getData()->car = kCarNone;
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Gendarmes, chapter2)
+ if (savepoint.action == kActionDefault)
+ getEntities()->clearSequences(kEntityGendarmes);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Gendarmes, chapter3)
+ if (savepoint.action == kActionDefault)
+ getEntities()->clearSequences(kEntityGendarmes);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Gendarmes, chapter4)
+ if (savepoint.action == kActionDefault)
+ getEntities()->clearSequences(kEntityGendarmes);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Gendarmes, chapter5)
+ if (savepoint.action == kActionDefault)
+ getEntities()->clearSequences(kEntityGendarmes);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Private functions
+//////////////////////////////////////////////////////////////////////////
+void Gendarmes::arrest(const SavePoint &savepoint, bool shouldPlaySound, SoundManager::FlagType flag, bool checkCallback, bool shouldUpdateEntity) {
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (checkCallback) {
+ EXPOSE_PARAMS(EntityData::EntityParametersIIII);
+ TIME_CHECK_CALLBACK_ACTION(params->param1, params->param2);
+ }
+
+ if (shouldUpdateEntity) {
+ EXPOSE_PARAMS(EntityData::EntityParametersIIII);
+ if (getEntities()->updateEntity(kEntityGendarmes, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ CALLBACK_ACTION();
+ break;
+ }
+ }
+ // Fallback to next action
+
+ case kActionDrawScene:
+ if (!ENTITY_PARAM(0, 1) && getEntities()->hasValidFrame(kEntityGendarmes)) {
+ getSound()->playSound(kEntityPlayer, "MUS007");
+ ENTITY_PARAM(0, 1) = 1;
+ }
+
+ if (getEntities()->isDistanceBetweenEntities(kEntityGendarmes, kEntityPlayer, 1000) && !getEntityData(kEntityPlayer)->location) {
+
+ if (shouldUpdateEntity)
+ if (getEntities()->isPlayerPosition(kCarRedSleeping, 22) && !getEntities()->isDistanceBetweenEntities(kEntityGendarmes, kEntityPlayer, 250))
+ break;
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventGendarmesArrestation);
+ }
+ break;
+
+ case kActionExitCompartment:
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ // Only handle when passing SIIS params
+ if (!checkCallback) {
+ EXPOSE_PARAMS(EntityData::EntityParametersSIIS);
+
+ if (!shouldPlaySound)
+ getEntities()->drawSequenceRight(kEntityGendarmes, (char *)&params->seq1);
+ else
+ getSound()->playSound(kEntityGendarmes, (char *)&params->seq1, flag);
+ }
+
+ if (shouldUpdateEntity) {
+ EXPOSE_PARAMS(EntityData::EntityParametersIIII);
+ if (getEntities()->updateEntity(kEntityGendarmes, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ CALLBACK_ACTION();
+ break;
+ }
+ }
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventGendarmesArrestation);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverPolice1, true);
+ }
+ break;
+ }
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/gendarmes.h b/engines/lastexpress/entities/gendarmes.h
new file mode 100644
index 0000000000..b0aec28bfb
--- /dev/null
+++ b/engines/lastexpress/entities/gendarmes.h
@@ -0,0 +1,99 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_GENDARMES_H
+#define LASTEXPRESS_GENDARMES_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+#include "lastexpress/game/sound.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Gendarmes : public Entity {
+public:
+ Gendarmes(LastExpressEngine *engine);
+ ~Gendarmes() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ DECLARE_FUNCTION_1(arrestDraw, const char *sequence)
+ DECLARE_FUNCTION_1(arrestPlaysound, const char *soundName)
+ DECLARE_FUNCTION_1(arrestPlaysound16, const char *soundName)
+ DECLARE_FUNCTION_1(arrestCallback, TimeValue timeValue)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ DECLARE_FUNCTION_2(arrestUpdateEntity, CarIndex car, EntityPosition entityPosition)
+ DECLARE_FUNCTION_4(function9, CarIndex car, EntityPosition entityPosition, const char *sequence1, const char *sequence2)
+ DECLARE_FUNCTION_3(function10, CarIndex car, EntityPosition entityPosition, ObjectIndex object)
+ DECLARE_FUNCTION(chapter1Handler)
+ DECLARE_FUNCTION(function12)
+ DECLARE_FUNCTION(function13)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+private:
+ void arrest(const SavePoint &savepoint, bool playSound = false, SoundManager::FlagType flag = SoundManager::kFlagInvalid, bool checkCallback = false, bool shouldUpdateEntity = false);
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_GENDARMES_H
diff --git a/engines/lastexpress/entities/hadija.cpp b/engines/lastexpress/entities/hadija.cpp
new file mode 100644
index 0000000000..564ac942ca
--- /dev/null
+++ b/engines/lastexpress/entities/hadija.cpp
@@ -0,0 +1,529 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/hadija.h"
+
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+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(Hadija, compartment6);
+ ADD_CALLBACK_FUNCTION(Hadija, compartment8);
+ ADD_CALLBACK_FUNCTION(Hadija, compartment6to8);
+ ADD_CALLBACK_FUNCTION(Hadija, compartment8to6);
+ ADD_CALLBACK_FUNCTION(Hadija, chapter1);
+ ADD_CALLBACK_FUNCTION(Hadija, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Hadija, function12);
+ ADD_CALLBACK_FUNCTION(Hadija, chapter2);
+ ADD_CALLBACK_FUNCTION(Hadija, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Hadija, chapter3);
+ ADD_CALLBACK_FUNCTION(Hadija, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Hadija, chapter4);
+ ADD_CALLBACK_FUNCTION(Hadija, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Hadija, function19);
+ ADD_CALLBACK_FUNCTION(Hadija, chapter5);
+ ADD_CALLBACK_FUNCTION(Hadija, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(Hadija, function22);
+ ADD_CALLBACK_FUNCTION(Hadija, function23);
+ ADD_NULL_FUNCTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Hadija, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(2, Hadija, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(3, Hadija, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(4, Hadija, updateFromTime)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(5, Hadija, updateEntity, CarIndex, EntityPosition)
+ Entity::updateEntity(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(6, Hadija, compartment6)
+ COMPARTMENT_TO(Hadija, kObjectCompartment6, kPosition_4070, "619Cf", "619Df");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(7, Hadija, compartment8)
+ COMPARTMENT_TO(Hadija, kObjectCompartment8, kPosition_2740, "619Ch", "619Dh");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(8, Hadija, compartment6to8)
+ COMPARTMENT_FROM_TO(Hadija, kObjectCompartment6, kPosition_4070, "619Bf", kObjectCompartment8, kPosition_2740, "619Ah");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(9, Hadija, compartment8to6)
+ COMPARTMENT_FROM_TO(Hadija, kObjectCompartment8, kPosition_2740, "619Bh", kObjectCompartment6, kPosition_4070, "619Af");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(10, Hadija, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Hadija, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_PLAYSOUND_UPDATEPOSITION(kTimeParisEpernay, params->param1, 1, "Har1100", kPosition_4840);
+
+label_callback1:
+ TIME_CHECK_CALLBACK(kTime1084500, params->param2, 2, setup_compartment6to8);
+
+label_callback2:
+ if (params->param3 != kTimeInvalid && getState()->time > kTime1093500) {
+
+ if (getState()->time <= kTime1134000) {
+
+ if (!getEntities()->isPlayerInCar(kCarGreenSleeping) || !getEntities()->isInsideCompartment(kEntityMahmud, kCarGreenSleeping, kPosition_5790) || !params->param3) {
+ params->param3 = getState()->time + 75;
+
+ if (!params->param3) {
+ setCallback(3);
+ setup_compartment8();
+ return;
+ }
+ }
+
+ if (params->param3 >= getState()->time)
+ return;
+ }
+
+ params->param3 = kTimeInvalid;
+
+ setCallback(3);
+ setup_compartment8();
+ }
+
+label_callback3:
+ TIME_CHECK_CALLBACK(kTime1156500, params->param4, 4, setup_compartment8to6);
+
+label_callback4:
+ if (params->param5 != kTimeInvalid && getState()->time > kTime1165500) {
+ if (getState()->time <= kTime1188000) {
+
+ if (!getEntities()->isPlayerInCar(kCarGreenSleeping) || !getEntities()->isInsideCompartment(kEntityMahmud, kCarGreenSleeping, kPosition_5790) || !params->param5) {
+ params->param5 = getState()->time + 75;
+
+ if (!params->param5) {
+ setCallback(5);
+ setup_compartment6();
+ return;
+ }
+ }
+
+ if (params->param5 >= getState()->time)
+ return;
+ }
+
+ params->param5 = kTimeInvalid;
+
+ setCallback(5);
+ setup_compartment6();
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_callback1;
+
+ case 2:
+ goto label_callback2;
+
+ case 3:
+ goto label_callback3;
+
+ case 4:
+ goto label_callback4;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Hadija, function12)
+ if (savepoint.action == kActionDefault) {
+ getObjects()->update(kObjectCompartment8, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+
+ getEntities()->clearSequences(kEntityHadija);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Hadija, chapter2)
+ if (savepoint.action == kActionDefault) {
+
+ getEntities()->clearSequences(kEntityHadija);
+
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ setup_chapter2Handler();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Hadija, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_POSITION(kTime1782000, params->param1, kPosition_2740);
+
+ if (params->param2 == kTimeInvalid || getState()->time <= kTime1786500) {
+ TIME_CHECK_CALLBACK(kTime1822500, params->param3, 2, setup_compartment8to6);
+ break;
+ }
+
+ if (getState()->time <= kTime1818000) {
+
+ if (!getEntities()->isPlayerInCar(kCarGreenSleeping) || !params->param2)
+ params->param2 = getState()->time + 75;
+
+ if (params->param2 >= getState()->time) {
+ TIME_CHECK_CALLBACK(kTime1822500, params->param3, 2, setup_compartment8to6);
+ break;
+ }
+ }
+
+ params->param2 = kTimeInvalid;
+
+ setCallback(1);
+ setup_compartment8();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ TIME_CHECK_CALLBACK(kTime1822500, params->param3, 2, setup_compartment8to6);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_playSound("Har2012");
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Hadija, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityHadija);
+
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Hadija, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CALLBACK(kTime1998000, params->param1, 1, setup_compartment6to8);
+
+label_callback1:
+ TIME_CHECK_CALLBACK(kTime2020500, params->param2, 2, setup_compartment8to6);
+
+label_callback2:
+ TIME_CHECK_CALLBACK(kTime2079000, params->param3, 3, setup_compartment6to8);
+
+label_callback3:
+ TIME_CHECK_CALLBACK(kTime2187000, params->param4, 4, setup_compartment8to6);
+
+label_callback4:
+ if (params->param5 != kTimeInvalid && getState()->time > kTime2196000)
+ TIME_CHECK_CAR(kTime2254500, params->param5, 5, setup_compartment6);
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityAlouan, kEntityTrain, kAction191070912, kPosition_4840);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_callback1;
+
+ case 2:
+ goto label_callback2;
+
+ case 3:
+ goto label_callback3;
+
+ case 4:
+ goto label_callback4;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Hadija, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Hadija, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1 != kTimeInvalid)
+ TIME_CHECK_CAR(kTime1714500, params->param1, 1, setup_compartment6);
+
+label_callback1:
+ TIME_CHECK_CALLBACK(kTime2367000, params->param2, 2, setup_compartment6to8);
+
+label_callback2:
+ TIME_CHECK_CALLBACK(kTime2421000, params->param3, 3, setup_compartment8to6);
+
+label_callback3:
+ if (params->param4 != kTimeInvalid && getState()->time > kTime2425500)
+ TIME_CHECK_CAR(kTime2484000, params->param4, 4, setup_compartment6);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_callback1;
+
+ case 2:
+ goto label_callback2;
+
+ case 3:
+ goto label_callback3;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Hadija, function19)
+ if (savepoint.action == kActionDefault) {
+ getObjects()->update(kObjectCompartment8, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+
+ getEntities()->clearSequences(kEntityHadija);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Hadija, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityHadija);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Hadija, chapter5Handler)
+ if (savepoint.action == kActionProceedChapter5)
+ setup_function22();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Hadija, function22)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param1, getState()->time, 2700);
+ setup_function23();
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5000;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ break;
+
+ case kActionDrawScene:
+ if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarGreenSleeping)) {
+ setup_function23();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Hadija, function23)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_4070);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("619AF", kObjectCompartment6);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityHadija);
+
+ getData()->entityPosition = kPosition_4840;
+ getData()->location = kLocationInsideCompartment;
+
+ getObjects()->update(kObjectCompartment5, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+ }
+ break;
+
+ case kAction135800432:
+ setup_nullfunction();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_NULL_FUNCTION(24, Hadija)
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/hadija.h b/engines/lastexpress/entities/hadija.h
new file mode 100644
index 0000000000..4792f97cad
--- /dev/null
+++ b/engines/lastexpress/entities/hadija.h
@@ -0,0 +1,144 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_HADIJA_H
+#define LASTEXPRESS_HADIJA_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Hadija : public Entity {
+public:
+ Hadija(LastExpressEngine *engine);
+ ~Hadija() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param savepoint The savepoint
+ * - Time to add
+ */
+ DECLARE_FUNCTION_NOSETUP(updateFromTime)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ DECLARE_FUNCTION(compartment6)
+ DECLARE_FUNCTION(compartment8)
+ DECLARE_FUNCTION(compartment6to8)
+ DECLARE_FUNCTION(compartment8to6)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function12)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ DECLARE_FUNCTION(function19)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_FUNCTION(function22)
+ DECLARE_FUNCTION(function23)
+
+ DECLARE_NULL_FUNCTION()
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_HADIJA_H
diff --git a/engines/lastexpress/entities/ivo.cpp b/engines/lastexpress/entities/ivo.cpp
new file mode 100644
index 0000000000..d56c184c15
--- /dev/null
+++ b/engines/lastexpress/entities/ivo.cpp
@@ -0,0 +1,829 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/ivo.h"
+
+#include "lastexpress/game/action.h"
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/fight.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+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(Ivo, callbackActionOnDirection);
+ ADD_CALLBACK_FUNCTION(Ivo, playSound);
+ ADD_CALLBACK_FUNCTION(Ivo, callbackActionRestaurantOrSalon);
+ ADD_CALLBACK_FUNCTION(Ivo, savegame);
+ ADD_CALLBACK_FUNCTION(Ivo, function11);
+ ADD_CALLBACK_FUNCTION(Ivo, sitAtTableWithSalko);
+ ADD_CALLBACK_FUNCTION(Ivo, leaveTableWithSalko);
+ ADD_CALLBACK_FUNCTION(Ivo, chapter1);
+ ADD_CALLBACK_FUNCTION(Ivo, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Ivo, function16);
+ ADD_CALLBACK_FUNCTION(Ivo, function17);
+ ADD_CALLBACK_FUNCTION(Ivo, chapter2);
+ ADD_CALLBACK_FUNCTION(Ivo, function19);
+ ADD_CALLBACK_FUNCTION(Ivo, function20);
+ ADD_CALLBACK_FUNCTION(Ivo, function21);
+ ADD_CALLBACK_FUNCTION(Ivo, chapter3);
+ ADD_CALLBACK_FUNCTION(Ivo, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Ivo, chapter4);
+ ADD_CALLBACK_FUNCTION(Ivo, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Ivo, function26);
+ ADD_CALLBACK_FUNCTION(Ivo, function27);
+ ADD_CALLBACK_FUNCTION(Ivo, function28);
+ ADD_CALLBACK_FUNCTION(Ivo, function29);
+ ADD_CALLBACK_FUNCTION(Ivo, chapter5);
+ ADD_CALLBACK_FUNCTION(Ivo, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(Ivo, fight);
+ ADD_CALLBACK_FUNCTION(Ivo, function33);
+ ADD_CALLBACK_FUNCTION(Ivo, function34);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Ivo, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(2, Ivo, draw)
+ Entity::draw(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(3, Ivo, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(4, Ivo, updateFromTime, uint32)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(5, Ivo, updateFromTicks, uint32)
+ Entity::updateFromTicks(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(6, Ivo, updateEntity, CarIndex, EntityPosition)
+ if (savepoint.action == kActionExcuseMeCath || savepoint.action == kActionExcuseMe) {
+ getSound()->playSound(kEntityPlayer, "CAT1127A");
+ return;
+ }
+
+ Entity::updateEntity(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(7, Ivo, callbackActionOnDirection)
+ Entity::callbackActionOnDirection(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(8, Ivo, playSound)
+ Entity::playSound(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(9, Ivo, callbackActionRestaurantOrSalon)
+ Entity::callbackActionRestaurantOrSalon(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(10, Ivo, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Ivo, function11)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isDistanceBetweenEntities(kEntityIvo, kEntitySalko, 750) || getEntities()->checkDistanceFromPosition(kEntitySalko, kPosition_2740, 500)) {
+ getSavePoints()->push(kEntityIvo, kEntitySalko, kAction123668192);
+
+ setCallback(4);
+ setup_enterExitCompartment("613Ah", kObjectCompartmentH);
+ }
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(kEntityIvo, "809DS");
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityIvo);
+
+ setCallback(1);
+ setup_callbackActionOnDirection();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityIvo, kEntitySalko, kAction125242096);
+
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_2740);
+ break;
+
+ case 2:
+ if (getEntities()->isDistanceBetweenEntities(kEntityIvo, kEntitySalko, 750) || getEntities()->checkDistanceFromPosition(kEntitySalko, kPosition_2740, 500)) {
+ getSavePoints()->push(kEntityIvo, kEntitySalko, kAction123668192);
+
+ setCallback(3);
+ setup_enterExitCompartment("613Ah", kObjectCompartmentH);
+ } else {
+ getEntities()->drawSequenceLeft(kEntityIvo, "613Hh");
+ getEntities()->enterCompartment(kEntityIvo, kObjectCompartmentH, true);
+ }
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityIvo);
+
+ CALLBACK_ACTION();
+ break;
+
+ case 4:
+ getEntities()->exitCompartment(kEntityIvo, kObjectCompartmentH, true);
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityIvo);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Ivo, sitAtTableWithSalko)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ getEntities()->clearSequences(kEntitySalko);
+ getSavePoints()->push(kEntityIvo, kEntityTables2, kAction136455232);
+
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(kEntityIvo, "023A1");
+ getEntities()->drawSequenceRight(kEntitySalko, "023A2");
+ getEntities()->drawSequenceRight(kEntityTables2, "023A3");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Ivo, leaveTableWithSalko)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ getSavePoints()->push(kEntityIvo, kEntityTables2, kActionDrawTablesWithChairs, "009E");
+ getEntities()->clearSequences(kEntitySalko);
+
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(kEntityIvo, "023D1");
+ getEntities()->drawSequenceRight(kEntitySalko, "023D2");
+ getEntities()->drawSequenceRight(kEntityTables2, "023D3");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Ivo, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentH, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject47, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ getData()->entityPosition = kPosition_4691;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Ivo, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ getData()->entityPosition = getEntityData(kEntityMilos)->entityPosition;
+ getData()->location = getEntityData(kEntityMilos)->location;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function11();
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityIvo, kEntityMilos, kAction135024800);
+ setup_function16();
+ break;
+ }
+ break;
+
+ case kAction125242096:
+ setCallback(1);
+ setup_updateFromTicks(75);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Ivo, function16)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getObjects()->update(kObjectCompartmentH, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getEntities()->clearSequences(kEntityIvo);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceLeft(kEntityIvo, "613Ch");
+ getEntities()->enterCompartment(kEntityIvo, kObjectCompartmentH);
+ getSavePoints()->push(kEntityIvo, kEntityCoudert, kAction88652208);
+ break;
+
+ case 2:
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+
+ getEntities()->clearSequences(kEntityIvo);
+ getObjects()->update(kObjectCompartmentH, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ break;
+ }
+ break;
+
+ case kAction122865568:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_enterExitCompartment("613Bh", kObjectCompartmentH);
+ break;
+
+ case kAction123852928:
+ getEntities()->exitCompartment(kEntityIvo, kObjectCompartmentH, true);
+
+ setCallback(2);
+ setup_enterExitCompartment("613Dh", kObjectCompartmentH);
+ break;
+
+ case kAction221683008:
+ getSavePoints()->push(kEntityIvo, kEntityCoudert, kAction123199584);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Ivo, function17)
+ if (savepoint.action == kActionDefault) {
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getEntities()->clearSequences(kEntityIvo);
+ getObjects()->update(kObjectCompartmentH, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Ivo, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK(kTime1777500, params->param1, setup_function19);
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityIvo);
+
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObjectCompartmentH, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject47, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Ivo, function19)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_enterExitCompartment("613FH", kObjectCompartmentH);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ if (getData()->entityPosition < kPosition_2087)
+ getData()->entityPosition = kPosition_2088;
+
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityIvo, kEntitySalko, kAction136184016);
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(4);
+ setup_draw("809US");
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_sitAtTableWithSalko();
+ break;
+
+ case 5:
+ getData()->location = kLocationInsideCompartment;
+ setup_function20();
+ break;
+ }
+ break;
+
+ case kAction102675536:
+ setCallback(3);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Ivo, function20)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime1809000 && params->param1) {
+ if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_leaveTableWithSalko();
+ }
+ }
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityIvo, kEntityServers1, kAction189688608);
+ getEntities()->drawSequenceLeft(kEntityIvo, "023B");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityIvo, kEntityServers1, kAction101106391);
+ getEntities()->drawSequenceLeft(kEntityIvo, "023B");
+ params->param1 = 1;
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function11();
+ break;
+
+ case 3:
+ getSavePoints()->push(kEntityIvo, kEntityServers1, kAction236237423);
+ setup_function21();
+ break;
+ }
+ break;
+
+ case kAction123712592:
+ getEntities()->drawSequenceLeft(kEntityIvo, "023C2");
+
+ setCallback(1);
+ setup_updateFromTime(450);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Ivo, function21)
+ if (savepoint.action == kActionDefault) {
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getObjects()->update(kObjectCompartmentH, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Ivo, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityIvo);
+
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Ivo, chapter3Handler)
+ if (savepoint.action == kActionDefault)
+ getObjects()->update(kObjectCompartmentH, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Ivo, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, Ivo, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime2361600 && getEntities()->isSomebodyInsideRestaurantOrSalon()) {
+ getData()->location = kLocationOutsideCompartment;
+ setup_function26();
+ }
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityIvo, kEntityTables2, kAction136455232);
+ getEntities()->drawSequenceLeft(kEntityIvo, "023B");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(26, Ivo, function26)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_leaveTableWithSalko();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function11();
+ break;
+
+ case 2:
+ setup_function27();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(27, Ivo, function27)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentH, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+
+ if (getData()->entityPosition < kPosition_2087)
+ getData()->entityPosition = kPosition_2088;
+
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityIvo);
+ setup_function28();
+ break;
+
+ case 3:
+ getEntities()->drawSequenceLeft(kEntityIvo, "613Ch");
+ getEntities()->enterCompartment(kEntityIvo, kObjectCompartmentH, true);
+ getSavePoints()->push(kEntityIvo, kEntityCoudert, kAction88652208);
+ break;
+
+ case 4:
+ getEntities()->exitCompartment(kEntityIvo, kObjectCompartmentH, true);
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityIvo);
+ break;
+ }
+ break;
+
+ case kAction55996766:
+ setCallback(1);
+ setup_enterExitCompartment("613FH", kObjectCompartmentH);
+ break;
+
+ case kAction122865568:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(3);
+ setup_enterExitCompartment("613Bh", kObjectCompartmentH);
+ break;
+
+ case kAction123852928:
+ setCallback(4);
+ setup_enterExitCompartment("613Dh", kObjectCompartmentH);
+ break;
+
+ case kAction221683008:
+ getSavePoints()->push(kEntityIvo, kEntityCoudert, kAction123199584);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(28, Ivo, function28)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime2425500 && !params->param1) {
+ params->param1 = 1;
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_2740);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("613EH", kObjectCompartmentH);
+ break;
+
+ case 2:
+ setup_function29();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(29, Ivo, function29)
+ if (savepoint.action == kActionDefault) {
+ getEntities()->clearSequences(kEntityIvo);
+ getObjects()->update(kObjectCompartmentH, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->inventoryItem = kItemNone;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(30, Ivo, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityIvo);
+
+ getData()->entityPosition = kPosition_540;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarBaggageRear;
+ getData()->inventoryItem = kItemNone;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(31, Ivo, chapter5Handler)
+ if (savepoint.action == kActionProceedChapter5)
+ setup_fight();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(32, Ivo, fight)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->location = kLocationOutsideCompartment;
+ getData()->entityPosition = kPosition_540;
+ getData()->car = kCarBaggageRear;
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventCathIvoFight);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSound()->playSound(kEntityPlayer, "LIB090");
+ getAction()->playAnimation(kEventCathIvoFight);
+
+ setCallback(2);
+ setup_savegame(kSavegameTypeTime, kTimeNone);
+ break;
+
+ case 2:
+ params->param1 = getFight()->setup(kFightIvo);
+ if (params->param1) {
+ getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, true);
+ } else {
+ getScenes()->loadSceneFromPosition(kCarBaggageRear, 96);
+ setup_function33();
+ }
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(33, Ivo, function33)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getState()->time += 1800;
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeTime, kTimeNone);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ getObjects()->update(kObject94, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+
+ break;
+
+ case kAction135800432:
+ setup_function34();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(34, Ivo, function34)
+ if (savepoint.action == kActionDefault)
+ getEntities()->clearSequences(kEntityIvo);
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/ivo.h b/engines/lastexpress/entities/ivo.h
new file mode 100644
index 0000000000..65bf9de165
--- /dev/null
+++ b/engines/lastexpress/entities/ivo.h
@@ -0,0 +1,177 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_IVO_H
+#define LASTEXPRESS_IVO_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Ivo : public Entity {
+public:
+ Ivo(LastExpressEngine *engine);
+ ~Ivo() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Draws the entity
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(draw, const char* sequence)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param time The time to add
+ */
+ DECLARE_FUNCTION_1(updateFromTime, uint32 time)
+
+ /**
+ * Updates parameter 2 using ticks value
+ *
+ * @param ticks The number of ticks to add
+ */
+ DECLARE_FUNCTION_1(updateFromTicks, uint32 ticks)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ /**
+ * Process callback action when the entity direction is not kDirectionRight
+ */
+ DECLARE_FUNCTION(callbackActionOnDirection)
+
+ /**
+ * Plays sound
+ *
+ * @param savepoint The savepoint
+ * - the sound filename
+ */
+ DECLARE_FUNCTION_NOSETUP(playSound)
+
+ /**
+ * Process callback action when somebody is standing in the restaurant or salon.
+ */
+ DECLARE_FUNCTION(callbackActionRestaurantOrSalon)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ DECLARE_FUNCTION(function11)
+ DECLARE_FUNCTION(sitAtTableWithSalko)
+ DECLARE_FUNCTION(leaveTableWithSalko)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function16)
+ DECLARE_FUNCTION(function17)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ DECLARE_FUNCTION(function19)
+ DECLARE_FUNCTION(function20)
+ DECLARE_FUNCTION(function21)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ DECLARE_FUNCTION(function26)
+ DECLARE_FUNCTION(function27)
+ DECLARE_FUNCTION(function28)
+ DECLARE_FUNCTION(function29)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_FUNCTION(fight)
+ DECLARE_FUNCTION(function33)
+ DECLARE_FUNCTION(function34)
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_IVO_H
diff --git a/engines/lastexpress/entities/kahina.cpp b/engines/lastexpress/entities/kahina.cpp
new file mode 100644
index 0000000000..b10b60476b
--- /dev/null
+++ b/engines/lastexpress/entities/kahina.cpp
@@ -0,0 +1,944 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/kahina.h"
+
+#include "lastexpress/game/action.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"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+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, function6);
+ ADD_CALLBACK_FUNCTION(Kahina, updateEntity2);
+ ADD_CALLBACK_FUNCTION(Kahina, updateEntity);
+ ADD_CALLBACK_FUNCTION(Kahina, enterExitCompartment);
+ ADD_CALLBACK_FUNCTION(Kahina, chapter1);
+ ADD_CALLBACK_FUNCTION(Kahina, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Kahina, function12);
+ ADD_CALLBACK_FUNCTION(Kahina, function13);
+ ADD_CALLBACK_FUNCTION(Kahina, function14);
+ ADD_CALLBACK_FUNCTION(Kahina, function15);
+ ADD_CALLBACK_FUNCTION(Kahina, chapter2);
+ ADD_CALLBACK_FUNCTION(Kahina, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Kahina, chapter3);
+ ADD_CALLBACK_FUNCTION(Kahina, function19);
+ ADD_CALLBACK_FUNCTION(Kahina, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Kahina, function21);
+ ADD_CALLBACK_FUNCTION(Kahina, function22);
+ ADD_CALLBACK_FUNCTION(Kahina, function23);
+ ADD_CALLBACK_FUNCTION(Kahina, function24);
+ ADD_CALLBACK_FUNCTION(Kahina, function25);
+ ADD_CALLBACK_FUNCTION(Kahina, function26);
+ ADD_CALLBACK_FUNCTION(Kahina, function27);
+ ADD_CALLBACK_FUNCTION(Kahina, chapter4);
+ ADD_CALLBACK_FUNCTION(Kahina, chapter5);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Kahina, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(2, Kahina, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(3, Kahina, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(4, Kahina, updateFromTime, uint32)
+ if (savepoint.action == kAction137503360) {
+ ENTITY_PARAM(0, 2) = 1;
+ CALLBACK_ACTION();
+ }
+
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(5, Kahina, updateFromTicks)
+ Entity::updateFromTicks(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(6, Kahina, function6, TimeValue)
+ error("Kahina: callback function 6 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(7 ,Kahina, updateEntity2, CarIndex, EntityPosition)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->updateEntity(_entityIndex, (CarIndex)params->param1, (EntityPosition)params->param2))
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ if (getEntities()->updateEntity(_entityIndex, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ CALLBACK_ACTION();
+ } else if (getEntities()->isDistanceBetweenEntities(kEntityKahina, kEntityPlayer, 1000)
+ && !getEntities()->isInGreenCarEntrance(kEntityPlayer)
+ && !getEntities()->isInsideCompartments(kEntityPlayer)
+ && !getEntities()->checkFields10(kEntityPlayer)) {
+
+ if (getData()->car == kCarGreenSleeping || getData()->car == kCarRedSleeping) {
+ ENTITY_PARAM(0, 1) = 1;
+ CALLBACK_ACTION();
+ }
+ }
+ break;
+
+ case kAction137503360:
+ ENTITY_PARAM(0, 2) = 1;
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(8, Kahina, updateEntity, CarIndex, EntityPosition)
+ if (savepoint.action == kActionExcuseMeCath) {
+ if (getEvent(kEventKronosConversation) || getEvent(kEventKronosConversationFirebird)) {
+ getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1019" : "CAT1019A");
+ } else {
+ getSound()->excuseMeCath();
+ }
+ return;
+ }
+
+ Entity::updateEntity(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(9, Kahina, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(10, Kahina, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentKronos, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ getData()->entityPosition = kPosition_5000;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarKronos;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Kahina, chapter1Handler)
+ if (savepoint.action != kActionNone)
+ return;
+
+ if (getProgress().jacket != kJacketOriginal)
+ TIME_CHECK_SAVEPOINT(kTime1107000, params->param1, kEntityKahina, kEntityMertens, kAction238732837);
+
+ if (getProgress().eventMertensKronosInvitation)
+ setup_function12();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Kahina, function12)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK(kTime1485000, params->param2, setup_function13);
+ break;
+
+ case kActionKnock:
+ getSound()->playSound(kEntityPlayer, "LIB012");
+ // Fallback to next action
+
+ case kActionOpenDoor:
+ if (!getEvent(kEventKronosGoingToInvitation)) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventKronosGoingToInvitation);
+ break;
+ }
+
+ if (savepoint.action == kActionOpenDoor)
+ getSound()->playSound(kEntityPlayer, "LIB014");
+
+ getScenes()->loadSceneFromPosition(kCarKronos, 80);
+ getSavePoints()->push(kEntityKahina, kEntityKronos, kAction171849314);
+ params->param1 = 1;
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentKronos, kEntityKahina, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventKronosGoingToInvitation);
+ getScenes()->loadSceneFromPosition(kCarKronos, 80);
+ getSavePoints()->push(kEntityKahina, kEntityKronos, kAction171849314);
+ params->param1 = 1;
+ }
+ break;
+
+ case kAction137685712:
+ setup_function13();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Kahina, function13)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getProgress().field_14 || getState()->time >= kTime1201500 || params->param2 == kTimeInvalid || params->param1 >= getState()->time)
+ break;
+
+ if (getState()->time <= kTime1197000) {
+ if (!getEntities()->isPlayerInCar(kCarGreenSleeping) || !params->param2) {
+ params->param2 = getState()->time;
+
+ if (!getState()->time)
+ goto label_callback;
+ }
+
+ if (params->param2 >= getState()->time)
+ break;
+ }
+
+ params->param2 = kTimeInvalid;
+
+label_callback:
+ setCallback(1);
+ setup_function15();
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarKronos;
+ getData()->entityPosition = kPosition_5000;
+ getData()->location = kLocationOutsideCompartment;
+
+ getObjects()->update(kObjectCompartmentKronos, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ params->param1 = getState()->time + 1800;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Kahina, function14)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ getEntities()->exitCompartment(kEntityKahina, kObjectCompartmentF);
+ CALLBACK_ACTION();
+ break;
+
+ case kAction4:
+ getEntities()->exitCompartment(kEntityKahina, kObjectCompartmentF);
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(kEntityKahina, "616Cf");
+ getEntities()->enterCompartment(kEntityKahina, kObjectCompartmentF);
+ getSavePoints()->push(kEntityKahina, kEntityMax, kAction158007856);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Kahina, function15)
+ error("Kahina: callback function 15 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Kahina, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter2Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityKahina);
+
+ getData()->entityPosition = kPosition_6000;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarKronos;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObjectCompartmentKronos, kEntityKahina, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Kahina, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1) {
+ UPDATE_PARAM_PROC(params->param2, getState()->time, 9000)
+ params->param1 = 1;
+ params->param2 = 0;
+ UPDATE_PARAM_PROC_END
+ }
+
+ if (getEvent(kEventKahinaAskSpeakFirebird) && getEvent(kEventKronosConversationFirebird) && getEntities()->isInsideTrainCar(kEntityPlayer, kCarKronos)) {
+ UPDATE_PARAM_PROC(params->param3, getState()->time, 900)
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventKronosConversationFirebird);
+ break;
+ UPDATE_PARAM_PROC_END
+ }
+
+label_callback_3:
+ if (getState()->time > kTime1845000 && getEvent(kEventKronosConversationFirebird) && getEntities()->isInKronosSalon(kEntityPlayer)) {
+ getObjects()->update(kObjectCompartmentKronos, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getScenes()->loadSceneFromPosition(kCarKronos, 87);
+ }
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ if (getEvent(kEventKronosConversationFirebird))
+ break;
+
+ if (getEvent(kEventKahinaAskSpeakFirebird)) {
+ if (getSound()->isBuffered(kEntityKahina))
+ getSound()->processEntry(kEntityKahina);
+
+ if (savepoint.action == kActionKnock)
+ getSound()->playSound(kEntityPlayer, "LIB012");
+
+ setCallback(4);
+ setup_savegame(kSavegameTypeEvent, kEventKronosConversationFirebird);
+ break;
+ }
+
+ if (getEvent(kEventMilosCompartmentVisitAugust) || getEvent(kEventTatianaGivePoem) || getEvent(kEventTatianaBreakfastGivePoem)) {
+ if (savepoint.action == kActionKnock)
+ getSound()->playSound(kEntityPlayer, "LIB012");
+
+ setCallback(7);
+ setup_savegame(kSavegameTypeEvent, kEventKahinaAskSpeakFirebird);
+ break;
+ }
+
+ if (params->param1) {
+ if (savepoint.action == kActionKnock)
+ getSound()->playSound(kEntityPlayer, "LIB012");
+
+ getAction()->playAnimation(kEventKahinaAskSpeak);
+ getScenes()->processScene();
+
+ getObjects()->update(kObjectCompartmentKronos, kEntityKahina, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(8);
+ setup_playSound("KRO3003");
+ } else {
+ getObjects()->update(kObjectCompartmentKronos, kEntityKahina, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(savepoint.action == kActionKnock ? 9 : 10);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ }
+ break;
+
+ case kActionDefault:
+ params->param1 = 1;
+ getObjects()->update(kObjectCompartmentKronos, kEntityKahina, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 4:
+ getAction()->playAnimation(kEventKronosConversationFirebird);
+ getObjects()->update(kObjectCompartmentKronos, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getScenes()->loadSceneFromPosition(kCarKronos, 80, 1);
+
+ setCallback(getCallback() == 1 ? 2 : 5);
+ setup_updateFromTime(900);
+ break;
+
+ case 2:
+ case 5:
+ setCallback(getCallback() == 2 ? 3 : 6);
+ setup_playSound("KRO3005");
+ break;
+
+ case 3:
+ goto label_callback_3;
+
+ case 7:
+ getAction()->playAnimation(kEventKahinaAskSpeakFirebird);
+ getScenes()->loadSceneFromPosition(kCarKronos, 81);
+ getSound()->playSound(kEntityKahina, "KRO3004");
+ break;
+
+ case 8:
+ case 9:
+ case 10:
+ getObjects()->update(kObjectCompartmentKronos, kEntityKahina, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ if (getCallback() == 8)
+ params->param1 = 0;
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Kahina, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityKahina);
+
+ getData()->entityPosition = kPosition_5000;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarKronos;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(19, Kahina, function19, CarIndex, EntityPosition)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEvent(kEventAnnaBaggageArgument))
+ RESET_ENTITY_STATE(kEntityKahina, Kahina, setup_function22);
+
+ if (getEntities()->updateEntity(kEntityKahina, (CarIndex)params->param1, (EntityPosition)params->param2))
+ CALLBACK_ACTION();
+ break;
+
+ case kActionExcuseMeCath:
+ if (getEvent(kEventKronosConversation) || getEvent(kEventKronosConversationFirebird))
+ getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1019" : "CAT1019A");
+ else
+ getSound()->excuseMeCath();
+ break;
+
+ case kActionExcuseMe:
+ getSound()->excuseMe(kEntityKahina);
+ break;
+
+ case kActionDefault:
+ if (getEntities()->updateEntity(kEntityKahina, (CarIndex)params->param1, (EntityPosition)params->param2))
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Kahina, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEvent(kEventKronosVisit))
+ getObjects()->update(kObjectCompartmentKronos, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ if (getEntities()->isInKronosSanctum(kEntityPlayer)) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventKahinaPunchSuite4);
+ break;
+ }
+
+label_callback_1:
+ if (getState()->time > kTime2079000 && !params->param2) {
+ params->param2 = 1;
+
+ if (getEvent(kEventKahinaAskSpeakFirebird)
+ && !getEvent(kEventKronosConversationFirebird)
+ && getEntities()->isInsideTrainCar(kEntityPlayer, kCarKronos)) {
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventKronosConversationFirebird);
+ break;
+ }
+
+label_callback_2:
+ if (getEntities()->isInKronosSalon(kEntityPlayer))
+ getScenes()->loadSceneFromPosition(kCarKronos, 87);
+
+ setup_function21();
+ break;
+ }
+
+ if (!params->param1) {
+ UPDATE_PARAM_PROC(params->param3, getState()->time, 9000)
+ params->param1 = 1;
+ params->param3 = 0;
+ UPDATE_PARAM_PROC_END
+ }
+
+ if (getEvent(kEventKahinaAskSpeakFirebird)
+ && !getEvent(kEventKronosConversationFirebird)
+ && getEntities()->isInsideTrainCar(kEntityPlayer, kCarKronos)) {
+ UPDATE_PARAM(params->param4, getState()->time, 900);
+
+ setCallback(3);
+ setup_savegame(kSavegameTypeEvent, kEventKronosConversationFirebird);
+ }
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ if (!getEvent(kEventKronosConversationFirebird)) {
+
+ if (getEvent(kEventKahinaAskSpeakFirebird)) {
+ if (savepoint.action == kActionKnock)
+ getSound()->playSound(kEntityPlayer, "LIB012");
+
+ setCallback(6);
+ setup_savegame(kSavegameTypeEvent, kEventKronosConversationFirebird);
+ break;
+ }
+
+ if (getEvent(kEventMilosCompartmentVisitAugust) || getEvent(kEventTatianaGivePoem) || getEvent(kEventTatianaBreakfastGivePoem)) {
+ if (savepoint.action == kActionKnock)
+ getSound()->playSound(kEntityPlayer, "LIB012");
+
+ setCallback(9);
+ setup_savegame(kSavegameTypeEvent, kEventKahinaAskSpeakFirebird);
+ break;
+ }
+
+ if (params->param1) {
+ if (savepoint.action == kActionKnock)
+ getSound()->playSound(kEntityPlayer, "LIB012");
+
+ getAction()->playAnimation(kEventKahinaAskSpeak);
+ getScenes()->processScene();
+ getObjects()->update(kObjectCompartmentKronos, kEntityKahina, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(10);
+ setup_playSound("KRO3003");
+ break;
+ }
+
+ getObjects()->update(kObjectCompartmentKronos, kEntityKahina, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(savepoint.action == kActionKnock ? 11 : 12);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ }
+ break;
+
+ case kActionDefault:
+ if (getEvent(kEventKronosConversationFirebird)) {
+ getObjects()->update(kObjectCompartmentKronos, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ } else {
+ getObjects()->update(kObjectCompartmentKronos, kEntityKahina, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ params->param1 = 1;
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventKahinaPunchSuite4);
+ getLogic()->gameOver(kSavegameTypeEvent2, kEventCathJumpDownCeiling, kSceneNone, false);
+ goto label_callback_1;
+
+ case 2:
+ getAction()->playAnimation(kEventKronosConversationFirebird);
+ getScenes()->loadSceneFromPosition(kCarKronos, 87);
+ goto label_callback_2;
+
+ case 3:
+ getAction()->playAnimation(kEventKronosConversationFirebird);
+ getObjects()->update(kObjectCompartmentKronos, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getScenes()->loadSceneFromPosition(kCarKronos, 80, 1);
+
+ setCallback(4);
+ setup_updateFromTime(900);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_playSound("KRO3005");
+ break;
+
+ case 6:
+ getAction()->playAnimation(kEventKronosConversationFirebird);
+ getObjects()->update(kObjectCompartmentKronos, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getScenes()->loadSceneFromPosition(kCarKronos, 80, 1);
+
+ setCallback(7);
+ setup_updateFromTime(900);
+ break;
+
+ case 7:
+ setCallback(8);
+ setup_playSound("KRO3005");
+ break;
+
+ case 9:
+ getAction()->playAnimation(kEventKahinaAskSpeakFirebird);
+ getScenes()->loadSceneFromPosition(kCarKronos, 81);
+ getSound()->playSound(kEntityKahina, "KRO3004");
+ break;
+
+ case 10:
+ params->param1 = 0;
+ // Fallback to next case
+
+ case 11:
+ case 12:
+ getObjects()->update(kObjectCompartmentKronos, kEntityKahina, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Kahina, function21)
+ error("Kahina: callback function 21 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Kahina, function22)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1) {
+ ObjectLocation location = getInventory()->get(kItemFirebird)->location;
+
+ if (ENTITY_PARAM(0, 3) || location == kObjectLocation3 || location == kObjectLocation7) {
+ setCallback(1);
+ setup_function25();
+ } else if (location == kObjectLocation2 || location == kObjectLocation1) {
+ setCallback(2);
+ setup_function26();
+ }
+ }
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarKronos;
+ getData()->entityPosition = kPosition_5000;
+ getData()->location = kLocationOutsideCompartment;
+ break;
+
+ case kActionDrawScene:
+ if (getData()->car > kCarGreenSleeping || (getData()->car == kCarGreenSleeping && getData()->entityPosition > kPosition_2740))
+ params->param1 = 1;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Kahina, function23)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getSound()->playSound(kEntityPlayer, "LIB014", getSound()->getSoundFlag(kEntityKahina));
+ getSound()->playSound(kEntityPlayer, "LIB015", getSound()->getSoundFlag(kEntityKahina), 15);
+
+ getEntities()->clearSequences(kEntityKahina);
+
+ getData()->car = kCarGreenSleeping;
+ getData()->entityPosition = kPosition_540;
+
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_4070);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (getEntities()->checkFields19(kEntityPlayer, kCarRedSleeping, kPosition_4455) || getEntities()->isOutsideAnnaWindow()) {
+ setCallback(5);
+ setup_updateEntity(kCarRedSleeping, kPosition_9460);
+ break;
+ } else {
+ setCallback(2);
+ setup_enterExitCompartment("616Cf", kObjectCompartmentF);
+ }
+ break;
+
+ case 2:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityKahina);
+
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, getObjects()->get(kObjectCompartmentF).location, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject53, kEntityPlayer, getObjects()->get(kObject53).location, kCursorNormal, kCursorNormal);
+
+ setCallback(3);
+ setup_updateFromTime(900);
+ break;
+
+ case 3:
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, getObjects()->get(kObjectCompartmentF).location, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityPlayer, getObjects()->get(kObject53).location, kCursorHandKnock, kCursorHand);
+
+ setCallback(4);
+ setup_enterExitCompartment("616Df", kObjectCompartmentF);
+ break;
+
+ case 4:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(5);
+ setup_updateEntity(kCarRedSleeping, kPosition_9460);
+ break;
+
+ case 5:
+ getEntities()->clearSequences(kEntityKahina);
+
+ setCallback(6);
+ setup_updateFromTime(900);
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_updateEntity(kCarKronos, kPosition_9270);
+ break;
+
+ case 7:
+ getEntities()->clearSequences(kEntityKahina);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Kahina, function24)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1 && getEntities()->updateEntity(kEntityKahina, (CarIndex)params->param2, (EntityPosition)params->param3)) {
+ getEntities()->clearSequences(kEntityKahina);
+ params->param1 = 0;
+ }
+ break;
+
+ case kActionEndSound:
+ if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarKronos))
+ getSavePoints()->push(kEntityKahina, kEntityKronos, kActionOpenDoor);
+ else
+ setup_function27();
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function6(kTime2241000);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (ENTITY_PARAM(0, 2)) {
+ getEntities()->clearSequences(kEntityKahina);
+ if (getSound()->isBuffered(kEntityKahina))
+ getSound()->processEntry(kEntityKahina);
+
+ getProgress().field_44 = 0;
+
+ setup_function22();
+ } else if (ENTITY_PARAM(0, 1)) {
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventKahinaGunYellow);
+ } else {
+ setup_function27();
+ }
+ break;
+
+ case 2:
+ if (getEntityData(kEntityPlayer)->entityPosition >= getData()->entityPosition)
+ getAction()->playAnimation(getData()->car < kCarRedSleeping ? kEventKahinaGunYellow : kEventKahinaGunBlue);
+ else
+ getAction()->playAnimation(kEventKahinaGun);
+
+ getEntities()->updateEntity(kEntityKahina, kCarKronos, kPosition_9270);
+ getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + 750));
+ getSavePoints()->push(kEntityKahina, kEntityKronos, kAction235599361);
+ getSound()->playSound(kEntityKahina, "MUS016", SoundManager::kFlagDefault);
+ getProgress().field_44 = 1;
+
+ params->param1 = true;
+ params->param2 = kCarKronos;
+ params->param3 = kPosition_9270;
+ break;
+ }
+ break;
+
+ case kAction137503360:
+ getEntities()->clearSequences(kEntityKahina);
+ if (getSound()->isBuffered(kEntityKahina))
+ getSound()->processEntry(kEntityKahina);
+
+ getProgress().field_44 = 0;
+
+ setup_function22();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, Kahina, function25)
+ error("Kahina: callback function 25 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(26, Kahina, function26)
+ error("Kahina: callback function 26 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(27, Kahina, function27)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isInGreenCarEntrance(kEntityPlayer))
+ params->param1 = kEventKahinaPunchCar;
+ else if (getEntities()->isPlayerInCar(kCarGreenSleeping))
+ params->param1 = kEventKahinaPunchBlue;
+ else if (getEntities()->isPlayerInCar(kCarRedSleeping))
+ params->param1 = kEventKahinaPunchYellow;
+ else if (getEntities()->isInSalon(kEntityPlayer))
+ params->param1 = kEventKahinaPunchSalon;
+ else if (getEntities()->isInRestaurant(kEntityPlayer))
+ params->param1 = kEventKahinaPunchRestaurant;
+ else if (getEntities()->isInKitchen(kEntityPlayer))
+ params->param1 = kEventKahinaPunchKitchen;
+ else if (getEntities()->isInBaggageCarEntrance(kEntityPlayer))
+ params->param1 = kEventKahinaPunchBaggageCarEntrance;
+ else if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarBaggage))
+ params->param1 = kEventKahinaPunchBaggageCar;
+
+ if (params->param1) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kSceneGameOverAlarm2);
+ }
+ break;
+
+ case kActionDefault:
+ getState()->timeDelta = 0;
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation((EventIndex)params->param1);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneNone, true);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(28, Kahina, chapter4)
+ if (savepoint.action == kActionDefault)
+ getEntities()->clearSequences(kEntityKahina);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(29, Kahina, chapter5)
+ if (savepoint.action == kActionDefault)
+ getEntities()->clearSequences(kEntityKahina);
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/kahina.h b/engines/lastexpress/entities/kahina.h
new file mode 100644
index 0000000000..1eba9c62d9
--- /dev/null
+++ b/engines/lastexpress/entities/kahina.h
@@ -0,0 +1,166 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_KAHINA_H
+#define LASTEXPRESS_KAHINA_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Kahina : public Entity {
+public:
+ Kahina(LastExpressEngine *engine);
+ ~Kahina() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param time The time to add
+ */
+ DECLARE_FUNCTION_1(updateFromTime, uint32 time)
+
+ /**
+ * Updates parameter 2 using ticks value
+ *
+ * @param savepoint The savepoint
+ * - ticks to add
+ */
+ DECLARE_FUNCTION_NOSETUP(updateFromTicks)
+
+ DECLARE_FUNCTION_1(function6, TimeValue timeValue)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity2, CarIndex car, EntityPosition entityPosition)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function12)
+ DECLARE_FUNCTION(function13)
+ DECLARE_FUNCTION(function14)
+ DECLARE_FUNCTION(function15)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Update the entity, handling excuse me events and resetting the entity state after the argument with Anna in the baggage car
+ *
+ * @param car The car index
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(function19, CarIndex car, EntityPosition entityPosition)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ DECLARE_FUNCTION(function21)
+ DECLARE_FUNCTION(function22)
+ DECLARE_FUNCTION(function23)
+ DECLARE_FUNCTION(function24)
+ DECLARE_FUNCTION(function25)
+ DECLARE_FUNCTION(function26)
+ DECLARE_FUNCTION(function27)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_KAHINA_H
diff --git a/engines/lastexpress/entities/kronos.cpp b/engines/lastexpress/entities/kronos.cpp
new file mode 100644
index 0000000000..f45f18bbd2
--- /dev/null
+++ b/engines/lastexpress/entities/kronos.cpp
@@ -0,0 +1,666 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/kronos.h"
+
+#include "lastexpress/entities/anna.h"
+#include "lastexpress/entities/august.h"
+#include "lastexpress/entities/rebecca.h"
+#include "lastexpress/entities/sophie.h"
+#include "lastexpress/entities/tatiana.h"
+
+#include "lastexpress/game/action.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"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+namespace LastExpress {
+
+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(Kronos, chapter1);
+ ADD_CALLBACK_FUNCTION(Kronos, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Kronos, function9);
+ ADD_CALLBACK_FUNCTION(Kronos, function10);
+ ADD_CALLBACK_FUNCTION(Kronos, function11);
+ ADD_CALLBACK_FUNCTION(Kronos, chapter2);
+ ADD_CALLBACK_FUNCTION(Kronos, chapter3);
+ ADD_CALLBACK_FUNCTION(Kronos, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Kronos, function15);
+ ADD_CALLBACK_FUNCTION(Kronos, function16);
+ ADD_CALLBACK_FUNCTION(Kronos, function17);
+ ADD_CALLBACK_FUNCTION(Kronos, function18);
+ ADD_CALLBACK_FUNCTION(Kronos, function19);
+ ADD_CALLBACK_FUNCTION(Kronos, function20);
+ ADD_CALLBACK_FUNCTION(Kronos, function21);
+ ADD_CALLBACK_FUNCTION(Kronos, function22);
+ ADD_CALLBACK_FUNCTION(Kronos, function23);
+ ADD_CALLBACK_FUNCTION(Kronos, chapter4);
+ ADD_CALLBACK_FUNCTION(Kronos, chapter5);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Kronos, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(2, Kronos, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(3, Kronos, updateEntity, CarIndex, EntityPosition)
+ Entity::updateEntity(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(4, Kronos, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(5, Kronos, updateFromTime)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(6, Kronos, updateFromTicks)
+ Entity::updateFromTicks(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(7, Kronos, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_6000;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarKronos;
+
+ getObjects()->update(kObjectCeiling, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(8, Kronos, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK(kTime1489500, params->param2, setup_function11);
+ break;
+
+ case kAction171849314:
+ params->param1 = 1;
+ break;
+
+ case kAction202621266:
+ setup_function9();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(9, Kronos, function9)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventKronosConversation);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventKronosConversation);
+ getScenes()->loadSceneFromPosition(kCarKronos, 87);
+ getSavePoints()->push(kEntityKronos, kEntityKahina, kAction137685712);
+ setup_function10();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(10, Kronos, function10)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK(kTime1489500, params->param1, setup_function11);
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_6000;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarKronos;
+
+ getEntities()->clearSequences(kEntityKronos);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Kronos, function11)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionEndSound:
+ params->param1++;
+ getSound()->playSound(kEntityKronos, (params->param1 & 1) ? "KRO1001" : "KRO1002");
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_7000;
+
+ if (!getSound()->isBuffered(kEntityKronos))
+ getSound()->playSound(kEntityKronos, "KRO1001");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Kronos, chapter2)
+ if (savepoint.action == kActionDefault)
+ getEntities()->clearSequences(kEntityKronos);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Kronos, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityKronos);
+
+ getData()->entityPosition = kPosition_6000;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarKronos;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObjectCeiling, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Kronos, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime1993500 && !params->param1 && !params->param2 && !params->param3)
+ setup_function15();
+ break;
+
+ case kAction157159392:
+ switch (savepoint.entity2) {
+ case kEntityAnna:
+ params->param1 = 1;
+ break;
+
+ case kEntityTatiana:
+ params->param2 = 1;
+ break;
+
+ case kEntityAbbot:
+ params->param3 = 1;
+ break;
+
+ default:
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Kronos, function15)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1 && !getEntities()->isInSalon(kEntityBoutarel)) {
+ UPDATE_PARAM_PROC(params->param2, getState()->timeTicks, 75)
+ setup_function16();
+ break;
+ UPDATE_PARAM_PROC_END
+ }
+
+ if (params->param3 != kTimeInvalid && getState()->time > kTime2002500) {
+ if (getState()->time <= kTime2052000) {
+ if (!getEntities()->isInSalon(kEntityPlayer) || getEntities()->isInSalon(kEntityPlayer) || !params->param3)
+ params->param3 = getState()->time + 900;
+
+ if (params->param3 >= getState()->time)
+ break;
+ }
+
+ params->param3 = kTimeInvalid;
+
+ if (getEntities()->isInSalon(kEntityPlayer)) {
+ setup_function16();
+ } else {
+ getSavePoints()->push(kEntityKronos, kEntityAnna, kAction101169422);
+ getSavePoints()->push(kEntityKronos, kEntityTatiana, kAction101169422);
+ getSavePoints()->push(kEntityKronos, kEntityAbbot, kAction101169422);
+
+ setup_function18();
+ }
+ }
+ break;
+
+ case kActionDefault:
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 60)
+ || getEntities()->isPlayerPosition(kCarRestaurant, 59)
+ || getEntities()->isPlayerPosition(kCarRestaurant, 83)
+ || getEntities()->isPlayerPosition(kCarRestaurant, 81)
+ || getEntities()->isPlayerPosition(kCarRestaurant, 87))
+ params->param1 = 1;
+ break;
+
+ case kActionDrawScene:
+ if (params->param1 && getEntities()->isPlayerPosition(kCarRestaurant, 51) && !getEntities()->isInSalon(kEntityBoutarel))
+ setup_function16();
+ else
+ params->param1 = getEntities()->isPlayerPosition(kCarRestaurant, 60)
+ || getEntities()->isPlayerPosition(kCarRestaurant, 59)
+ || getEntities()->isPlayerPosition(kCarRestaurant, 83)
+ || getEntities()->isPlayerPosition(kCarRestaurant, 81)
+ || getEntities()->isPlayerPosition(kCarRestaurant, 87);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16 ,Kronos, function16)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventKronosVisit);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventKronosVisit);
+ getSavePoints()->push(kEntityKronos, kEntityAnna, kAction101169422);
+ getSavePoints()->push(kEntityKronos, kEntityTatiana, kAction101169422);
+ getSavePoints()->push(kEntityKronos, kEntityAbbot, kAction101169422);
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 60);
+
+ setup_function17();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Kronos, function17)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_7500;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_9270);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function18();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Kronos, function18)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime2079000 && !params->param2) {
+ getObjects()->updateLocation2(kObjectCompartmentKronos, kObjectLocation3);
+ getObjects()->update(kObjectCompartmentKronos, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ params->param1 = 1;
+ params->param2 = 1;
+ }
+
+ TIME_CHECK(kTime2106000, params->param3, setup_function19)
+ else {
+ if (params->param1 && getEntities()->isInKronosSanctum(kEntityPlayer)) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventKahinaPunchSuite4);
+ }
+ }
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_6000;
+ getData()->car = kCarKronos;
+ getData()->location = kLocationOutsideCompartment;
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventKahinaPunchSuite4);
+ getLogic()->gameOver(kSavegameTypeEvent2, kEventCathJumpDownCeiling, kSceneNone, true);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Kronos, function19)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentKronos, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
+ break;
+
+ case kActionDrawScene:
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventKahinaPunchSuite4);
+ getLogic()->gameOver(kSavegameTypeEvent2, kEventCathJumpDownCeiling, kSceneNone, true);
+ break;
+
+ case 2:
+ getAction()->playAnimation(kEventConcertStart);
+ getSound()->setupEntry(SoundManager::kSoundType7, kEntityKronos);
+ getScenes()->loadSceneFromPosition(kCarKronos, 83);
+
+ RESET_ENTITY_STATE(kEntityRebecca, Rebecca, setup_function39);
+ RESET_ENTITY_STATE(kEntitySophie, Sophie, setup_chaptersHandler);
+ RESET_ENTITY_STATE(kEntityAugust, August, setup_function50);
+ RESET_ENTITY_STATE(kEntityAnna, Anna, setup_function56);
+ RESET_ENTITY_STATE(kEntityTatiana, Tatiana, setup_function35);
+
+ setup_function20();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Kronos, function20)
+ error("Kronos: callback function 20 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Kronos, function21)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isInKronosSanctum(kEntityPlayer)) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventKahinaWrongDoor);
+ }
+ break;
+
+ case kActionDefault:
+ getProgress().field_40 = 0;
+ getObjects()->update(kObjectCompartmentKronos, kEntityPlayer, kObjectLocation3, kCursorNormal, kCursorNormal);
+ getSavePoints()->push(kEntityKronos, kEntityRebecca, kAction191668032);
+ if (!getEvent(kEventConcertLeaveWithBriefcase))
+ setup_function22();
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventKahinaWrongDoor);
+
+ if (getInventory()->hasItem(kItemBriefcase))
+ getInventory()->removeItem(kItemBriefcase);
+
+ getSound()->playSound(kEntityPlayer, "BUMP");
+
+ getScenes()->loadSceneFromPosition(kCarKronos, 81);
+
+ getSound()->playSound(kEntityPlayer, "LIB015");
+ }
+ break;
+
+ case kAction235599361:
+ setup_function22();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Kronos, function22)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getProgress().field_44) {
+ setCallback(5);
+ setup_savegame(kSavegameTypeEvent, kEventKahinaPunchBaggageCarEntrance);
+ } else {
+ setCallback(6);
+ setup_savegame(kSavegameTypeEvent, kEventKahinaWrongDoor);
+ }
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ if (!getSound()->isBuffered(savepoint.action == kActionKnock ? "LIB012" : "LIB013", true))
+ getSound()->playSound(kEntityPlayer, savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+
+ if (getEvent(kEventConcertLeaveWithBriefcase))
+ getSavePoints()->call(kEntityKronos, kEntityKahina, kAction137503360);
+
+ if (getInventory()->hasItem(kItemBriefcase)) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventKronosReturnBriefcase);
+ break;
+ }
+
+ if (getInventory()->hasItem(kItemFirebird) && getEvent(kEventConcertLeaveWithBriefcase)) {
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventKronosBringEggCeiling);
+ break;
+ }
+
+ if (getInventory()->hasItem(kItemFirebird)) {
+ setCallback(3);
+ setup_savegame(kSavegameTypeEvent, kEventKronosBringEggCeiling);
+ break;
+ }
+
+ if (getEvent(kEventConcertLeaveWithBriefcase)) {
+ setCallback(4);
+ setup_savegame(kSavegameTypeEvent, kEventKronosBringNothing);
+ break;
+ }
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentKronos, kEntityKronos, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventKronosReturnBriefcase);
+ getScenes()->loadSceneFromPosition(kCarKronos, 87);
+ getInventory()->removeItem(kItemFirebird);
+ getInventory()->removeItem(kItemScarf);
+
+ setup_function23();
+ break;
+
+ case 2:
+ getAction()->playAnimation(kEventKronosBringEggCeiling);
+ getScenes()->loadSceneFromPosition(kCarKronos, 87);
+ getInventory()->removeItem(kItemFirebird);
+ getInventory()->get(kItemFirebird)->location = kObjectLocation5;
+
+ setup_function23();
+ break;
+
+ case 3:
+ getInventory()->removeItem(kItemFirebird);
+ getInventory()->get(kItemFirebird)->location = kObjectLocation5;
+ getAction()->playAnimation(kEventKronosBringEgg);
+ getScenes()->loadSceneFromPosition(kCarKronos, 87);
+ getInventory()->addItem(kItemBriefcase);
+ setup_function23();
+ break;
+
+ case 4:
+ getAction()->playAnimation(kEventKronosBringNothing);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneNone, true);
+ break;
+
+ case 5:
+ getAction()->playAnimation(kEventKahinaPunchSuite4);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneNone, true);
+ break;
+
+ case 6:
+ getAction()->playAnimation(kEventKahinaWrongDoor);
+ if (getInventory()->hasItem(kItemBriefcase))
+ getInventory()->removeItem(kItemBriefcase);
+
+ getSound()->playSound(kEntityPlayer, "BUMP");
+ getScenes()->loadSceneFromPosition(kCarKronos, 81);
+ getSound()->playSound(kEntityPlayer, "LIB015");
+ break;
+ }
+ break;
+
+ case kAction138085344:
+ setup_function23();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Kronos, function23)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isInKronosSanctum(kEntityPlayer)) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventKahinaWrongDoor);
+ }
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentKronos, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventKahinaWrongDoor);
+
+ if (getInventory()->hasItem(kItemBriefcase))
+ getInventory()->removeItem(kItemBriefcase);
+
+ getSound()->playSound(kEntityPlayer, "BUMP");
+
+ getScenes()->loadSceneFromPosition(kCarKronos, 81);
+
+ getSound()->playSound(kEntityPlayer, "LIB015");
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Kronos, chapter4)
+ if (savepoint.action == kActionDefault)
+ getEntities()->clearSequences(kEntityKronos);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, Kronos, chapter5)
+ if (savepoint.action == kActionDefault)
+ getEntities()->clearSequences(kEntityKronos);
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/kronos.h b/engines/lastexpress/entities/kronos.h
new file mode 100644
index 0000000000..5d8efbd4c2
--- /dev/null
+++ b/engines/lastexpress/entities/kronos.h
@@ -0,0 +1,138 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_KRONOS_H
+#define LASTEXPRESS_KRONOS_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Kronos : public Entity {
+public:
+ Kronos(LastExpressEngine *engine);
+ ~Kronos() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ /**
+ * Plays sound
+ *
+ * @param savepoint The savepoint
+ * - the sound filename
+ */
+ DECLARE_FUNCTION_NOSETUP(playSound)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param savepoint The savepoint
+ * - Time to add
+ */
+ DECLARE_FUNCTION_NOSETUP(updateFromTime)
+
+ /**
+ * Updates parameter 2 using ticks value
+ *
+ * @param savepoint The savepoint
+ * - ticks to add
+ */
+ DECLARE_FUNCTION_NOSETUP(updateFromTicks)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function9)
+ DECLARE_FUNCTION(function10)
+ DECLARE_FUNCTION(function11)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ DECLARE_FUNCTION(function15)
+ DECLARE_FUNCTION(function16)
+ DECLARE_FUNCTION(function17)
+ DECLARE_FUNCTION(function18)
+ DECLARE_FUNCTION(function19)
+ DECLARE_FUNCTION(function20)
+ DECLARE_FUNCTION(function21)
+ DECLARE_FUNCTION(function22)
+ DECLARE_FUNCTION(function23)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_KRONOS_H
diff --git a/engines/lastexpress/entities/mahmud.cpp b/engines/lastexpress/entities/mahmud.cpp
new file mode 100644
index 0000000000..0200f0b554
--- /dev/null
+++ b/engines/lastexpress/entities/mahmud.cpp
@@ -0,0 +1,839 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/data/scene.h"
+
+#include "lastexpress/entities/mahmud.h"
+
+#include "lastexpress/game/action.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"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+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(Mahmud, function11);
+ ADD_CALLBACK_FUNCTION(Mahmud, function12);
+ ADD_CALLBACK_FUNCTION(Mahmud, function13);
+ ADD_CALLBACK_FUNCTION(Mahmud, chaptersHandler);
+ ADD_CALLBACK_FUNCTION(Mahmud, chapter1);
+ ADD_CALLBACK_FUNCTION(Mahmud, resetChapter);
+ ADD_CALLBACK_FUNCTION(Mahmud, chapter2);
+ ADD_CALLBACK_FUNCTION(Mahmud, chapter3);
+ ADD_CALLBACK_FUNCTION(Mahmud, chapter4);
+ ADD_CALLBACK_FUNCTION(Mahmud, chapter5);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Mahmud, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(2, Mahmud, draw)
+ Entity::draw(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(3, Mahmud, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SIII(4, Mahmud, enterExitCompartment2, ObjectIndex, uint32, ObjectIndex)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param7, getState()->timeTicks, params->param5);
+
+ if (!getScenes()->checkPosition(kSceneNone, SceneManager::kCheckPositionLookingUp))
+ getScenes()->loadSceneFromObject((ObjectIndex)params->param6, true);
+ break;
+
+ case kActionExitCompartment:
+ getEntities()->exitCompartment(kEntityMahmud, (ObjectIndex)params->param4);
+
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(kEntityMahmud, (char *)&params->seq);
+ getEntities()->enterCompartment(kEntityMahmud, (ObjectIndex)params->param4);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(5, Mahmud, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(6, Mahmud, playSoundMertens)
+ Entity::playSound(savepoint, false, getSound()->getSoundFlag(kEntityMertens));
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(7, Mahmud, updateFromTime)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(8, Mahmud, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(9, Mahmud, updateEntity, CarIndex, EntityPosition)
+ if (savepoint.action == kActionExcuseMeCath) {
+ if (getInventory()->hasItem(kItemPassengerList))
+ getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1025" : "CAT1025Q");
+ else
+ getSound()->excuseMeCath();
+
+ return;
+ }
+
+ Entity::updateEntity(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(10, Mahmud, function10, ObjectIndex, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param6, getState()->time, 13500);
+
+ getObjects()->update(kObjectCompartment5, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment6, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment7, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment8, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ setCallback(2);
+ setup_enterExitCompartment("614Ed", kObjectCompartment4);
+ break;
+
+ case kActionEndSound:
+ case kActionDrawScene:
+ if (!getSound()->isBuffered(kEntityMahmud)) {
+ EntityPosition position = getEntityData(kEntityPlayer)->entityPosition;
+ if (position < kPosition_1500 || position >= kPosition_5790 || (position > kPosition_4455 && params->param5 != 5)) {
+ getObjects()->update(kObjectCompartment5, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment6, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment7, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment8, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ setCallback(3);
+ setup_enterExitCompartment("614Ed", kObjectCompartment4);
+ }
+ }
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ if (!getSound()->isBuffered((savepoint.action == kActionKnock) ? "LIB012" : "LIB013", true))
+ getSound()->playSound(kEntityPlayer, (savepoint.action == kActionKnock) ? "LIB012" : "LIB013");
+
+ params->param5 = savepoint.param.intValue;
+
+ if (!getSound()->isBuffered(kEntityMahmud)) {
+ params->param3++;
+
+ switch(params->param3) {
+ default:
+ params->param4 = 1;
+ break;
+
+ case 1:
+ getSound()->playSound(kEntityMahmud, "MAH1174");
+ break;
+
+ case 2:
+ getSound()->playSound(kEntityMahmud, "MAH1173B");
+ break;
+
+ case 3:
+ getSound()->playSound(kEntityMahmud, params->param2 ? "MAH1170E" : "MAH1173A");
+ break;
+ }
+ }
+
+ if (params->param4) {
+ if (getState()->time >= kTimeCityGalanta) {
+ params->param3 = 0;
+ } else {
+ getSound()->playSound(kEntityTrain, "LIB050", SoundManager::kFlagDefault);
+ getLogic()->gameOver(kSavegameTypeIndex, 0, (getProgress().chapter == kChapter1) ? kSceneGameOverPolice1 : kSceneGameOverPolice2, true);
+ }
+ break;
+ }
+
+ getAction()->handleOtherCompartment((ObjectIndex)savepoint.param.intValue, false, false);
+
+ switch (getScenes()->get(getState()->scene)->position) {
+ default:
+ break;
+
+ case 55:
+ getScenes()->loadSceneFromObject(kObjectCompartment5, true);
+ break;
+
+ case 56:
+ getScenes()->loadSceneFromObject(kObjectCompartment6, true);
+ break;
+
+ case 57:
+ getScenes()->loadSceneFromObject(kObjectCompartment7, true);
+ break;
+
+ case 58:
+ getScenes()->loadSceneFromObject(kObjectCompartment8, true);
+ break;
+ }
+ break;
+
+ case kActionDefault:
+ getSound()->playSound(kEntityMahmud, params->param2 ? "MAH1170A" : "MAH1173", SoundManager::kFlagInvalid, 45);
+ getProgress().field_C4 = 1;
+
+ setCallback(1);
+ setup_enterExitCompartment2("614Dd", kObjectCompartment4, 30, (ObjectIndex)params->param1);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartment5, kEntityMahmud, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment6, kEntityMahmud, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment7, kEntityMahmud, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment8, kEntityMahmud, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ getData()->location = kLocationOutsideCompartment;
+
+ getEntities()->drawSequenceLeft(kEntityMahmud, "614Md");
+ getEntities()->enterCompartment(kEntityMahmud, kObjectCompartment4, true);
+ break;
+
+ case 2:
+ case 3:
+ getEntities()->exitCompartment(kEntityMahmud, kObjectCompartment4, true);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMahmud);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Mahmud, function11)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor: {
+ getSound()->playSound(kEntityPlayer, (savepoint.action == kActionKnock ? "LIB012" : "LIB013"));
+
+ if (!getSound()->isBuffered(kEntityMahmud)) {
+ params->param1++;
+
+ getSound()->playSound(kEntityMahmud, (params->param1 == 1 ? "MAH1170E" : (params->param1 == 2 ? "MAH1173B" : "MAH1174")));
+ }
+
+ switch (getScenes()->get(getState()->scene)->position) {
+ default:
+ break;
+
+ case 55:
+ getScenes()->loadSceneFromObject(kObjectCompartment5, true);
+ break;
+
+ case 56:
+ getScenes()->loadSceneFromObject(kObjectCompartment6, true);
+ break;
+
+ case 57:
+ getScenes()->loadSceneFromObject(kObjectCompartment7, true);
+ break;
+
+ case 58:
+ getScenes()->loadSceneFromObject(kObjectCompartment8, true);
+ break;
+ }
+ break;
+ }
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityMahmud, kEntityMertens, kAction102227384);
+ setCallback(1);
+ setup_enterExitCompartment("614Ad", kObjectCompartment4);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ getObjects()->update(kObjectCompartment4, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getEntities()->drawSequenceLeft(kEntityMahmud, "614Kd");
+ getEntities()->enterCompartment(kEntityMahmud, kObjectCompartment4, true);
+
+ setCallback(2);
+ setup_playSound("MAH1170A");
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_playSoundMertens("MAH1170B");
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_playSound("MAH1170C");
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_playSoundMertens("MAH1170D");
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_playSound("MAH1170E");
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_playSoundMertens("MAH1170F");
+ break;
+
+ case 7:
+ setCallback(8);
+ setup_enterExitCompartment("614Ld", kObjectCompartment4);
+ break;
+
+ case 8:
+ getSavePoints()->push(kEntityMahmud, kEntityMertens, kAction156567128);
+ getEntities()->drawSequenceLeft(kEntityMahmud, "614Bd");
+ getEntities()->enterCompartment(kEntityMahmud, kObjectCompartment4, true);
+
+ setCallback(9);
+ setup_playSound("MAH1170G");
+ break;
+
+ case 9:
+ setCallback(10);
+ setup_playSoundMertens("MAH1170H");
+ break;
+
+ case 10:
+ getObjects()->update(kObjectCompartment5, kEntityMahmud, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment6, kEntityMahmud, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment7, kEntityMahmud, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment8, kEntityMahmud, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ break;
+
+ case 11:
+ getEntities()->exitCompartment(kEntityMahmud, kObjectCompartment4, true);
+ getData()->location = kLocationInsideCompartment;
+
+ getEntities()->clearSequences(kEntityMahmud);
+ getObjects()->update(kObjectCompartment4, kEntityMahmud, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction123852928:
+ if (getSound()->isBuffered(kEntityMahmud))
+ getSound()->processEntry(kEntityMahmud);
+
+ getObjects()->update(kObjectCompartment5, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment6, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment7, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment8, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ setCallback(11);
+ setup_enterExitCompartment("614Cd", kObjectCompartment4);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// TODO: factorize code between function12 & function13
+IMPLEMENT_FUNCTION(12, Mahmud, function12)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_enterExitCompartment("614Gd", kObjectCompartment4);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ getObjects()->update(kObjectCompartment4, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ setCallback(2);
+ setup_updateEntity(kCarGreenSleeping, kPosition_4070);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_enterExitCompartment("614Ff", kObjectCompartment6);
+ break;
+
+ case 3:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMahmud);
+
+ setCallback(4);
+ setup_playSound("Har1105");
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_enterExitCompartment("614Gf", kObjectCompartment6);
+ break;
+
+ case 5:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(6);
+ setup_updateEntity(kCarGreenSleeping, kPosition_5790);
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_enterExitCompartment("614Fd", kObjectCompartment4);
+ break;
+
+ case 7:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMahmud);
+
+ CALLBACK_ACTION();
+ break;
+
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Mahmud, function13)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_enterExitCompartment("614Gd", kObjectCompartment4);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ getObjects()->update(kObjectCompartment4, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ setCallback(2);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2740);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_enterExitCompartment("614Fh", kObjectCompartment8);
+ break;
+
+ case 3:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMahmud);
+
+ setCallback(4);
+ setup_playSound("Har1107");
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_enterExitCompartment("614Gh", kObjectCompartment8);
+ break;
+
+ case 5:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(6);
+ setup_updateEntity(kCarGreenSleeping, kPosition_5790);
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_enterExitCompartment("614Fd", kObjectCompartment4);
+ break;
+
+ case 7:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMahmud);
+
+ CALLBACK_ACTION();
+ break;
+
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Mahmud, chaptersHandler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (ENTITY_PARAM(0, 1)) {
+ params->param2 = 1;
+ getSavePoints()->push(kEntityMahmud, kEntityMertens, kAction204379649);
+ ENTITY_PARAM(0, 1) = 0;
+ }
+
+ if (!params->param2 && getProgress().chapter == kChapter1) {
+
+ TIME_CHECK_CALLBACK(kTime1098000, params->param6, 1, setup_function13);
+
+ if (!getSound()->isBuffered("HAR1104") && getState()->time > kTime1167300 && !params->param7) {
+ params->param7 = 1;
+
+ setCallback(2);
+ setup_function12();
+ break;
+ }
+ }
+
+ if (params->param5) {
+ UPDATE_PARAM(params->param8, getState()->timeTicks, 75);
+
+ params->param4 = 1;
+ params->param5 = 0;
+
+ getObjects()->update(kObjectCompartment4, kEntityMahmud, kObjectLocation3, kCursorNormal, kCursorNormal);
+ }
+
+ params->param8 = 0;
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ if (params->param5) {
+ getObjects()->update(kObjectCompartment4, kEntityMahmud, kObjectLocation3, kCursorNormal, kCursorNormal);
+
+ if (getProgress().jacket == kJacketBlood || getEvent(kEventMahmudWrongDoor) || getEvent(kEventMahmudWrongDoorOriginalJacket) || getEvent(kEventMahmudWrongDoorDay)) {
+ // Check if we have the passenger list
+ if (getInventory()->hasItem(kItemPassengerList)) {
+ setCallback(6);
+ setup_playSound(rnd(2) == 0 ? "CAT1501" : getSound()->wrongDoorCath());
+ } else {
+ setCallback(7);
+ setup_playSound(getSound()->wrongDoorCath());
+ }
+ } else {
+ setCallback(savepoint.action == kActionKnock ? 8 : 9);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ }
+ } else {
+ getObjects()->update(kObjectCompartment4, kEntityMahmud, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(savepoint.action == kActionKnock ? 3 : 4);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ }
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+
+ getEntities()->clearSequences(kEntityMahmud);
+ params->param3 = 1;
+
+ getObjects()->update(kObjectCompartment4, kEntityMahmud, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionDrawScene:
+ if (params->param4 || params->param5) {
+ getObjects()->update(kObjectCompartment4, kEntityMahmud, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ params->param4 = 0;
+ params->param5 = 0;
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ return;
+
+ case 1:
+ getObjects()->update(kObjectCompartment4, kEntityMahmud, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ params->param4 = 0;
+ params->param5 = 0;
+
+ if (!getSound()->isBuffered("HAR1104") && getState()->time > kTime1167300 && !params->param7) {
+ params->param7 = 1;
+ setCallback(2);
+ setup_function12();
+ break;
+ }
+
+ params->param8 = 0;
+ break;
+
+ case 2:
+ getObjects()->update(kObjectCompartment4, kEntityMahmud, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ params->param4 = 0;
+ params->param5 = 0;
+ params->param8 = 0;
+ break;
+
+ case 3:
+ case 4:
+ setCallback(5);
+ setup_playSound("MAH1175");
+ break;
+
+ case 5: {
+ CursorStyle cursor = kCursorHand;
+ CursorStyle cursor2 = kCursorHandKnock;
+
+ if (getProgress().jacket == kJacketBlood
+ || getEvent(kEventMahmudWrongDoor)
+ || getEvent(kEventMahmudWrongDoorOriginalJacket)
+ || getEvent(kEventMahmudWrongDoorDay)) {
+ cursor = kCursorNormal;
+ cursor2 = kCursorTalk;
+ }
+
+ getObjects()->update(kObjectCompartment4, kEntityMahmud, kObjectLocation1, cursor, cursor2);
+ params->param5 = 1;
+ break;
+ }
+
+ case 6:
+ case 7:
+ params->param4 = 1;
+ break;
+
+ case 8:
+ case 9:
+ setCallback(10);
+ setup_savegame(kSavegameTypeEvent, kEventMahmudWrongDoor);
+ return;
+
+ case 10:
+ getAction()->playAnimation((getProgress().jacket == kJacketGreen) ? (isNight() ? kEventMahmudWrongDoor : kEventMahmudWrongDoorDay) : kEventMahmudWrongDoorOriginalJacket);
+ getSound()->playSound(kEntityPlayer, "LIB015");
+ getScenes()->processScene();
+
+ params->param4 = 1;
+ break;
+
+ case 11:
+ getObjects()->update(kObjectCompartment4, kEntityMahmud, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ params->param4 = 0;
+ params->param5 = 0;
+ break;
+
+ case 12:
+ getObjects()->update(kObjectCompartment4, kEntityMahmud, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ params->param2 = 0;
+ params->param4 = 0;
+ params->param5 = 0;
+ break;
+ }
+ break;
+
+ case kAction225563840:
+ setCallback(12);
+ setup_function11();
+ break;
+
+ case kAction290410610:
+ params->param3 = (params->param3 < 1) ? 1 : 0;
+ setCallback(11);
+ setup_function10((ObjectIndex)savepoint.param.intValue, (bool)params->param3);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Mahmud, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chaptersHandler);
+ break;
+
+ case kActionDefault:
+ getSavePoints()->addData(kEntityMahmud, kAction170483072, 0);
+
+ getData()->entityPosition = kPosition_540;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarGreenSleeping;
+
+ getObjects()->update(kObjectCompartment4, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject20, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Mahmud, resetChapter)
+ if (savepoint.action != kActionDefault)
+ return;
+
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+
+ getObjects()->update(kObjectCompartment4, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getEntities()->clearSequences(kEntityMahmud);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Mahmud, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chaptersHandler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityMahmud);
+
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Mahmud, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chaptersHandler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityMahmud);
+
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Mahmud, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chaptersHandler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityMahmud);
+
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Mahmud, chapter5)
+ if (savepoint.action == kActionDefault)
+ getEntities()->clearSequences(kEntityMahmud);
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/mahmud.h b/engines/lastexpress/entities/mahmud.h
new file mode 100644
index 0000000000..0b65a8bcff
--- /dev/null
+++ b/engines/lastexpress/entities/mahmud.h
@@ -0,0 +1,153 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_MAHMUD_H
+#define LASTEXPRESS_MAHMUD_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Mahmud : public Entity {
+public:
+ Mahmud(LastExpressEngine *engine);
+ ~Mahmud() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Draws the entity
+ *
+ * @param savepoint The savepoint
+ * - The sequence to draw
+ */
+ DECLARE_FUNCTION_NOSETUP(draw)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ * @param ticks The time ticks
+ * @param object The object for loading the scene
+ */
+ DECLARE_FUNCTION_4(enterExitCompartment2, const char* sequence, ObjectIndex compartment, uint32 ticks, ObjectIndex object)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSoundMertens, const char* filename)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param savepoint The savepoint
+ * - Time to add
+ */
+ DECLARE_FUNCTION_NOSETUP(updateFromTime)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ DECLARE_FUNCTION_2(function10, ObjectIndex, bool)
+ DECLARE_FUNCTION(function11)
+ DECLARE_FUNCTION(function12)
+ DECLARE_FUNCTION(function13)
+
+ /**
+ * Handle chapters events
+ */
+ DECLARE_FUNCTION(chaptersHandler)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Reset chapter data
+ */
+ DECLARE_FUNCTION(resetChapter)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_MAHMUD_H
diff --git a/engines/lastexpress/entities/max.cpp b/engines/lastexpress/entities/max.cpp
new file mode 100644
index 0000000000..5bc1c1f357
--- /dev/null
+++ b/engines/lastexpress/entities/max.cpp
@@ -0,0 +1,628 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/max.h"
+
+#include "lastexpress/game/action.h"
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+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(Max, chapter12_handler);
+ ADD_CALLBACK_FUNCTION(Max, function7);
+ ADD_CALLBACK_FUNCTION(Max, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Max, function9);
+ ADD_CALLBACK_FUNCTION(Max, chapter1);
+ ADD_CALLBACK_FUNCTION(Max, chapter2);
+ ADD_CALLBACK_FUNCTION(Max, chapter3);
+ ADD_CALLBACK_FUNCTION(Max, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Max, freeFromCage);
+ ADD_CALLBACK_FUNCTION(Max, function15);
+ ADD_CALLBACK_FUNCTION(Max, chapter4);
+ ADD_CALLBACK_FUNCTION(Max, function17);
+ ADD_CALLBACK_FUNCTION(Max, chapter5);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Max, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(2, Max, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(3, Max, draw)
+ Entity::draw(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(4, Max, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(5, Max, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(6, Max, chapter12_handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param2, getState()->time, params->param1);
+
+ if (!getSound()->isBuffered(kEntityMax))
+ getSound()->playSound(kEntityMax, "Max1122");
+
+ params->param1 = 255 * (4 * rnd(20) + 40);
+ params->param2 = 0;
+ break;
+
+ case kActionDefault:
+ params->param1 = 255 * (4 * rnd(20) + 40);
+ break;
+
+ case kAction71277948:
+ setCallback(1);
+ setup_function7();
+ break;
+
+ case kAction158007856:
+ if (!getSound()->isBuffered(kEntityMax)) {
+ getSound()->playSound(kEntityMax, "Max1122");
+ params->param1 = 255 * (4 * rnd(20) + 40);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(7, Max, function7)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param2, getState()->time, params->param1)
+
+ if (!getSound()->isBuffered(kEntityMax))
+ getSound()->playSound(kEntityMax, "Max1122");
+
+ params->param1 = 255 * (4 * rnd(20) + 40);
+ params->param2 = 0;
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ getObjects()->update(kObjectCompartmentF, kEntityMax, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject53, kEntityMax, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ if (getSound()->isBuffered(kEntityMax))
+ getSound()->processEntry(kEntityMax);
+
+ setCallback((savepoint.action == kActionKnock) ? 1 : 2);
+ setup_playSound((savepoint.action == kActionKnock) ? "LIB012" : "LIB013");
+ break;
+
+ case kActionDefault:
+ params->param1 = 255 * (4 * rnd(20) + 40);
+
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getObjects()->update(kObjectCompartmentF, kEntityMax, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityMax, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionDrawScene:
+ if (!getSound()->isBuffered(kEntityMax)) {
+ if (getEntities()->isPlayerPosition(kCarRedSleeping, 56) || getEntities()->isPlayerPosition(kCarRedSleeping, 78))
+ getSound()->playSound(kEntityMax, "Max1120");
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ case 0:
+ default:
+ break;
+
+ case 1:
+ case 2:
+ setCallback(3);
+ setup_playSound("Max1122");
+ break;
+
+ case 3:
+ getObjects()->update(kObjectCompartmentF, kEntityMax, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityMax, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+ }
+ break;
+
+ case kAction101687594:
+ getEntities()->clearSequences(kEntityMax);
+
+ CALLBACK_ACTION();
+ break;
+
+ case kAction122358304:
+ case kActionMaxFreeFromCage:
+ getSavePoints()->push(kEntityMax, kEntityMax, kActionMaxFreeFromCage);
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ CALLBACK_ACTION();
+ break;
+
+ case kAction158007856:
+ if (!getSound()->isBuffered(kEntityMax)) {
+ getSound()->playSound(kEntityMax, "Max1122");
+ params->param1 = 255 * (4 * rnd(20) + 40);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(8, Max, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param3, getState()->time, params->param2);
+
+ if (!getSound()->isBuffered(kEntityMax))
+ getSound()->playSound(kEntityMax, "Max3101");
+
+ params->param2 = 255 * (4 * rnd(20) + 40);
+ params->param3 = 0;
+ break;
+
+ case kActionOpenDoor:
+ if (params->param1) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventCathMaxLickHand);
+ break;
+ }
+
+ if (getSound()->isBuffered(kEntityMax))
+ getSound()->processEntry(kEntityMax);
+
+ getAction()->playAnimation(kEventCathMaxLickHand);
+ getScenes()->processScene();
+
+ params->param1 = 1;
+ break;
+
+ case kActionDefault:
+ params->param2 = 255 * (4 * rnd(20) + 40);
+
+ getObjects()->update(kObjectCageMax, kEntityMax, kObjectLocationNone, kCursorNormal, kCursorHand);
+ getEntities()->clearSequences(kEntityMax);
+
+ getData()->entityPosition = kPosition_8000;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarBaggage;
+
+ if (!getSound()->isBuffered(kEntityMax))
+ getSound()->playSound(kEntityMax, "Max3101");
+ break;
+
+ case kActionCallback:
+ if (getCallback() != 1)
+ break;
+
+ if (getSound()->isBuffered(kEntityMax))
+ getSound()->processEntry(kEntityMax);
+
+ getSound()->playSound(kEntityPlayer, "LIB026");
+ getAction()->playAnimation(kEventCathMaxFree);
+ getScenes()->loadSceneFromPosition(kCarBaggage, 92);
+ getObjects()->update(kObjectCageMax, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorHand);
+ setup_function9();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(9, Max, function9)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param2 == kTimeInvalid || !getState()->time)
+ break;
+
+ if (params->param1 >= getState()->time) {
+ if (!getEntities()->hasValidFrame(kEntityMax) || !params->param2) {
+
+ params->param2 = getState()->time;
+ if (!params->param2)
+ goto setup_functions;
+ }
+
+ if (params->param2 >= getState()->time)
+ break;
+ }
+
+ params->param2 = kTimeInvalid;
+
+setup_functions:
+ if (getProgress().chapter == kChapter3)
+ setup_function15();
+
+ if (getProgress().chapter == kChapter4)
+ setup_function17();
+ break;
+
+ //////////////////////////////////////////////////////////////////////////
+ // Draw Max outside of cage
+ case kActionDefault:
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getEntities()->drawSequenceLeft(kEntityMax, "630Af");
+ getEntities()->enterCompartment(kEntityMax, kObjectCompartmentF, true);
+
+ params->param1 = getState()->time + 2700;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(10, Max, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter12_handler);
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Max, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter12_handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityMax);
+
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Max, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityMax);
+
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Max, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param2) {
+ getData()->entityPosition = getEntityData(kEntityCoudert)->entityPosition;
+ break;
+ }
+
+ UPDATE_PARAM(params->param3, getState()->time, params->param1);
+
+ if (!getSound()->isBuffered(kEntityMax))
+ getSound()->playSound(kEntityMax, "Max1122");
+
+ params->param1 = 255 * (4 * rnd(20) + 40);
+ params->param3 = 0;
+ break;
+
+ case kActionDefault:
+ params->param1 = 255 * (4 * rnd(20) + 40);
+
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ break;
+
+ case kAction71277948:
+ setCallback(1);
+ setup_function7();
+ break;
+
+ case kAction122358304:
+ params->param2 = 1;
+ break;
+
+ case kActionMaxFreeFromCage:
+ setup_freeFromCage();
+ break;
+
+ case kAction158007856:
+ if (params->param2)
+ break;
+
+ if (!getSound()->isBuffered(kEntityMax)) {
+ getSound()->playSound(kEntityMax, "Max1122");
+ params->param1 = 255 * (4 * rnd(20) + 40);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Max, freeFromCage)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ break;
+
+ case kActionEndSound:
+ getSound()->playSound(kEntityMax, "Max1122");
+ break;
+
+ //////////////////////////////////////////////////////////////////////////
+ // Save game after freeing Max from his cage
+ case kActionOpenDoor:
+ if (getEvent(kEventCathMaxCage)) {
+ if (getEvent(kEventCathMaxFree)) {
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventCathMaxFree);
+ }
+
+ } else {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventCathMaxCage);
+ }
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCageMax, kEntityMax, kObjectLocationNone, kCursorNormal, kCursorHand);
+
+ getData()->entityPosition = kPosition_8000;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarBaggage;
+
+ if (!getSound()->isBuffered(kEntityMax))
+ getSound()->playSound(kEntityMax, "Max1122");
+ break;
+
+ //////////////////////////////////////////////////////////////////////////
+ // Play animation for Max in the cage and after opening it
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (getSound()->isBuffered(kEntityMax))
+ getSound()->removeFromQueue(kEntityMax);
+
+ getAction()->playAnimation(kEventCathMaxCage);
+ getSound()->setupEntry(SoundManager::kSoundType7, kEntityMax);
+ getScenes()->processScene();
+ break;
+
+ case 2:
+ if (getSound()->isBuffered(kEntityMax))
+ getSound()->processEntry(kEntityMax);
+
+ getSound()->playSound(kEntityPlayer, "LIB026");
+ getAction()->playAnimation(kEventCathMaxFree);
+ getScenes()->loadSceneFromPosition(kCarBaggage, 92);
+ getObjects()->update(kObjectCageMax, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorHand);
+ setup_function9();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Max, function15)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param2) {
+ getData()->entityPosition = getEntityData(kEntityCoudert)->entityPosition;
+ getData()->car = getEntityData(kEntityCoudert)->car;
+ }
+
+ if (!params->param1) {
+ UPDATE_PARAM(params->param3, getState()->time, 900);
+
+ getSavePoints()->push(kEntityMax, kEntityCoudert, kAction157026693);
+ }
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ if (!getSound()->isBuffered(kEntityMax))
+ getSound()->playSound(kEntityMax, "Max3010");
+
+ setCallback(1);
+ setup_enterExitCompartment("630Bf", kObjectCompartment4);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getEntities()->drawSequenceLeft(kEntityMax, "630Af");
+ getEntities()->enterCompartment(kEntityMax, kObjectCompartmentF, true);
+ getSavePoints()->push(kEntityMax, kEntityAnna, kAction156622016);
+ }
+ break;
+
+ case kAction122358304:
+ (savepoint.entity2 == kEntityAnna) ? (params->param1 = 1) : (params->param2 = 1);
+ getEntities()->exitCompartment(kEntityMax, kObjectCompartmentF, true);
+ getEntities()->drawSequenceLeft(kEntityMax, "BLANK");
+ break;
+
+ case kActionMaxFreeFromCage:
+ getEntities()->exitCompartment(kEntityMax, kObjectCompartmentF, true);
+ setup_chapter4Handler();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Max, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityMax);
+
+ getData()->entityPosition = kPosition_8000;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarBaggage;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Max, function17)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1) {
+ getData()->entityPosition = getEntityData(kEntityCoudert)->entityPosition;
+ getData()->car = getEntityData(kEntityCoudert)->car;
+ }
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_4070;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getEntities()->drawSequenceLeft(kEntityMax, "630Af");
+ getSavePoints()->push(kEntityMax, kEntityCoudert, kAction157026693);
+ break;
+
+ case kAction122358304:
+ params->param1 = 1;
+ getEntities()->exitCompartment(kEntityMax, kObjectCompartmentF, true);
+ getEntities()->drawSequenceLeft(kEntityMax, "BLANK");
+ break;
+
+ case kActionMaxFreeFromCage:
+ getEntities()->exitCompartment(kEntityMax, kObjectCompartmentF, true);
+ setup_chapter4Handler();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Max, chapter5)
+ if (savepoint.action == kActionDefault) {
+ getEntities()->clearSequences(kEntityMax);
+
+ getData()->entityPosition = kPositionNone;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarNone;
+
+ getObjects()->update(kObjectCageMax, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorHand);
+ }
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/max.h b/engines/lastexpress/entities/max.h
new file mode 100644
index 0000000000..404ee42f5f
--- /dev/null
+++ b/engines/lastexpress/entities/max.h
@@ -0,0 +1,129 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_MAX_H
+#define LASTEXPRESS_MAX_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Max : public Entity {
+public:
+ Max(LastExpressEngine *engine);
+ ~Max() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Draws the entity
+ *
+ * @param savepoint The savepoint
+ * - The sequence to draw
+ */
+ DECLARE_FUNCTION_NOSETUP(draw)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ /**
+ * Handle Chapter 1 & 2 events
+ */
+ DECLARE_FUNCTION(chapter12_handler)
+
+ DECLARE_FUNCTION(function7)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ DECLARE_FUNCTION(function9)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ DECLARE_FUNCTION(freeFromCage)
+ DECLARE_FUNCTION(function15)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ DECLARE_FUNCTION(function17)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_MAX_H
diff --git a/engines/lastexpress/entities/mertens.cpp b/engines/lastexpress/entities/mertens.cpp
new file mode 100644
index 0000000000..a59a8eebe8
--- /dev/null
+++ b/engines/lastexpress/entities/mertens.cpp
@@ -0,0 +1,4113 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/mertens.h"
+
+#include "lastexpress/game/action.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"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/state.h"
+#include "lastexpress/game/sound.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+namespace LastExpress {
+
+#define SAVEGAME_BLOOD_JACKET() \
+ if (getProgress().jacket == kJacketBlood \
+ && getEntities()->isDistanceBetweenEntities(kEntityMertens, kEntityPlayer, 1000) \
+ && !getEntities()->isInsideCompartments(kEntityPlayer) \
+ && !getEntities()->checkFields10(kEntityPlayer)) { \
+ setCallback(1); \
+ setup_savegame(kSavegameTypeEvent, kEventMertensBloodJacket); \
+ }
+
+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(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(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(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(Mertens, function32);
+ ADD_CALLBACK_FUNCTION(Mertens, function33);
+ ADD_CALLBACK_FUNCTION(Mertens, chapter1);
+ ADD_CALLBACK_FUNCTION(Mertens, function35);
+ ADD_CALLBACK_FUNCTION(Mertens, function36);
+ ADD_CALLBACK_FUNCTION(Mertens, function37);
+ ADD_CALLBACK_FUNCTION(Mertens, function38);
+ ADD_CALLBACK_FUNCTION(Mertens, function39);
+ ADD_CALLBACK_FUNCTION(Mertens, function40);
+ ADD_CALLBACK_FUNCTION(Mertens, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Mertens, function42);
+ ADD_CALLBACK_FUNCTION(Mertens, chapter2);
+ ADD_CALLBACK_FUNCTION(Mertens, function44);
+ ADD_CALLBACK_FUNCTION(Mertens, chapter3);
+ ADD_CALLBACK_FUNCTION(Mertens, function46);
+ ADD_CALLBACK_FUNCTION(Mertens, chapter4);
+ ADD_CALLBACK_FUNCTION(Mertens, function48);
+ ADD_CALLBACK_FUNCTION(Mertens, function49);
+ ADD_CALLBACK_FUNCTION(Mertens, chapter5);
+ ADD_CALLBACK_FUNCTION(Mertens, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(Mertens, function52);
+ ADD_CALLBACK_FUNCTION(Mertens, function53);
+ ADD_NULL_FUNCTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Mertens, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(2, Mertens, bloodJacket)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ SAVEGAME_BLOOD_JACKET();
+ break;
+
+ case kActionExitCompartment:
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(kEntityMertens, (char *)&params->seq1);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventMertensBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(3, Mertens, enterExitCompartment, ObjectIndex)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ SAVEGAME_BLOOD_JACKET();
+ return;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventMertensBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ }
+ return;
+ }
+
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(4, Mertens, enterExitCompartment2, ObjectIndex)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ SAVEGAME_BLOOD_JACKET();
+ return;
+
+ case kAction4:
+ getEntities()->exitCompartment(kEntityMertens, (ObjectIndex)params->param4);
+ CALLBACK_ACTION();
+ return;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventMertensBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ }
+ return;
+ }
+
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SIII(5, Mertens, enterExitCompartment3, ObjectIndex, EntityPosition, EntityPosition)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ SAVEGAME_BLOOD_JACKET();
+ break;
+
+ case kActionExitCompartment:
+ getEntities()->exitCompartment(_entityIndex, (ObjectIndex)params->param4);
+ getData()->entityPosition = (EntityPosition)params->param5;
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(_entityIndex, (char *)&params->seq);
+ getEntities()->enterCompartment(_entityIndex, (ObjectIndex)params->param4);
+ getData()->entityPosition = (EntityPosition)params->param5;
+
+ if (getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, (EntityPosition)params->param5) || getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, (EntityPosition)params->param6)) {
+ getAction()->playAnimation(isNight() ? kEventCathTurningNight : kEventCathTurningDay);
+ getSound()->playSound(kEntityPlayer, "BUMP");
+ getScenes()->loadSceneFromObject((ObjectIndex)params->param4);
+ }
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventMertensBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(6, Mertens, callbackActionOnDirection)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getData()->direction != kDirectionRight) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ SAVEGAME_BLOOD_JACKET();
+ break;
+
+ case kActionExitCompartment:
+ CALLBACK_ACTION();
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventMertensBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(7, Mertens, playSound)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ SAVEGAME_BLOOD_JACKET();
+ break;
+
+ case kActionEndSound:
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getSound()->playSound(kEntityMertens, (char *)&params->seq1);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventMertensBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(8, Mertens, playSound16)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ SAVEGAME_BLOOD_JACKET();
+ break;
+
+ case kActionEndSound:
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getSound()->playSound(kEntityMertens, (char *)&params->seq1, SoundManager::kFlagDefault);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventMertensBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(9, Mertens, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(10, Mertens, updateEntity, CarIndex, EntityPosition)
+
+#define LOADSCENE_FROM_POSITION() \
+ if (getData()->direction != kDirectionUp) { \
+ getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + 750)); \
+ } else { \
+ getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition - 750), true); \
+ }
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param3 && getEntities()->isDistanceBetweenEntities(kEntityMertens, kEntityPlayer, 2000))
+ getData()->inventoryItem = (InventoryItem)(getData()->inventoryItem | kItemInvalid);
+ else
+ getData()->inventoryItem = (InventoryItem)(getData()->inventoryItem & kItemToggleHigh);
+
+ if (!getEntities()->isDistanceBetweenEntities(kEntityMertens, kEntityPlayer, 1000)
+ || getEntities()->isInsideCompartments(kEntityPlayer)
+ || getEntities()->checkFields10(kEntityPlayer)) {
+ if (getEntities()->updateEntity(kEntityMertens, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ getData()->inventoryItem = kItemNone;
+ CALLBACK_ACTION();
+ }
+ break;
+ }
+
+ if (getProgress().jacket == kJacketBlood) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventMertensBloodJacket);
+ break;
+ }
+
+ if ((ENTITY_PARAM(0, 6) || ENTITY_PARAM(0, 7)) && (!getEvent(kEventKronosConversation) && getProgress().jacket == kJacketGreen)) {
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventMertensKronosInvitation);
+ break;
+ }
+
+ if (ENTITY_PARAM(1, 2) && getProgress().jacket == kJacketGreen && !getProgress().eventMetAugust) {
+ setCallback(3);
+ setup_savegame(kSavegameTypeEvent, kEventMertensAugustWaiting);
+ break;
+ }
+
+ if (ENTITY_PARAM(2, 4) && getState()->time < kTime2133000) {
+ setCallback(4);
+ setup_savegame(kSavegameTypeEvent, kEventMertensKronosConcertInvitation);
+ break;
+ }
+
+ if (getEntities()->updateEntity(kEntityMertens, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ getData()->inventoryItem = kItemNone;
+ CALLBACK_ACTION();
+ }
+ break;
+
+ case kAction1:
+ params->param3 = 0;
+ if (getProgress().eventCorpseFound || getEvent(kEventMertensAskTylerCompartment) || getEvent(kEventMertensAskTylerCompartmentD)) {
+ if (ENTITY_PARAM(0, 4) && getProgress().jacket == kJacketGreen && !getEvent(kEventMertensDontMakeBed) && !getProgress().eventCorpseThrown) {
+ setCallback(6);
+ setup_savegame(kSavegameTypeEvent, kEventMertensDontMakeBed);
+ }
+ } else {
+ setCallback(5);
+ setup_savegame(kSavegameTypeEvent, kEventMertensAskTylerCompartment);
+ }
+ break;
+
+ case kActionExcuseMeCath:
+ getSound()->playSound(kEntityMertens, "CON1110B");
+ break;
+
+ case kActionExcuseMe:
+ getSound()->excuseMe(kEntityMertens);
+ break;
+
+ case kActionDefault:
+ if ((!getProgress().eventCorpseFound && !getEvent(kEventMertensAskTylerCompartment) && !getEvent(kEventMertensAskTylerCompartment))
+ || (ENTITY_PARAM(0, 4) && getProgress().jacket == kJacketGreen && !getEvent(kEventMertensDontMakeBed) && !getProgress().eventCorpseThrown))
+ params->param3 = 1;
+
+ if (getEntities()->updateEntity(kEntityMertens, (CarIndex)params->param1, (EntityPosition)params->param2))
+ CALLBACK_ACTION();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventMertensBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ break;
+
+ case 2:
+ getAction()->playAnimation(getData()->entityPosition < getEntityData(kEntityPlayer)->entityPosition ? kEventMertensKronosInvitation : kEventMertensKronosInvitationClosedWindows);
+ getProgress().eventMertensKronosInvitation = true;
+
+ ENTITY_PARAM(0, 6) = 0;
+ ENTITY_PARAM(0, 7) = 0;
+
+ if (params->param1 != 3 || (params->param2 != kPosition_8200 && params->param2 != kPosition_9510)) {
+ LOADSCENE_FROM_POSITION();
+ break;
+ }
+
+ getData()->inventoryItem = kItemNone;
+
+ if (getData()->car == kCarGreenSleeping && getEntities()->checkDistanceFromPosition(kEntityMertens, kPosition_2000, 500))
+ getData()->entityPosition = kPosition_2500;
+
+ getEntities()->updateEntity(kEntityMertens, kCarGreenSleeping, kPosition_2000);
+ getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + 750));
+
+ CALLBACK_ACTION();
+ break;
+
+ case 3:
+ getAction()->playAnimation(kEventMertensAugustWaiting);
+ getProgress().eventMertensAugustWaiting = true;
+
+ ENTITY_PARAM(1, 2) = 0;
+
+ if (params->param1 == 3 && params->param2 == kPosition_8200) {
+ if (getData()->car == kCarGreenSleeping && getEntities()->checkDistanceFromPosition(kEntityMertens, kPosition_2000, 500))
+ getData()->entityPosition = kPosition_2500;
+
+ getEntities()->updateEntity(kEntityMertens, kCarGreenSleeping, kPosition_2000);
+ getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + 750));
+
+ CALLBACK_ACTION();
+ break;
+ }
+
+ LOADSCENE_FROM_POSITION();
+ break;
+
+ case 4:
+ getAction()->playAnimation(kEventMertensKronosConcertInvitation);
+ ENTITY_PARAM(2, 4) = 0;
+
+ LOADSCENE_FROM_POSITION();
+ break;
+
+ case 5:
+ getAction()->playAnimation(getData()->entityPosition < getEntityData(kEntityPlayer)->entityPosition ? kEventMertensAskTylerCompartmentD : kEventMertensAskTylerCompartment);
+ LOADSCENE_FROM_POSITION();
+ break;
+
+ case 6:
+ getAction()->playAnimation(kEventMertensDontMakeBed);
+ LOADSCENE_FROM_POSITION();
+ ENTITY_PARAM(0, 4) = 0;
+ break;
+ }
+ break;
+ }
+
+#undef LOADSCENE_FROM_POSITION
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(11, Mertens, function11, uint32)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ SAVEGAME_BLOOD_JACKET();
+
+ UPDATE_PARAM(params->param2, getState()->time, params->param1)
+
+ CALLBACK_ACTION();
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventMertensBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(12, Mertens, bonsoir, EntityIndex)
+ EntityIndex entity = (EntityIndex)params->param1;
+
+ if (savepoint.action == kActionDefault)
+ return;
+
+ if (getSound()->isBuffered(kEntityMertens)) {
+ CALLBACK_ACTION();
+ return;
+ }
+
+ if (isNight()) {
+ if (Entities::isFemale(entity)) {
+ getSound()->playSound(kEntityMertens, rnd(2) ? "CON1112" : "CON1112A");
+ } else {
+ if (entity || getProgress().field_18 != 2) {
+ getSound()->playSound(kEntityMertens, "CON1112F");
+ } else {
+ switch (rnd(3)) {
+ default:
+ case 0:
+ getSound()->playSound(kEntityMertens, "CON1061");
+ break;
+
+ case 1:
+ getSound()->playSound(kEntityMertens, "CON1110G");
+ break;
+
+ case 2:
+ getSound()->playSound(kEntityMertens, "CON1110H");
+ break;
+ }
+ }
+ }
+ } else {
+ if (Entities::isFemale(entity))
+ getSound()->playSound(kEntityMertens, rnd(2) ? "CON1112B" : "CON1112C");
+ else
+ getSound()->playSound(kEntityMertens, "CON1112G");
+ }
+
+ CALLBACK_ACTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(13, Mertens, function13, bool, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ SAVEGAME_BLOOD_JACKET();
+
+ if (!params->param2 && !params->param3) {
+ UPDATE_PARAM_PROC(params->param4, getState()->timeTicks, 75)
+ getData()->inventoryItem = kItemNone;
+ setCallback(5);
+ setup_function18();
+ break;
+ UPDATE_PARAM_PROC_END
+ }
+
+ UPDATE_PARAM_PROC(params->param5, getState()->timeTicks, 225)
+ getData()->inventoryItem = kItemNone;
+ setCallback(6);
+ setup_function18();
+ break;
+ UPDATE_PARAM_PROC_END
+
+ getData()->inventoryItem = (getProgress().chapter == kChapter1
+ && !ENTITY_PARAM(2, 1)
+ && !getProgress().eventCorpseFound
+ && !getEvent(kEventMertensAskTylerCompartment)
+ && !getEvent(kEventMertensAskTylerCompartmentD)) ? kItemMatchBox : kItemNone;
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+ setCallback(7);
+ setup_savegame(kSavegameTypeEvent, kEventMertensAskTylerCompartmentD);
+ break;
+
+ case kAction11:
+ params->param3++;
+ setCallback(11);
+ setup_bonsoir(savepoint.entity2);
+ break;
+
+ case kActionDefault:
+ if (params->param2)
+ params->param3 = 1;
+
+ if (!getSound()->isBuffered(kEntityMertens)) {
+
+ }
+
+ setCallback(3);
+ setup_function20();
+ break;
+
+ case kAction16:
+ params->param3--;
+
+ if (params->param2 && !params->param3) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(10);
+ setup_function18();
+ }
+ break;
+
+ case kActionDrawScene:
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 23) && ENTITY_PARAM(0, 7) && !getEvent(kEventKronosConversation)) {
+ setCallback(8);
+ setup_savegame(kSavegameTypeEvent, kEventMertensKronosInvitation);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ setCallback(3);
+ setup_function20();
+ break;
+
+ case 3:
+ getEntities()->drawSequenceLeft(kEntityMertens, params->param1 ? "601I" : "601H");
+ break;
+
+ case 4:
+ getAction()->playAnimation(kEventMertensBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ break;
+
+ case 5:
+ case 6:
+ case 9:
+ case 10:
+ CALLBACK_ACTION();
+ break;
+
+ case 7:
+ getAction()->playAnimation(kEventMertensAskTylerCompartmentD);
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 25);
+ break;
+
+ case 8:
+ getAction()->playAnimation(kEventMertensKronosInvitation);
+ ENTITY_PARAM(0, 6) = 0;
+ ENTITY_PARAM(0, 7) = 0;
+ getScenes()->processScene();
+
+ if (!params->param3) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(10);
+ setup_function18();
+ }
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(14, Mertens, function14, EntityIndex)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ SAVEGAME_BLOOD_JACKET();
+ break;
+
+ case kActionDefault:
+ getData()->inventoryItem = kItemNone;
+
+ if (ENTITY_PARAM(2, 1)) {
+ ENTITY_PARAM(2, 1) = 0;
+
+ setCallback(3);
+ setup_updateEntity(kCarGreenSleeping, kPosition_1500);
+ } else {
+ setCallback(1);
+ setup_function11(15);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityMertens, (EntityIndex)params->param1, kAction202558662);
+
+ setCallback(2);
+ setup_function20();
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityMertens, (EntityIndex)params->param1, kAction155853632);
+ getEntities()->drawSequenceLeft(kEntityMertens, "601K");
+ break;
+
+ case 3:
+ getSavePoints()->push(kEntityMertens, (EntityIndex)params->param1, kAction202558662);
+ getSavePoints()->push(kEntityMertens, (EntityIndex)params->param1, kAction155853632);
+ getEntities()->drawSequenceLeft(kEntityMertens, "601K");
+ getScenes()->loadSceneFromItemPosition(kItem7);
+ break;
+
+ case 4:
+ getAction()->playAnimation(kEventMertensBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ break;
+
+ case 5:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction125499160:
+ if (params->param1 == kEntityVerges)
+ ENTITY_PARAM(0, 8) = 0;
+
+ setCallback(5);
+ setup_function18();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(15, Mertens, function15, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ ENTITY_PARAM(1, 4) = 0;
+ ENTITY_PARAM(1, 5) = 0;
+
+ setCallback(1);
+ setup_function19();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarGreenSleeping, kPosition_4070);
+ break;
+
+ case 2:
+ getSound()->playSound(kEntityMertens, params->param1 ? "CON1059A" : "CON1059");
+
+ setCallback(3);
+ setup_updateEntity(kCarGreenSleeping, kPosition_7500);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_enterExitCompartment("601Xb", kObjectCompartment2);
+ break;
+
+ case 4:
+ getSavePoints()->push(kEntityMertens, kEntityAlexei, kAction135664192);
+
+ setCallback(5);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_function17();
+ break;
+
+ case 6:
+ CALLBACK_ACTION();;
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(16, Mertens, function16, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ ENTITY_PARAM(1, 6) = 0;
+ ENTITY_PARAM(1, 7) = 0;
+
+ setCallback(1);
+ setup_function19();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarGreenSleeping, kPosition_4070);
+ break;
+
+ case 2:
+ switch (rnd(4)) {
+ default:
+ break;
+
+ case 0:
+ getSound()->playSound(kEntityMertens, "AUG2095A");
+ break;
+
+ case 1:
+ getSound()->playSound(kEntityMertens, "AUG2096A");
+ break;
+
+ case 2:
+ getSound()->playSound(kEntityMertens, "AUG2094B");
+ break;
+
+ case 3:
+ getSound()->playSound(kEntityMertens, "AUG2094C");
+ break;
+ }
+
+ setCallback(3);
+ setup_updateEntity(kCarGreenSleeping, kPosition_6470);
+ break;
+
+ case 3:
+ getSound()->playSound(kEntityMertens, params->param1 ? "AUG2097" : "AUG2098");
+
+ setCallback(4);
+ setup_enterExitCompartment("601Xc", kObjectCompartment3);
+ break;
+
+ case 4:
+ getSavePoints()->push(kEntityMertens, kEntityAugust, kAction69239528);
+
+ setCallback(5);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_function17();
+ break;
+
+ case 6:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Mertens, function17)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ // FIXME: Check that we are using the correct parameter struct
+ if (ENTITY_PARAM(0, 6) || ((EntityData::EntityParametersIIII*)_data->getParameters(8, 1))->hasNonNullParameter()) {
+ getInventory()->setLocationAndProcess(kItem7, kObjectLocation1);
+
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_540);
+ break;
+ }
+
+ if (ENTITY_PARAM(0, 8)) {
+ getEntities()->drawSequenceLeft(kEntityMertens, "601K");
+ getScenes()->loadSceneFromItemPosition(kItem7);
+ ENTITY_PARAM(2, 1) = 1;
+
+ CALLBACK_ACTION();
+ break;
+ }
+
+ // Mertens sits on his chair at the back of the train
+ if (!getInventory()->hasItem(kItemPassengerList) || ENTITY_PARAM(0, 2)) {
+ getEntities()->drawSequenceRight(kEntityMertens, "601A");
+ } else {
+ // Got the passenger list, Mertens is looking for it before sitting
+ ENTITY_PARAM(0, 2) = 1;
+ getSound()->playSound(kEntityMertens, "CON1058", SoundManager::kFlagInvalid, 75);
+ getEntities()->drawSequenceRight(kEntityMertens, "601D");
+ }
+
+ getScenes()->loadSceneFromItemPosition(kItem7);
+
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 68)) {
+ getSound()->playSound(kEntityPlayer, "CON1110");
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 25);
+ }
+
+ setCallback(3);
+ setup_callbackActionOnDirection();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->clearSequences(kEntityMertens);
+ ENTITY_PARAM(2, 1) = 1;
+ setCallback(2);
+ setup_function11(75);
+ break;
+
+ case 2:
+ CALLBACK_ACTION();
+ break;
+
+ case 3:
+ if (!ENTITY_PARAM(0, 3)
+ && !getInventory()->hasItem(kItemPassengerList)
+ && ENTITY_PARAM(0, 2)) {
+ getSavePoints()->push(kEntityMertens, kEntityVerges, kAction158617345);
+ ENTITY_PARAM(0, 3) = 1;
+ }
+
+ getEntities()->drawSequenceLeft(kEntityMertens, "601B");
+
+ ENTITY_PARAM(0, 1) = 0;
+ getData()->inventoryItem = kItemNone;
+
+ getSavePoints()->push(kEntityMertens, kEntityMertens, kActionDrawScene);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Mertens, function18)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (ENTITY_PARAM(0, 6)
+ || ENTITY_PARAM(1, 1)
+ || ENTITY_PARAM(1, 2)
+ || ENTITY_PARAM(1, 3)
+ || ENTITY_PARAM(1, 4)
+ || ENTITY_PARAM(1, 5)
+ || ENTITY_PARAM(1, 6)
+ || ENTITY_PARAM(1, 7)
+ || ENTITY_PARAM(1, 8)) {
+ getInventory()->setLocationAndProcess(kItem7, kObjectLocation1);
+ ENTITY_PARAM(2, 1) = 1;
+
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (ENTITY_PARAM(0, 8)) {
+ getScenes()->loadSceneFromItemPosition(kItem7);
+ ENTITY_PARAM(2, 1) = 1;
+
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (!getInventory()->hasItem(kItemPassengerList) || ENTITY_PARAM(0, 2)) {
+ getEntities()->drawSequenceRight(kEntityMertens, "601A");
+ } else {
+ ENTITY_PARAM(0, 2) = 1;
+ getSound()->playSound(kEntityMertens, "CON1058", SoundManager::kFlagInvalid, 75);
+ getEntities()->drawSequenceRight(kEntityMertens, "601D");
+ }
+
+ getScenes()->loadSceneFromItemPosition(kItem7);
+
+ setCallback(1);
+ setup_callbackActionOnDirection();
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ if (!ENTITY_PARAM(0, 3)
+ && !getInventory()->hasItem(kItemPassengerList)
+ && ENTITY_PARAM(0, 2)) {
+ getSavePoints()->push(kEntityMertens, kEntityVerges, kAction158617345);
+ ENTITY_PARAM(0, 3) = 1;
+ }
+
+ getEntities()->drawSequenceLeft(kEntityMertens, "601B");
+ ENTITY_PARAM(0, 1) = 0;
+ getData()->inventoryItem = kItemNone;
+
+ CALLBACK_ACTION();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Mertens, function19)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (ENTITY_PARAM(2, 1)) {
+ getInventory()->setLocationAndProcess(kItem7, kObjectLocation1);
+ ENTITY_PARAM(2, 1) = 0;
+ CALLBACK_ACTION();
+ } else {
+ setCallback(1);
+ setup_bloodJacket("601C");
+ }
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getInventory()->setLocationAndProcess(kItem7, kObjectLocation1);
+
+ if (!getEntities()->isPlayerPosition(kCarGreenSleeping, 2))
+ getData()->entityPosition = kPosition_2088;
+
+ CALLBACK_ACTION();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Mertens, function20)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getScenes()->loadSceneFromItemPosition(kItem7);
+
+ if (ENTITY_PARAM(2, 1)) {
+ ENTITY_PARAM(2, 1) = 0;
+
+ CALLBACK_ACTION();
+ } else {
+ setCallback(1);
+ setup_bloodJacket("601C");
+ }
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(21, Mertens, function21, ObjectIndex, ObjectIndex)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM_PROC(CURRENT_PARAMS(1, 4), getState()->time, 300)
+ getSound()->playSound(kEntityPlayer, "ZFX1004", getSound()->getSoundFlag(kEntityMertens));
+ UPDATE_PARAM_PROC_END
+
+ UPDATE_PARAM(CURRENT_PARAMS(1, 5), getState()->time, 900);
+
+ // Update objects
+ getObjects()->updateLocation2((ObjectIndex)params->param1, kObjectLocation1);
+ if (params->param5 != kObjectLocation2)
+ getObjects()->update((ObjectIndex)params->param1, (EntityIndex)params->param4, (ObjectLocation)params->param5, (CursorStyle)params->param6, (CursorStyle)params->param7);
+
+ if (params->param2)
+ getObjects()->update((ObjectIndex)params->param2, (EntityIndex)params->param8, (ObjectLocation)CURRENT_PARAMS(1, 1), (CursorStyle)CURRENT_PARAMS(1, 2), (CursorStyle)CURRENT_PARAMS(1, 3));
+
+ CALLBACK_ACTION();
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ getObjects()->update((ObjectIndex)params->param1, kEntityMertens, kObjectLocation1, kCursorNormal, kCursorNormal);
+ if (params->param2)
+ getObjects()->update((ObjectIndex)params->param2, kEntityMertens, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(savepoint.action == kActionKnock ? 1 : 2);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ break;
+
+ case kActionDefault:
+ params->param3 = 1;
+ params->param4 = getObjects()->get((ObjectIndex)params->param1).entity;
+ params->param5 = getObjects()->get((ObjectIndex)params->param1).location;
+ params->param6 = getObjects()->get((ObjectIndex)params->param1).cursor;
+ params->param7 = getObjects()->get((ObjectIndex)params->param1).cursor2;
+
+ if (params->param2) {
+ params->param8 = getObjects()->get((ObjectIndex)params->param2).entity;
+ CURRENT_PARAMS(1, 1) = getObjects()->get((ObjectIndex)params->param2).location;
+ CURRENT_PARAMS(1, 2) = getObjects()->get((ObjectIndex)params->param2).cursor;
+ CURRENT_PARAMS(1, 3) = getObjects()->get((ObjectIndex)params->param2).cursor2;
+
+ getObjects()->update((ObjectIndex)params->param2, kEntityMertens, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ }
+
+ if (params->param5 != kObjectLocation2)
+ getObjects()->update((ObjectIndex)params->param1, kEntityMertens, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ setCallback(params->param3 ? 3 : 4);
+ setup_playSound(params->param3 ? "Con1017" : "Con1017A");
+ break;
+
+ case 3:
+ case 4:
+ params->param3 = 0;
+ getObjects()->update((ObjectIndex)params->param1, kEntityMertens, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ if (params->param2)
+ getObjects()->update((ObjectIndex)params->param2, kEntityMertens, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Mertens, function22)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2740);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("601Mh", kObjectCompartment8);
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityMertens, "601Nh");
+ getEntities()->enterCompartment(kEntityMertens, kObjectCompartment8, true);
+
+ setCallback(3);
+ setup_function11(150);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_enterExitCompartment("601Mh", kObjectCompartment8);
+ break;
+
+ case 4:
+ getEntities()->drawSequenceLeft(kEntityMertens, "601Nh");
+ getEntities()->enterCompartment(kEntityMertens, kObjectCompartment8);
+ getSavePoints()->push(kEntityMertens, kEntityMahmud, kAction225563840);
+ break;
+
+ case 5:
+ if (!getSound()->isBuffered(kEntityMertens))
+ getSound()->playSound(kEntityMertens, "MAH1170I");
+
+ setCallback(6);
+ setup_enterExitCompartment("601Zd", kObjectCompartment4);
+ break;
+
+ case 6:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMertens);
+ if (!getSound()->isBuffered(kEntityMertens))
+ getSound()->playSound(kEntityMertens, "MAH1172", SoundManager::kFlagInvalid, 225);
+
+ setCallback(7);
+ setup_function21(kObjectCompartment4, kObject20);
+ break;
+
+ case 7:
+ setCallback(8);
+ setup_enterExitCompartment("671Ad", kObjectCompartment4);
+ break;
+
+ case 8:
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityMertens, kEntityMahmud, kAction123852928);
+
+ setCallback(9);
+ setup_updateEntity(kCarGreenSleeping, kPosition_540);
+
+ break;
+
+ case 9:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction102227384:
+ getEntities()->drawSequenceLeft(kEntityMertens, "671Dh");
+ break;
+
+ case kAction156567128:
+ getEntities()->exitCompartment(kEntityMertens, kObjectCompartment8, true);
+
+ setCallback(5);
+ setup_updateEntity(kCarGreenSleeping, kPosition_5790);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Mertens, function23)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_5790);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("601Vd", kObjectCompartment4);
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityMertens, "601Wd");
+ getEntities()->enterCompartment(kEntityMertens, kObjectCompartment4, true);
+
+ setCallback(3);
+ setup_function11(150);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_enterExitCompartment("601Zd", kObjectCompartment4);
+ break;
+
+ case 4:
+ getEntities()->exitCompartment(kEntityMertens, kObjectCompartment4);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMertens);
+
+ setCallback(5);
+ setup_function21(kObjectCompartment4, kObject20);
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_enterExitCompartment("671Ad", kObjectCompartment4);
+ break;
+
+ case 6:
+ getData()->location = kLocationOutsideCompartment;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Mertens, function24)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1) {
+ UPDATE_PARAM(params->param2, getState()->timeTicks, 75);
+
+ setCallback(3);
+ setup_enterExitCompartment3("601Rc", kObjectCompartment3, kPosition_6470, kPosition_6130);
+ }
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_6470);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("601Mc", kObjectCompartment3);
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityMertens, kEntityAugust, kAction221617184);
+ getEntities()->drawSequenceLeft(kEntityMertens, "601Nc");
+ getEntities()->enterCompartment(kEntityMertens, kObjectCompartment3, true);
+ break;
+
+ case 3:
+ getEntities()->exitCompartment(kEntityMertens, kObjectCompartment3, true);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMertens);
+
+ setCallback(4);
+ setup_function21(kObjectCompartment3, kObjectKitchen);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_enterExitCompartment("601Sc", kObjectCompartment3);
+ break;
+
+ case 5:
+ getData()->location = kLocationOutsideCompartment;
+
+ CALLBACK_ACTION();
+ break;
+
+ case 6:
+ getEntities()->exitCompartment(kEntityMertens, kObjectCompartment3, true);
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMertens);
+
+ setCallback(7);
+ setup_function21(kObjectCompartment3, kObjectKitchen);
+ break;
+
+ case 7:
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(8);
+ setup_enterExitCompartment("601Uc", kObjectCompartment3);
+ break;
+
+ case 8:
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityMertens, kEntityAugust, kAction124697504);
+
+ setCallback(9);
+ setup_updateEntity(kCarGreenSleeping, kPosition_540);
+ break;
+
+ case 9:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction100906246:
+ getSavePoints()->push(kEntityMertens, kEntityAugust, kAction192849856);
+ getEntities()->drawSequenceLeft(kEntityMertens, "601Qc");
+ break;
+
+ case kAction102675536:
+ params->param1 = 1;
+ break;
+
+ case kAction156567128:
+ setCallback(6);
+ setup_enterExitCompartment("601Tc", kObjectCompartment3);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, Mertens, function25)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1) {
+ UPDATE_PARAM(params->param2, getState()->timeTicks, 75);
+
+ setCallback(3);
+ setup_enterExitCompartment3("601Zb", kObjectCompartment2, kPosition_7500, kPositionNone);
+ }
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_7500);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("601Vb", kObjectCompartment2);
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityMertens, kEntityAlexei, kAction221617184);
+ getEntities()->drawSequenceLeft(kEntityMertens, "601Wb");
+ getEntities()->enterCompartment(kEntityMertens, kObjectCompartment2, true);
+ break;
+
+ case 3:
+ getEntities()->exitCompartment(kEntityMertens, kObjectCompartment2, true);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMertens);
+
+ if (getProgress().chapter == kChapter1 && ENTITY_PARAM(0, 4))
+ if (getProgress().field_14 != 29)
+ getProgress().field_14 = 3;
+
+ setCallback(4);
+ setup_function21(kObjectCompartment2, kObjectHandleInsideBathroom);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_enterExitCompartment("671Ab", kObjectCompartment2);
+ break;
+
+ case 5:
+ getData()->location = kLocationOutsideCompartment;
+
+ CALLBACK_ACTION();
+ break;
+
+ case 6:
+ getEntities()->exitCompartment(kEntityMertens, kObjectCompartment2, true);
+ getObjects()->update(kObjectCompartment2, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMertens);
+
+ if (getProgress().chapter == kChapter1 && ENTITY_PARAM(0, 4))
+ if (getProgress().field_14 != 29)
+ getProgress().field_14 = 3;
+
+ setCallback(7);
+ setup_function21(kObjectCompartment2, kObjectHandleInsideBathroom);
+ break;
+
+ case 7:
+ getSound()->playSound(kEntityMertens, "CON1024A");
+ getObjects()->update(kObjectCompartment2, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(8);
+ setup_enterExitCompartment("641Ub", kObjectCompartment2);
+ break;
+
+ case 8:
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityMertens, kEntityAlexei, kAction124697504);
+
+ setCallback(9);
+ setup_updateEntity(kCarGreenSleeping, kPosition_9460);
+ break;
+
+ case 9:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction100906246:
+ params->param1 = 1;
+ break;
+
+ case kAction156567128:
+ setCallback(6);
+ setup_enterExitCompartment("641Tb", kObjectCompartment2);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(26, Mertens, function26, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (getProgress().eventCorpseThrown
+ || !params->param1
+ || getProgress().chapter != kChapter1
+ || getProgress().jacket != kJacketGreen) {
+
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMertens);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+
+ setCallback(3);
+ setup_playSound16("ZNU1001");
+ } else {
+ setCallback(1);
+ setup_savegame(kSavegameTypeTime, kTimeNone);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+
+ setCallback(2);
+ setup_playSound16("CON1062");
+ break;
+
+ case 2:
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorHandKnock, kCursorHand);
+
+ CALLBACK_ACTION();
+ break;
+
+ case 3:
+ if (getProgress().jacket == kJacketBlood) {
+ setCallback(4);
+ setup_savegame(kSavegameTypeEvent, kEventMertensBloodJacket);
+ } else if (getProgress().eventCorpseMovedFromFloor) {
+ getEntities()->enterCompartment(kEntityMertens, kObjectCompartment1);
+ getEntities()->drawSequenceRight(kEntityMertens, "601Ra");
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 16);
+
+ setCallback(6);
+ setup_callbackActionOnDirection();
+ } else {
+ setCallback(5);
+ setup_savegame(kSavegameTypeEvent, kEventMertensCorpseFloor);
+ }
+ break;
+
+ case 4:
+ getAction()->playAnimation(kEventMertensBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ break;
+
+ case 5:
+ getAction()->playAnimation(kEventMertensCorpseFloor);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, getProgress().eventCorpseFound ? kSceneGameOverStopPolice : kSceneGameOverPolice, true);
+ break;
+
+ case 6:
+ getEntities()->exitCompartment(kEntityMertens, kObjectCompartment1);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMertens);
+
+ setCallback(7);
+ setup_function21(kObjectCompartment1, kObjectHandleBathroom);
+ break;
+
+ case 7:
+ if (getProgress().eventCorpseThrown || getProgress().chapter != kChapter1) {
+ if (getEntities()->isDistanceBetweenEntities(kEntityMertens, kEntityPlayer, 1000)) {
+ if (!getEntities()->checkFields10(kEntityPlayer))
+ getSound()->playSound(kEntityMertens, "CON1061");
+ }
+
+ setCallback(9);
+ setup_enterExitCompartment("601Sa", kObjectCompartment1);
+ } else {
+ if (!getEntities()->isInsideTrainCar(kEntityPlayer, kCarGreenSleeping))
+ getScenes()->loadSceneFromPosition(kCarNone, 1);
+
+ setCallback(8);
+ setup_savegame(kSavegameTypeEvent, kEventMertensCorpseBed);
+ }
+ break;
+
+ case 8:
+ getAction()->playAnimation(kEventMertensCorpseBed);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverPolice1, true);
+ break;
+
+ case 9:
+ getData()->location = kLocationOutsideCompartment;
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(27, Mertens, tylerCompartment, MertensActionType)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getProgress().field_14 == 29) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ UPDATE_PARAM_PROC(params->param2, getState()->timeTicks, 150)
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+
+ setCallback(10);
+ setup_playSound16("CON1018A");
+ break;
+ UPDATE_PARAM_PROC_END
+
+label_callback10:
+ if (!params->param3)
+ params->param3 = getState()->timeTicks + 300;
+
+ if (params->param3 >= getState()->timeTicks) {
+label_callback11:
+ UPDATE_PARAM(params->param4, getState()->timeTicks, 375);
+
+ getSound()->playSound(kEntityPlayer, "LIB033");
+
+ if (getProgress().eventCorpseMovedFromFloor) {
+
+ if (getProgress().jacket == kJacketBlood) {
+ setCallback(18);
+ setup_savegame(kSavegameTypeEvent, kEventMertensBloodJacket);
+ break;
+ }
+
+ if (params->param1) {
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ switch (params->param1) {
+ case 1:
+ setCallback(20);
+ setup_savegame(kSavegameTypeEvent, kEventMertensAugustWaitingCompartment);
+ break;
+
+ case 2:
+ setCallback(21);
+ setup_savegame(kSavegameTypeEvent, kEventMertensKronosInvitationCompartment);
+ break;
+
+ case 3:
+ getAction()->playAnimation(isNight() ? kEventMertensPushCallNight : kEventMertensPushCall);
+ // fallback to default case
+
+ default:
+ getSound()->playSound(kEntityPlayer, "LIB015");
+ getScenes()->loadScene(kScene41);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ } else {
+ setCallback(26);
+ setup_function26(false);
+ }
+
+ } else {
+ if (!getEntities()->isInsideTrainCar(kEntityPlayer, kCarGreenSleeping))
+ getScenes()->loadSceneFromPosition(kCarNone, 1);
+
+ setCallback(17);
+ setup_savegame(kSavegameTypeEvent, kEventMertensCorpseFloor);
+ }
+ } else {
+ params->param3 = kTimeInvalid;
+
+ if (getObjects()->get(kObjectCompartment1).location == kObjectLocation1) {
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(11);
+ setup_playSound16("CON1018B");
+ break;
+ }
+
+ getSound()->playSound(kEntityPlayer, "LIB014");
+
+ if (getProgress().eventCorpseMovedFromFloor) {
+
+ if (getProgress().jacket == kJacketBlood) {
+ setCallback(13);
+ setup_savegame(kSavegameTypeEvent, kEventMertensBloodJacket);
+ break;
+ }
+
+ if (params->param1) {
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ switch (params->param1) {
+ case 1:
+ setCallback(15);
+ setup_savegame(kSavegameTypeEvent, kEventMertensAugustWaitingCompartment);
+ break;
+
+ case 2:
+ setCallback(16);
+ setup_savegame(kSavegameTypeEvent, kEventMertensKronosInvitationCompartment);
+ break;
+
+ case 3:
+ getAction()->playAnimation(isNight() ? kEventMertensPushCallNight : kEventMertensPushCall);
+ // fallback to default case
+
+ default:
+ getSound()->playSound(kEntityPlayer, "LIB015");
+ getScenes()->loadScene(kScene41);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ } else {
+ setCallback(14);
+ setup_function26(false);
+ }
+ } else {
+ if (!getEntities()->isInsideTrainCar(kEntityPlayer, kCarGreenSleeping))
+ getScenes()->loadSceneFromPosition(kCarNone, 1);
+
+ setCallback(12);
+ setup_savegame(kSavegameTypeEvent, kEventMertensCorpseFloor);
+ }
+ }
+ break;
+
+ case kActionKnock:
+ if (params->param1) {
+ getObjects()->update(kObjectCompartment1, kEntityMertens, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+
+ switch (params->param1) {
+ default:
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorHandKnock, kCursorHand);
+
+ CALLBACK_ACTION();
+ break;
+
+ case 1:
+ setCallback(23);
+ setup_playSound16("CON1018D");
+ break;
+
+ case 2:
+ setCallback(24);
+ setup_playSound16("CON1018E");
+ break;
+
+ case 3:
+ setCallback(25);
+ setup_playSound16("CON1025");
+ break;
+ }
+
+ } else {
+ setCallback(22);
+ setup_function26(true);
+ }
+ break;
+
+ case kActionOpenDoor:
+ getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).location == kObjectLocation1 ? "LIB012" : "LIB014");
+
+ if (getProgress().eventCorpseMovedFromFloor) {
+
+ if (getProgress().jacket == kJacketBlood) {
+ setCallback(27);
+ setup_savegame(kSavegameTypeEvent, kEventMertensBloodJacket);
+ break;
+ }
+
+ if (params->param1) {
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ switch (params->param1) {
+ case 1:
+ setCallback(29);
+ setup_savegame(kSavegameTypeEvent, kEventMertensAugustWaitingCompartment);
+ break;
+
+ case 2:
+ setCallback(30);
+ setup_savegame(kSavegameTypeEvent, kEventMertensKronosInvitationCompartment);
+ break;
+
+ case 3:
+ getAction()->playAnimation(isNight() ? kEventMertensPushCallNight : kEventMertensPushCall);
+ // fallback to default case
+
+ default:
+ getSound()->playSound(kEntityPlayer, "LIB015");
+ getScenes()->loadScene(kScene41);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ } else {
+ setCallback(28);
+ setup_function26(false);
+ }
+ } else {
+ if (!getEntities()->isInsideTrainCar(kEntityPlayer, kCarGreenSleeping))
+ getScenes()->loadSceneFromPosition(kCarNone, 1);
+
+ setCallback(26);
+ setup_savegame(kSavegameTypeEvent, kEventMertensCorpseFloor);
+ }
+ break;
+
+ case kActionDefault:
+ getData()->inventoryItem = kItemNone;
+
+ if (getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, kPosition_8200)
+ || getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, kPosition_7850)
+ || getEntities()->isOutsideAlexeiWindow()) {
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+
+ if (getEntities()->isOutsideAlexeiWindow())
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
+
+ setCallback(params->param1 ? 9 : 8);
+ setup_playSound16(params->param1 ? "CON1018" : "CON1060");
+ } else {
+ getSound()->playSound(kEntityMertens, "CON1019");
+
+ setCallback(1);
+ setup_enterExitCompartment("601Ma", kObjectCompartment1);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (getProgress().eventCorpseMovedFromFloor) {
+ setCallback(4);
+ setup_enterExitCompartment("601Ra", kObjectCompartment1);
+ } else {
+ if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarGreenSleeping)) {
+ setCallback(2);
+ setup_enterExitCompartment("601Ra", kObjectCompartment1);
+ } else {
+ getScenes()->loadSceneFromPosition(kCarNone, 1);
+
+ setCallback(3);
+ setup_savegame(kSavegameTypeEvent, kEventMertensCorpseFloor);
+ }
+ }
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_savegame(kSavegameTypeEvent, kEventMertensCorpseFloor);
+ break;
+
+ case 3:
+ case 12:
+ case 17:
+ case 26:
+ getAction()->playAnimation(kEventMertensCorpseFloor);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, getProgress().eventCorpseFound ? kSceneGameOverStopPolice : kSceneGameOverPolice, true);
+ break;
+
+ case 4:
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMertens);
+
+ if (params->param1) {
+ setCallback(7);
+ setup_enterExitCompartment("601Sa", kObjectCompartment1);
+ break;
+ }
+
+ if (getProgress().eventCorpseThrown || getProgress().chapter != kChapter1) {
+ setCallback(6);
+ setup_function21(kObjectCompartment1, kObjectHandleBathroom);
+ } else {
+ if (!getEntities()->isInsideTrainCar(kEntityPlayer, kCarGreenSleeping))
+ getScenes()->loadSceneFromPosition(kCarNone, 1);
+
+ setCallback(5);
+ setup_savegame(kSavegameTypeEvent, kEventMertensCorpseBed);
+ }
+ break;
+
+ case 5:
+ getAction()->playAnimation(kEventMertensCorpseBed);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverPolice1, true);
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_enterExitCompartment("601Sa", kObjectCompartment1);
+ break;
+
+ case 7:
+ getData()->location = kLocationOutsideCompartment;
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ CALLBACK_ACTION();
+ break;
+
+ case 8:
+ case 9:
+ getObjects()->update(kObjectCompartment1, kEntityMertens, getObjects()->get(kObjectCompartment1).location, kCursorTalk, kCursorHand);
+ break;
+
+ case 10:
+ getObjects()->update(kObjectCompartment1, kEntityMertens, getObjects()->get(kObjectCompartment1).location, kCursorTalk, kCursorHand);
+ goto label_callback10;
+
+ case 11:
+ getObjects()->update(kObjectCompartment1, kEntityMertens, getObjects()->get(kObjectCompartment1).location, kCursorTalk, kCursorHand);
+ goto label_callback11;
+
+ case 13:
+ case 18:
+ case 27:
+ getAction()->playAnimation(kEventMertensBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ break;
+
+ case 14:
+ case 19:
+ case 22:
+ case 28:
+ CALLBACK_ACTION();
+ break;
+
+ case 15:
+ case 20:
+ case 29:
+ getAction()->playAnimation(kEventMertensAugustWaitingCompartment);
+ getProgress().eventMertensAugustWaiting = true;
+
+ getSound()->playSound(kEntityPlayer, "LIB015");
+ getScenes()->loadScene(kScene41);
+
+ CALLBACK_ACTION();
+ break;
+
+ case 16:
+ case 21:
+ case 30:
+ getAction()->playAnimation(kEventMertensKronosInvitationCompartment);
+ getProgress().eventMertensKronosInvitation = true;
+
+ getSound()->playSound(kEntityPlayer, "LIB015");
+ getScenes()->loadScene(kScene41);
+
+ CALLBACK_ACTION();
+ break;
+
+ case 23:
+ getProgress().eventMertensAugustWaiting = true;
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorHandKnock, kCursorHand);
+
+ CALLBACK_ACTION();
+ break;
+
+ case 24:
+ getProgress().eventMertensKronosInvitation = true;
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorHandKnock, kCursorHand);
+
+ CALLBACK_ACTION();
+ break;
+
+ case 25:
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorHandKnock, kCursorHand);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(28, Mertens, function28)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param4 && params->param5) {
+ getSavePoints()->push(kEntityMertens, kEntityCoudert, kAction125499160);
+
+ setCallback(3);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ }
+ break;
+
+ case kActionEndSound:
+ params->param4 = 1;
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function19();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_1500);
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityMertens, "601O");
+ getSavePoints()->push(kEntityMertens, kEntityCoudert, kAction154005632);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function17();
+ break;
+
+ case 4:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction155853632:
+ params->param5 = 1;
+ break;
+
+ case kAction202558662:
+ getEntities()->drawSequenceLeft(kEntityMertens, "601L");
+ getSound()->playSound(kEntityMertens, (char *)&params->seq1);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SS(29, Mertens, function29)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param7 > 1 && params->param8) {
+ getSavePoints()->push(kEntityMertens, kEntityCoudert, kAction125499160);
+
+ setCallback(3);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ }
+ break;
+
+ case kActionEndSound:
+ params->param7++;
+ if (params->param7 == 1)
+ getSound()->playSound(kEntityMertens, (char *)&params->seq2);
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function19();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_1500);
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityMertens, "601O");
+ getSavePoints()->push(kEntityMertens, kEntityCoudert, kAction154005632);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function17();
+ break;
+
+ case 4:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction155853632:
+ params->param8 = 1;
+ break;
+
+ case kAction202558662:
+ getEntities()->drawSequenceLeft(kEntityMertens, "601L");
+ getSound()->playSound(kEntityMertens, (char *)&params->seq1);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(30, Mertens, function30, MertensActionType)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ switch (params->param1) {
+ default:
+ CALLBACK_ACTION();
+ return;
+
+ case 1:
+ params->param2 = kPosition_8200;
+
+ if (getProgress().field_14) {
+ CALLBACK_ACTION();
+ return;
+ }
+
+ getProgress().field_14 = 3;
+ break;
+
+ case 2:
+ params->param2 = kPosition_7500;
+ break;
+
+ case 3:
+ params->param2 = kPosition_6470;
+ break;
+ }
+
+ setCallback(1);
+ setup_function19();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarGreenSleeping, (EntityPosition)params->param2);
+ break;
+
+ case 2:
+ switch (params->param1) {
+ default:
+ if (getProgress().field_14 == 3)
+ getProgress().field_14 = 0;
+
+ setCallback(8);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ break;
+
+ case 1:
+ if (getProgress().chapter == kChapter4)
+ getSavePoints()->push(kEntityMertens, kEntityTatiana, kAction238790488);
+
+ setCallback(3);
+ setup_tylerCompartment(kMertensAction3);
+ break;
+
+ case 2:
+ if (getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, kPosition_7500)) {
+ getObjects()->update(kObjectCompartment2, kEntityPlayer, getObjects()->get(kObjectCompartment2).location, kCursorNormal, kCursorNormal);
+ params->param3 = 1;
+ }
+
+ setCallback(4);
+ setup_enterExitCompartment("601Vb", kObjectCompartment2);
+ break;
+
+ case 3:
+ if (getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, kPosition_6470)) {
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, getObjects()->get(kObjectCompartment3).location, kCursorNormal, kCursorNormal);
+ params->param3 = 1;
+ }
+
+ setCallback(6);
+ setup_enterExitCompartment("601Mc", kObjectCompartment3);
+ break;
+ }
+ break;
+
+ case 3:
+ if (getProgress().field_14 == 3)
+ getProgress().field_14 = 0;
+
+ setCallback(8);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ break;
+
+ case 4:
+ getEntities()->drawSequenceLeft(kEntityMertens, "601Wb");
+ getEntities()->enterCompartment(kEntityMertens, kObjectCompartment2, true);
+
+ setCallback(5);
+ setup_playSound("CON3020");
+ break;
+
+ case 5:
+ if (params->param3)
+ getObjects()->update(kObjectCompartment2, kEntityPlayer, getObjects()->get(kObjectCompartment2).location, kCursorHandKnock, kCursorHand);
+
+ getEntities()->exitCompartment(kEntityMertens, kObjectCompartment2);
+
+ if (getProgress().field_14 == 3)
+ getProgress().field_14 = 0;
+
+ setCallback(8);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ break;
+
+ case 6:
+ getEntities()->drawSequenceLeft(kEntityMertens, "601Nc");
+ getEntities()->enterCompartment(kEntityMertens, kObjectCompartment3, true);
+
+ setCallback(7);
+ setup_playSound("CON3020");
+ break;
+
+ case 7:
+ if (params->param3)
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, getObjects()->get(kObjectCompartment3).location, kCursorHandKnock, kCursorHand);
+
+ getEntities()->exitCompartment(kEntityMertens, kObjectCompartment3);
+
+ if (getProgress().field_14 == 3)
+ getProgress().field_14 = 0;
+
+ setCallback(8);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ break;
+
+ case 8:
+ setCallback(9);
+ setup_function17();
+ break;
+
+ case 9:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(31, Mertens, function31, MertensActionType)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionEndSound:
+ setCallback(3);
+ setup_function17();
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_bloodJacket("601G");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (getSound()->isBuffered(kEntityMertens)) {
+ getEntities()->drawSequenceLeft(kEntityMertens, "601J");
+ } else {
+ setCallback(2);
+ setup_function17();
+ }
+ break;
+
+ case 2:
+ case 3:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(32, Mertens, function32)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function19();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarGreenSleeping, kPosition_9510);
+ break;
+
+ case 2:
+ if (getData()->entityPosition >= kPosition_9460) {
+ getEntities()->clearSequences(kEntityMertens);
+ setCallback(3);
+ setup_function11(900);
+ break;
+ }
+ // Fallback to next case
+
+ case 3:
+ setCallback(4);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_function17();
+ break;
+
+ case 5:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(33, Mertens, function33)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (ENTITY_PARAM(0, 8) || ENTITY_PARAM(0, 6)
+ || ENTITY_PARAM(1, 1) || ENTITY_PARAM(1, 2) || ENTITY_PARAM(1, 3) || ENTITY_PARAM(1, 4) || ENTITY_PARAM(1, 5) || ENTITY_PARAM(1, 6) || ENTITY_PARAM(1, 7)
+ || ENTITY_PARAM(2, 2)) {
+ ENTITY_PARAM(1, 8) = 1;
+
+ setCallback(ENTITY_PARAM(0, 8) ? 1 : 3);
+ setup_updateEntity(kCarGreenSleeping, ENTITY_PARAM(0, 8) ? kPosition_1500 : kPosition_540);
+ } else {
+ CALLBACK_ACTION();
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ ENTITY_PARAM(2, 1) = 1;
+
+ setCallback(2);
+ setup_function14(kEntityVerges);
+ break;
+
+ case 2:
+ ENTITY_PARAM(1, 8) = 0;
+
+ CALLBACK_ACTION();
+ break;
+
+ case 3:
+ getEntities()->clearSequences(kEntityMertens);
+
+ setCallback(4);
+ setup_function11(75);
+ break;
+
+ case 4:
+ if (ENTITY_PARAM(1, 6)) {
+ setCallback(5);
+ setup_function16(true);
+ break;
+ }
+ // Fallback to next case
+
+ case 5:
+ if (ENTITY_PARAM(1, 7)) {
+ setCallback(6);
+ setup_function16(false);
+ break;
+ }
+ // Fallback to next case
+
+ case 6:
+ if (ENTITY_PARAM(1, 5)) {
+ setCallback(7);
+ setup_function15(true);
+ break;
+ }
+ // Fallback to next case
+
+ case 7:
+ if (ENTITY_PARAM(1, 4)) {
+ setCallback(8);
+ setup_function15(false);
+ break;
+ }
+ // Fallback to next case
+
+ case 8:
+ if (ENTITY_PARAM(1, 2)) {
+ setCallback(9);
+ setup_function35();
+ break;
+ }
+ // Fallback to next case
+
+ case 9:
+ if (ENTITY_PARAM(0, 6)) {
+ setCallback(10);
+ setup_function36();
+ break;
+ }
+ // Fallback to next case
+
+ case 10:
+ if (ENTITY_PARAM(1, 3)) {
+ setCallback(11);
+ setup_function40();
+ break;
+ }
+ // Fallback to next case
+
+ case 11:
+ if (ENTITY_PARAM(1, 1)) {
+ setCallback(12);
+ setup_function28("CON1200");
+ break;
+ }
+
+ if (ENTITY_PARAM(2, 2)) {
+ setCallback(13);
+ setup_function37();
+ break;
+ }
+
+ CALLBACK_ACTION();
+ break;
+
+ case 12:
+ getSavePoints()->push(kEntityMertens, kEntityCoudert, kAction168254872);
+ ENTITY_PARAM(1, 1) = 0;
+
+ if (ENTITY_PARAM(2, 2)) {
+ setCallback(13);
+ setup_function37();
+ break;
+ }
+
+ CALLBACK_ACTION();
+ break;
+
+ case 13:
+ ENTITY_PARAM(2, 2) = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(34, Mertens, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getSavePoints()->addData(kEntityMertens, kAction171394341, 7);
+ getSavePoints()->addData(kEntityMertens, kAction169633856, 9);
+ getSavePoints()->addData(kEntityMertens, kAction238732837, 10);
+ getSavePoints()->addData(kEntityMertens, kAction269624833, 12);
+ getSavePoints()->addData(kEntityMertens, kAction302614416, 11);
+ getSavePoints()->addData(kEntityMertens, kAction190082817, 8);
+ getSavePoints()->addData(kEntityMertens, kAction269436673, 13);
+ getSavePoints()->addData(kEntityMertens, kAction303343617, 14);
+ getSavePoints()->addData(kEntityMertens, kAction224122407, 17);
+ getSavePoints()->addData(kEntityMertens, kAction201431954, 18);
+ getSavePoints()->addData(kEntityMertens, kAction188635520, 19);
+ getSavePoints()->addData(kEntityMertens, kAction204379649, 4);
+
+ ENTITY_PARAM(0, 1) = 0;
+
+ getData()->entityPosition = kPosition_9460;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarGreenSleeping;
+
+ break;
+ }
+
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(35, Mertens, function35)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (getProgress().field_14 == 29) {
+ CALLBACK_ACTION();
+ break;
+ } else {
+ getProgress().field_14 = 3;
+
+ setCallback(1);
+ setup_function19();
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarGreenSleeping, kPosition_8200);
+ break;
+
+ case 2:
+ if (!ENTITY_PARAM(1, 2) || getProgress().eventMetAugust) {
+ ENTITY_PARAM(1, 2) = 0;
+
+ if (getProgress().field_14 == 3)
+ getProgress().field_14 = 0;
+
+ setCallback(3);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ } else {
+ setCallback(5);
+ setup_tylerCompartment(kMertensAction1);
+ }
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function17();
+ break;
+
+ case 4:
+ CALLBACK_ACTION();
+ break;
+
+ case 5:
+ if (getProgress().field_14 == 3)
+ getProgress().field_14 = 0;
+
+ if (getProgress().eventMertensAugustWaiting)
+ ENTITY_PARAM(1, 2) = 0;
+
+ setCallback(6);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ break;
+
+ case 6:
+ ENTITY_PARAM(1, 2) = 0;
+
+ setCallback(7);
+ setup_function17();
+ break;
+
+ case 7:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(36, Mertens, function36)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (getProgress().field_14 == 29) {
+ CALLBACK_ACTION();
+ } else {
+ getProgress().field_14 = 3;
+
+ setCallback(1);
+ setup_function19();
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarGreenSleeping, kPosition_8200);
+ 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);
+ }
+ } else {
+ ENTITY_PARAM(0, 6) = 0;
+ ENTITY_PARAM(0, 7) = 0;
+
+ if (getProgress().field_14 == 3)
+ getProgress().field_14 = 0;
+
+ setCallback(5);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ }
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_updateEntity(kCarGreenSleeping, kPosition_8200);
+ break;
+
+ case 4:
+ if (ENTITY_PARAM(0, 6)) {
+ setCallback(7);
+ setup_tylerCompartment(kMertensAction2);
+ } else {
+ ENTITY_PARAM(0, 6) = 0;
+ ENTITY_PARAM(0, 7) = 0;
+
+ if (getProgress().field_14 == 3)
+ getProgress().field_14 = 0;
+
+ setCallback(5);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ }
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_function17();
+ break;
+
+ case 7:
+ if (getProgress().field_14 == 3)
+ getProgress().field_14 = 0;
+
+ if (!getProgress().eventMertensKronosInvitation)
+ ENTITY_PARAM(0, 7) = 1;
+
+ ENTITY_PARAM(0, 6) = 0;
+
+ setCallback(8);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ break;
+
+ case 8:
+ setCallback(9);
+ setup_function17();
+ break;
+
+ case 6:
+ case 9:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(37, Mertens, function37)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1 >= 2 && params->param2) {
+ getSavePoints()->push(kEntityMertens, kEntityCoudert, kAction125499160);
+
+ setCallback(3);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ }
+ break;
+
+ case kActionEndSound:
+ ++params->param6;
+
+ if (params->param6 == 1)
+ getSound()->playSound(kEntityMertens, getEntities()->isDistanceBetweenEntities(kEntityMertens, kEntityPlayer, 2000) ? "CON1152" : "CON1151");
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function19();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_1500);
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityMertens, "601O");
+ getSavePoints()->push(kEntityMertens, kEntityCoudert, kAction154005632);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function17();
+ break;
+
+ case 4:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction155853632:
+ params->param2 = 1;
+ break;
+
+ case kAction202558662:
+ getEntities()->drawSequenceLeft(kEntityMertens, "601L");
+ getSound()->playSound(kEntityMertens, "CON1150");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(38, Mertens, function38)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (!ENTITY_PARAM(0, 4)) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (getProgress().field_14 == 29) {
+ CALLBACK_ACTION();
+ } else {
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_8200);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (!ENTITY_PARAM(0, 4)) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ setCallback(2);
+ setup_tylerCompartment(kMertensActionNone);
+ break;
+
+ case 2:
+ ENTITY_PARAM(0, 4) = 0;
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(39, Mertens, function39)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ ENTITY_PARAM(0, 4) = 1;
+
+ setCallback(1);
+ setup_function19();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function22();
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function33();
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function24();
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_function33();
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_function25();
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_function33();
+ break;
+
+ case 7:
+ setCallback(8);
+ setup_function38();
+ break;
+
+ case 8:
+ if (getProgress().field_14 == 3)
+ getProgress().field_14 = 0;
+
+ setCallback(9);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ break;
+
+ case 9:
+ setCallback(10);
+ setup_function17();
+ break;
+
+ case 10:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(40, Mertens, function40)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ ENTITY_PARAM(1, 3) = 0;
+ setCallback(1);
+ setup_function19();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarKronos, kPosition_9460);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function11(1800);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_updateEntity(kCarGreenSleeping, kPosition_1500);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_function17();
+ break;
+
+ case 5:
+ ENTITY_PARAM(0, 6) = 1;
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(41, Mertens, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function17();
+ break;
+
+ case 2:
+ setup_function42();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(42, Mertens, function42)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (ENTITY_PARAM(2, 3)) {
+ ENTITY_PARAM(0, 1) = 1;
+ ENTITY_PARAM(0, 6) = 0;
+ ENTITY_PARAM(0, 7) = 0;
+ ENTITY_PARAM(0, 8) = 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;
+
+ ENTITY_PARAM(2, 1) = 0; // BUG: is set twice. Maybe a bug?
+ ENTITY_PARAM(2, 2) = 0;
+ ENTITY_PARAM(2, 3) = 0;
+
+ params->param1 = 1;
+ params->param2 = 1;
+
+ getEntities()->drawSequenceLeft(kEntityMertens, "601E");
+ }
+
+ if (ENTITY_PARAM(2, 1) || getProgress().eventCorpseFound || getEvent(kEventMertensAskTylerCompartmentD) || getEvent(kEventMertensAskTylerCompartment))
+ getData()->inventoryItem = kItemNone;
+ else
+ getData()->inventoryItem = kItemInvalid;
+
+ if (!params->param2) {
+ TIME_CHECK_SAVEPOINT(kTime1125000, params->param3, kEntityMertens, kEntityMahmud, kAction170483072);
+
+ if (params->param4 != kTimeInvalid && getState()->time > kTimeCityChalons) {
+
+ if (getState()->time <= kTime1188000) {
+ if ((!getEntities()->isPlayerInCar(kCarGreenSleeping) && !getEntities()->isPlayerInCar(kCarRedSleeping))
+ || getSound()->isBuffered("REB1205")
+ || !getEntities()->isInsideCompartment(kEntityMmeBoutarel, kCarRedSleeping, kPosition_5790)
+ || !params->param4) {
+ params->param4 = getState()->time;
+ }
+
+ if (params->param4 >= getState()->time)
+ break;
+ }
+
+ ENTITY_PARAM(0, 4) = kTimeInvalid;
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(8);
+ setup_function29("CON1210", "CON1210A");
+ break;
+ }
+ }
+
+label_callback_8:
+ if (getState()->time > kTime1215000 && !ENTITY_PARAM(0, 1) && !ENTITY_PARAM(2, 1)) {
+ UPDATE_PARAM_PROC(params->param5, getState()->time, 2700)
+ getEntities()->drawSequenceLeft(kEntityMertens, "601E");
+ ENTITY_PARAM(0, 1) = 1;
+ params->param5 = 0;
+ UPDATE_PARAM_PROC_END
+ }
+
+ if (ENTITY_PARAM(0, 8)) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(9);
+ setup_function14(kEntityVerges);
+ break;
+ }
+
+ if (getProgress().field_14 == 29)
+ goto label_callback_13;
+
+label_callback_9:
+ if (ENTITY_PARAM(1, 6)) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(10);
+ setup_function16(true);
+ break;
+ }
+
+label_callback_10:
+ if (ENTITY_PARAM(1, 7)) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(11);
+ setup_function16(false);
+ break;
+ }
+
+label_callback_11:
+ if (ENTITY_PARAM(1, 5)) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(12);
+ setup_function15(true);
+ break;
+ }
+
+label_callback_12:
+ if (ENTITY_PARAM(1, 4)) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(13);
+ setup_function15(false);
+ break;
+ }
+
+label_callback_13:
+ if (ENTITY_PARAM(1, 2)) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(14);
+ setup_function35();
+ break;
+ }
+
+label_callback_14:
+ if (ENTITY_PARAM(0, 6)) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(15);
+ setup_function36();
+ break;
+ }
+
+label_callback_15:
+ if (ENTITY_PARAM(1, 3)) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(16);
+ setup_function40();
+ break;
+ }
+
+label_callback_16:
+ if (ENTITY_PARAM(1, 1)) {
+ ENTITY_PARAM(1, 1) = 0;
+ getData()->inventoryItem = kItemNone;
+ setCallback(17);
+ setup_function28("CON1200");
+ break;
+ }
+
+label_callback_17:
+ if (ENTITY_PARAM(2, 2)) {
+ ENTITY_PARAM(2, 2) = 0;
+ getData()->inventoryItem = kItemNone;
+ setCallback(18);
+ setup_function37();
+ break;
+ }
+
+label_callback_18:
+ if (!params->param1 && ENTITY_PARAM(0, 5)) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(19);
+ setup_function39();
+ break;
+ }
+
+label_callback_19:
+ if (ENTITY_PARAM(0, 1) && !getSound()->isBuffered(kEntityMertens)) {
+ if (getProgress().field_18 != 4)
+ getSound()->playSound(kEntityMertens, "CON1505");
+ }
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+ setCallback(21);
+ setup_savegame(kSavegameTypeEvent, kEventMertensAskTylerCompartmentD);
+ break;
+
+ case kAction11:
+ if (!ENTITY_PARAM(0, 1) && !ENTITY_PARAM(2, 1)) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(20);
+ setup_function13((bool)savepoint.param.intValue, (bool)savepoint.entity2);
+ }
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarGreenSleeping;
+ getData()->entityPosition = kPosition_1500;
+ getData()->location = kLocationOutsideCompartment;
+ getScenes()->loadSceneFromItemPosition(kItem7);
+ break;
+
+ case kActionDrawScene:
+ if (ENTITY_PARAM(2, 1))
+ break;
+
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 23) && ENTITY_PARAM(0, 7) && !getEvent(kEventKronosConversation)) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventMertensKronosInvitation);
+ break;
+ }
+
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 23) && !getProgress().eventMertensKronosInvitation && !getEvent(kEventMertensLastCar) && !getEvent(kEventMertensLastCarOriginalJacket)) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventMertensLastCar);
+ break;
+ }
+
+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);
+ break;
+ }
+
+label_callback_5_6:
+ if (getEntities()->isPlayerInCar(kCarGreenSleeping) && getData()->entityPosition < getEntityData(kEntityPlayer)->entityPosition) {
+ if (getProgress().jacket == kJacketOriginal || ENTITY_PARAM(0, 7)) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(7);
+ setup_function32();
+ }
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getAction()->playAnimation(kEventMertensKronosInvitation);
+ getProgress().eventMertensKronosInvitation = true;
+ ENTITY_PARAM(0, 6) = 0;
+ ENTITY_PARAM(0, 7) = 0;
+ getEntities()->drawSequenceRight(kEntityMertens, "601A");
+ getScenes()->loadSceneFromItemPosition(kItem7);
+ ENTITY_PARAM(0, 1) = 0;
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(2);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 2:
+ case 4:
+ getEntities()->drawSequenceLeft(kEntityMertens, "601B");
+ goto label_callback_2_4;
+
+ case 3:
+ getAction()->playAnimation(getProgress().jacket == kJacketOriginal ? kEventMertensLastCarOriginalJacket : kEventMertensLastCar);
+ getEntities()->drawSequenceRight(kEntityMertens, "601A");
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 6);
+ getScenes()->loadSceneFromItemPosition(kItem7);
+ ENTITY_PARAM(0, 1) = 0;
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(4);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 5:
+ case 6:
+ goto label_callback_5_6;
+
+ case 8:
+ goto label_callback_8;
+
+ case 9:
+ goto label_callback_9;
+
+ case 10:
+ goto label_callback_10;
+
+ case 11:
+ goto label_callback_11;
+
+ case 12:
+ goto label_callback_12;
+
+ case 13:
+ goto label_callback_13;
+
+ case 14:
+ goto label_callback_14;
+
+ case 15:
+ goto label_callback_15;
+
+ case 16:
+ goto label_callback_16;
+
+ case 17:
+ goto label_callback_17;
+
+ case 18:
+ goto label_callback_18;
+
+ case 19:
+ params->param1 = 1;
+ goto label_callback_19;
+
+ case 21:
+ getAction()->playAnimation(kEventMertensAskTylerCompartmentD);
+ getEntities()->drawSequenceRight(kEntityMertens, "601A");
+ getInventory()->get(kItem7)->location = kObjectLocationNone;
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 25);
+
+ setCallback(22);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 22:
+ getEntities()->drawSequenceLeft(kEntityMertens, "601B");
+ break;
+ }
+ break;
+
+ case kAction225358684:
+ if (!ENTITY_PARAM(0, 1)) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(23);
+ setup_function30((MertensActionType)savepoint.param.intValue);
+ }
+ break;
+
+ case kAction225932896:
+ if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1))
+ getSavePoints()->push(kEntityMertens, kEntityFrancois, kAction205346192);
+ break;
+
+ case kAction305159806:
+ if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1)) {
+ getData()->inventoryItem = kItemNone;
+ setCallback(24);
+ setup_function31((MertensActionType)savepoint.param.intValue);
+ }
+ break;
+
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(43, Mertens, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setCallback(1);
+ setup_function17();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityMertens);
+
+ getData()->entityPosition = kPosition_1500;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ getData()->inventoryItem = kItemNone;
+
+ 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;
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function44();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(44, Mertens, function44)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (ENTITY_PARAM(1, 6)) {
+ setCallback(1);
+ setup_function16(true);
+ break;
+ }
+
+label_callback1:
+ if (ENTITY_PARAM(1, 7)) {
+ setCallback(2);
+ setup_function16(false);
+ break;
+ }
+
+label_callback2:
+ if (ENTITY_PARAM(1, 5)) {
+ setCallback(3);
+ setup_function15(true);
+ break;
+ }
+
+label_callback3:
+ if (ENTITY_PARAM(1, 4)) {
+ setCallback(4);
+ setup_function15(false);
+ break;
+ }
+
+ break;
+
+ case kAction11:
+ if (!ENTITY_PARAM(2, 1)) {
+ setCallback(5);
+ setup_function13((bool)savepoint.param.intValue, (bool)savepoint.entity2);
+ }
+ break;
+
+ case kActionDrawScene:
+ if (ENTITY_PARAM(2, 1))
+ break;
+
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 1)) {
+ setCallback(6);
+ setup_function13(true, false);
+
+ } else if (getEntities()->isPlayerPosition(kCarGreenSleeping, 23)) {
+ setCallback(7);
+ setup_function13(false, false);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_callback1;
+
+ case 2:
+ goto label_callback2;
+
+ case 3:
+ goto label_callback3;
+ }
+ break;
+
+ case kAction225358684:
+ if (!ENTITY_PARAM(0, 1)) {
+ setCallback(9);
+ setup_function30((MertensActionType)savepoint.param.intValue);
+ }
+ break;
+
+ case kAction225932896:
+ if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1))
+ getSavePoints()->push(kEntityMertens, kEntityFrancois, kAction205346192);
+ break;
+
+ case kAction226078300:
+ if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1)) {
+ setCallback(8);
+ setup_playSound("CON2020");
+ }
+ break;
+
+ case kAction305159806:
+ if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1)) {
+ setCallback(10);
+ setup_function31((MertensActionType)savepoint.param.intValue);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(45, Mertens, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setCallback(1);
+ setup_function17();
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_1500;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ getData()->inventoryItem = kItemNone;
+
+ ENTITY_PARAM(0, 6) = 0;
+ ENTITY_PARAM(0, 8) = 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;
+
+ ENTITY_PARAM(2, 3) = 0;
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function46();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(46, Mertens, function46)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (ENTITY_PARAM(1, 6)) {
+ setCallback(1);
+ setup_function16(true);
+ break;
+ }
+
+label_callback_1:
+ if (ENTITY_PARAM(1, 7)) {
+ setCallback(2);
+ setup_function16(false);
+ break;
+ }
+
+label_callback_2:
+ if (ENTITY_PARAM(1, 5)) {
+ setCallback(3);
+ setup_function15(true);
+ break;
+ }
+
+label_callback_3:
+ if (ENTITY_PARAM(1, 4)) {
+ setCallback(4);
+ setup_function15(false);
+ break;
+ }
+
+label_callback_4:
+ if (ENTITY_PARAM(0, 8)) {
+ setCallback(5);
+ setup_function14(kEntityVerges);
+ break;
+ }
+
+label_callback_5:
+ if (ENTITY_PARAM(2, 4)
+ && (getEvent(kEventKronosVisit) || getState()->time > kTime2052000)
+ && getState()->time < kTime2133000
+ && getEntities()->isPlayerInCar(kCarGreenSleeping)) {
+ setCallback(6);
+ setup_function32();
+ break;
+ }
+
+label_callback_6:
+ TIME_CHECK_CALLBACK_1(kTime1971000, params->param1, 7, setup_function28, "CON3012");
+
+label_callback_7:
+ TIME_CHECK_CALLBACK(kTime2117700, params->param2, 8, setup_function32);
+
+label_callback_8:
+ TIME_CHECK_CALLBACK_1(kTime2124000, params->param3, 9, setup_function28, "CON2010");
+
+label_callback_9:
+ TIME_CHECK_CALLBACK(kTime2146500, params->param4, 10, setup_function32);
+
+label_callback_10:
+ TIME_CHECK_CALLBACK(kTime2169000, params->param5, 11, setup_function32);
+ break;
+
+ case kAction11:
+ if (!ENTITY_PARAM(2, 1)) {
+ setCallback(12);
+ setup_function13((bool)savepoint.param.intValue, savepoint.entity2 != kEntityPlayer);
+ }
+ break;
+
+ case kActionDefault:
+ break;
+
+ case kActionDrawScene:
+ if (!ENTITY_PARAM(2, 1)) {
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 1)) {
+ setCallback(13);
+ setup_function13(true, false);
+ } else if (getEntities()->isPlayerPosition(kCarGreenSleeping, 23)) {
+ setCallback(14);
+ setup_function13(false, false);
+ }
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_callback_1;
+
+ case 2:
+ goto label_callback_2;
+
+ case 3:
+ goto label_callback_3;
+
+ case 4:
+ goto label_callback_4;
+
+ case 5:
+ goto label_callback_5;
+
+ case 6:
+ goto label_callback_6;
+
+ case 7:
+ goto label_callback_7;
+
+ case 8:
+ goto label_callback_8;
+
+ case 9:
+ goto label_callback_9;
+
+ case 10:
+ goto label_callback_10;
+ }
+ break;
+
+ case kAction225358684:
+ if (!ENTITY_PARAM(0, 1)) {
+ setCallback(16);
+ setup_function30((MertensActionType)savepoint.param.intValue);
+ }
+ break;
+
+ case kAction225932896:
+ if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1))
+ getSavePoints()->push(kEntityMertens, kEntityFrancois, kAction205346192);
+ break;
+
+ case kAction226078300:
+ if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1)) {
+ setCallback(15);
+ setup_playSound("CON2020");
+ }
+ break;
+
+ case kAction305159806:
+ if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1)) {
+ setCallback(17);
+ setup_function31((MertensActionType)savepoint.param.intValue);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(47, Mertens, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setCallback(1);
+ setup_function17();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityMertens);
+
+ getData()->entityPosition = kPosition_1500;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ getData()->inventoryItem = kItemNone;
+
+ ENTITY_PARAM(0, 6) = 0;
+ ENTITY_PARAM(0, 8) = 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;
+
+ ENTITY_PARAM(2, 4) = 0;
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function48();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(48, Mertens, function48)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (ENTITY_PARAM(2, 3)) {
+ params->param1 = 1;
+
+ getObjects()->updateLocation2(kObjectCompartment2, kObjectLocation1);
+ getObjects()->updateLocation2(kObjectCompartment3, kObjectLocation1);
+ getObjects()->updateLocation2(kObjectCompartment4, kObjectLocation1);
+
+ ENTITY_PARAM(1, 4) = 0;
+ ENTITY_PARAM(1, 5) = 0;
+ ENTITY_PARAM(1, 6) = 0;
+ ENTITY_PARAM(1, 7) = 0;
+
+ getEntities()->drawSequenceLeft(kEntityMertens, "601E");
+
+ ENTITY_PARAM(2, 3) = 0;
+ }
+
+ if (ENTITY_PARAM(1, 6)) {
+ setCallback(1);
+ setup_function16(true);
+ break;
+ }
+
+label_callback_1:
+ if (ENTITY_PARAM(1, 7)) {
+ setCallback(2);
+ setup_function16(false);
+ break;
+ }
+
+label_callback_2:
+ if (ENTITY_PARAM(1, 5)) {
+ setCallback(3);
+ setup_function15(true);
+ break;
+ }
+
+label_callback_3:
+ if (ENTITY_PARAM(1, 4)) {
+ setCallback(4);
+ setup_function15(false);
+ break;
+ }
+
+label_callback_4:
+ if (!params->param1) {
+ TIME_CHECK_CALLBACK(kTime2403000, params->param2, 5, setup_function49);
+
+label_callback_5:
+ TIME_CHECK_CALLBACK(kTime2430000, params->param3, 6, setup_function32);
+
+label_callback_6:
+ TIME_CHECK_CALLBACK(kTime2439000, params->param4, 7, setup_function32);
+
+label_callback_7:
+ TIME_CHECK_CALLBACK(kTime2448000, params->param5, 8, setup_function32);
+ }
+
+label_callback_8:
+ if (getState()->time > kTime2538000 && !ENTITY_PARAM(0, 1) && !ENTITY_PARAM(2, 1)) {
+ UPDATE_PARAM(params->param6, getState()->time, 2700);
+
+ getEntities()->drawSequenceLeft(kEntityMertens, "601E");
+
+ ENTITY_PARAM(0, 1) = 1;
+ params->param6 = 0;
+ }
+ break;
+
+ case kAction11:
+ if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1)) {
+ setCallback(9);
+ setup_function13((bool)savepoint.param.intValue, savepoint.entity2 != kEntityPlayer);
+ }
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarGreenSleeping;
+ getData()->entityPosition = kPosition_1500;
+ getData()->location = kLocationOutsideCompartment;
+
+ getScenes()->loadSceneFromItemPosition(kItem7);
+ break;
+
+ case kActionDrawScene:
+ if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1)) {
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 1)) {
+ setCallback(10);
+ setup_function13(true, false);
+ } else if (getEntities()->isPlayerPosition(kCarGreenSleeping, 23)) {
+ setCallback(11);
+ setup_function13(false, false);
+ }
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_callback_1;
+
+ case 2:
+ goto label_callback_2;
+
+ case 3:
+ goto label_callback_3;
+
+ case 4:
+ goto label_callback_4;
+
+ case 5:
+ goto label_callback_5;
+
+ case 6:
+ goto label_callback_6;
+
+ case 7:
+ goto label_callback_7;
+
+ case 8:
+ goto label_callback_8;
+ }
+ break;
+
+ case kAction225358684:
+ if (!ENTITY_PARAM(0, 1)) {
+ setCallback(13);
+ setup_function30((MertensActionType)savepoint.param.intValue);
+ }
+ break;
+
+ case kAction226078300:
+ if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1)) {
+ setCallback(12);
+ setup_playSound("CON2020");
+ }
+ break;
+
+ case kAction305159806:
+ if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1)) {
+ setCallback(14);
+ setup_function31((MertensActionType)savepoint.param.intValue);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(49, Mertens, function49)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function19();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarGreenSleeping, kPosition_8200);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_tylerCompartment(kMertensActionNone);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function33();
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_function25();
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_function33();
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_function24();
+ break;
+
+ case 7:
+ setCallback(8);
+ setup_function33();
+ break;
+
+ case 8:
+ setCallback(9);
+ setup_function23();
+ break;
+
+ case 9:
+ setCallback(10);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ break;
+
+ case 10:
+ setCallback(11);
+ setup_function17();
+ break;
+
+ case 11:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(50, Mertens, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityMertens);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(51, Mertens, chapter5Handler)
+ if (savepoint.action == kActionProceedChapter5)
+ setup_function52();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(52, Mertens, function52)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param2 == kTimeInvalid)
+ break;
+
+ if (params->param1 >= getState()->time) {
+
+ if (!getEntities()->isPlayerInCar(kCarRedSleeping) || !params->param2)
+ params->param2 = getState()->time;
+
+ if (params->param2 >= getState()->time)
+ break;
+ }
+
+ params->param2 = kTimeInvalid;
+
+ setCallback(1);
+ setup_playSound("Mme5010");
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ params->param1 = getState()->time + 4500;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("671Ad", kObjectCompartmentD);
+ break;
+
+ case 2:
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityMertens, kEntityMmeBoutarel, kAction155604840);
+ setup_function53();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(53, Mertens, function53)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1) {
+ UPDATE_PARAM(params->param4, getState()->timeTicks, 75);
+
+ params->param1 = 0;
+ params->param2 = 0;
+
+ getObjects()->update(kObjectCompartment4, kEntityMertens, kObjectLocation1, kCursorNormal, kCursorNormal);
+ }
+
+ params->param4 = 0;
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ if (params->param1) {
+ getObjects()->update(kObjectCompartment4, kEntityMertens, kObjectLocation1, kCursorNormal, kCursorNormal);
+ params->param1 = 0;
+
+ setCallback(3);
+ setup_playSound(getSound()->justCheckingCath());
+ }
+
+ setCallback(savepoint.action == kActionKnock ? 4 : 5);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_5790);
+ break;
+
+ case kActionDrawScene:
+ if (params->param2 || params->param1) {
+ params->param1 = 0;
+ params->param2 = 0;
+ params->param3 = 0;
+
+ getObjects()->update(kObjectCompartment4, kEntityMertens, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("601ZD", kObjectCompartment4);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityMertens);
+ getData()->location = kLocationInsideCompartment;
+ getData()->entityPosition = kPosition_5790;
+ // Fallback to next case
+
+ case 3:
+ getObjects()->update(kObjectCompartment4, kEntityMertens, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case 4:
+ case 5:
+ params->param3++;
+
+ if (params->param3 == 1) {
+ getObjects()->update(kObjectCompartment4, kEntityMertens, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(6);
+ setup_playSound("Con5002");
+
+ } else if (params->param3 == 2) {
+ getObjects()->update(kObjectCompartment4, kEntityMertens, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(7);
+ setup_playSound("Con5002A");
+ }
+ break;
+
+ case 6:
+ params->param1 = 1;
+ getObjects()->update(kObjectCompartment4, kEntityMertens, kObjectLocation1, kCursorTalk, kCursorNormal);
+ break;
+
+ case 7:
+ params->param2 = 1;
+ break;
+ }
+ break;
+
+ case kAction135800432:
+ setup_nullfunction();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_NULL_FUNCTION(54, Mertens)
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/mertens.h b/engines/lastexpress/entities/mertens.h
new file mode 100644
index 0000000000..c6b800f1ff
--- /dev/null
+++ b/engines/lastexpress/entities/mertens.h
@@ -0,0 +1,220 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_MERTENS_H
+#define LASTEXPRESS_MERTENS_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Mertens : public Entity {
+private:
+ // The type of action when entering Tyler compartment
+ enum MertensActionType {
+ kMertensActionNone = 0,
+ kMertensAction1 = 1,
+ kMertensAction2 = 2,
+ kMertensAction3 = 3
+ };
+
+public:
+ Mertens(LastExpressEngine *engine);
+ ~Mertens() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Handle meeting Coudert with the blooded jacket
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(bloodJacket, const char *sequence)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Handles entering/exiting a compartment and updates position/play animation
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment2, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ * @param entityPosition1 The entity position
+ * @param entityPosition1 The entity position to check
+ *
+ * @note We are not using the shared function due to too many differences
+ */
+ DECLARE_FUNCTION_4(enterExitCompartment3, const char* sequence, ObjectIndex compartment, EntityPosition entityPosition1, EntityPosition entityPosition2)
+
+ /**
+ * Process callback action when the entity direction is not kDirectionRight
+ */
+ DECLARE_FUNCTION(callbackActionOnDirection)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound16, const char* filename)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ DECLARE_FUNCTION_1(function11, uint32 time)
+
+ /**
+ * Says "Bonsoir" to another character
+ *
+ * @param entity The entity
+ */
+ DECLARE_FUNCTION_1(bonsoir, EntityIndex entity)
+ DECLARE_FUNCTION_2(function13, bool, bool)
+ DECLARE_FUNCTION_1(function14, EntityIndex entity)
+ DECLARE_FUNCTION_1(function15, bool)
+ DECLARE_FUNCTION_1(function16, bool)
+ DECLARE_FUNCTION(function17)
+ DECLARE_FUNCTION(function18)
+ DECLARE_FUNCTION(function19)
+ DECLARE_FUNCTION(function20)
+
+ /**
+ * ???
+ *
+ * @param object1 First object index
+ * @param object2 Second object index
+ */
+ DECLARE_FUNCTION_2(function21, ObjectIndex object1, ObjectIndex object2)
+ DECLARE_FUNCTION(function22)
+ DECLARE_FUNCTION(function23)
+ DECLARE_FUNCTION(function24)
+ DECLARE_FUNCTION(function25)
+ DECLARE_FUNCTION_1(function26, bool)
+ DECLARE_FUNCTION_1(tylerCompartment, MertensActionType action)
+ DECLARE_FUNCTION_1(function28, const char *soundName)
+ DECLARE_FUNCTION_2(function29, const char *soundName1, const char *soundName2)
+ DECLARE_FUNCTION_1(function30, MertensActionType action)
+ DECLARE_FUNCTION_1(function31, MertensActionType action)
+ DECLARE_FUNCTION(function32)
+ DECLARE_FUNCTION(function33)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+ DECLARE_FUNCTION(function35)
+ DECLARE_FUNCTION(function36)
+ DECLARE_FUNCTION(function37)
+ DECLARE_FUNCTION(function38)
+ DECLARE_FUNCTION(function39)
+ DECLARE_FUNCTION(function40)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function42)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ DECLARE_FUNCTION(function44)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ DECLARE_FUNCTION(function46)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ DECLARE_FUNCTION(function48)
+ DECLARE_FUNCTION(function49)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_FUNCTION(function52)
+ DECLARE_FUNCTION(function53)
+
+ DECLARE_NULL_FUNCTION()
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_MERTENS_H
diff --git a/engines/lastexpress/entities/milos.cpp b/engines/lastexpress/entities/milos.cpp
new file mode 100644
index 0000000000..30ed546106
--- /dev/null
+++ b/engines/lastexpress/entities/milos.cpp
@@ -0,0 +1,1077 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/milos.h"
+
+#include "lastexpress/game/action.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"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+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(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(Milos, chapter1);
+ ADD_CALLBACK_FUNCTION(Milos, function13);
+ ADD_CALLBACK_FUNCTION(Milos, function14);
+ ADD_CALLBACK_FUNCTION(Milos, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Milos, function16);
+ ADD_CALLBACK_FUNCTION(Milos, function17);
+ ADD_CALLBACK_FUNCTION(Milos, function18);
+ ADD_CALLBACK_FUNCTION(Milos, chapter2);
+ ADD_CALLBACK_FUNCTION(Milos, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Milos, function21);
+ ADD_CALLBACK_FUNCTION(Milos, chapter3);
+ 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(Milos, chapter4);
+ ADD_CALLBACK_FUNCTION(Milos, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Milos, function30);
+ ADD_CALLBACK_FUNCTION(Milos, function31);
+ ADD_CALLBACK_FUNCTION(Milos, function32);
+ ADD_CALLBACK_FUNCTION(Milos, chapter5);
+ ADD_CALLBACK_FUNCTION(Milos, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(Milos, function35);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Milos, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(2, Milos, draw)
+ Entity::draw(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(3, Milos, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(4, Milos, enterExitCompartment2, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(5, Milos, callbackActionOnDirection)
+ Entity::callbackActionOnDirection(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(6, Milos, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(7, Milos, playSound16)
+ Entity::playSound(savepoint, false, SoundManager::kFlagDefault);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(8, Milos, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(9, Milos, updateFromTime, uint32)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(10, Milos, enterCompartmentDialog, CarIndex, EntityPosition)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ case kActionDefault:
+ if (getEntities()->updateEntity(kEntityMilos, (CarIndex)params->param1, (EntityPosition)params->param2))
+ CALLBACK_ACTION();
+ break;
+
+ case kActionExcuseMeCath:
+ case kActionExcuseMe:
+ if (getEvent(kEventMilosTylerCompartmentDefeat)) {
+ // Robert saying: "Milos"
+ switch(rnd(3)) {
+ default:
+ case 0:
+ getSound()->playSound(kEntityPlayer, "CAT1014");
+ break;
+
+ case 1:
+ getSound()->playSound(kEntityPlayer, "CAT1014A");
+ break;
+
+ case 2:
+ getSound()->playSound(kEntityPlayer, "CAT1014B");
+ break;
+ }
+ } else {
+ getSound()->excuseMeCath();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(11, Milos, function11, TimeValue)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ error("Milos: callback function 11 not implemented!");
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorNormal, kCursorNormal);
+
+ if (params->param2) {
+ if (getInventory()->hasItem(kItemPassengerList)) {
+ setCallback(10);
+ setup_playSound((rnd(2) ? "CAT1504" : getSound()->wrongDoorCath()));
+ } else {
+ setCallback(11);
+ setup_playSound(getSound()->wrongDoorCath());
+ }
+ } else {
+ if (savepoint.action == kActionKnock) {
+ setCallback(7);
+ setup_playSound("LIB012");
+ } else {
+ setCallback(8);
+ setup_playSound("LIB013");
+ }
+ }
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionDrawScene:
+ if (params->param3 || params->param2) {
+ getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ params->param3 = 0;
+ params->param2 = 0;
+ }
+ break;
+
+ case kActionCallback:
+ switch(getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ setCallback(2);
+ setup_enterCompartmentDialog(kCarGreenSleeping, kPosition_8200);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function14();
+ break;
+
+ case 3:
+ if (getProgress().field_14 == 14)
+ getProgress().field_14 = 0;
+
+ params->param6 = 1;
+ setCallback(4);
+ setup_enterCompartmentDialog(kCarRedSleeping, kPosition_3050);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_enterExitCompartment("609Bg", kObjectCompartmentG);
+ break;
+
+ case 5:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMilos);
+ getSavePoints()->push(kEntityMilos, kEntityVesna, kAction101687594);
+ getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ break;
+
+ case 6:
+ getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ break;
+
+ case 7:
+ case 8:
+ setCallback(9);
+ // Milos asking: "Yeah? Who is it?"
+ setup_playSound("MIL1117A");
+ break;
+
+ case 9:
+ getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorTalk, kCursorNormal);
+ params->param2 = 1;
+ break;
+
+ case 10:
+ case 11:
+ params->param2 = 0;
+ params->param3 = 1;
+ break;
+
+ case 12:
+ getEntities()->drawSequenceLeft(kEntityMilos, "611Cg");
+ getEntities()->enterCompartment(kEntityMilos, kObjectCompartmentG, true);
+ getSavePoints()->push(kEntityMilos, kEntityCoudert, kAction88652208);
+ break;
+
+ case 13:
+ getEntities()->exitCompartment(kEntityMilos, kObjectCompartmentG, true);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMilos);
+ getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ params->param5 = 0;
+ break;
+
+ }
+ break;
+
+ case kAction122865568:
+ getData()->location = kLocationOutsideCompartment;
+ setCallback(12);
+ setup_enterExitCompartment("611Bg", kObjectCompartmentG);
+ break;
+
+ case kAction123852928:
+ params->param1 = 13;
+ setup_enterExitCompartment("611Dg", kObjectCompartmentG);
+ break;
+
+ case kAction221683008:
+ params->param5 = 1;
+ getSavePoints()->push(kEntityMilos, kEntityCoudert, kAction123199584);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Milos, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentG, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject46, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ getData()->entityPosition = kPosition_4689;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+
+ getSavePoints()->addData(kEntityMilos, kAction157691176, 0);
+ getSavePoints()->addData(kEntityMilos, kAction208228224, 2);
+ getSavePoints()->addData(kEntityMilos, kAction259125998, 3);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Milos, function13)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ getSavePoints()->push(kEntityMilos, kEntityTables2, kActionDrawTablesWithChairs, "009E");
+ getEntities()->clearSequences(kEntityVesna);
+ getEntities()->clearSequences(kEntityIvo);
+ getEntities()->clearSequences(kEntitySalko);
+
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(kEntitySalko, "009D5");
+ getEntities()->drawSequenceRight(kEntityTables2, "009D4");
+ getEntities()->drawSequenceRight(kEntityIvo, "009D3");
+ getEntities()->drawSequenceRight(kEntityVesna, "009D2");
+ getEntities()->drawSequenceRight(kEntityMilos, "009D1");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Milos, function14)
+ error("Milos: callback function 14 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Milos, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_SAVEPOINT(kTime1071000, params->param3, kEntityMilos, kEntityServers1, kAction223002560);
+
+ if (getState()->time > kTime1089000 && getEntities()->isSomebodyInsideRestaurantOrSalon()) {
+ setup_function16();
+ break;
+ }
+
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 61) && !params->param1) {
+ UPDATE_PARAM_PROC(params->param4, getState()->timeTicks, 45)
+ setCallback(1);
+ setup_draw("009C");
+ break;
+ UPDATE_PARAM_PROC_END
+ }
+
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 70) && !params->param2) {
+ UPDATE_PARAM(params->param5, getState()->timeTicks, 45);
+
+ setCallback(2);
+ setup_draw("009C");
+ }
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityMilos, kEntityTables2, kAction136455232);
+ getEntities()->drawSequenceLeft(kEntityMilos, "009A");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceLeft(kEntityMilos, "009A");
+ params->param1 = 1;
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityMilos, "009A");
+ params->param2 = 1;
+ break;
+ }
+ break;
+ }
+
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Milos, function16)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1) {
+ if (getEntities()->isDistanceBetweenEntities(kEntityMilos, kEntityVesna, 750)
+ || getEntities()->checkDistanceFromPosition(kEntityVesna, kPosition_3050, 500)) {
+ getSavePoints()->push(kEntityMilos, kEntityVesna, kAction123668192);
+
+ setCallback(5);
+ setup_enterExitCompartment("611Ag", kObjectCompartmentG);
+ }
+ }
+ break;
+
+ case kActionDefault:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_function13();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityMilos, kEntityServers1, kAction269485588);
+ getSavePoints()->push(kEntityMilos, kEntityIvo, kAction125242096);
+ getEntities()->drawSequenceRight(kEntityMilos, "807DS");
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityMilos);
+
+ setCallback(2);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityMilos);
+ break;
+
+ case 3:
+ if (getEntities()->isDistanceBetweenEntities(kEntityMilos, kEntityVesna, 750)
+ || getEntities()->checkDistanceFromPosition(kEntityVesna, kPosition_3050, 500)) {
+ getSavePoints()->push(kEntityMilos, kEntityVesna, kAction123668192);
+
+ setCallback(4);
+ setup_enterExitCompartment("611Ag", kObjectCompartmentG);
+ } else {
+ params->param1 = 1;
+
+ getEntities()->drawSequenceLeft(kEntityMilos, "609Dg");
+ getEntities()->enterCompartment(kEntityMilos, kObjectCompartmentG, true);
+ }
+ break;
+
+ case 4:
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMilos);
+
+ setup_function17();
+ break;
+
+ case 5:
+ getEntities()->exitCompartment(kEntityMilos, kObjectCompartmentG, true);
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMilos);
+
+ setup_function17();
+ break;
+ }
+ break;
+
+ case kAction135024800:
+ getSavePoints()->push(kEntityMilos, kEntityVesna, kAction204832737);
+
+ setCallback(3);
+ setup_enterCompartmentDialog(kCarRedSleeping, kPosition_3050);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Milos, function17)
+ if (savepoint.action == kActionDefault) {
+ setCallback(1);
+ setup_function11(kTimeBedTime);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Milos, function18)
+ if (savepoint.action == kActionDefault) {
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getEntities()->clearSequences(kEntityMilos);
+ getObjects()->update(kObjectCompartmentG, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Milos, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter2Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityMilos);
+
+ getData()->entityPosition = kPosition_4689;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+
+ getObjects()->update(kObjectCompartmentG, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject46, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Milos, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_540;
+ getData()->location = kLocationOutsideCompartment;
+
+ getSavePoints()->push(kEntityMilos, kEntityVesna, kAction137165825);
+ break;
+
+ case kActionDrawScene:
+ if (getEntities()->isPlayerInCar(kCarRedSleeping) && !getEntities()->isPlayerPosition(kCarRedSleeping, 1)) {
+ setCallback(1);
+ setup_enterCompartmentDialog(kCarRedSleeping, kPosition_3050);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("609Bg", kObjectCompartmentG);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityMilos);
+
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+
+ getSavePoints()->push(kEntityMilos, kEntityVesna, kAction101687594);
+
+ setup_function21();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Milos, function21)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param2, getState()->time, 4500);
+
+ params->param1 = 1;
+ break;
+
+ case kActionKnock:
+ getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorNormal, kCursorNormal);
+
+ setCallback(1);
+ setup_playSound("LIB012");
+ break;
+
+ case kActionOpenDoor:
+ getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorNormal, kCursorNormal);
+
+ setCallback(3);
+ setup_savegame(kSavegameTypeEvent, kEventMilosCompartmentVisitAugust);
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionDrawScene:
+ if (!getEvent(kEventMilosCompartmentVisitAugust)
+ && !getEntities()->isInsideTrainCar(kEntityPlayer, kCarRedSleeping)
+ && params->param1)
+ setup_chapter2Handler();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_playSound("Mil1118");
+ break;
+
+ case 2:
+ getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ break;
+
+ case 3:
+ getAction()->playAnimation(kEventMilosCompartmentVisitAugust);
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 5);
+ getSavePoints()->push(kEntityMilos, kEntityVesna, kAction135024800);
+
+ setCallback(4);
+ setup_function11(kTimeEnd);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Milos, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->events[kEventMilosCompartmentVisitAugust])
+ setup_function24();
+ else
+ setup_function23();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityMilos);
+
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ ENTITY_PARAM(0, 1) = 0;
+ ENTITY_PARAM(0, 4) = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Milos, function23)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime2106000 && !params->param1) {
+ params->param1 = 1;
+
+ setCallback(1);
+ setup_enterCompartmentDialog(kCarRedSleeping, kPosition_3050);
+ }
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_540;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getSavePoints()->push(kEntityMilos, kEntityVesna, kAction137165825);
+ break;
+
+ case kActionDrawScene:
+ if (getEntities()->isPlayerInCar(kCarRedSleeping)
+ && !getEntities()->isPlayerPosition(kCarRedSleeping, 1)) {
+ setCallback(3);
+ setup_enterCompartmentDialog(kCarRedSleeping, kPosition_3050);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("609Bg", kObjectCompartmentG);
+ break;
+
+ case 2:
+ case 4:
+ getEntities()->clearSequences(kEntityMilos);
+ getData()->location = kLocationInsideCompartment;
+ getSavePoints()->push(kEntityMilos, kEntityVesna, kAction101687594);
+
+ setup_function24();
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_enterExitCompartment("609Bg", kObjectCompartmentG);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Milos, function24)
+ error("Milos: callback function 24 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, Milos, function25)
+ error("Milos: callback function 25 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(26, Milos, function26, TimeValue)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1 < getState()->time && !params->param2) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (getEntities()->isPlayerInCar(kCarGreenSleeping) || getEntities()->isPlayerInCar(kCarRedSleeping)) {
+ if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarGreenSleeping)) {
+ setCallback(2);
+ setup_function27(kCarGreenSleeping, kPosition_540);
+ } else {
+ setCallback(3);
+ setup_function27(kCarRedSleeping, kPosition_9460);
+ }
+ }
+ break;
+
+ case kActionDefault:
+ ENTITY_PARAM(0, 2) = 0;
+
+ setCallback(1);
+ setup_function27(kCarRedSleeping, kPosition_540);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (ENTITY_PARAM(0, 2)) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ getEntities()->clearSequences(kEntityMilos);
+ break;
+
+ case 2:
+ case 3:
+ if (ENTITY_PARAM(0, 2)) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ getEntities()->clearSequences(kEntityMilos);
+
+ setCallback(4);
+ setup_updateFromTime(450);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_function27(kCarRedSleeping, kPosition_540);
+ break;
+
+ case 5:
+ if (ENTITY_PARAM(0, 2)) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ getEntities()->clearSequences(kEntityMilos);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(27, Milos, function27, CarIndex, EntityPosition)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->updateEntity(kEntityMilos, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (getEntities()->isDistanceBetweenEntities(kEntityMilos, kEntityPlayer, 1000)
+ && !getEntities()->isInGreenCarEntrance(kEntityPlayer)
+ && !getEntities()->isInsideCompartments(kEntityPlayer)
+ && !getEntities()->checkFields10(kEntityPlayer)) {
+ if (getData()->car == kCarRedSleeping || getData()->car == kCarGreenSleeping) {
+ ENTITY_PARAM(0, 2) = 1;
+
+ CALLBACK_ACTION();
+ }
+ }
+ break;
+
+ case kActionDefault:
+ if (getEntities()->updateEntity(kEntityMilos, (CarIndex)params->param1, (EntityPosition)params->param2))
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(28, Milos, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityMilos);
+
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->inventoryItem = kItemNone;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(29, Milos, chapter4Handler)
+#define TIME_CHECK_PLAYSOUND_MILOS(timeValue, parameter, sound) \
+ if (getState()->time > timeValue && !parameter) { \
+ parameter = 1; \
+ getSound()->playSound(kEntityMilos, sound); \
+ if (getEntities()->isDistanceBetweenEntities(kEntityMilos, kEntityPlayer, 2000)) \
+ getProgress().field_94 = 1; \
+ break; \
+ }
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1)
+ break;
+
+ if (params->param2) {
+ setup_function30();
+ break;
+ }
+
+ TIME_CHECK_PLAYSOUND_MILOS(kTime2356200, params->param3, "Mil4013");
+
+ TIME_CHECK_PLAYSOUND_MILOS(kTime2360700, params->param4, "Mil4014");
+
+ TIME_CHECK_PLAYSOUND_MILOS(kTime2370600, params->param5, "Mil4015");
+
+ TIME_CHECK_SAVEPOINT(kTime2407500, params->param6, kEntityMilos, kEntityVesna, kAction55996766);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ getEntities()->drawSequenceLeft(kEntityMilos, "611Cg");
+ getEntities()->enterCompartment(kEntityMilos, kObjectCompartmentG, true);
+ getSavePoints()->push(kEntityMilos, kEntityCoudert, kAction88652208);
+ break;
+
+ case 2:
+ getEntities()->exitCompartment(kEntityMilos, kObjectCompartmentG);
+
+ getData()->location = kLocationInsideCompartment;
+ getData()->entityPosition = kPosition_3050;
+
+ getEntities()->clearSequences(kEntityMilos);
+
+ params->param1 = 0;
+ break;
+ }
+ break;
+
+ case kAction122865568:
+ setCallback(1);
+ setup_enterExitCompartment("611Bg", kObjectCompartmentG);
+ break;
+
+ case kAction123852928:
+ setCallback(2);
+ setup_enterExitCompartment("611Dg", kObjectCompartmentG);
+ break;
+
+ case kAction135600432:
+ params->param2 = 1;
+ break;
+
+ case kAction221683008:
+ if (getSound()->isBuffered(kEntityMilos))
+ getSound()->processEntry(kEntityMilos);
+
+ params->param1 = 1;
+ getSavePoints()->push(kEntityMilos, kEntityCoudert, kAction123199584);
+ break;
+ }
+
+#undef TIME_CHECK_PLAYSOUND_MILOS
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(30, Milos, function30)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setCallback(1);
+ setup_function11(kTime2410200);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityMilos, kEntityIvo, kAction55996766);
+
+ setCallback(2);
+ setup_function11(kTime2412000);
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityMilos, kEntitySalko, kAction55996766);
+
+ setCallback(3);
+ setup_function11(kTime2415600);
+ break;
+
+ case 3:
+ setup_function31();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(31, Milos, function31)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setCallback(1);
+ setup_enterExitCompartment("609CG", kObjectCompartmentG);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ getObjects()->update(kObjectCompartmentG, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ setCallback(2);
+ setup_enterCompartmentDialog(kCarGreenSleeping, kPosition_540);
+ break;
+
+ case 2:
+ setup_function32();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(32, Milos, function32)
+ if (savepoint.action == kActionDefault) {
+ getEntities()->clearSequences(kEntityMilos);
+ getObjects()->update(kObjectCompartmentG, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ getData()->entityPosition = kPosition_540;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarCoalTender;
+ getData()->inventoryItem = kItemNone;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(33, Milos, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityMilos);
+
+ getData()->entityPosition = kPosition_540;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarCoalTender;
+ getData()->inventoryItem = kItemNone;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(34, Milos, chapter5Handler)
+ error("Milos: callback function 34 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(35, Milos, function35)
+ if (savepoint.action == kActionDefault)
+ getEntities()->clearSequences(kEntityMilos);
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/milos.h b/engines/lastexpress/entities/milos.h
new file mode 100644
index 0000000000..4bbafaaaa7
--- /dev/null
+++ b/engines/lastexpress/entities/milos.h
@@ -0,0 +1,175 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_MILOS_H
+#define LASTEXPRESS_MILOS_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Milos : public Entity {
+public:
+ Milos(LastExpressEngine *engine);
+ ~Milos() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Draws the entity
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(draw, const char* sequence)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Handles entering/exiting a compartment and updates position/play animation
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment2, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Process callback action when the entity direction is not kDirectionRight
+ */
+ DECLARE_FUNCTION(callbackActionOnDirection)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound16, const char* filename)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param time The time to add
+ */
+ DECLARE_FUNCTION_1(updateFromTime, uint32 time)
+
+ DECLARE_FUNCTION_2(enterCompartmentDialog, CarIndex car, EntityPosition entityPosition)
+ DECLARE_FUNCTION_1(function11, TimeValue timeValue)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ DECLARE_FUNCTION(function13)
+ DECLARE_FUNCTION(function14)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function16)
+ DECLARE_FUNCTION(function17)
+ DECLARE_FUNCTION(function18)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+
+ DECLARE_FUNCTION(function21)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ DECLARE_FUNCTION(function23)
+ DECLARE_FUNCTION(function24)
+ DECLARE_FUNCTION(function25)
+ DECLARE_FUNCTION_1(function26, TimeValue timeValue)
+ DECLARE_FUNCTION_2(function27, CarIndex car, EntityPosition entityPosition)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ DECLARE_FUNCTION(function30)
+ DECLARE_FUNCTION(function31)
+ DECLARE_FUNCTION(function32)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_FUNCTION(function35)
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_MILOS_H
diff --git a/engines/lastexpress/entities/mmeboutarel.cpp b/engines/lastexpress/entities/mmeboutarel.cpp
new file mode 100644
index 0000000000..ce9ebf3abd
--- /dev/null
+++ b/engines/lastexpress/entities/mmeboutarel.cpp
@@ -0,0 +1,939 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/mmeboutarel.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"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+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(MmeBoutarel, function9);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, chapter1);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, function11);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, function13);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, function14);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, function15);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, function16);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, chapter2);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, function19);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, chapter3);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, chapter4);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, function24);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, function25);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, chapter5);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(MmeBoutarel, function28);
+ ADD_NULL_FUNCTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, MmeBoutarel, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(2, MmeBoutarel, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(3, MmeBoutarel, draw)
+ Entity::draw(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(4, MmeBoutarel, updateFromTime, uint32)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(5, MmeBoutarel, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(6, MmeBoutarel, enterExitCompartment2, ObjectIndex)
+ Entity::enterExitCompartment(savepoint, kPosition_5790, kPosition_6130, kCarRedSleeping, kObjectCompartmentD, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(7, MmeBoutarel, updateEntity, CarIndex, EntityPosition)
+ if (savepoint.action == kActionExcuseMeCath) {
+ getInventory()->hasItem(kItemPassengerList) ? getSound()->playSound(kEntityPlayer, "CAT1021") : getSound()->excuseMeCath();
+
+ return;
+ }
+
+ Entity::updateEntity(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(8, MmeBoutarel, function8)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param4 && params->param5) {
+ getSavePoints()->push(kEntityMmeBoutarel, kEntityCoudert, kAction125499160);
+
+ if (!getEntities()->isPlayerPosition(kCarRedSleeping, 2))
+ getData()->entityPosition = kPosition_2088;
+
+ CALLBACK_ACTION();
+ }
+ break;
+
+ case kActionEndSound:
+ params->param5 = 1;
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "606U");
+ getSavePoints()->push(kEntityMmeBoutarel, kEntityCoudert, kAction169557824);
+ break;
+
+ case kAction155853632:
+ params->param4 = 1;
+ break;
+
+ case kAction202558662:
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "606L");
+ getSound()->playSound(kEntityMmeBoutarel, (char *)&params->seq1);
+
+ if (getEntities()->hasValidFrame(kEntityMmeBoutarel) || getEntities()->isDistanceBetweenEntities(kEntityMmeBoutarel, kEntityPlayer, 2000)) {
+ if (getProgress().chapter == kChapter1)
+ getProgress().field_A8 = 1;
+ else if (getProgress().chapter == kChapter3)
+ getProgress().field_A4 = 1;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(9, MmeBoutarel, function9)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1) {
+ getData()->entityPosition = getEntityData(kEntityBoutarel)->entityPosition;
+ getData()->location = getEntityData(kEntityBoutarel)->location;
+ }
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject51, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ setCallback(1);
+ setup_enterExitCompartment("606Rd", kObjectCompartmentD);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityMmeBoutarel);
+ getSavePoints()->push(kEntityMmeBoutarel, kEntityBoutarel, kAction203520448);
+ break;
+
+ case 3:
+ if (getEntities()->isInsideCompartment(kEntityFrancois, kCarRedSleeping, kPosition_5790)) {
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorNormal);
+
+ setCallback(4);
+ setup_enterExitCompartment2("606Ad", kObjectCompartmentD);
+ } else {
+ params->param1 = 1;
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "606Md");
+ getEntities()->enterCompartment(kEntityMmeBoutarel, kObjectCompartmentD, true);
+ }
+ break;
+
+ case 4:
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation2, kCursorNormal, kCursorNormal);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMmeBoutarel);
+
+ CALLBACK_ACTION();
+ break;
+
+ case 5:
+ getEntities()->exitCompartment(kEntityMmeBoutarel, kObjectCompartmentD, true);
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation2, kCursorNormal, kCursorNormal);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityMmeBoutarel);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction100901266:
+ setCallback(3);
+ setup_updateEntity(kCarRedSleeping, kPosition_5790);
+ break;
+
+ case kAction100957716:
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorNormal);
+
+ setCallback(5);
+ setup_enterExitCompartment2("606Ad", kObjectCompartmentD);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(10, MmeBoutarel, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getSavePoints()->addData(kEntityMmeBoutarel, kAction242526416, 0);
+
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation2, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject51, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, MmeBoutarel, function11)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param2 == kTimeInvalid)
+ break;
+
+ if (params->param1 >= getState()->time) {
+ if (!getEntities()->isDistanceBetweenEntities(kEntityMmeBoutarel, kEntityPlayer, 1000) || !params->param2)
+ params->param2 = getState()->time + 150;
+
+ if (params->param2 >= getState()->time)
+ break;
+ }
+
+ params->param2 = kTimeInvalid;
+
+ setCallback(1);
+ setup_playSound("MME1040");
+ break;
+
+ case kActionDefault:
+ params->param1 = getState()->time + 1800;
+ getObjects()->update(kObjectCompartmentD, kEntityMmeBoutarel, kObjectLocation1, kCursorNormal, kCursorNormal);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_playSound("MME1040A");
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_playSound("MME1041");
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_updateFromTime(900);
+ break;
+
+ case 4:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, MmeBoutarel, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ params->param1 = 1;
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "501");
+ break;
+
+ case kActionDrawScene:
+ if (getEntities()->isPlayerPosition(kCarRedSleeping, 44)) {
+ setCallback(1);
+ setup_draw("502B");
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "502A");
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "606Qd");
+ getEntities()->enterCompartment(kEntityMmeBoutarel, kObjectCompartmentD, true);
+ break;
+
+ case 3:
+ getData()->location = kLocationInsideCompartment;
+ params->param1 = 1;
+ getEntities()->clearSequences(kEntityMmeBoutarel);
+ setup_function13();
+ break;
+ }
+ break;
+
+ case kAction102484312:
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "501");
+ params->param1 = 1;
+ break;
+
+ case kAction134289824:
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "502A");
+ params->param1 = 0;
+ break;
+
+ case kAction168986720:
+ getSavePoints()->push(kEntityMmeBoutarel, kEntityFrancois, kAction102752636);
+ getSound()->playSound(kEntityMmeBoutarel, "MME1036");
+ getEntities()->exitCompartment(kEntityMmeBoutarel, kObjectCompartmentD, true);
+
+ setCallback(3);
+ setup_enterExitCompartment("606Fd", kObjectCompartmentD);
+ break;
+
+ case kAction202221040:
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ getData()->location = kLocationOutsideCompartment;
+
+ getSound()->playSound(kEntityMmeBoutarel, "MME1035A");
+
+ if (getEntities()->hasValidFrame(kEntityMmeBoutarel) || getEntities()->isDistanceBetweenEntities(kEntityMmeBoutarel, kEntityPlayer, 2000) )
+ getProgress().field_AC = 1;
+
+ setCallback(2);
+ setup_enterExitCompartment("606Ed", kObjectCompartmentD);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, MmeBoutarel, function13)
+ error("MmeBoutarel: callback function 13 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, MmeBoutarel, function14)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_enterExitCompartment("606Dd", kObjectCompartmentD);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation2, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject51, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "503");
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "503");
+
+ setCallback(3);
+ setup_playSound("MRB1080");
+ break;
+
+ case 3:
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(4);
+ setup_enterExitCompartment("606Cd", kObjectCompartmentD);
+ break;
+
+ case 4:
+ getEntities()->clearSequences(kEntityMmeBoutarel);
+
+ setup_function15();
+ break;
+ }
+ break;
+
+ case kAction101107728:
+ setCallback(2);
+ setup_function9();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, MmeBoutarel, function15)
+ error("MmeBoutarel: callback function 15 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, MmeBoutarel, function16)
+ if (savepoint.action == kActionDefault) {
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject51, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ getEntities()->clearSequences(kEntityMmeBoutarel);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, MmeBoutarel, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter2Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityMmeBoutarel);
+
+ getData()->entityPosition = kPosition_4689;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject51, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject43, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, MmeBoutarel, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (getEntities()->isInsideCompartment(kEntityFrancois, kCarRedSleeping, kPosition_5790)) {
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorNormal);
+
+ setCallback(2);
+ setup_enterExitCompartment2("606Ad", kObjectCompartmentD);
+ } else {
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "606Md");
+ getEntities()->enterCompartment(kEntityMmeBoutarel, kObjectCompartmentD, true);
+ }
+ break;
+
+ case 2:
+ case 3:
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation2, kCursorNormal, kCursorNormal);
+ getData()->location = kLocationInsideCompartment;
+ setup_function19();
+ break;
+ }
+ break;
+
+ case kAction100901266:
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_5790);
+ break;
+
+ case kAction100957716:
+ getEntities()->exitCompartment(kEntityMmeBoutarel, kObjectCompartmentD, true);
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorNormal);
+
+ setCallback(3);
+ setup_enterExitCompartment2("606Ad", kObjectCompartmentD);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, MmeBoutarel, function19)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isPlayerPosition(kCarRedSleeping, 44) && !params->param2) {
+ if (params->param1) {
+ setCallback(1);
+ setup_draw("502B");
+ } else {
+ params->param1 = 1;
+ }
+ }
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation2, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject51, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ params->param2 = 1;
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "501");
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ if (getEntities()->isPlayerPosition(kCarRedSleeping , 44))
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 11);
+ }
+ break;
+
+ case kAction102484312:
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "501");
+ params->param2 = 1;
+ break;
+
+ case kAction134289824:
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "502A");
+ params->param2 = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, MmeBoutarel, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityMmeBoutarel);
+
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, MmeBoutarel, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (ENTITY_PARAM(0, 1) && params->param2 != kTimeInvalid) {
+
+ if (getState()->time <= kTime2038500) {
+ if (!getEntities()->isPlayerInCar(kCarRedSleeping)
+ || !params->param1
+ || getSound()->isBuffered("FRA2012")
+ || getSound()->isBuffered("FRA2010")
+ ||!params->param2)
+ params->param2 = getState()->time;
+
+ if (params->param2 >= getState()->time)
+ break;
+ }
+
+ params->param2 = kTimeInvalid;
+
+ getSavePoints()->push(kEntityMmeBoutarel, kEntityFrancois, kAction189872836);
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ setCallback(1);
+ setup_enterExitCompartment("606Cd", kObjectCompartmentD);
+ }
+ break;
+
+ case kActionDefault:
+ params->param1 = 1;
+
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation2, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject51, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject43, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "501");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("606Rd", kObjectCompartmentD);
+ break;
+
+ case 2:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(3);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function8("MME3001");
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_updateEntity(kCarRedSleeping, kPosition_5790);
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_enterExitCompartment2("606Td", kObjectCompartmentD);
+ break;
+
+ case 6:
+ getEntities()->clearSequences(kEntityMmeBoutarel);
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ setCallback(7);
+ setup_updateFromTime(150);
+ break;
+
+ case 7:
+ setCallback(8);
+ setup_enterExitCompartment("606Dd", kObjectCompartmentD);
+ break;
+
+ case 8:
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation2, kCursorNormal, kCursorNormal);
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "501");
+ getSavePoints()->push(kEntityMmeBoutarel, kEntityFrancois, kAction190390860);
+ break;
+
+ case 9:
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "501");
+ params->param1 = 1;
+ break;
+ }
+ break;
+
+ case kAction101107728:
+ setCallback(9);
+ setup_function9();
+ break;
+
+ case kAction102484312:
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "501");
+ params->param1 = 1;
+ break;
+
+ case kAction134289824:
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "502A");
+ params->param1 = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, MmeBoutarel, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityMmeBoutarel);
+
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, MmeBoutarel, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1) {
+ UPDATE_PARAM(params->param2, getState()->time, 900);
+
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
+
+ setCallback(1);
+ setup_enterExitCompartment("606Cd", kObjectCompartmentD);
+ }
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation2, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject51, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "501");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->clearSequences(kEntityMmeBoutarel);
+ setup_function24();
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "501");
+ params->param1 = 1;
+ break;
+ }
+ break;
+
+ case kAction101107728:
+ setCallback(2);
+ setup_function9();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, MmeBoutarel, function24)
+ error("MmeBoutarel: callback function 24 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, MmeBoutarel, function25)
+ if (savepoint.action == kActionDefault) {
+ getEntities()->clearSequences(kEntityMmeBoutarel);
+
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject51, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(26, MmeBoutarel, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityMmeBoutarel);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(27, MmeBoutarel, chapter5Handler)
+ if (savepoint.action == kActionProceedChapter5)
+ setup_function28();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(28, MmeBoutarel, function28)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1) {
+ UPDATE_PARAM(params->param3, getState()->timeTicks, 75);
+
+ params->param1 = 0;
+ params->param2 = 1;
+
+ getObjects()->update(kObjectCompartmentD, kEntityMmeBoutarel, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject51, kEntityMmeBoutarel, kObjectLocation1, kCursorNormal, kCursorNormal);
+ }
+
+ params->param3 = 0;
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ if (params->param1) {
+ getObjects()->update(kObjectCompartmentD, kEntityMmeBoutarel, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject51, kEntityMmeBoutarel, kObjectLocation1, kCursorNormal, kCursorNormal);
+ params->param1 = 0;
+
+ setCallback(1);
+ setup_playSound(getSound()->justCheckingCath());
+ break;
+ }
+
+ setCallback(savepoint.action == kActionKnock ? 2 : 3);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_5790;
+ getData()->location = kLocationInsideCompartment;
+
+ getEntities()->clearSequences(kEntityMmeBoutarel);
+ break;
+
+ case kActionDrawScene:
+ if (params->param1 || params->param2) {
+ params->param1 = 0;
+ params->param2 = 0;
+
+ getObjects()->update(kObjectCompartmentD, kEntityMmeBoutarel, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject51, kEntityMmeBoutarel, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartmentD, kEntityMmeBoutarel, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject51, kEntityMmeBoutarel, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case 2:
+ case 3:
+ getObjects()->update(kObjectCompartmentD, kEntityMmeBoutarel, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject51, kEntityMmeBoutarel, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(4);
+ setup_playSound("Mme5001");
+ break;
+
+ case 4:
+ params->param1 = 1;
+ getObjects()->update(kObjectCompartmentD, kEntityMmeBoutarel, kObjectLocation1, kCursorTalk, kCursorNormal);
+ getObjects()->update(kObject51, kEntityMmeBoutarel, kObjectLocation1, kCursorTalk, kCursorNormal);
+ break;
+ }
+ break;
+
+ case kAction135800432:
+ setup_nullfunction();
+ break;
+
+ case kAction155604840:
+ getObjects()->update(kObjectCompartmentD, kEntityMmeBoutarel, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject51, kEntityMmeBoutarel, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_NULL_FUNCTION(29, MmeBoutarel)
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/mmeboutarel.h b/engines/lastexpress/entities/mmeboutarel.h
new file mode 100644
index 0000000000..548a0635cb
--- /dev/null
+++ b/engines/lastexpress/entities/mmeboutarel.h
@@ -0,0 +1,164 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_MMEBOUTAREL_H
+#define LASTEXPRESS_MMEBOUTAREL_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class MmeBoutarel : public Entity {
+public:
+ MmeBoutarel(LastExpressEngine *engine);
+ ~MmeBoutarel() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Draws the entity
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(draw, const char* sequence)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param time The time to add
+ */
+ DECLARE_FUNCTION_1(updateFromTime, uint32 time)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Handles entering/exiting a compartment and updates position/play animation
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment2, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ DECLARE_FUNCTION_1(function8, const char *soundName)
+
+ DECLARE_FUNCTION(function9)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ DECLARE_FUNCTION(function11)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function13)
+ DECLARE_FUNCTION(function14)
+ DECLARE_FUNCTION(function15)
+ DECLARE_FUNCTION(function16)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+
+ DECLARE_FUNCTION(function19)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ DECLARE_FUNCTION(function24)
+ DECLARE_FUNCTION(function25)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_FUNCTION(function28)
+
+ DECLARE_NULL_FUNCTION()
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_MMEBOUTAREL_H
diff --git a/engines/lastexpress/entities/pascale.cpp b/engines/lastexpress/entities/pascale.cpp
new file mode 100644
index 0000000000..dfb0854eda
--- /dev/null
+++ b/engines/lastexpress/entities/pascale.cpp
@@ -0,0 +1,1232 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/pascale.h"
+
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+namespace LastExpress {
+
+Pascale::Pascale(LastExpressEngine *engine) : Entity(engine, kEntityPascale) {
+ ADD_CALLBACK_FUNCTION(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(Pascale, welcomeSophieAndRebecca);
+ ADD_CALLBACK_FUNCTION(Pascale, sitSophieAndRebecca);
+ ADD_CALLBACK_FUNCTION(Pascale, welcomeCath);
+ ADD_CALLBACK_FUNCTION(Pascale, function11);
+ ADD_CALLBACK_FUNCTION(Pascale, chapter1);
+ ADD_CALLBACK_FUNCTION(Pascale, getMessageFromAugustToTyler);
+ ADD_CALLBACK_FUNCTION(Pascale, sitAnna);
+ ADD_CALLBACK_FUNCTION(Pascale, welcomeAnna);
+ ADD_CALLBACK_FUNCTION(Pascale, serveTatianaVassili);
+ ADD_CALLBACK_FUNCTION(Pascale, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Pascale, function18);
+ ADD_CALLBACK_FUNCTION(Pascale, function19);
+ ADD_CALLBACK_FUNCTION(Pascale, chapter2);
+ ADD_CALLBACK_FUNCTION(Pascale, chapter3);
+ ADD_CALLBACK_FUNCTION(Pascale, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Pascale, function23);
+ ADD_CALLBACK_FUNCTION(Pascale, welcomeAbbot);
+ ADD_CALLBACK_FUNCTION(Pascale, chapter4);
+ ADD_CALLBACK_FUNCTION(Pascale, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Pascale, function27);
+ ADD_CALLBACK_FUNCTION(Pascale, messageFromAnna);
+ ADD_CALLBACK_FUNCTION(Pascale, function29);
+ ADD_CALLBACK_FUNCTION(Pascale, function30);
+ ADD_CALLBACK_FUNCTION(Pascale, chapter5);
+ ADD_CALLBACK_FUNCTION(Pascale, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(Pascale, function33);
+ ADD_NULL_FUNCTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(1, Pascale, draw)
+ Entity::draw(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(2, Pascale, callbackActionRestaurantOrSalon)
+ Entity::callbackActionRestaurantOrSalon(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(3, Pascale, callbackActionOnDirection)
+ if (savepoint.action == kActionExcuseMeCath) {
+ if (!params->param1) {
+ getSound()->excuseMe(kEntityPascale);
+ params->param1 = 1;
+ }
+
+ return;
+ }
+
+ Entity::callbackActionOnDirection(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(4, Pascale, updateFromTime, uint32)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(5, Pascale, updatePosition)
+ Entity::updatePosition(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(6, Pascale, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(7, Pascale, draw2)
+ Entity::draw2(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(8, Pascale, welcomeSophieAndRebecca)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_850;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_draw("901");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ switch (getProgress().chapter) {
+ default:
+ break;
+
+ case kChapter1:
+ getSound()->playSound(kEntityPascale, "REB1198", SoundManager::kFlagInvalid, 30);
+ break;
+
+ case kChapter3:
+ getSound()->playSound(kEntityPascale, "REB3001", SoundManager::kFlagInvalid, 30);
+ break;
+
+ case kChapter4:
+ getSound()->playSound(kEntityPascale, "REB4001", SoundManager::kFlagInvalid, 30);
+ break;
+ }
+
+ setCallback(2);
+ setup_sitSophieAndRebecca();
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityPascale, kEntityRebecca, kAction157370960);
+
+ setCallback(3);
+ setup_draw("905");
+ break;
+
+ case 3:
+ getEntities()->clearSequences(kEntityPascale);
+ getData()->entityPosition = kPosition_5900;
+ ENTITY_PARAM(0, 4) = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(9, Pascale, sitSophieAndRebecca)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityPascale, "012C1");
+ getEntities()->drawSequenceLeft(kEntityRebecca, "012C2");
+ getEntities()->drawSequenceLeft(kEntityTables3, "012C3");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(10, Pascale, welcomeCath)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1 && !getSound()->isBuffered(kEntityPascale))
+ getEntities()->updatePositionExit(kEntityPascale, kCarRestaurant, 64);
+ break;
+
+ case kActionExitCompartment:
+ if (!params->param2) {
+ params->param2 = 1;
+
+ getSound()->playSound(kEntityPascale, "HED1001A");
+ getSound()->playSound(kEntityPlayer, "LIB004");
+
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 69);
+ }
+
+ CALLBACK_ACTION();
+ break;
+
+ case kAction4:
+ if (!params->param1) {
+ params->param1 = 1;
+ getSound()->playSound(kEntityPascale, "HED1001");
+ }
+ break;
+
+ case kActionDefault:
+ getEntities()->updatePositionEnter(kEntityPascale, kCarRestaurant, 64);
+ getEntities()->drawSequenceRight(kEntityPascale, "035A");
+ break;
+
+ case kActionDrawScene:
+ if (params->param1 && getEntities()->isPlayerPosition(kCarRestaurant, 64)) {
+ getSound()->playSound(kEntityPascale, "HED1001A");
+ getSound()->playSound(kEntityPlayer, "LIB004");
+
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 69);
+
+ CALLBACK_ACTION();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Pascale, function11)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ getSavePoints()->push(kEntityPascale, kEntityAugust, kAction168046720);
+ getSavePoints()->push(kEntityPascale, kEntityAnna, kAction168046720);
+ getSavePoints()->push(kEntityPascale, kEntityAlexei, kAction168046720);
+ getEntities()->updatePositionEnter(kEntityPascale, kCarRestaurant, 55);
+
+ setCallback(1);
+ setup_welcomeCath();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityPascale, kEntityAugust, kAction168627977);
+ getSavePoints()->push(kEntityPascale, kEntityAnna, kAction168627977);
+ getSavePoints()->push(kEntityPascale, kEntityAlexei, kAction168627977);
+ getEntities()->updatePositionExit(kEntityPascale, kCarRestaurant, 55);
+
+ setCallback(2);
+ setup_draw("905");
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityPascale);
+ getData()->entityPosition = kPosition_5900;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Pascale, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter1Handler();
+ break;
+
+ case kActionDefault:
+ getSavePoints()->addData(kEntityPascale, kAction239072064, 0);
+ getSavePoints()->addData(kEntityPascale, kAction257489762, 2);
+ getSavePoints()->addData(kEntityPascale, kAction207769280, 6);
+ getSavePoints()->addData(kEntityPascale, kAction101824388, 7);
+ getSavePoints()->addData(kEntityPascale, kAction136059947, 8);
+ getSavePoints()->addData(kEntityPascale, kAction223262556, 1);
+ getSavePoints()->addData(kEntityPascale, kAction269479296, 3);
+ getSavePoints()->addData(kEntityPascale, kAction352703104, 4);
+ getSavePoints()->addData(kEntityPascale, kAction352768896, 5);
+ getSavePoints()->addData(kEntityPascale, kAction191604416, 10);
+ getSavePoints()->addData(kEntityPascale, kAction190605184, 11);
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Pascale, getMessageFromAugustToTyler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_draw("902");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (!ENTITY_PARAM(1, 3)) {
+ getEntities()->drawSequenceLeft(kEntityPascale, "010E");
+ getEntities()->drawSequenceLeft(kEntityAugust, "BLANK");
+
+ setCallback(2);
+ setup_playSound("AUG1001");
+ break;
+ }
+
+ setCallback(3);
+ setup_draw("905");
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityPascale, "010B");
+
+ setCallback(3);
+ setup_draw("905");
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_5900;
+ getEntities()->clearSequences(kEntityPascale);
+ getSavePoints()->push(kEntityPascale, kEntityVerges, kActionDeliverMessageToTyler);
+ ENTITY_PARAM(0, 1) = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Pascale, sitAnna)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExitCompartment:
+ getEntities()->updatePositionExit(kEntityPascale, kCarRestaurant, 62);
+
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceRight(kEntityTables0, "001C3");
+ getEntities()->drawSequenceRight(kEntityAnna, "001C2");
+ getEntities()->drawSequenceRight(kEntityPascale, "001C1");
+
+ getEntities()->updatePositionEnter(kEntityPascale, kCarRestaurant, 62);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Pascale, welcomeAnna)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_draw("901");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSound()->playSound(kEntityPascale, "ANN1047");
+
+ setCallback(2);
+ setup_sitAnna();
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityPascale, kEntityAnna, kAction157370960);
+
+ setCallback(3);
+ setup_draw("904");
+ break;
+
+ case 3:
+ getEntities()->clearSequences(kEntityPascale);
+ getData()->entityPosition = kPosition_5900;
+ ENTITY_PARAM(0, 2) = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Pascale, serveTatianaVassili)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_draw("903");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityPascale, kEntityTatiana, kAction122358304);
+ getEntities()->drawSequenceLeft(kEntityPascale, "014B");
+ getEntities()->updatePositionEnter(kEntityPascale, kCarRestaurant, 67);
+
+ if (getSound()->isBuffered("TAT1069A"))
+ getSound()->processEntry("TAT1069A");
+ else if (getSound()->isBuffered("TAT1069B"))
+ getSound()->processEntry("TAT1069B");
+
+ setCallback(2);
+ setup_playSound("TAT1066");
+ break;
+
+ case 2:
+ getEntities()->updatePositionExit(kEntityPascale, kCarRestaurant, 67);
+ getSavePoints()->push(kEntityPascale, kEntityTatiana, kAction122288808);
+
+ setCallback(3);
+ setup_draw("906");
+ break;
+
+ case 3:
+ getEntities()->clearSequences(kEntityPascale);
+ getData()->entityPosition = kPosition_5900;
+ ENTITY_PARAM(0, 3) = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Pascale, chapter1Handler)
+switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param2) {
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 69)
+ || getEntities()->isPlayerPosition(kCarRestaurant, 70)
+ || getEntities()->isPlayerPosition(kCarRestaurant, 71))
+ params->param2 = 1;
+
+ if (!params->param2 && getEntities()->isPlayerPosition(kCarRestaurant, 61))
+ params->param1 = 1;
+ }
+
+ if (!getEntities()->isInKitchen(kEntityPascale))
+ break;
+
+ if (ENTITY_PARAM(0, 5) && ENTITY_PARAM(0, 6)) {
+ setup_function18();
+ break;
+ }
+
+ if (!getEntities()->isSomebodyInsideRestaurantOrSalon())
+ goto label_callback3;
+
+ if (params->param1 && !params->param2 && getEntities()->isPlayerPosition(kCarRestaurant, 61)) {
+ setCallback(1);
+ setup_function11();
+ break;
+ }
+
+label_callback1:
+ if (ENTITY_PARAM(0, 1) && !ENTITY_PARAM(1, 3)) {
+ setCallback(2);
+ setup_getMessageFromAugustToTyler();
+ break;
+ }
+
+label_callback2:
+ if (ENTITY_PARAM(0, 3)) {
+ setCallback(3);
+ setup_serveTatianaVassili();
+ break;
+ }
+
+label_callback3:
+ if (ENTITY_PARAM(0, 2)) {
+ setCallback(4);
+ setup_welcomeAnna();
+ break;
+ }
+
+label_callback4:
+ if (ENTITY_PARAM(0, 4)) {
+ setCallback(5);
+ setup_welcomeSophieAndRebecca();
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ params->param1 = 0;
+ params->param2 = 1;
+ goto label_callback1;
+
+ case 2:
+ goto label_callback2;
+
+ case 3:
+ goto label_callback3;
+
+ case 4:
+ goto label_callback4;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Pascale, function18)
+ if (savepoint.action != kActionNone)
+ return;
+
+ if (getState()->time > kTime1242000 && !params->param1) {
+ params->param1 = 1;
+
+ getSavePoints()->push(kEntityPascale, kEntityServers0, kAction101632192);
+ getSavePoints()->push(kEntityPascale, kEntityServers1, kAction101632192);
+ getSavePoints()->push(kEntityPascale, kEntityCooks, kAction101632192);
+ getSavePoints()->push(kEntityPascale, kEntityVerges, kAction101632192);
+
+ setup_function19();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Pascale, function19)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1 && getEntityData(kEntityPlayer)->entityPosition < kPosition_3650) {
+ getObjects()->update(kObject65, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getSavePoints()->push(kEntityPascale, kEntityTables0, kActionDrawTablesWithChairs, "001P");
+ getSavePoints()->push(kEntityPascale, kEntityTables1, kActionDrawTablesWithChairs, "005J");
+ getSavePoints()->push(kEntityPascale, kEntityTables2, kActionDrawTablesWithChairs, "009G");
+ getSavePoints()->push(kEntityPascale, kEntityTables3, kActionDrawTablesWithChairs, "010M");
+ getSavePoints()->push(kEntityPascale, kEntityTables4, kActionDrawTablesWithChairs, "014F");
+ getSavePoints()->push(kEntityPascale, kEntityTables5, kActionDrawTablesWithChairs, "024D");
+
+ params->param1 = 1;
+ }
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarRestaurant;
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+
+ getEntities()->clearSequences(kEntityPascale);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Pascale, chapter2)
+ if (savepoint.action == kActionDefault) {
+ getEntities()->clearSequences(kEntityPascale);
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothes1;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObject65, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Pascale, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityPascale);
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+
+ ENTITY_PARAM(0, 4) = 0;
+ ENTITY_PARAM(0, 7) = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Pascale, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!getEntities()->isInKitchen(kEntityPascale))
+ break;
+
+ if (ENTITY_PARAM(0, 7)) {
+ setCallback(1);
+ setup_function23();
+ break;
+ }
+
+label_callback:
+ if (ENTITY_PARAM(0, 4)) {
+ setCallback(2);
+ setup_welcomeSophieAndRebecca();
+ }
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ goto label_callback;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Pascale, function23)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+ getEntities()->updatePositionEnter(kEntityPascale, kCarRestaurant, 67);
+
+ setCallback(1);
+ setup_welcomeAbbot();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->updatePositionExit(kEntityPascale, kCarRestaurant, 67);
+ getSavePoints()->push(kEntityPascale, kEntityAbbot, kAction122288808);
+
+ setCallback(2);
+ setup_draw("906");
+ break;
+
+ case 2:
+ getData()->entityPosition = kPosition_5900;
+ ENTITY_PARAM(0, 7) = 0;
+ getEntities()->clearSequences(kEntityPascale);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Pascale, welcomeAbbot)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1) {
+ getSound()->playSound(kEntityPascale, "ABB3015A");
+ params->param1 = 1;
+ }
+ break;
+
+ case kActionExitCompartment:
+ CALLBACK_ACTION();
+ break;
+
+ case kAction10:
+ getSavePoints()->push(kEntityPascale, kEntityTables4, kAction136455232);
+ break;
+
+ case kActionDefault:
+ getSound()->playSound(kEntityPascale, "ABB3015", SoundManager::kFlagInvalid, 105);
+ getEntities()->drawSequenceRight(kEntityPascale, "029A1");
+ getEntities()->drawSequenceRight(kEntityAbbot, "029A2");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, Pascale, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityPascale);
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+
+ ENTITY_PARAM(0, 4) = 0;
+ ENTITY_PARAM(0, 8) = 0;
+
+ ENTITY_PARAM(1, 1) = 0;
+ ENTITY_PARAM(1, 2) = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(26, Pascale, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime2511000 && !params->param4) {
+ params->param2 = 1;
+ params->param4 = 1;
+ }
+
+ if (!getEntities()->isInKitchen(kEntityPascale))
+ break;
+
+ if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
+ if (ENTITY_PARAM(0, 8)) {
+ setCallback(1);
+ setup_function27();
+ break;
+ }
+
+label_callback1:
+ if (ENTITY_PARAM(1, 2) && ENTITY_PARAM(1, 4)) {
+ if (!params->param3)
+ params->param3 = getState()->time + 9000;
+
+ if (params->param5 != kTimeInvalid) {
+
+ if (params->param3 < getState()->time) {
+ params->param5 = kTimeInvalid;
+ setCallback(2);
+ setup_messageFromAnna();
+ break;
+ }
+
+ if (!getEntities()->isInRestaurant(kEntityPlayer) || !params->param5)
+ params->param5 = getState()->time;
+
+ if (params->param5 < getState()->time) {
+ params->param5 = kTimeInvalid;
+ setCallback(2);
+ setup_messageFromAnna();
+ break;
+ }
+ }
+ }
+
+label_callback2:
+ if (params->param1 && !params->param2 && getEntities()->isPlayerPosition(kCarRestaurant, 61)) {
+ setCallback(3);
+ setup_function11();
+ break;
+ }
+ }
+
+label_callback3:
+ if (ENTITY_PARAM(0, 4)) {
+ setCallback(4);
+ setup_welcomeSophieAndRebecca();
+ }
+ break;
+
+ case kActionDefault:
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 69)
+ || getEntities()->isPlayerPosition(kCarRestaurant, 70)
+ || getEntities()->isPlayerPosition(kCarRestaurant, 71))
+ params->param2 = 1;
+ break;
+
+ case kActionDrawScene:
+ if (!params->param2) {
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 69)
+ || getEntities()->isPlayerPosition(kCarRestaurant, 70)
+ || getEntities()->isPlayerPosition(kCarRestaurant, 71))
+ params->param2 = 1;
+
+ if (!params->param2 && getEntities()->isPlayerPosition(kCarRestaurant, 61))
+ params->param1 = 1;
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_callback1;
+
+ case 2:
+ goto label_callback2;
+
+ case 3:
+ params->param1 = 0;
+ params->param2 = 1;
+ goto label_callback3;
+ }
+ break;
+
+ case kAction201431954:
+ ENTITY_PARAM(0, 4) = 0;
+ ENTITY_PARAM(0, 8) = 0;
+
+ getSavePoints()->push(kEntityPascale, kEntityTables0, kActionDrawTablesWithChairs, "001P");
+ getSavePoints()->push(kEntityPascale, kEntityTables1, kActionDrawTablesWithChairs, "005J");
+ getSavePoints()->push(kEntityPascale, kEntityTables2, kActionDrawTablesWithChairs, "009G");
+ getSavePoints()->push(kEntityPascale, kEntityTables3, kActionDrawTablesWithChairs, "010M");
+ getSavePoints()->push(kEntityPascale, kEntityTables4, kActionDrawTablesWithChairs, "014F");
+ getSavePoints()->push(kEntityPascale, kEntityTables5, kActionDrawTablesWithChairs, "024D");
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(27, Pascale, function27)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (ENTITY_PARAM(1, 1)) {
+ setCallback(2);
+ setup_updateFromTime(450);
+ }
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function29();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->clearSequences(kEntityPascale);
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityPascale, kEntityCoudert, kAction123712592);
+
+ setCallback(3);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function30();
+ break;
+
+ case 4:
+ getEntities()->clearSequences(kEntityPascale);
+ getData()->entityPosition = kPosition_5900;
+ ENTITY_PARAM(0, 8) = 0;
+ ENTITY_PARAM(1, 1) = 0;
+ ENTITY_PARAM(1, 2) = 1;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(28, Pascale, messageFromAnna)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_draw("902");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityPascale, kEntityAugust, kAction122358304);
+ getEntities()->drawSequenceLeft(kEntityPascale, "010E2");
+
+ setCallback(2);
+ setup_playSound("Aug4001");
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityPascale, kEntityAugust, kAction123793792);
+
+ setCallback(3);
+ setup_draw("905");
+ break;
+
+ case 3:
+ getEntities()->clearSequences(kEntityPascale);
+ getData()->entityPosition = kPosition_5900;
+ ENTITY_PARAM(1, 2) = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(29, Pascale, function29)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_draw("817DD");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceRight(kEntityPascale, "817DS");
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityPascale);
+
+ setCallback(2);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 2:
+ getData()->entityPosition = kPosition_850;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(30, Pascale, function30)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_9270;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_draw("817US");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceRight(kEntityPascale, "817UD");
+ if (getEntities()->isInSalon(kEntityPlayer))
+ getEntities()->updateFrame(kEntityPascale);
+
+ setCallback(2);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 2:
+ getData()->entityPosition = kPosition_5900;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(31, Pascale, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityPascale);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(32, Pascale, chapter5Handler)
+ if (savepoint.action == kActionProceedChapter5)
+ setup_function33();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(33, Pascale, function33)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param4) {
+ UPDATE_PARAM_PROC(params->param5, getState()->time, 4500)
+ getObjects()->update(kObjectCompartmentG, kEntityPascale, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(1);
+ setup_playSound("Wat5010");
+ break;
+ UPDATE_PARAM_PROC_END
+ }
+
+label_callback1:
+ if (params->param1) {
+ UPDATE_PARAM(params->param6, getState()->timeTicks, 75);
+
+ params->param1 = 0;
+ params->param2 = 2;
+
+ getObjects()->update(kObjectCompartmentG, kEntityPascale, kObjectLocation1, kCursorNormal, kCursorNormal);
+ }
+
+ params->param6 = 0;
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ if (params->param1) {
+ getObjects()->update(kObjectCompartmentG, kEntityPascale, kObjectLocation1, kCursorNormal, kCursorNormal);
+ params->param1 = 0;
+
+ setCallback(2);
+ setup_playSound(getSound()->justCheckingCath());
+ } else {
+ setCallback(savepoint.action == kActionKnock ? 3 : 4);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ }
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+
+ getObjects()->update(kObjectCompartmentG, kEntityPascale, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionDrawScene:
+ if (params->param2 || params->param1) {
+ params->param1 = 0;
+ params->param2 = 0;
+ params->param3 = 0;
+
+ getObjects()->update(kObjectCompartmentG, kEntityPascale, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartmentG, kEntityPascale, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ goto label_callback1;
+
+ case 2:
+ getObjects()->update(kObjectCompartmentG, kEntityPascale, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case 3:
+ case 4:
+ params->param3++;
+
+ 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");
+ }
+ break;
+
+ case 5:
+ params->param1 = 1;
+ getObjects()->update(kObjectCompartmentG, kEntityPascale, kObjectLocation1, kCursorTalk, kCursorNormal);
+ break;
+
+ case 6:
+ params->param2 = 1;
+ break;
+
+ case 7:
+ params->param4 = 1;
+ break;
+ }
+ break;
+
+ case kAction135800432:
+ setup_nullfunction();
+ break;
+
+ case kAction169750080:
+ if (getSound()->isBuffered(kEntityPascale)) {
+ params->param4 = 1;
+ } else {
+ setCallback(7);
+ setup_playSound("Wat5002");
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_NULL_FUNCTION(34, Pascale)
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/pascale.h b/engines/lastexpress/entities/pascale.h
new file mode 100644
index 0000000000..d899037c0b
--- /dev/null
+++ b/engines/lastexpress/entities/pascale.h
@@ -0,0 +1,166 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_PASCALE_H
+#define LASTEXPRESS_PASCALE_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Pascale : public Entity {
+public:
+ Pascale(LastExpressEngine *engine);
+ ~Pascale() {};
+
+
+ /**
+ * Draws the entity
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(draw, const char* sequence)
+
+ /**
+ * Process callback action when somebody is standing in the restaurant or salon.
+ */
+ DECLARE_FUNCTION(callbackActionRestaurantOrSalon)
+
+ /**
+ * Process callback action when the entity direction is not kDirectionRight
+ */
+ DECLARE_FUNCTION(callbackActionOnDirection)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param time The time to add
+ */
+ DECLARE_FUNCTION_1(updateFromTime, uint32 time)
+
+ /**
+ * Updates the position
+ *
+ * @param savepoint The savepoint
+ * - The sequence to draw
+ * - The car
+ * - The position
+ */
+ DECLARE_FUNCTION_NOSETUP(updatePosition)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Draws the entity along with another one
+ *
+ * @param savepoint The savepoint
+ * - The sequence to draw
+ * - The sequence to draw for the second entity
+ * - The EntityIndex of the second entity
+ */
+ DECLARE_FUNCTION_NOSETUP(draw2)
+
+ DECLARE_FUNCTION(welcomeSophieAndRebecca)
+ DECLARE_FUNCTION(sitSophieAndRebecca)
+ DECLARE_FUNCTION(welcomeCath)
+ DECLARE_FUNCTION(function11)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ DECLARE_FUNCTION(getMessageFromAugustToTyler)
+ DECLARE_FUNCTION(sitAnna)
+ DECLARE_FUNCTION(welcomeAnna)
+ DECLARE_FUNCTION(serveTatianaVassili)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function18)
+ DECLARE_FUNCTION(function19)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ DECLARE_FUNCTION(function23)
+ DECLARE_FUNCTION(welcomeAbbot)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ DECLARE_FUNCTION(function27)
+ DECLARE_FUNCTION(messageFromAnna)
+ DECLARE_FUNCTION(function29)
+ DECLARE_FUNCTION(function30)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_FUNCTION(function33)
+
+ DECLARE_NULL_FUNCTION()
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_PASCALE_H
diff --git a/engines/lastexpress/entities/rebecca.cpp b/engines/lastexpress/entities/rebecca.cpp
new file mode 100644
index 0000000000..b9c3f23401
--- /dev/null
+++ b/engines/lastexpress/entities/rebecca.cpp
@@ -0,0 +1,1732 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/rebecca.h"
+
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+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(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(Rebecca, function15);
+ ADD_CALLBACK_FUNCTION(Rebecca, function16);
+ ADD_CALLBACK_FUNCTION(Rebecca, function17);
+ ADD_CALLBACK_FUNCTION(Rebecca, function18);
+ ADD_CALLBACK_FUNCTION(Rebecca, function19);
+ ADD_CALLBACK_FUNCTION(Rebecca, function20);
+ ADD_CALLBACK_FUNCTION(Rebecca, chapter1);
+ ADD_CALLBACK_FUNCTION(Rebecca, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Rebecca, function23);
+ ADD_CALLBACK_FUNCTION(Rebecca, function24);
+ ADD_CALLBACK_FUNCTION(Rebecca, function25);
+ ADD_CALLBACK_FUNCTION(Rebecca, function26);
+ ADD_CALLBACK_FUNCTION(Rebecca, function27);
+ ADD_CALLBACK_FUNCTION(Rebecca, chapter2);
+ ADD_CALLBACK_FUNCTION(Rebecca, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Rebecca, function30);
+ ADD_CALLBACK_FUNCTION(Rebecca, function31);
+ ADD_CALLBACK_FUNCTION(Rebecca, chapter3);
+ ADD_CALLBACK_FUNCTION(Rebecca, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Rebecca, function34);
+ ADD_CALLBACK_FUNCTION(Rebecca, function35);
+ ADD_CALLBACK_FUNCTION(Rebecca, function36);
+ ADD_CALLBACK_FUNCTION(Rebecca, function37);
+ ADD_CALLBACK_FUNCTION(Rebecca, function38);
+ ADD_CALLBACK_FUNCTION(Rebecca, function39);
+ ADD_CALLBACK_FUNCTION(Rebecca, function40);
+ ADD_CALLBACK_FUNCTION(Rebecca, function41);
+ ADD_CALLBACK_FUNCTION(Rebecca, chapter4);
+ ADD_CALLBACK_FUNCTION(Rebecca, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Rebecca, function44);
+ ADD_CALLBACK_FUNCTION(Rebecca, function45);
+ ADD_CALLBACK_FUNCTION(Rebecca, chapter5);
+ ADD_CALLBACK_FUNCTION(Rebecca, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(Rebecca, function48);
+ ADD_NULL_FUNCTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Rebecca, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(2, Rebecca, updateFromTime, uint32)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(3, Rebecca, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(4, Rebecca, playSound16)
+ Entity::playSound(savepoint, false, getSound()->getSoundFlag(kEntityCoudert));
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SIIS(5, Rebecca, callSavepoint, EntityIndex, ActionIndex)
+ Entity::callSavepoint(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(6, Rebecca, draw)
+ Entity::draw(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(7, Rebecca, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(8, Rebecca, enterExitCompartment2, ObjectIndex)
+ Entity::enterExitCompartment(savepoint, kPosition_4840, kPosition_4455, kCarRedSleeping, kObjectCompartmentE, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(9, Rebecca, enterExitCompartment3, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(10, Rebecca, callbackActionOnDirection)
+ Entity::callbackActionOnDirection(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Rebecca, callbackActionRestaurantOrSalon)
+ Entity::callbackActionRestaurantOrSalon(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(12, Rebecca, updateEntity, CarIndex, EntityPosition)
+ Entity::updateEntity(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SII(13, Rebecca, updatePosition, CarIndex, Position)
+ Entity::updatePosition(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SSI(14, Rebecca, draw2, EntityIndex)
+ Entity::draw2(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Rebecca, function15)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (getEntities()->isOutsideAnnaWindow())
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 49);
+
+ setCallback(1);
+ setup_enterExitCompartment2("624Ae", kObjectCompartmentE);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getObjects()->update(kObjectOutsideBetweenCompartments, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityRebecca);
+
+ CALLBACK_ACTION();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(16, Rebecca, function16, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param2) {
+ if (getEntities()->isDistanceBetweenEntities(kEntityRebecca, kEntitySophie, 750)) {
+ if (!getEntities()->hasValidFrame(kEntitySophie)) {
+ getSavePoints()->push(kEntityRebecca, kEntitySophie, kAction123668192);
+
+ setCallback(3);
+ setup_callbackActionRestaurantOrSalon();
+ }
+ }
+ }
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_enterExitCompartment(params->param1 ? "624Be" : "623Ee", kObjectCompartmentE);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartmentE, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject52, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityRebecca, kEntitySophie, kAction125242096);
+
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityRebecca);
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(4);
+ setup_draw("810US");
+ break;
+
+ case 4:
+ getEntities()->drawSequenceRight(kEntityRebecca, "012B");
+ if (getEntities()->isInSalon(kEntityPlayer))
+ getEntities()->updateFrame(kEntityRebecca);
+
+ setCallback(4);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 5:
+ getEntities()->drawSequenceLeft(kEntityRebecca, "012A");
+ if (getProgress().chapter == kChapter3)
+ getSound()->playSound(kEntityRebecca, "REB3000");
+
+ getSavePoints()->push(kEntityRebecca, kEntityPascale, kAction269479296);
+
+ params->param2 = 1;
+ break;
+ }
+ break;
+
+ case kAction157370960:
+ getSavePoints()->push(kEntityRebecca, kEntityTables3, kAction136455232);
+ getData()->location = kLocationInsideCompartment;
+
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(17, Rebecca, function17, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isDistanceBetweenEntities(kEntityRebecca, kEntitySophie, 750)
+ && !getEntities()->hasValidFrame(kEntitySophie)) {
+ getSavePoints()->push(kEntityRebecca, kEntitySophie, kAction123668192);
+
+ setCallback(3);
+ setup_updateFromTime(0);
+ }
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_enterExitCompartment("624Be", kObjectCompartmentE);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartmentE, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject52, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ getData()->location = kLocationOutsideCompartment;
+
+ getSavePoints()->push(kEntityRebecca, kEntitySophie, kAction125242096);
+
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntitySophie);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 4:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ if (getProgress().chapter == kChapter3)
+ getSound()->playSound(kEntityRebecca, "Reb3005", SoundManager::kFlagInvalid, 75);
+
+ if (params->param1) {
+ setCallback(5);
+ setup_updatePosition("118A", kCarRestaurant, 52);
+ } else {
+ getEntities()->updatePositionEnter(kEntityRebecca, kCarRestaurant, 57);
+
+ setCallback(6);
+ setup_draw2("107A1", "107A2", kEntitySophie);
+ }
+ break;
+
+ case 5:
+ getData()->location = kLocationInsideCompartment;
+
+ CALLBACK_ACTION();
+ break;
+
+ case 6:
+ getEntities()->updatePositionExit(kEntityRebecca, kCarRestaurant, 57);
+ getEntities()->clearSequences(kEntitySophie);
+
+ getData()->location = kLocationInsideCompartment;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Rebecca, function18)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isDistanceBetweenEntities(kEntityRebecca, kEntitySophie, 750)
+ || getEntities()->checkDistanceFromPosition(kEntitySophie, kPosition_4840, 500)) {
+ getSavePoints()->push(kEntityRebecca, kEntitySophie, kAction123668192);
+ getEntities()->exitCompartment(kEntityRebecca, kObjectCompartmentE, true);
+
+ setCallback(3);
+ setup_function15();
+ }
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_9270;
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityRebecca, kEntitySophie, kAction136654208);
+
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_4840);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (getEntities()->isDistanceBetweenEntities(kEntityRebecca, kEntitySophie, 750)
+ || getEntities()->checkDistanceFromPosition(kEntitySophie, kPosition_4840, 500)) {
+ getSavePoints()->push(kEntityRebecca, kEntitySophie, kAction123668192);
+
+ setCallback(2);
+ setup_function15();
+ } else {
+ getEntities()->drawSequenceLeft(kEntityRebecca, "623Ge");
+ getEntities()->enterCompartment(kEntityRebecca, kObjectCompartmentE, true);
+ }
+ break;
+
+ case 2:
+ case 3:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Rebecca, function19)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isDistanceBetweenEntities(kEntityRebecca, kEntitySophie, 750)
+ || getEntities()->checkDistanceFromPosition(kEntitySophie, kPosition_4840, 500)) {
+ getSavePoints()->push(kEntityRebecca, kEntitySophie, kAction123668192);
+ getEntities()->exitCompartment(kEntityRebecca, kObjectCompartmentE, true);
+
+ setCallback(6);
+ setup_function15();
+ }
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_callSavepoint("012H", kEntityTables3, kActionDrawTablesWithChairs, "010M");
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityRebecca, kEntityServers0, kAction337548856);
+ getEntities()->drawSequenceRight(kEntityRebecca, "810DS");
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityRebecca);
+
+ setCallback(4);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 3:
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_9270;
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityRebecca, kEntitySophie, kAction136654208);
+
+ setCallback(4);
+ setup_updateEntity(kCarRedSleeping, kPosition_4840);
+ break;
+
+ case 4:
+ if (getEntities()->isDistanceBetweenEntities(kEntityRebecca, kEntitySophie, 750)
+ || getEntities()->checkDistanceFromPosition(kEntitySophie, kPosition_4840, 500)) {
+ getSavePoints()->push(kEntityRebecca, kEntitySophie, kAction123668192);
+
+ setCallback(5);
+ setup_function15();
+ } else {
+ getEntities()->drawSequenceLeft(kEntityRebecca, "623Ge");
+ getEntities()->enterCompartment(kEntityRebecca, kObjectCompartmentE, true);
+ }
+ break;
+
+ case 5:
+ case 6:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(20, Rebecca, function20, TimeValue)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1 < getState()->time && !params->param5) {
+ params->param5 = 1;
+
+ getObjects()->update(kObjectCompartmentE, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject52, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (!params->param2) {
+ params->param6 = 0;
+ } else {
+ UPDATE_PARAM_PROC(params->param6, getState()->timeTicks, 75)
+ params->param2 = 0;
+ params->param3 = 1;
+ getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject52, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ params->param6 = 0;
+ UPDATE_PARAM_PROC_END
+ }
+
+ if (getProgress().chapter == kChapter1 && !ENTITY_PARAM(0, 3)) {
+ if (params->param7 != kTimeInvalid && getState()->time > kTime1174500) {
+ if (getState()->time <= kTime1183500) {
+ if (!getEntities()->isDistanceBetweenEntities(kEntityRebecca, kEntityPlayer, 2000) || getSound()->isBuffered("CON1210") || !params->param7)
+ params->param7 = getState()->time;
+
+ if (params->param7 >= getState()->time)
+ goto label_callback;
+ }
+
+ params->param7 = kTimeInvalid;
+ ENTITY_PARAM(0, 3) = 1;
+
+ getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject52, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(1);
+ setup_playSound("REB1205");
+ break;
+ }
+ goto label_callback;
+ }
+
+ if (getProgress().chapter == kChapter3 && !ENTITY_PARAM(0, 4) && params->param8 != kTimeInvalid && getState()->time > kTime2097000) {
+ if (getState()->time <= kTime2106000) {
+ if (!getEntities()->isDistanceBetweenEntities(kEntityRebecca, kEntityPlayer, 1000) || !params->param8)
+ params->param8 = getState()->time;
+
+ if (params->param8 >= getState()->time)
+ goto label_callback;
+ }
+
+ params->param8 = kTimeInvalid;
+ ENTITY_PARAM(0, 4) = 1;
+
+ getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject52, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(2);
+ setup_playSound("REB3010");
+ break;
+ }
+
+label_callback:
+ if (ENTITY_PARAM(0, 2) && getEntities()->isDistanceBetweenEntities(kEntityRebecca, kEntityPlayer, 1000)) {
+ getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject52, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(3);
+ setup_playSound("REB1040");
+ }
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject52, kEntityRebecca, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ break;
+
+ case kActionDrawScene:
+ if (params->param3 || params->param2) {
+ getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject52, kEntityRebecca, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ params->param2 = 0;
+ params->param3 = 0;
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ case 3:
+ getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject52, kEntityRebecca, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ if (getCallback() != 2)
+ ENTITY_PARAM(0, 2) = 0;
+
+ if (getCallback() != 3)
+ goto label_callback;
+ break;
+
+ case 4:
+ case 5:
+ if (rnd(2)) {
+ setCallback(6);
+ setup_playSound("REB1039");
+ } else {
+ setCallback(7);
+ setup_playSound(rnd(2) ? "SOP1039" : "SOP1039A");
+ }
+ break;
+
+ case 6:
+ case 7:
+ params->param4 = (getCallback() == 6 ? 0 : 1);
+ getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorTalk, kCursorNormal);
+ getObjects()->update(kObject52, kEntityRebecca, kObjectLocation1, kCursorTalk, kCursorNormal);
+ params->param2 = 1;
+ break;
+
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ params->param2 = 0;
+ params->param3 = 1;
+ break;
+
+ case 12:
+ setCallback(13);
+ setup_playSound16("JAC1012B");
+ break;
+
+ case 13:
+ getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject52, kEntityRebecca, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+ }
+ break;
+
+ case kAction254915200:
+ getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject52, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(12);
+ setup_playSound("REB1039A");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Rebecca, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getSavePoints()->addData(kEntityRebecca, kAction224253538, 0);
+
+ getObjects()->update(kObjectCompartmentE, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject52, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectOutsideBetweenCompartments, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ getObjects()->updateLocation2(kObject110, kObjectLocation1);
+
+ getData()->entityPosition = kPosition_2830;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+
+ ENTITY_PARAM(0, 2) = 1;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Rebecca, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_PLAYSOUND(kTime1084500, params->param3, 1, "REB1015");
+
+ if (params->param4 == kTimeInvalid)
+ goto label_callback_4;
+
+ if (getState()->time > kTime1080000)
+ goto label_playConversation;
+
+ if (!getEntities()->isInSalon(kEntityPlayer) || !params->param4)
+ params->param4 = getState()->time + 150;
+
+ if (params->param4 >= getState()->time) {
+label_callback_4:
+ if (params->param1) {
+ UPDATE_PARAM_CHECK(params->param5, getState()->time, 900)
+ if (getEntities()->isInSalon(kEntityPlayer)) {
+ setCallback(5);
+ setup_playSound("REB1013");
+ break;
+ }
+ }
+ }
+
+label_callback_5:
+ if (params->param2) {
+ UPDATE_PARAM(params->param6, getState()->timeTicks, 90);
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 55);
+ } else {
+ params->param6 = 0;
+ }
+ } else {
+label_playConversation:
+ params->param4 = kTimeInvalid;
+
+ if (getEntities()->isInSalon(kEntityPlayer))
+ getProgress().field_B8 = 1;
+
+ setCallback(4);
+ setup_playSound("REB1012");
+ }
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityRebecca, "107B");
+ break;
+
+ case kActionDrawScene:
+ params->param2 = (getEntities()->isPlayerPosition(kCarRestaurant, 57) ? 1 : 0);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updatePosition("107C", kCarRestaurant, 57);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function18();
+ break;
+
+ case 3:
+ setup_function23();
+ break;
+
+ case 4:
+ params->param1 = 1;
+ goto label_callback_4;
+
+ case 5:
+ getProgress().field_B4 = 1;
+ params->param1 = 0;
+ goto label_callback_5;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Rebecca, function23)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CALLBACK_2(kTime1111500, params->param2, 3, setup_enterExitCompartment, "623De", kObjectCompartmentE);
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateFromTime(900);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("623Ce", kObjectCompartmentE);
+ break;
+
+ case 2:
+ getObjects()->update(kObjectCompartmentE, kEntityPlayer, kObjectLocation2, kCursorNormal, kCursorNormal);
+ getEntities()->drawSequenceLeft(kEntityRebecca, "504");
+ break;
+
+ case 3:
+ case 6:
+ getEntities()->clearSequences(kEntityRebecca);
+ getData()->entityPosition = kPosition_4840;
+ getData()->location = kLocationInsideCompartment;
+
+ setCallback((byte)(getCallback() + 1));
+ setup_function20(kTime1120500);
+ break;
+
+ case 4:
+ case 5:
+ if (ENTITY_PARAM(0, 1)) {
+ setup_function24();
+ } else {
+ setCallback(5);
+ setup_function20((TimeValue)(getState()->time + 900));
+ }
+ break;
+
+ case 7:
+ case 8:
+ if (ENTITY_PARAM(0, 1)) {
+ setup_function24();
+ } else {
+ setCallback(8);
+ setup_function20((TimeValue)(getState()->time + 900));
+ }
+ break;
+ }
+ break;
+
+ case kAction285528346:
+ setCallback(6);
+ setup_enterExitCompartment("623De", kObjectCompartmentE);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Rebecca, function24)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_SAVEPOINT(kTime1134000, params->param2, kEntityRebecca, kEntityServers0, kAction223712416);
+
+ if (!params->param1)
+ break;
+
+ TIME_CHECK_CALLBACK(kTime1165500, params->param3, 6, setup_function19);
+
+ if (params->param4 != kTimeInvalid) {
+ if (getState()->time <= kTime1161000) {
+ if (!getEntities()->isInRestaurant(kEntityPlayer) || !params->param4)
+ params->param4 = getState()->time + 150;
+
+ if (params->param4 >= getState()->time)
+ break;
+ }
+
+ params->param4 = kTimeInvalid;
+
+ setCallback(7);
+ setup_playSound("REB1200A");
+ }
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function16(true);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceLeft(kEntityRebecca, "012D");
+
+ setCallback(2);
+ setup_playSound("REB1199");
+ break;
+
+ case 2:
+ if (getEntities()->isInRestaurant(kEntityPlayer)) {
+ setCallback(3);
+ setup_playSound("REB1199A");
+ break;
+ }
+ // Fallback to next case
+
+ case 3:
+ if (getCallback() == 3)
+ getProgress().field_BC = 1;
+
+ if (getEntities()->isInRestaurant(kEntityAnna)) {
+ setCallback(4);
+ setup_playSound("REB1199B");
+ break;
+ }
+ // Fallback to next case
+
+ case 4:
+ setCallback(5);
+ setup_playSound("REB1199C");
+ break;
+
+ case 6:
+ setup_function25();
+ break;
+
+ case 8:
+ getSavePoints()->push(kEntityRebecca, kEntityServers0, kAction136702400);
+ getEntities()->drawSequenceLeft(kEntityRebecca, "012G");
+ params->param1 = 1;
+ break;
+ }
+ break;
+
+ case kAction123712592:
+ getEntities()->drawSequenceLeft(kEntityServers0, "BLANK");
+ getEntities()->drawSequenceLeft(kEntityRebecca, "012E");
+
+ setCallback(8);
+ setup_playSound("REB1200");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, Rebecca, function25)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function20(kTime1184400);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function17(false);
+ break;
+
+ case 2:
+ setup_function26();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(26, Rebecca, function26)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CALLBACK_3(kTime1224000, params->param2, 1, setup_updatePosition, "118H", kCarRestaurant, 52);
+
+ if (params->param1) {
+ UPDATE_PARAM(params->param3, getState()->timeTicks, 90);
+
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 51);
+ }
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityRebecca, "118D");
+ break;
+
+ case kActionDrawScene:
+ params->param1 = getEntities()->isPlayerPosition(kCarRestaurant, 52);
+ params->param3 = 0;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function18();
+ break;
+
+ case 2:
+ setup_function27();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(27, Rebecca, function27)
+ if (savepoint.action == kActionDefault) {
+ getData()->entityPosition = kPosition_4840;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getObjects()->update(kObjectCompartmentE, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject52, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ getEntities()->clearSequences(kEntityRebecca);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(28, Rebecca, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter2Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityRebecca);
+
+ getData()->entityPosition = kPosition_4840;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObjectCompartmentE, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject52, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ getObjects()->updateLocation2(kObject110, kObjectLocation2);
+
+ ENTITY_PARAM(0, 2) = 1;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(29, Rebecca, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function20(kTime1764000);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function17(false);
+ break;
+
+ case 2:
+ setup_function30();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(30, Rebecca, function30)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1 && params->param4 != kTimeInvalid) {
+
+ if (getState()->time <= kTimeEnd)
+ if (!getEntities()->isInSalon(kEntityPlayer) || !params->param4)
+ params->param4 = getState()->time + 450;
+
+ if (params->param4 < getState()->time || getState()->time > kTimeEnd) {
+ params->param4 = kTimeInvalid;
+
+ getSound()->playSound(kEntityRebecca, "Reb2001");
+ getProgress().field_B0 = 1;
+ params->param2 = 1;
+ }
+ }
+
+ if (!params->param3 && !params->param2 && params->param5 != kTimeInvalid) {
+
+ if (getState()->time <= kTime10881000) {
+ if (!getEntities()->isInSalon(kEntityPlayer) || !params->param5)
+ params->param5 = getState()->time + 450;
+
+ if (params->param5 >= getState()->time)
+ break;
+ }
+
+ params->param5 = kTimeInvalid;
+
+ getSavePoints()->push(kEntityRebecca, kEntityAugust, kAction169358379);
+ }
+ break;
+
+ case kActionEndSound:
+ params->param2 = 0;
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityRebecca, "107B");
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function31();
+ break;
+
+ case kAction125496184:
+ setCallback(1);
+ setup_function18();
+ break;
+
+ case kAction155465152:
+ getEntities()->drawSequenceLeft(kEntityRebecca, "BLANK");
+ break;
+
+ case kAction155980128:
+ params->param1 = 1;
+ params->param3 = 1;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(31, Rebecca, function31)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateFromTime(900);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("623CE", kObjectCompartmentE);
+ break;
+
+ case 2:
+ getObjects()->update(kObjectCompartmentE, kEntityPlayer, kObjectLocation2, kCursorNormal, kCursorNormal);
+ getEntities()->drawSequenceLeft(kEntityRebecca, "504");
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(32, Rebecca, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityRebecca);
+
+ getData()->entityPosition = kPosition_4840;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(33, Rebecca, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function20(kTime2016000);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function34();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(34, Rebecca, function34)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param2 == kTimeInvalid) {
+ if (getState()->time <= kTime1386000) {
+ if (!getEntities()->isInRestaurant(kEntityPlayer) || !params->param2)
+ params->param2 = getState()->time;
+
+ if (params->param2 >= getState()->time) {
+ TIME_CHECK_CALLBACK(kTime2052000, params->param3, 1, setup_function19);
+ break;
+ }
+ }
+
+ params->param2 = kTimeInvalid;
+
+ getSavePoints()->push(kEntityRebecca, kEntityServers0, kAction223712416);
+ }
+
+ TIME_CHECK_CALLBACK(kTime2052000, params->param3, 1, setup_function19);
+ break;
+
+ case kActionEndSound:
+ setCallback(5);
+ setup_playSound("Reb3004");
+ break;
+
+ case kActionDefault:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_function16(true);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceLeft(kEntityRebecca, "012D");
+ getData()->location = kLocationInsideCompartment;
+
+ setCallback(2);
+ setup_playSound("Reb3002");
+ break;
+
+ case 3:
+ setup_function35();
+ break;
+
+ case 4:
+ getSavePoints()->push(kEntityRebecca, kEntityServers0, kAction136702400);
+ getEntities()->drawSequenceLeft(kEntityRebecca, "012G");
+ params->param1 = 1;
+ break;
+ }
+ break;
+
+ case kAction123712592:
+ getEntities()->drawSequenceLeft(kEntityServers0, "BLANK");
+ getSound()->playSound(kEntityRebecca, "Reb3003");
+
+ setCallback(4);
+ setup_draw("012E");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(35, Rebecca, function35)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function20(kTime2070000);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function36();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(36, Rebecca, function36)
+ error("Rebecca: callback function 36 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(37, Rebecca, function37)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function20(kTime2110500);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function38();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(38, Rebecca, function38)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_enterExitCompartment3("624Be", kObjectCompartmentE);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartmentE, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getSavePoints()->push(kEntityRebecca, kEntitySophie, kAction259921280);
+
+ setCallback(2);
+ setup_updateEntity(kCarKronos, kPosition_9270);
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityRebecca, kEntitySophie, kAction123668192);
+ setup_function39();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(39, Rebecca, function39)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityRebecca);
+
+ getObjects()->update(kObjectCompartmentE, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject52, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ getData()->entityPosition = kPosition_6000;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarKronos;
+ break;
+
+ case kAction191668032:
+ setup_function40();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(40, Rebecca, function40)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_9270;
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2740);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityRebecca, kEntitySophie, kAction292775040);
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_2740);
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityRebecca, kEntityAnna, kAction191668032);
+ setCallback(3);
+ setup_updateEntity(kCarRedSleeping, kPosition_4840);
+ break;
+
+ case 3:
+ getSavePoints()->push(kEntityRebecca, kEntitySophie, kAction123668192);
+ setCallback(4);
+ setup_function15();
+ break;
+
+ case 4:
+ setup_function41();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(41, Rebecca, function41)
+ if (savepoint.action == kActionDefault) {
+ ENTITY_PARAM(0, 2) = 1;
+
+ setCallback(1);
+ setup_function20(kTimeEnd);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(42, Rebecca, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityRebecca);
+
+ getData()->entityPosition = kPosition_4840;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->updateLocation2(kObject110, kObjectLocation3);
+
+ ENTITY_PARAM(0, 1) = 0;
+ ENTITY_PARAM(0, 2) = 1;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(43, Rebecca, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function20(kTime2385000);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1 || getCallback() == 2) {
+ if (ENTITY_PARAM(0, 1)) {
+ setup_function44();
+ } else {
+ setCallback(2);
+ setup_function20((TimeValue)(getState()->time + 900));
+ }
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(44, Rebecca, function44)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param3 != kTimeInvalid) {
+ if (getState()->time <= kTime2412000) {
+ if (!getEntities()->isInRestaurant(kEntityPlayer) || !params->param3)
+ params->param3 = getState()->time;
+
+ if (params->param3 >= getState()->time)
+ goto label_next;
+ }
+
+ params->param3 = kTimeInvalid;
+
+ getSavePoints()->push(kEntityRebecca, kEntityServers0, kAction223712416);
+ }
+
+label_next:
+ if (params->param1 && params->param4 != kTimeInvalid) {
+ if (getState()->time <= kTime2430000) {
+ if (!getEntities()->isInRestaurant(kEntityPlayer) || !params->param4)
+ params->param4 = getState()->time + 150;
+
+ if (params->param4 >= getState()->time)
+ goto label_callback_2;
+ }
+
+ params->param4 = kTimeInvalid;
+
+ setCallback(2);
+ setup_playSound("Reb4004");
+ break;
+ }
+
+label_callback_2:
+ if (params->param2)
+ TIME_CHECK_CALLBACK(kTime2443500, params->param5, 3, setup_function19);
+ break;
+
+ case kActionEndSound:
+ if (getEntities()->isInRestaurant(kEntityPlayer)) {
+ setCallback(5);
+ setup_playSound("Reb4004");
+ break;
+ }
+
+ params->param1 = 1;
+ break;
+
+ case kActionDefault:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_function16(true);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceLeft(kEntityRebecca, "012D");
+ getData()->location = kLocationInsideCompartment;
+ break;
+
+ case 2:
+ goto label_callback_2;
+
+ case 3:
+ setup_function45();
+ break;
+
+ case 4:
+ getSavePoints()->push(kEntityRebecca, kEntityServers0, kAction136702400);
+ getEntities()->drawSequenceLeft(kEntityRebecca, "012G");
+ params->param2 = 1;
+ break;
+ }
+ break;
+
+ case kAction123712592:
+ getEntities()->drawSequenceLeft(kEntityRebecca, "BLANK");
+ getSound()->playSound(kEntityRebecca, "Reb4003");
+
+ setCallback(4);
+ setup_draw("012E");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(45, Rebecca, function45)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_4840;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getObjects()->update(kObjectCompartmentE, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject52, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ getEntities()->clearSequences(kEntityRebecca);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ params->param1 = 1;
+ break;
+
+ case kAction205034665:
+ if (!params->param1 && getState()->time < kTime2511000) {
+ setCallback(1);
+ setup_playSound("Reb6969");
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(46, Rebecca, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityRebecca);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->updateLocation2(kObject110, kObjectLocation4);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(47, Rebecca, chapter5Handler)
+ if (savepoint.action == kActionProceedChapter5)
+ setup_function48();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(48, Rebecca, function48)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1) {
+ UPDATE_PARAM(params->param3, getState()->timeTicks, 75);
+
+ params->param1 = 0;
+ params->param2 = 1;
+ getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+ }
+
+ params->param3 = 0;
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ if (params->param1) {
+ params->param1 = 0;
+
+ setCallback(2);
+ setup_playSound(getSound()->justCheckingCath());
+ } else {
+ setCallback(savepoint.action == kActionKnock ? 3 : 4);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ }
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarRedSleeping;
+
+ setCallback(1);
+ setup_enterExitCompartment("624AE", kObjectCompartmentE);
+ break;
+
+ case kActionDrawScene:
+ if (params->param1 || params->param2) {
+ params->param1 = 0;
+ params->param2 = 0;
+
+ getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->clearSequences(kEntityRebecca);
+ getData()->location = kLocationInsideCompartment;
+ getData()->entityPosition = kPosition_4840;
+ getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case 3:
+ case 4:
+ setCallback(5);
+ setup_playSound("Reb5001");
+ break;
+
+ case 5:
+ params->param1 = 1;
+ getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorTalk, kCursorNormal);
+ break;
+ }
+ break;
+
+ case kAction135800432:
+ setup_nullfunction();
+ break;
+
+ case kAction155604840:
+ getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_NULL_FUNCTION(49, Rebecca)
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/rebecca.h b/engines/lastexpress/entities/rebecca.h
new file mode 100644
index 0000000000..bf836b1fa3
--- /dev/null
+++ b/engines/lastexpress/entities/rebecca.h
@@ -0,0 +1,230 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_REBECCA_H
+#define LASTEXPRESS_REBECCA_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Rebecca : public Entity {
+public:
+ Rebecca(LastExpressEngine *engine);
+ ~Rebecca() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param time The time to add
+ */
+ DECLARE_FUNCTION_1(updateFromTime, uint32 time)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound16, const char* filename)
+
+ /**
+ * Call a savepoint (or draw sequence in default case)
+ *
+ * @param sequence1 The sequence to draw in the default case
+ * @param entity The entity
+ * @param action The action
+ * @param sequence2 The sequence name for the savepoint
+ */
+ DECLARE_FUNCTION_4(callSavepoint, const char* sequence1, EntityIndex entity, ActionIndex action, const char* sequence2)
+
+ /**
+ * Draws the entity
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(draw, const char* sequence)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Handles entering/exiting a compartment and updates position/play animation
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment2, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment3, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Process callback action when the entity direction is not kDirectionRight
+ */
+ DECLARE_FUNCTION(callbackActionOnDirection)
+
+ /**
+ * Process callback action when somebody is standing in the restaurant or salon.
+ */
+ DECLARE_FUNCTION(callbackActionRestaurantOrSalon)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+
+ /**
+ * Updates the position
+ *
+ * @param sequence1 The sequence to draw
+ * @param car The car
+ * @param position The position
+ */
+ DECLARE_FUNCTION_3(updatePosition, const char* sequence1, CarIndex car, Position position)
+
+ /**
+ * Draws the entity along with another one
+ *
+ * @param sequence1 The sequence to draw
+ * @param sequence2 The sequence to draw for the second entity
+ * @param entity The EntityIndex of the second entity
+ */
+ DECLARE_FUNCTION_3(draw2, const char* sequence1, const char* sequence2, EntityIndex entity)
+
+ DECLARE_FUNCTION(function15)
+ DECLARE_FUNCTION_1(function16, bool)
+ DECLARE_FUNCTION_1(function17, bool)
+ DECLARE_FUNCTION(function18)
+ DECLARE_FUNCTION(function19)
+ DECLARE_FUNCTION_1(function20, TimeValue timeValue)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function23)
+ DECLARE_FUNCTION(function24)
+ DECLARE_FUNCTION(function25)
+ DECLARE_FUNCTION(function26)
+ DECLARE_FUNCTION(function27)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+
+ DECLARE_FUNCTION(function30)
+ DECLARE_FUNCTION(function31)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ DECLARE_FUNCTION(function34)
+ DECLARE_FUNCTION(function35)
+ DECLARE_FUNCTION(function36)
+ DECLARE_FUNCTION(function37)
+ DECLARE_FUNCTION(function38)
+ DECLARE_FUNCTION(function39)
+ DECLARE_FUNCTION(function40)
+ DECLARE_FUNCTION(function41)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ DECLARE_FUNCTION(function44)
+ DECLARE_FUNCTION(function45)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_FUNCTION(function48)
+
+ DECLARE_NULL_FUNCTION()
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_REBECCA_H
diff --git a/engines/lastexpress/entities/salko.cpp b/engines/lastexpress/entities/salko.cpp
new file mode 100644
index 0000000000..688208f30a
--- /dev/null
+++ b/engines/lastexpress/entities/salko.cpp
@@ -0,0 +1,642 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/salko.h"
+
+#include "lastexpress/game/action.h"
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/fight.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+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(Salko, function8);
+ ADD_CALLBACK_FUNCTION(Salko, chapter1);
+ ADD_CALLBACK_FUNCTION(Salko, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Salko, function11);
+ ADD_CALLBACK_FUNCTION(Salko, chapter2);
+ ADD_CALLBACK_FUNCTION(Salko, function13);
+ ADD_CALLBACK_FUNCTION(Salko, chapter3);
+ ADD_CALLBACK_FUNCTION(Salko, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Salko, function16);
+ ADD_CALLBACK_FUNCTION(Salko, function17);
+ ADD_CALLBACK_FUNCTION(Salko, chapter4);
+ ADD_CALLBACK_FUNCTION(Salko, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Salko, function20);
+ ADD_CALLBACK_FUNCTION(Salko, function21);
+ ADD_CALLBACK_FUNCTION(Salko, function22);
+ ADD_CALLBACK_FUNCTION(Salko, chapter5);
+ ADD_CALLBACK_FUNCTION(Salko, chapter5Handler);
+ ADD_NULL_FUNCTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Salko, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(2, Salko, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(3, Salko, draw)
+ Entity::draw(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(4, Salko, updateEntity, CarIndex, EntityPosition)
+ Entity::updateEntity(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(5, Salko, updateFromTime, uint32)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(6, Salko, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(7, Salko, function7, CarIndex, EntityPosition)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone: {
+ params->param3 = 0;
+
+ EntityDirection direction = getData()->direction;
+ CarIndex carSalko = getData()->car;
+ CarIndex carIvo = getEntityData(kEntityIvo)->car;
+ EntityPosition positionSalko = getData()->entityPosition;
+ EntityPosition positionIvo = getEntityData(kEntityIvo)->entityPosition;
+
+ if (getEntities()->isDistanceBetweenEntities(kEntitySalko, kEntityIvo, 500)
+ || (direction == kDirectionUp && (carSalko > carIvo || (carSalko == carIvo && positionSalko > positionIvo)))
+ || (direction == kDirectionDown && (carSalko < carIvo || (carSalko == carIvo && positionSalko < positionIvo)))) {
+ getData()->field_49B = 0;
+ params->param3 = 1;
+ }
+
+ if (!params->param3)
+ getEntities()->updateEntity(kEntitySalko, (CarIndex)params->param1, (EntityPosition)params->param2);
+
+ }
+ break;
+
+ case kActionExcuseMeCath:
+ case kActionExcuseMe:
+ getSound()->playSound(kEntityPlayer, "ZFX1002", getSound()->getSoundFlag(kEntitySalko));
+ getSound()->playSound(kEntityPlayer, "CAT1127A");
+ break;
+
+ case kActionDefault:
+ getEntities()->updateEntity(kEntitySalko, (CarIndex)params->param1, (EntityPosition)params->param2);
+ break;
+
+ case kAction123668192:
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(8, Salko, function8)
+ if (savepoint.action == kActionDefault) {
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(9, Salko, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_4691;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(10, Salko, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ getData()->entityPosition = getEntityData(kEntityIvo)->entityPosition;
+ getData()->location = getEntityData(kEntityIvo)->location;
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getEntities()->clearSequences(kEntitySalko);
+ setup_function8();
+ }
+ break;
+
+ case kAction125242096:
+ setCallback(1);
+ setup_function7(kCarRedSleeping, kPosition_2740);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Salko, function11)
+ if (savepoint.action == kActionDefault) {
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getEntities()->clearSequences(kEntitySalko);
+ getObjects()->update(kObjectCompartmentH, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Salko, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntitySalko);
+
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+
+ case kAction136184016:
+ setCallback(1);
+ setup_function13();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Salko, function13)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_enterExitCompartment("612DH", kObjectCompartmentH);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntitySalko, kEntityIvo, kAction102675536);
+ getEntities()->clearSequences(kEntitySalko);
+ break;
+
+ case 3:
+ getEntities()->drawSequenceLeft(kEntitySalko, "BLANK");
+ getData()->location = kLocationInsideCompartment;
+
+ setup_function8();
+ break;
+ }
+ break;
+
+ case kAction125242096:
+ setCallback(3);
+ setup_function7(kCarRedSleeping, kPosition_2740);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Salko, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntitySalko);
+
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Salko, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time < kTime2200500) {
+ UPDATE_PARAM(params->param1, getState()->time, 81000);
+
+ setCallback(1);
+ setup_function16();
+ }
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ params->param1 = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Salko, function16)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->hasValidFrame(kEntitySalko) && getEntities()->isDistanceBetweenEntities(kEntitySalko, kEntityPlayer, 5000)) {
+ getSavePoints()->push(kEntitySalko, kEntityMax, kAction158007856);
+
+ setCallback(3);
+ setup_updateFromTime(75);
+ break;
+ }
+
+label_callback3:
+ UPDATE_PARAM(params->param1, getState()->time, 4500);
+
+ getSavePoints()->push(kEntitySalko, kEntitySalko, kAction101169464);
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_enterExitCompartment("612DH", kObjectCompartmentH);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+
+ if (getData()->entityPosition < kPosition_2087)
+ getData()->entityPosition = kPosition_2088;
+
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_4070);
+ break;
+
+ case 2:
+ break;
+
+ case 3:
+ getSavePoints()->push(kEntitySalko, kEntitySalko, kAction101169464);
+ goto label_callback3;
+
+ case 4:
+ getEntities()->exitCompartment(kEntitySalko, kObjectCompartmentF, true);
+
+ setCallback(5);
+ setup_updateEntity(kCarRedSleeping, kPosition_9460);
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_updateFromTime(4500);
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_updateEntity(kCarRedSleeping, kPosition_2740);
+ break;
+
+ case 7:
+ setCallback(8);
+ setup_enterExitCompartment("612Ch", kObjectCompartmentH);
+ break;
+
+ case 8:
+ getData()->location = kLocationInsideCompartment;
+ getData()->entityPosition = kPosition_2740;
+ getEntities()->clearSequences(kEntitySalko);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction101169464:
+ setCallback(4);
+ setup_enterExitCompartment("612Bf", kObjectCompartmentF);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Salko, function17)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_6470;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2740);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("612Ch", kObjectCompartmentH);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntitySalko);
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getSavePoints()->push(kEntitySalko, kEntityMilos, kAction157691176);
+
+ setup_chapter3Handler();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Salko, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntitySalko);
+
+ getData()->entityPosition = kPosition_5420;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Salko, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getEntities()->drawSequenceLeft(kEntitySalko, "BLANK");
+
+ getData()->location = kLocationInsideCompartment;
+
+ setup_function20();
+ }
+ break;
+
+ case kAction125242096:
+ setCallback(1);
+ setup_function7(kCarRedSleeping, kPosition_2740);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Salko, function20)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ if (getData()->entityPosition < kPosition_2087)
+ getData()->entityPosition = kPosition_2088;
+
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntitySalko);
+ setup_function21();
+ break;
+ }
+ break;
+
+ case kAction55996766:
+ setCallback(1);
+ setup_enterExitCompartment("612Dh", kObjectCompartmentH);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Salko, function21)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime2422800 && !params->param1) {
+ params->param1 = 1;
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_2740);
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment("612Ch", kObjectCompartmentH);
+ break;
+
+ case 2:
+ setup_function22();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Salko, function22)
+ if (savepoint.action == kActionDefault) {
+ getEntities()->clearSequences(kEntitySalko);
+ getObjects()->update(kObjectCompartmentH, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ getData()->entityPosition = kPosition_2740;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->inventoryItem = kItemNone;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Salko, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntitySalko);
+
+ getData()->entityPosition = kPosition_9460;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Salko, chapter5Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (getSound()->isBuffered("MUS050"))
+ getSound()->processEntry("MUS050");
+
+ getAction()->playAnimation(kEventCathSalkoTrainTopFight);
+
+ setCallback(2);
+ setup_savegame(kSavegameTypeTime, kTimeNone);
+ break;
+
+ case 2:
+ params->param1 = getFight()->setup(kFightSalko);
+
+ if (params->param1 == Fight::kFightEndWin) {
+ getState()->time += 1800;
+ setCallback(3);
+ setup_savegame(kSavegameTypeEvent, kEventCathSalkoTrainTopWin);
+ } else {
+ getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, params->param1 == Fight::kFightEndLost);
+ }
+ break;
+
+ case 3:
+ getAction()->playAnimation(kEventCathSalkoTrainTopWin);
+ getSavePoints()->push(kEntitySalko, kEntityVesna, kAction134427424);
+
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 10);
+ setup_nullfunction();
+ break;
+ }
+ break;
+
+ case kAction167992577:
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventCathSalkoTrainTopFight);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_NULL_FUNCTION(25, Salko)
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/salko.h b/engines/lastexpress/entities/salko.h
new file mode 100644
index 0000000000..49059c4b40
--- /dev/null
+++ b/engines/lastexpress/entities/salko.h
@@ -0,0 +1,149 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_SALKO_H
+#define LASTEXPRESS_SALKO_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Salko : public Entity {
+public:
+ Salko(LastExpressEngine *engine);
+ ~Salko() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Draws the entity
+ *
+ * @param savepoint The savepoint
+ * - The sequence to draw
+ */
+ DECLARE_FUNCTION_NOSETUP(draw)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param time The time to add
+ */
+ DECLARE_FUNCTION_1(updateFromTime, uint32 time)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ DECLARE_FUNCTION_2(function7, CarIndex car, EntityPosition entityPosition)
+
+ DECLARE_FUNCTION(function8)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function11)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+ DECLARE_FUNCTION(function13)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ DECLARE_FUNCTION(function16)
+ DECLARE_FUNCTION(function17)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ DECLARE_FUNCTION(function20)
+ DECLARE_FUNCTION(function21)
+ DECLARE_FUNCTION(function22)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_NULL_FUNCTION()
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_SALKO_H
diff --git a/engines/lastexpress/entities/servers0.cpp b/engines/lastexpress/entities/servers0.cpp
new file mode 100644
index 0000000000..33f2943c43
--- /dev/null
+++ b/engines/lastexpress/entities/servers0.cpp
@@ -0,0 +1,1039 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/servers0.h"
+
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+namespace LastExpress {
+
+#define HANDLE_TABLE(index, param, callback, function) \
+ if (ENTITY_PARAM(index, param)) { \
+ setCallback(callback); \
+ function(); \
+ break; \
+ }
+
+Servers0::Servers0(LastExpressEngine *engine) : Entity(engine, kEntityServers0) {
+ ADD_CALLBACK_FUNCTION(Servers0, callSavepoint);
+ ADD_CALLBACK_FUNCTION(Servers0, updateFromTime);
+ ADD_CALLBACK_FUNCTION(Servers0, draw);
+ ADD_CALLBACK_FUNCTION(Servers0, updatePosition);
+ ADD_CALLBACK_FUNCTION(Servers0, callbackActionOnDirection);
+ ADD_CALLBACK_FUNCTION(Servers0, playSound);
+ ADD_CALLBACK_FUNCTION(Servers0, function7);
+ ADD_CALLBACK_FUNCTION(Servers0, function8);
+ ADD_CALLBACK_FUNCTION(Servers0, function9);
+ ADD_CALLBACK_FUNCTION(Servers0, function10);
+ ADD_CALLBACK_FUNCTION(Servers0, chapter1);
+ ADD_CALLBACK_FUNCTION(Servers0, function12);
+ ADD_CALLBACK_FUNCTION(Servers0, function13);
+ ADD_CALLBACK_FUNCTION(Servers0, function14);
+ ADD_CALLBACK_FUNCTION(Servers0, function15);
+ ADD_CALLBACK_FUNCTION(Servers0, function16);
+ ADD_CALLBACK_FUNCTION(Servers0, function17);
+ ADD_CALLBACK_FUNCTION(Servers0, function18);
+ ADD_CALLBACK_FUNCTION(Servers0, function19);
+ ADD_CALLBACK_FUNCTION(Servers0, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Servers0, function21);
+ ADD_CALLBACK_FUNCTION(Servers0, function22);
+ ADD_CALLBACK_FUNCTION(Servers0, chapter2);
+ ADD_CALLBACK_FUNCTION(Servers0, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Servers0, function25);
+ ADD_CALLBACK_FUNCTION(Servers0, function26);
+ ADD_CALLBACK_FUNCTION(Servers0, chapter3);
+ ADD_CALLBACK_FUNCTION(Servers0, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Servers0, augustAnnaDateOrder);
+ ADD_CALLBACK_FUNCTION(Servers0, function30);
+ ADD_CALLBACK_FUNCTION(Servers0, chapter4);
+ ADD_CALLBACK_FUNCTION(Servers0, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Servers0, augustOrderSteak);
+ ADD_CALLBACK_FUNCTION(Servers0, augustServeDuck);
+ ADD_CALLBACK_FUNCTION(Servers0, function35);
+ ADD_CALLBACK_FUNCTION(Servers0, chapter5);
+ ADD_CALLBACK_FUNCTION(Servers0, chapter5Handler);
+ ADD_NULL_FUNCTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SIIS(1, Servers0, callSavepoint, EntityIndex, ActionIndex)
+ Entity::callSavepoint(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(2, Servers0, updateFromTime)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(3, Servers0, draw)
+ Entity::draw(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(4, Servers0, updatePosition)
+ Entity::updatePosition(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(5, Servers0, callbackActionOnDirection)
+ EXPOSE_PARAMS(EntityData::EntityParametersIIII);
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getData()->direction != kDirectionRight)
+ CALLBACK_ACTION();
+ break;
+
+ case kActionExitCompartment:
+ CALLBACK_ACTION();
+ break;
+
+ case kActionExcuseMeCath:
+ if (!params->param1) {
+ getSound()->excuseMe(kEntityServers0);
+ params->param1 = 1;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(6, Servers0, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(7, Servers0, function7)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ ENTITY_PARAM(0, 3) = 0;
+
+ setCallback(1);
+ setup_draw("911");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->clearSequences(kEntityServers0);
+ getSavePoints()->push(kEntityServers0, kEntityRebecca, kAction123712592);
+ break;
+
+ case 2:
+ getEntities()->clearSequences(kEntityServers0);
+ getData()->entityPosition = kPosition_5900;
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction136702400:
+ setCallback(2);
+ setup_draw("913");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(8, Servers0, function8)
+ serveTable(savepoint, "911", kEntityTables3, "010L", "010M", "913", &ENTITY_PARAM(1, 2));
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(9, Servers0, function9)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_draw("915");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityServers0, kEntityAbbot, kAction122358304);
+ getEntities()->drawSequenceLeft(kEntityServers0, "029D");
+
+ setCallback(2);
+ setup_playSound(getProgress().chapter == kChapter3 ? "Abb3016" : "Abb4001");
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityServers0, kEntityAbbot, kAction122288808);
+
+ setCallback(3);
+ setup_draw("917");
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_5900;
+ getEntities()->clearSequences(kEntityServers0);
+ ENTITY_PARAM(2, 2) = 0;
+ ENTITY_PARAM(1, 6) = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(10, Servers0, function10)
+ serveTable(savepoint, "916", kEntityTables4, "014E", "014F", "918", &ENTITY_PARAM(2, 3), false);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Servers0, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter1Handler();
+ break;
+
+ case kActionDefault:
+ getSavePoints()->addData(kEntityServers0, kAction270410280, 0);
+ getSavePoints()->addData(kEntityServers0, kAction304061224, 1);
+ getSavePoints()->addData(kEntityServers0, kAction252568704, 10);
+ getSavePoints()->addData(kEntityServers0, kAction286534136, 11);
+ getSavePoints()->addData(kEntityServers0, kAction218983616, 12);
+ getSavePoints()->addData(kEntityServers0, kAction218586752, 13);
+ getSavePoints()->addData(kEntityServers0, kAction207330561, 14);
+ getSavePoints()->addData(kEntityServers0, kAction286403504, 16);
+ getSavePoints()->addData(kEntityServers0, kAction218128129, 17);
+ getSavePoints()->addData(kEntityServers0, kAction270068760, 18);
+ getSavePoints()->addData(kEntityServers0, kAction223712416, 2);
+ getSavePoints()->addData(kEntityServers0, kAction237485916, 5);
+ getSavePoints()->addData(kEntityServers0, kAction188893625, 8);
+ getSavePoints()->addData(kEntityServers0, kAction204704037, 6);
+ getSavePoints()->addData(kEntityServers0, kAction292758554, 7);
+ getSavePoints()->addData(kEntityServers0, kAction337548856, 9);
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Servers0, function12)
+ handleServer(savepoint, "907", kEntityAnna, kAction268773672, &ENTITY_PARAM(0, 1));
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Servers0, function13)
+ handleServer(savepoint, "911", kEntityAugust, kAction268773672, &ENTITY_PARAM(0, 2), "010F");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Servers0, function14)
+ handleServer(savepoint, "908", kEntityAnna, kAction170016384, &ENTITY_PARAM(0, 4));
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Servers0, function15)
+ handleServer(savepoint, "912", kEntityAugust, kAction170016384, &ENTITY_PARAM(0, 5));
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Servers0, function16)
+ serveTable(savepoint, "907", kEntityTables0, "001N", "001P", "909", &ENTITY_PARAM(0, 6));
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Servers0, function17)
+ serveTable(savepoint, "915", kEntityTables4, "014E", "014F", "917", &ENTITY_PARAM(1, 1), true, false, 67);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Servers0, function18)
+ serveTable(savepoint, "911", kEntityTables3, "010L", "010H", "913", &ENTITY_PARAM(0, 7));
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Servers0, function19)
+ serveTable(savepoint, "911", kEntityTables3, "010L", "010M", "913", &ENTITY_PARAM(0, 8), true, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Servers0, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param2) {
+ UPDATE_PARAM_PROC(params->param3, getState()->time, 2700);
+ ENTITY_PARAM(0, 4) = 1;
+ params->param2 = 0;
+ UPDATE_PARAM_PROC_END
+ }
+
+ if (params->param1) {
+ UPDATE_PARAM_PROC(params->param4, getState()->time, 4500)
+ ENTITY_PARAM(0, 5) = 1;
+ params->param1 = 0;
+ UPDATE_PARAM_PROC_END
+ }
+
+ if (!getEntities()->isInKitchen(kEntityServers0) && !getEntities()->isSomebodyInsideRestaurantOrSalon())
+ break;
+
+ HANDLE_TABLE(0, 1, 1, setup_function12);
+ HANDLE_TABLE(0, 2, 2, setup_function13);
+ HANDLE_TABLE(0, 3, 3, setup_function7);
+ HANDLE_TABLE(0, 4, 4, setup_function14);
+ HANDLE_TABLE(0, 5, 5, setup_function15);
+ HANDLE_TABLE(0, 6, 6, setup_function16);
+ HANDLE_TABLE(1, 1, 7, setup_function17);
+ HANDLE_TABLE(0, 7, 8, setup_function18);
+ HANDLE_TABLE(0, 8, 9, setup_function19);
+ HANDLE_TABLE(1, 2, 10, setup_function8);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 10:
+ getSavePoints()->push(kEntityServers0, kEntityPascale, kAction352703104);
+ setup_function21();
+ break;
+
+ case 11:
+ case 12:
+ getEntities()->clearSequences(kEntityServers0);
+ getData()->entityPosition = kPosition_5900;
+
+ if (getCallback() == 11)
+ params->param2 = 1;
+ else
+ params->param1 = 1;
+ break;
+
+ case 13:
+ case 14:
+ getEntities()->clearSequences(kEntityServers0);
+ getData()->entityPosition = kPosition_5900;
+ break;
+ }
+ break;
+
+ case kAction136702400:
+ setCallback(savepoint.entity2 == kEntityAnna ? 13 : 14);
+ setup_draw(savepoint.entity2 == kEntityAnna ? "909" : "913");
+ break;
+
+ case kAction203859488:
+ setCallback(savepoint.entity2 == kEntityAnna ? 11 : 12);
+ setup_draw(savepoint.entity2 == kEntityAnna ? "910" : "913");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Servers0, function21)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5900;
+ break;
+
+ case kAction101632192:
+ setup_function22();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Servers0, function22)
+ if (savepoint.action == kActionDefault) {
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+
+ getEntities()->clearSequences(kEntityServers0);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Servers0, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter2Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityServers0);
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothes1;
+ getData()->inventoryItem = kItemNone;
+
+ ENTITY_PARAM(1, 3) = 0;
+ ENTITY_PARAM(1, 4) = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Servers0, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!getEntities()->isInKitchen(kEntityServers0) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
+ break;
+
+ HANDLE_TABLE(1, 3, 1, setup_function25);
+ HANDLE_TABLE(1, 4, 2, setup_function26);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ HANDLE_TABLE(1, 4, 2, setup_function26);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, Servers0, function25)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_draw("957");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityServers0, kEntityAugust, kAction123712592);
+ getEntities()->drawSequenceLeft(kEntityServers0, "BLANK");
+ break;
+
+ case 2:
+ getData()->entityPosition = kPosition_5900;
+ getEntities()->clearSequences(kEntityServers0);
+ ENTITY_PARAM(1, 3) = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+
+ case kAction219522616:
+ setCallback(2);
+ setup_draw("959");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(26, Servers0, function26)
+ serveTable(savepoint, "957", kEntityTables0, "016E", "016D", "959", &ENTITY_PARAM(1, 4));
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(27, Servers0, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityServers0);
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothes1;
+ getData()->inventoryItem = kItemNone;
+
+ ENTITY_PARAM(0, 3) = 0;
+ ENTITY_PARAM(1, 2) = 0;
+ ENTITY_PARAM(1, 5) = 0;
+ ENTITY_PARAM(1, 6) = 0;
+ ENTITY_PARAM(2, 3) = 0;
+ ENTITY_PARAM(2, 4) = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(28, Servers0, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!getEntities()->isInKitchen(kEntityServers1) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
+ break;
+
+ if (ENTITY_PARAM(1, 5)) {
+ setCallback(1);
+ setup_augustAnnaDateOrder();
+ break;
+ }
+
+label_callback_1:
+ if (ENTITY_PARAM(1, 6)) {
+ setCallback(2);
+ setup_function9();
+ break;
+ }
+
+label_callback_2:
+ if (ENTITY_PARAM(2, 4)) {
+ setCallback(3);
+ setup_function30();
+ break;
+ }
+
+label_callback_3:
+ if (ENTITY_PARAM(2, 3)) {
+ setCallback(4);
+ setup_function10();
+ break;
+ }
+
+label_callback_4:
+ if (ENTITY_PARAM(0, 3)) {
+ setCallback(5);
+ setup_function7();
+ break;
+ }
+
+label_callback_5:
+ if (ENTITY_PARAM(1, 2)) {
+ setCallback(6);
+ setup_function8();
+ break;
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_callback_1;
+
+ case 2:
+ goto label_callback_2;
+
+ case 3:
+ goto label_callback_3;
+
+ case 4:
+ goto label_callback_4;
+
+ case 5:
+ goto label_callback_5;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(29, Servers0, augustAnnaDateOrder)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_draw("911");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityServers0, kEntityAnna, kAction122358304);
+ getEntities()->drawSequenceLeft(kEntityServers0, "026D");
+
+ setCallback(2);
+ setup_playSound("Ann3138");
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityServers0, kEntityAnna, kAction122288808);
+
+ setCallback(3);
+ setup_draw("913");
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_5900;
+ getEntities()->clearSequences(kEntityServers0);
+ ENTITY_PARAM(1, 5) = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(30, Servers0, function30)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_draw("916");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityServers0, kEntityAbbot, kAction122358304);
+ getEntities()->drawSequenceLeft(kEntityServers0, "029D");
+
+ setCallback(2);
+ setup_playSound("Abb3016a");
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityServers0, kEntityAbbot, kAction122288808);
+
+ setCallback(3);
+ setup_draw("918");
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_5900;
+ getEntities()->clearSequences(kEntityServers0);
+ ENTITY_PARAM(2, 4) = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(31, Servers0, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityServers0);
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ ENTITY_PARAM(0, 3) = 0;
+ ENTITY_PARAM(1, 7) = 0;
+ ENTITY_PARAM(1, 8) = 0;
+ ENTITY_PARAM(2, 1) = 0;
+ ENTITY_PARAM(2, 2) = 0;
+ ENTITY_PARAM(2, 3) = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(32, Servers0, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM_PROC(params->param2, getState()->time, 3600)
+ ENTITY_PARAM(1, 8) = 1;
+ params->param1 = 0;
+ UPDATE_PARAM_PROC_END
+
+ if (!getEntities()->isInKitchen(kEntityServers1) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
+ break;
+
+ if (ENTITY_PARAM(1, 7)) {
+ setCallback(1);
+ setup_augustOrderSteak();
+ break;
+ }
+
+label_callback_1:
+ if (ENTITY_PARAM(1, 8)) {
+ setCallback(2);
+ setup_augustServeDuck();
+ break;
+ }
+
+label_callback_2:
+ if (ENTITY_PARAM(2, 1)) {
+ setCallback(3);
+ setup_function35();
+ break;
+ }
+
+label_callback_3:
+ if (ENTITY_PARAM(2, 2)) {
+ setCallback(4);
+ setup_function9();
+ break;
+ }
+
+label_callback_4:
+ if (ENTITY_PARAM(2, 3)) {
+ setCallback(5);
+ setup_function10();
+ break;
+ }
+
+label_callback_5:
+ if (ENTITY_PARAM(0, 3)) {
+ setCallback(6);
+ setup_function7();
+ break;
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ params->param1 = 1;
+ goto label_callback_1;
+
+ case 2:
+ goto label_callback_2;
+
+ case 3:
+ goto label_callback_3;
+
+ case 4:
+ goto label_callback_4;
+
+ case 5:
+ goto label_callback_5;
+ }
+ break;
+
+ case kAction201431954:
+ ENTITY_PARAM(0, 3) = 0;
+ ENTITY_PARAM(1, 7) = 0;
+ ENTITY_PARAM(1, 8) = 0;
+ ENTITY_PARAM(2, 1) = 0;
+ ENTITY_PARAM(2, 3) = 0;
+ params->param1 = 0;
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(33, Servers0, augustOrderSteak)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_draw("911");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceLeft(kEntityServers0, "010F3");
+ getEntities()->drawSequenceLeft(kEntityAugust, "010D3");
+
+ setCallback(2);
+ setup_playSound("AUG4002");
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityServers0, kEntityAugust, kAction122288808);
+
+ setCallback(3);
+ setup_draw("913");
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_5900;
+ getEntities()->clearSequences(kEntityServers0);
+ ENTITY_PARAM(1, 7) = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(34, Servers0, augustServeDuck)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_draw("912");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityServers0, kEntityAugust, kAction122358304);
+ getSound()->playSound(kEntityServers0, "AUG1053");
+
+ setCallback(2);
+ setup_draw("010G3");
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityServers0, kEntityAugust, kAction201964801);
+
+ setCallback(3);
+ setup_draw("914");
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_5900;
+ getEntities()->clearSequences(kEntityServers0);
+ ENTITY_PARAM(1, 8) = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(35, Servers0, function35)
+ serveTable(savepoint, "911", kEntityTables3, "010L", "010M", "914", &ENTITY_PARAM(2, 1), false, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(36, Servers0, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityServers0);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(37, Servers0, chapter5Handler)
+ if (savepoint.action == kActionProceedChapter5)
+ setup_nullfunction();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_NULL_FUNCTION(38, Servers0)
+
+
+//////////////////////////////////////////////////////////////////////////
+// Private functions
+//////////////////////////////////////////////////////////////////////////
+void Servers0::handleServer(const SavePoint &savepoint, const char* name, EntityIndex entity, ActionIndex action, uint *parameter, const char* name2) {
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_draw(name);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ // Prepare or draw sequences depending of value of string
+ if (strcmp(name2, ""))
+ getEntities()->clearSequences(kEntityServers0);
+ else
+ getEntities()->drawSequenceLeft(kEntityServers0, name2);
+
+ getSavePoints()->push(kEntityServers0, entity, action);
+ *parameter = 0;
+
+ CALLBACK_ACTION();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void Servers0::serveTable(const SavePoint &savepoint, const char* seq1, EntityIndex entity, const char* seq2, const char* seq3, const char* seq4, uint *parameter, bool shouldUpdatePosition, bool pushSavepoint, Position position) {
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (shouldUpdatePosition) {
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+ }
+
+ setCallback(1);
+ setup_draw(seq1);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (position)
+ getEntities()->updatePositionEnter(kEntityServers0, kCarRestaurant, position);
+
+ getSavePoints()->push(kEntityServers0, entity, kAction136455232);
+
+ setCallback(2);
+ setup_callSavepoint(seq2, entity, kActionDrawTablesWithChairs, seq3);
+ break;
+
+ case 2:
+ if (position)
+ getEntities()->updatePositionExit(kEntityServers0, kCarRestaurant, position);
+
+ setCallback(3);
+ setup_draw(seq4);
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_5900;
+
+ // Special case for functions 19 & 35
+ if (pushSavepoint)
+ getSavePoints()->push(kEntityServers0, kEntityRebecca, kAction224253538);
+
+ getEntities()->clearSequences(kEntityServers0);
+ *parameter = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/servers0.h b/engines/lastexpress/entities/servers0.h
new file mode 100644
index 0000000000..61a060f0c2
--- /dev/null
+++ b/engines/lastexpress/entities/servers0.h
@@ -0,0 +1,173 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_SERVERS0_H
+#define LASTEXPRESS_SERVERS0_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Servers0 : public Entity {
+public:
+ Servers0(LastExpressEngine *engine);
+ ~Servers0() {};
+
+
+ /**
+ * Call a savepoint (or draw sequence in default case)
+ *
+ * @param sequence1 The sequence to draw in the default case
+ * @param entity The entity
+ * @param action The action
+ * @param sequence2 The sequence name for the savepoint
+ */
+ DECLARE_FUNCTION_4(callSavepoint, const char* sequence1, EntityIndex entity, ActionIndex action, const char* sequence2)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param savepoint The savepoint
+ * - Time to add
+ */
+ DECLARE_FUNCTION_NOSETUP(updateFromTime)
+
+ /**
+ * Draws the entity
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(draw, const char* sequence)
+
+ /**
+ * Updates the position
+ *
+ * @param sequence1 The sequence to draw
+ * @param car The car
+ * @param position The position
+ */
+ DECLARE_FUNCTION_3(updatePosition, const char* sequence1, CarIndex car, Position position)
+
+ /**
+ * Process callback action when the entity direction is not kDirectionRight
+ */
+ DECLARE_FUNCTION_NOSETUP(callbackActionOnDirection)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ DECLARE_FUNCTION(function7)
+ DECLARE_FUNCTION(function8)
+ DECLARE_FUNCTION(function9)
+ DECLARE_FUNCTION(function10)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+ DECLARE_FUNCTION(function12)
+ DECLARE_FUNCTION(function13)
+ DECLARE_FUNCTION(function14)
+ DECLARE_FUNCTION(function15)
+ DECLARE_FUNCTION(function16)
+ DECLARE_FUNCTION(function17)
+ DECLARE_FUNCTION(function18)
+ DECLARE_FUNCTION(function19)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function21)
+ DECLARE_FUNCTION(function22)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+
+ DECLARE_FUNCTION(function25)
+ DECLARE_FUNCTION(function26)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ DECLARE_FUNCTION(augustAnnaDateOrder)
+ DECLARE_FUNCTION(function30)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ DECLARE_FUNCTION(augustOrderSteak)
+ DECLARE_FUNCTION(augustServeDuck)
+ DECLARE_FUNCTION(function35)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_NULL_FUNCTION()
+
+private:
+ void handleServer(const SavePoint &savepoint, const char* name, EntityIndex entity, ActionIndex action, uint *parameter, const char* name2 = "");
+ void serveTable(const SavePoint &savepoint, const char* seq1, EntityIndex entity, const char* seq2, const char* seq3, const char* seq4, uint *parameter, bool shouldUpdatePosition = true, bool pushSavepoint = false, Position position = 0);
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_SERVERS0_H
diff --git a/engines/lastexpress/entities/servers1.cpp b/engines/lastexpress/entities/servers1.cpp
new file mode 100644
index 0000000000..ea383dbacb
--- /dev/null
+++ b/engines/lastexpress/entities/servers1.cpp
@@ -0,0 +1,787 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/servers1.h"
+
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+namespace LastExpress {
+
+Servers1::Servers1(LastExpressEngine *engine) : Entity(engine, kEntityServers1) {
+ ADD_CALLBACK_FUNCTION(Servers1, updateFromTime);
+ ADD_CALLBACK_FUNCTION(Servers1, draw);
+ ADD_CALLBACK_FUNCTION(Servers1, updatePosition);
+ ADD_CALLBACK_FUNCTION(Servers1, callbackActionOnDirection);
+ ADD_CALLBACK_FUNCTION(Servers1, callSavepoint);
+ ADD_CALLBACK_FUNCTION(Servers1, playSound);
+ ADD_CALLBACK_FUNCTION(Servers1, function7);
+ ADD_CALLBACK_FUNCTION(Servers1, chapter1);
+ ADD_CALLBACK_FUNCTION(Servers1, function9);
+ ADD_CALLBACK_FUNCTION(Servers1, function10);
+ ADD_CALLBACK_FUNCTION(Servers1, function11);
+ ADD_CALLBACK_FUNCTION(Servers1, function12);
+ ADD_CALLBACK_FUNCTION(Servers1, function13);
+ ADD_CALLBACK_FUNCTION(Servers1, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Servers1, function15);
+ ADD_CALLBACK_FUNCTION(Servers1, function16);
+ ADD_CALLBACK_FUNCTION(Servers1, chapter2);
+ ADD_CALLBACK_FUNCTION(Servers1, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Servers1, function19);
+ ADD_CALLBACK_FUNCTION(Servers1, function20);
+ ADD_CALLBACK_FUNCTION(Servers1, function21);
+ ADD_CALLBACK_FUNCTION(Servers1, chapter3);
+ ADD_CALLBACK_FUNCTION(Servers1, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Servers1, function24);
+ ADD_CALLBACK_FUNCTION(Servers1, chapter4);
+ ADD_CALLBACK_FUNCTION(Servers1, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Servers1, function27);
+ ADD_CALLBACK_FUNCTION(Servers1, function28);
+ ADD_CALLBACK_FUNCTION(Servers1, function29);
+ ADD_CALLBACK_FUNCTION(Servers1, chapter5);
+ ADD_CALLBACK_FUNCTION(Servers1, chapter5Handler);
+ ADD_NULL_FUNCTION()
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(1, Servers1, updateFromTime)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(2, Servers1, draw)
+ Entity::draw(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SII(3, Servers1, updatePosition, CarIndex, Position)
+ Entity::updatePosition(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(4, Servers1, callbackActionOnDirection)
+ if (savepoint.action == kActionExcuseMeCath) {
+ if (!params->param1) {
+ getSound()->excuseMe(kEntityServers1);
+ params->param1 = 1;
+ }
+ }
+
+ Entity::callbackActionOnDirection(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SIIS(5, Servers1, callSavepoint, EntityIndex, ActionIndex)
+ Entity::callSavepoint(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(6, Servers1, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(7, Servers1, function7)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_draw("924");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getSavePoints()->push(kEntityServers1, kEntityBoutarel, kAction122358304);
+ setCallback(2);
+ setup_draw("008C");
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityServers1, kEntityBoutarel, kAction122288808);
+ setCallback(2);
+ setup_draw("926");
+ break;
+
+ case 3:
+ getEntities()->clearSequences(kEntityServers1);
+ getData()->entityPosition = kPosition_5900;
+ ENTITY_PARAM(1, 2) = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(8, Servers1, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter1Handler();
+ break;
+
+ case kActionDefault:
+ getSavePoints()->addData(kEntityServers1, kAction223002560, 0);
+ getSavePoints()->addData(kEntityServers1, kAction302996448, 2);
+ getSavePoints()->addData(kEntityServers1, kAction269485588, 3);
+ getSavePoints()->addData(kEntityServers1, kAction326144276, 4);
+ getSavePoints()->addData(kEntityServers1, kAction302203328, 5);
+ getSavePoints()->addData(kEntityServers1, kAction189688608, 6);
+ getSavePoints()->addData(kEntityServers1, kAction236237423, 7);
+ getSavePoints()->addData(kEntityServers1, kAction219377792, 8);
+ getSavePoints()->addData(kEntityServers1, kAction256200848, 9);
+ getSavePoints()->addData(kEntityServers1, kAction291721418, 10);
+ getSavePoints()->addData(kEntityServers1, kAction258136010, 11);
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(9, Servers1, function9)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_draw("924");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceLeft(kEntityMilos, "BLANK");
+ getEntities()->drawSequenceLeft(kEntityServers1, "009B");
+
+ setCallback(2);
+ setup_playSound("WAT1001");
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityMilos, "009A");
+
+ setCallback(3);
+ setup_draw("926");
+ break;
+
+ case 3:
+ getEntities()->clearSequences(kEntityServers1);
+ getData()->entityPosition = kPosition_5900;
+ ENTITY_PARAM(0, 1) = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(10, Servers1, function10)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_draw("924");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceLeft(kEntityBoutarel, "BLANK");
+ getEntities()->drawSequenceLeft(kEntityServers1, "008C");
+
+ setCallback(2);
+ setup_playSound("MRB1077");
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityServers1, kEntityBoutarel, kAction168717392);
+
+ setCallback(3);
+ setup_draw("926");
+ break;
+
+ case 3:
+ getEntities()->clearSequences(kEntityServers1);
+ getData()->entityPosition = kPosition_5900;
+ ENTITY_PARAM(0, 2) = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Servers1, function11)
+ serveTable(savepoint, "919", kEntityTables1, "005H", "005J", "921", &ENTITY_PARAM(0, 3), 63);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Servers1, function12)
+ serveTable(savepoint, "923", kEntityTables2, "009F", "009G", "926", &ENTITY_PARAM(0, 4));
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Servers1, function13)
+ serveTable(savepoint, "923", kEntityTables2, "009F", "009G", "926", &ENTITY_PARAM(0, 5));
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Servers1, chapter1Handler)
+switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (!getEntities()->isInKitchen(kEntityServers1) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
+ break;
+
+ if (ENTITY_PARAM(0, 1)) {
+ setCallback(1);
+ setup_function9();
+ break;
+ }
+
+ if (ENTITY_PARAM(1, 2)) {
+ setCallback(2);
+ setup_function10();
+ break;
+ }
+
+ if (ENTITY_PARAM(0, 3)) {
+ setCallback(3);
+ setup_function11();
+ break;
+ }
+
+ if (ENTITY_PARAM(0, 4)) {
+ setCallback(4);
+ setup_function12();
+ break;
+ }
+
+ if (ENTITY_PARAM(0, 5)) {
+ setCallback(5);
+ setup_function13();
+ }
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 5) {
+ getSavePoints()->push(kEntityServers1, kEntityPascale, kAction352768896);
+ setup_function15();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Servers1, function15)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5900;
+ break;
+
+ case kAction101632192:
+ setup_function16();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Servers1, function16)
+ if (savepoint.action == kActionDefault) {
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+
+ getEntities()->clearSequences(kEntityServers1);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Servers1, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter2Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityServers1);
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothes1;
+ getData()->inventoryItem = kItemNone;
+
+ ENTITY_PARAM(0, 6) = 0;
+ ENTITY_PARAM(0, 7) = 0;
+ ENTITY_PARAM(0, 8) = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Servers1, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!getEntities()->isInKitchen(kEntityServers1) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
+ break;
+
+ if (ENTITY_PARAM(0, 6)) {
+ setCallback(1);
+ setup_function19();
+ break;
+ }
+
+label_callback_1:
+ if (ENTITY_PARAM(0, 7)) {
+ setCallback(2);
+ setup_function20();
+ break;
+ }
+
+label_callback_2:
+ if (ENTITY_PARAM(0, 8) || ENTITY_PARAM(0, 5)) {
+ setCallback(3);
+ setup_function21();
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_callback_1;
+
+ case 2:
+ goto label_callback_2;
+
+ case 4:
+ getEntities()->clearSequences(kEntityServers1);
+ getData()->entityPosition = kPosition_5900;
+ break;
+ }
+ break;
+
+ case kAction101106391:
+ setCallback(4);
+ setup_draw("975");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Servers1, function19)
+ serveTable(savepoint, "969", kEntityTables1, "005H2", "018A", "971", &ENTITY_PARAM(0, 6), 63);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Servers1, function20)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_draw("973");
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getSavePoints()->push(kEntityServers1, kEntityIvo, kAction123712592);
+ getEntities()->drawSequenceLeft(kEntityServers1, "BLANK");
+ ENTITY_PARAM(0, 7) = 0;
+
+ CALLBACK_ACTION();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Servers1, function21)
+ serveTable(savepoint, "974", kEntityTables2, "009F2", "009G", "976", &ENTITY_PARAM(0, 8), 0, true, &ENTITY_PARAM(0, 5));
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Servers1, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityServers1);
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothes1;
+ getData()->inventoryItem = kItemNone;
+
+ ENTITY_PARAM(1, 1) = 0;
+ ENTITY_PARAM(1, 2) = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Servers1, chapter3Handler)
+ if (savepoint.action != kActionNone)
+ return;
+
+ if (!getEntities()->isInKitchen(kEntityServers1) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
+ return;
+
+ if (ENTITY_PARAM(1, 1)) {
+ setCallback(1);
+ setup_function24();
+ return;
+ }
+
+ if (ENTITY_PARAM(1, 2)) {
+ setCallback(2);
+ setup_function7();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Servers1, function24)
+ serveSalon(savepoint, "927", "Ann3143A", kEntityAnna, "Ann31444", "112C", kAction122288808, "928", &ENTITY_PARAM(1, 1));
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, Servers1, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityServers1);
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+
+ getEntities()->clearSequences(kEntityServers1);
+
+ ENTITY_PARAM(1, 2) = 0;
+ ENTITY_PARAM(1, 3) = 0;
+ ENTITY_PARAM(1, 4) = 0;
+ ENTITY_PARAM(1, 5) = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(26, Servers1, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param2) {
+ UPDATE_PARAM_PROC(params->param2, getState()->time, 900)
+ ENTITY_PARAM(1, 5) = 1;
+ params->param1 = 0;
+ UPDATE_PARAM_PROC_END
+ }
+
+ if (!getEntities()->isInKitchen(kEntityServers1) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
+ break;
+
+ if (ENTITY_PARAM(1, 5)) {
+ setCallback(2);
+ setup_function28();
+ break;
+ }
+
+ if (ENTITY_PARAM(1, 4)) {
+ setCallback(3);
+ setup_function29();
+ break;
+ }
+
+ if (ENTITY_PARAM(1, 2)) {
+ setCallback(4);
+ setup_function7();
+ }
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ params->param1 = 1;
+ break;
+
+ case kAction201431954:
+ ENTITY_PARAM(1, 2) = 0;
+ ENTITY_PARAM(1, 3) = 0;
+ ENTITY_PARAM(1, 4) = 0;
+ ENTITY_PARAM(1, 5) = 0;
+
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationOutsideCompartment;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(27, Servers1, function27)
+ serveSalon(savepoint, "929", "", kEntityAugust, "Aug4003", "122D", kAction134486752, "930", &ENTITY_PARAM(1, 3));
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(28, Servers1, function28)
+ serveSalon(savepoint, "931", "", kEntityAugust, "Aug4004", "122E", kAction125826561, "930", &ENTITY_PARAM(1, 5));
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(29, Servers1, function29)
+ serveSalon(savepoint, "932", "", kEntityAnna, "Ann4151", "127D", kAction122288808, "930", &ENTITY_PARAM(1, 4));
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(30, Servers1, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityServers1);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(31, Servers1, chapter5Handler)
+ if (savepoint.action == kActionProceedChapter5)
+ setup_nullfunction();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_NULL_FUNCTION(32, Servers1)
+
+
+//////////////////////////////////////////////////////////////////////////
+// Private functions
+//////////////////////////////////////////////////////////////////////////
+void Servers1::serveTable(const SavePoint &savepoint, const char* seq1, EntityIndex entity, const char* seq2, const char* seq3, const char* seq4, uint *parameter, Position position, bool shouldUpdatePosition, uint* parameter2) {
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ if (shouldUpdatePosition) {
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+ }
+
+ setCallback(1);
+ setup_draw(seq1);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (position)
+ getEntities()->updatePositionEnter(kEntityServers1, kCarRestaurant, position);
+
+ getSavePoints()->push(kEntityServers1, entity, kAction136455232);
+
+ setCallback(2);
+ setup_callSavepoint(seq2, entity, kActionDrawTablesWithChairs, seq3);
+ break;
+
+ case 2:
+ if (position)
+ getEntities()->updatePositionExit(kEntityServers1, kCarRestaurant, position);
+
+ setCallback(3);
+ setup_draw(seq4);
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_5900;
+ getEntities()->clearSequences(kEntityServers1);
+ *parameter = 0;
+
+ if (parameter2 != NULL)
+ *parameter2 = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void Servers1::serveSalon(const SavePoint &savepoint, const char* seq1, const char* snd1, EntityIndex entity, const char* snd2, const char* seq2, ActionIndex action, const char* seq3, uint *parameter) {
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_draw("816DD");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceRight(kEntityServers1, seq1);
+
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityServers1);
+
+ if (!strcmp(snd1, ""))
+ getSound()->playSound(kEntityServers1, snd1);
+
+ setCallback(2);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 2:
+ getSavePoints()->push(kEntityServers1, entity, kAction122358304);
+
+ getSound()->playSound(kEntityServers1, snd2);
+
+ setCallback(3);
+ setup_updatePosition(seq2, kCarRestaurant, 57);
+ break;
+
+ case 3:
+ getSavePoints()->push(kEntityServers1, entity, action);
+
+ setCallback(4);
+ setup_draw(seq3);
+ break;
+
+ case 4:
+ getEntities()->drawSequenceRight(kEntityServers1, "816UD");
+
+ if (getEntities()->isInSalon(kEntityPlayer))
+ getEntities()->updateFrame(kEntityServers1);
+
+ setCallback(5);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 5:
+ getEntities()->clearSequences(kEntityServers1);
+ getData()->entityPosition = kPosition_5900;
+ *parameter = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/servers1.h b/engines/lastexpress/entities/servers1.h
new file mode 100644
index 0000000000..f05d994d21
--- /dev/null
+++ b/engines/lastexpress/entities/servers1.h
@@ -0,0 +1,167 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_SERVERS1_H
+#define LASTEXPRESS_SERVERS1_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Servers1 : public Entity {
+public:
+ Servers1(LastExpressEngine *engine);
+ ~Servers1() {};
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param savepoint The savepoint
+ * - Time to add
+ */
+ DECLARE_FUNCTION_NOSETUP(updateFromTime)
+
+ /**
+ * Draws the entity
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(draw, const char* sequence)
+
+ /**
+ * Updates the position
+ *
+ * @param sequence1 The sequence to draw
+ * @param car The car
+ * @param position The position
+ */
+ DECLARE_FUNCTION_3(updatePosition, const char *sequence, CarIndex car, Position position)
+
+ /**
+ * Process callback action when the entity direction is not kDirectionRight
+ */
+ DECLARE_FUNCTION(callbackActionOnDirection)
+
+ /**
+ * Call a savepoint (or draw sequence in default case)
+ *
+ * @param sequence1 The sequence to draw in the default case
+ * @param entity The entity
+ * @param action The action
+ * @param sequence2 The sequence name for the savepoint
+ */
+ DECLARE_FUNCTION_4(callSavepoint, const char* sequence1, EntityIndex entity, ActionIndex action, const char* sequence2)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ DECLARE_FUNCTION(function7)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ DECLARE_FUNCTION(function9)
+ DECLARE_FUNCTION(function10)
+ DECLARE_FUNCTION(function11)
+ DECLARE_FUNCTION(function12)
+ DECLARE_FUNCTION(function13)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function15)
+ DECLARE_FUNCTION(function16)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+
+ DECLARE_FUNCTION(function19)
+ DECLARE_FUNCTION(function20)
+ DECLARE_FUNCTION(function21)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ DECLARE_FUNCTION(function24)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ DECLARE_FUNCTION(function27)
+ DECLARE_FUNCTION(function28)
+ DECLARE_FUNCTION(function29)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_NULL_FUNCTION()
+
+private:
+ void serveTable(const SavePoint &savepoint, const char* seq1, EntityIndex entity, const char* seq2, const char* seq3, const char* seq4, uint *parameter, Position position = 0, bool updatePosition = true, uint *parameter2 = NULL);
+ void serveSalon(const SavePoint &savepoint, const char* seq1, const char* snd1, EntityIndex entity, const char* snd2, const char* seq2, ActionIndex action, const char* seq3, uint *parameter);
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_SERVERS1_H
diff --git a/engines/lastexpress/entities/sophie.cpp b/engines/lastexpress/entities/sophie.cpp
new file mode 100644
index 0000000000..bab74ad1f2
--- /dev/null
+++ b/engines/lastexpress/entities/sophie.cpp
@@ -0,0 +1,279 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/sophie.h"
+
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+
+namespace LastExpress {
+
+#define CHAPTER_IMPLEMENTATION() \
+ switch (savepoint.action) { \
+ default: \
+ break; \
+ case kActionNone: \
+ setup_chaptersHandler(); \
+ break; \
+ case kActionDefault: \
+ getEntities()->clearSequences(kEntitySophie); \
+ getData()->entityPosition = kPosition_4840; \
+ getData()->location = kLocationInsideCompartment; \
+ getData()->car = kCarRedSleeping; \
+ getData()->clothes = kClothesDefault; \
+ getData()->inventoryItem = kItemNone; \
+ break; \
+ }
+
+#define DEFAULT_ACTION_IMPLEMENTATION() \
+ if (savepoint.action == kActionDefault) { \
+ getData()->entityPosition = kPosition_4840; \
+ getData()->location = kLocationInsideCompartment; \
+ getData()->car = kCarRedSleeping; \
+ getEntities()->clearSequences(kEntitySophie); \
+ }
+
+Sophie::Sophie(LastExpressEngine *engine) : Entity(engine, kEntitySophie) {
+ ADD_CALLBACK_FUNCTION(Sophie, reset);
+ ADD_CALLBACK_FUNCTION(Sophie, updateEntity);
+ ADD_CALLBACK_FUNCTION(Sophie, chaptersHandler);
+ ADD_CALLBACK_FUNCTION(Sophie, chapter1);
+ ADD_CALLBACK_FUNCTION(Sophie, function5);
+ ADD_CALLBACK_FUNCTION(Sophie, chapter2);
+ ADD_CALLBACK_FUNCTION(Sophie, chapter3);
+ ADD_CALLBACK_FUNCTION(Sophie, chapter4);
+ ADD_CALLBACK_FUNCTION(Sophie, function9);
+ ADD_CALLBACK_FUNCTION(Sophie, chapter5);
+ ADD_CALLBACK_FUNCTION(Sophie, chapter5Handler);
+ ADD_NULL_FUNCTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Sophie, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(2, Sophie, updateEntity, CarIndex, EntityPosition)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone: {
+ params->param3 = 0;
+
+ // Sophie
+ byte direction = getData()->direction;
+ EntityPosition position = getData()->entityPosition;
+ CarIndex car = getData()->car;
+
+ // Rebecca
+ EntityPosition rebecca_position = getEntityData(kEntityRebecca)->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)) {
+ getData()->field_49B = 0;
+ params->param3 = 1;
+ }
+
+ if (!params->param3)
+ getEntities()->updateEntity(kEntitySophie, (CarIndex)params->param1, (EntityPosition)params->param2);
+
+ break;
+ }
+
+ case kActionExcuseMeCath:
+ getSound()->excuseMeCath();
+ break;
+
+ case kActionExcuseMe:
+ getSound()->excuseMe(kEntitySophie);
+ break;
+
+ case kActionDefault:
+ getEntities()->updateEntity(kEntitySophie, (CarIndex)params->param1, (EntityPosition)params->param2);
+ break;
+
+ case kAction123668192:
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(3, Sophie, chaptersHandler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ getData()->entityPosition = getEntityData(kEntityRebecca)->entityPosition;
+ getData()->car = getEntityData(kEntityRebecca)->car;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->clearSequences(kEntitySophie);
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntitySophie, "BLANK");
+ break;
+
+ case 3:
+ getEntities()->clearSequences(kEntitySophie);
+ break;
+
+ case 4:
+ getEntities()->drawSequenceLeft(kEntitySophie, "BLANK");
+ break;
+ }
+ break;
+
+ case kAction125242096:
+ getData()->entityPosition = (EntityPosition)(getEntityData(kEntityRebecca)->entityPosition - 100);
+ getData()->location = getEntityData(kEntityRebecca)->location;
+ getData()->car = getEntityData(kEntityRebecca)->car;
+
+ setCallback(1);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case kAction136654208:
+ getData()->entityPosition = (EntityPosition)(getEntityData(kEntityRebecca)->entityPosition + 100);
+ getData()->location = getEntityData(kEntityRebecca)->location;
+ getData()->car = getEntityData(kEntityRebecca)->car;
+
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_4840);
+ break;
+
+ case kAction259921280:
+ getData()->entityPosition = (EntityPosition)(getEntityData(kEntityRebecca)->entityPosition + 100);
+ getData()->location = getEntityData(kEntityRebecca)->location;
+ getData()->car = getEntityData(kEntityRebecca)->car;
+
+ setCallback(3);
+ setup_updateEntity(kCarKronos, kPosition_9460);
+ break;
+
+ case kAction292775040:
+ getData()->entityPosition = kPosition_9270;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarKronos;
+
+ setCallback(4);
+ setup_updateEntity(kCarRedSleeping, kPosition_4840);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(4, Sophie, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chaptersHandler);
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_4840;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(5, Sophie, function5)
+ DEFAULT_ACTION_IMPLEMENTATION()
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(6, Sophie, chapter2)
+ CHAPTER_IMPLEMENTATION()
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(7, Sophie, chapter3)
+ CHAPTER_IMPLEMENTATION()
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(8, Sophie, chapter4)
+ CHAPTER_IMPLEMENTATION()
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(9, Sophie, function9)
+ DEFAULT_ACTION_IMPLEMENTATION()
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(10, Sophie, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntitySophie);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Sophie, chapter5Handler)
+ if (savepoint.action == kActionProceedChapter5)
+ setup_nullfunction();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_NULL_FUNCTION(12, Sophie)
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/sophie.h b/engines/lastexpress/entities/sophie.h
new file mode 100644
index 0000000000..51d3d084b6
--- /dev/null
+++ b/engines/lastexpress/entities/sophie.h
@@ -0,0 +1,98 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_SOPHIE_H
+#define LASTEXPRESS_SOPHIE_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Sophie : public Entity {
+public:
+ Sophie(LastExpressEngine *engine);
+ ~Sophie() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ /**
+ * Handle chapters events
+ */
+ DECLARE_FUNCTION(chaptersHandler)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ DECLARE_FUNCTION(function5)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ DECLARE_FUNCTION(function9)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_NULL_FUNCTION()
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_SOPHIE_H
diff --git a/engines/lastexpress/entities/tables.cpp b/engines/lastexpress/entities/tables.cpp
new file mode 100644
index 0000000000..eca60a536b
--- /dev/null
+++ b/engines/lastexpress/entities/tables.cpp
@@ -0,0 +1,221 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/tables.h"
+
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+namespace LastExpress {
+
+Tables::Tables(LastExpressEngine *engine, EntityIndex id) : Entity(engine, id) {
+ _id = id;
+
+ ADD_CALLBACK_FUNCTION(Tables, chapter1);
+ ADD_CALLBACK_FUNCTION(Tables, chapter2);
+ ADD_CALLBACK_FUNCTION(Tables, chapter3);
+ ADD_CALLBACK_FUNCTION(Tables, chapter4);
+ ADD_CALLBACK_FUNCTION(Tables, chapter5);
+ ADD_CALLBACK_FUNCTION(Tables, draw);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Tables, chapter1)
+ if (savepoint.action == kActionDefault) {
+ if (_id == kEntityTables2)
+ getSound()->playSoundWithSubtitles("LOOP8A.SND", SoundManager::kFlagLoop, kEntityTables2);
+
+ setup_draw();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(2, Tables, chapter2)
+ if (savepoint.action == kActionDefault) {
+ if (_id == kEntityTables2)
+ getSound()->playSoundWithSubtitles("LOOP8A.SND", SoundManager::kFlagLoop, kEntityTables2);
+
+ setup_draw();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(3, Tables, chapter3)
+ if (savepoint.action == kActionDefault) {
+ if (_id == kEntityTables2)
+ getSound()->playSoundWithSubtitles("LOOP8A.SND", SoundManager::kFlagLoop, kEntityTables2);
+
+ setup_draw();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(4, Tables, chapter4)
+ if (savepoint.action == kActionDefault) {
+ if (_id == kEntityTables2)
+ getSound()->playSoundWithSubtitles("LOOP8A.SND", SoundManager::kFlagLoop, kEntityTables2);
+
+ setup_draw();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(5, Tables, chapter5)
+ if (savepoint.action == kActionDefault) {
+ if (_id == kEntityTables2 && getSound()->isBuffered(kEntityTables2))
+ getSound()->processEntry(kEntityTables2);
+
+ setup_draw();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(6, Tables, draw)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ // Only applicable to Tables2 entity
+ if (_id != kEntityTables2)
+ break;
+
+ switch (getProgress().chapter) {
+ default:
+ break;
+
+ case kChapter1:
+ if (getState()->time > kTime1165500 && !params->param1) {
+ params->param1 = 1;
+ getSound()->processEntry(kEntityTables2);
+ }
+ break;
+
+ case kChapter3:
+ if (getState()->time > kTime2052000 && !params->param2) {
+ params->param2 = 1;
+ getSound()->processEntry(kEntityTables2);
+ }
+ break;
+
+ case kChapter4:
+ if (getState()->time > kTime2488500 && !params->param3) {
+ params->param3 = 1;
+ getSound()->processEntry(kEntityTables2);
+ }
+ break;
+
+ }
+ break;
+
+ case kActionDefault:
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ switch(_id) {
+ default:
+ break;
+
+ case kEntityTables0:
+ getData()->entityPosition = kPosition_3970;
+ getEntities()->drawSequenceLeft(_id, "001P");
+ break;
+
+ case kEntityTables1:
+ getData()->entityPosition = kPosition_3970;
+ getEntities()->drawSequenceLeft(_id, "005J");
+ break;
+
+ case kEntityTables2:
+ getData()->entityPosition = kPosition_4690;
+ getEntities()->drawSequenceLeft(_id, "009G");
+ break;
+
+ case kEntityTables3:
+ getData()->entityPosition = kPosition_4690;
+ getEntities()->drawSequenceLeft(_id, "010M");
+ break;
+
+ case kEntityTables4:
+ getData()->entityPosition = kPosition_5420;
+ getEntities()->drawSequenceLeft(_id, "014F");
+ break;
+
+ case kEntityTables5:
+ getData()->entityPosition = kPosition_5420;
+ getEntities()->drawSequenceLeft(_id, "024D");
+ break;
+ }
+
+ break;
+
+ case kActionDrawTablesWithChairs:
+ if (!strcmp(savepoint.param.charValue, "")) {
+ getEntities()->drawSequenceLeft(_id, savepoint.param.charValue);
+ } else {
+ switch(_id) {
+ default:
+ break;
+
+ case kEntityTables0:
+ getEntities()->drawSequenceLeft(_id, "001P");
+ break;
+
+ case kEntityTables1:
+ getEntities()->drawSequenceLeft(_id, "005J");
+ break;
+
+ case kEntityTables2:
+ getEntities()->drawSequenceLeft(_id, "009G");
+ break;
+
+ case kEntityTables3:
+ getEntities()->drawSequenceLeft(_id, "010M");
+ break;
+
+ case kEntityTables4:
+ getEntities()->drawSequenceLeft(_id, "014F");
+ break;
+
+ case kEntityTables5:
+ getEntities()->drawSequenceLeft(_id, "024D");
+ break;
+ }
+ }
+ break;
+
+ case kAction136455232:
+ getEntities()->drawSequenceLeft(_id, "BLANK");
+ break;
+ }
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/tables.h b/engines/lastexpress/entities/tables.h
new file mode 100644
index 0000000000..e7f51da66a
--- /dev/null
+++ b/engines/lastexpress/entities/tables.h
@@ -0,0 +1,77 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_TABLES_H
+#define LASTEXPRESS_TABLES_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Tables : public Entity {
+public:
+ Tables(LastExpressEngine *engine, EntityIndex id);
+ ~Tables() {};
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Draws tables
+ */
+ DECLARE_FUNCTION(draw)
+
+private:
+ EntityIndex _id; ///< Table entity id
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_TABLES_H
diff --git a/engines/lastexpress/entities/tatiana.cpp b/engines/lastexpress/entities/tatiana.cpp
new file mode 100644
index 0000000000..14567f8afa
--- /dev/null
+++ b/engines/lastexpress/entities/tatiana.cpp
@@ -0,0 +1,1711 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/tatiana.h"
+
+#include "lastexpress/entities/alexei.h"
+
+#include "lastexpress/game/action.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"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+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(Tatiana, callbackActionOnDirection);
+ ADD_CALLBACK_FUNCTION(Tatiana, updateFromTicks);
+ ADD_CALLBACK_FUNCTION(Tatiana, updateFromTime);
+ ADD_CALLBACK_FUNCTION(Tatiana, callbackActionRestaurantOrSalon);
+ ADD_CALLBACK_FUNCTION(Tatiana, savegame);
+ ADD_CALLBACK_FUNCTION(Tatiana, updateEntity);
+ ADD_CALLBACK_FUNCTION(Tatiana, function14);
+ ADD_CALLBACK_FUNCTION(Tatiana, function15);
+ ADD_CALLBACK_FUNCTION(Tatiana, function16);
+ ADD_CALLBACK_FUNCTION(Tatiana, chapter1);
+ ADD_CALLBACK_FUNCTION(Tatiana, function18);
+ ADD_CALLBACK_FUNCTION(Tatiana, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Tatiana, function20);
+ ADD_CALLBACK_FUNCTION(Tatiana, function21);
+ ADD_CALLBACK_FUNCTION(Tatiana, function22);
+ ADD_CALLBACK_FUNCTION(Tatiana, function23);
+ ADD_CALLBACK_FUNCTION(Tatiana, function24);
+ ADD_CALLBACK_FUNCTION(Tatiana, chapter2);
+ ADD_CALLBACK_FUNCTION(Tatiana, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Tatiana, function27);
+ ADD_CALLBACK_FUNCTION(Tatiana, function28);
+ ADD_CALLBACK_FUNCTION(Tatiana, function29);
+ ADD_CALLBACK_FUNCTION(Tatiana, function30);
+ ADD_CALLBACK_FUNCTION(Tatiana, chapter3);
+ ADD_CALLBACK_FUNCTION(Tatiana, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Tatiana, function33);
+ ADD_CALLBACK_FUNCTION(Tatiana, function34);
+ ADD_CALLBACK_FUNCTION(Tatiana, function35);
+ ADD_CALLBACK_FUNCTION(Tatiana, function36);
+ ADD_CALLBACK_FUNCTION(Tatiana, function37);
+ ADD_CALLBACK_FUNCTION(Tatiana, function38);
+ ADD_CALLBACK_FUNCTION(Tatiana, function39);
+ ADD_CALLBACK_FUNCTION(Tatiana, function40);
+ ADD_CALLBACK_FUNCTION(Tatiana, function41);
+ ADD_CALLBACK_FUNCTION(Tatiana, function42);
+ ADD_CALLBACK_FUNCTION(Tatiana, chapter4);
+ ADD_CALLBACK_FUNCTION(Tatiana, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Tatiana, function45);
+ ADD_CALLBACK_FUNCTION(Tatiana, function46);
+ ADD_CALLBACK_FUNCTION(Tatiana, function47);
+ ADD_CALLBACK_FUNCTION(Tatiana, function48);
+ ADD_CALLBACK_FUNCTION(Tatiana, function49);
+ ADD_CALLBACK_FUNCTION(Tatiana, function50);
+ ADD_CALLBACK_FUNCTION(Tatiana, function51);
+ ADD_CALLBACK_FUNCTION(Tatiana, chapter5);
+ ADD_CALLBACK_FUNCTION(Tatiana, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(Tatiana, function54);
+ ADD_CALLBACK_FUNCTION(Tatiana, function55);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Tatiana, reset)
+ Entity::reset(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(2, Tatiana, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(3, Tatiana, draw)
+ Entity::draw(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SII(4, Tatiana, updatePosition, CarIndex, Position)
+ Entity::updatePosition(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(5, Tatiana, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(6, Tatiana, enterExitCompartment2, ObjectIndex)
+ Entity::enterExitCompartment(savepoint, kPosition_7500, kPosition_7850, kCarRedSleeping, kObjectCompartmentB);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SIIS(7, Tatiana, callSavepoint, EntityIndex, ActionIndex)
+ Entity::callSavepoint(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(8, Tatiana, callbackActionOnDirection)
+ Entity::callbackActionOnDirection(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(9, Tatiana, updateFromTicks)
+ Entity::updateFromTicks(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(10, Tatiana, updateFromTime, uint32)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Tatiana, callbackActionRestaurantOrSalon)
+ Entity::callbackActionRestaurantOrSalon(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(12, Tatiana, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(13, Tatiana, updateEntity, CarIndex, EntityPosition)
+ if (savepoint.action == kActionExcuseMeCath) {
+ if (getEvent(kEventTatianaAskMatchSpeakRussian) || getEvent(kEventTatianaAskMatch) || getEvent(kEventVassiliSeizure)) {
+ getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1010" : "CAT1010A");
+ } else {
+ getSound()->excuseMeCath();
+ }
+ return;
+ }
+
+ Entity::updateEntity(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Tatiana, function14)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityTatiana, kEntityCoudert, kAction326348944);
+ getEntities()->drawSequenceLeft(kEntityTatiana, getProgress().chapter == kChapter1 ? "603Fb" : "673Fb");
+ getEntities()->enterCompartment(kEntityTatiana, kObjectCompartmentB, true);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1 || getCallback() == 2) {
+ getEntities()->exitCompartment(kEntityTatiana, kObjectCompartmentB, true);
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityTatiana);
+
+ CALLBACK_ACTION();
+ }
+ break;
+
+ case kAction69239528:
+ setCallback(getProgress().chapter == kChapter1 ? 1 : 2);
+ setup_enterExitCompartment2(getProgress().chapter == kChapter1 ? "603Db" : "673Db", kObjectCompartmentB);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Tatiana, function15)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(getProgress().chapter == kChapter1 ? 1 : 2);
+ setup_enterExitCompartment2(getProgress().chapter == kChapter1 ? "603Bb" : "673Bb", kObjectCompartmentB);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1 || getCallback() == 2) {
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityTatiana, kEntityCoudert, kAction292048641);
+
+ getEntities()->drawSequenceLeft(kEntityTatiana, getProgress().chapter == kChapter1 ? "603Fb" : "673Fb");
+ getEntities()->enterCompartment(kEntityTatiana, kObjectCompartmentB, true);
+ }
+ break;
+
+ case kAction69239528:
+ getEntities()->exitCompartment(kEntityTatiana, kObjectCompartmentB, true);
+ getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(16, Tatiana, function16, uint32)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1 < getState()->time && !params->param4) {
+ params->param4 = 1;
+
+ getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject49, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (params->param2) {
+ UPDATE_PARAM(params->param5, getState()->timeTicks, 75);
+
+ params->param2 = 0;
+ params->param3 = 1;
+
+ getObjects()->update(kObjectCompartmentB, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject49, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorNormal);
+ }
+
+ params->param5 = 0;
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ if (params->param2) {
+ getObjects()->update(kObjectCompartmentB, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject49, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ if (savepoint.param.intValue == 49) {
+ setCallback(4);
+ setup_playSound(getSound()->justAMinuteCath());
+ break;
+ }
+
+ if (getInventory()->hasItem(kItemPassengerList)) {
+ setCallback(5);
+ setup_playSound(rnd(2) ? "CAT1512" : getSound()->wrongDoorCath());
+ break;
+ }
+
+ setCallback(6);
+ setup_playSound(getSound()->wrongDoorCath());
+ } else {
+ getObjects()->update(kObjectCompartmentB, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject49, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorNormal);
+
+ setCallback(savepoint.action == kActionKnock ? 1 : 2);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ }
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentB, kEntityTatiana, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject49, kEntityTatiana, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionDrawScene:
+ if (params->param2 || params->param3) {
+ getObjects()->update(kObjectCompartmentB, kEntityTatiana, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject49, kEntityTatiana, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ params->param2 = 0;
+ params->param3 = 0;
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ setCallback(3);
+ setup_playSound(rnd(2) ? "TAT1133A" : "TAT1133B");
+ break;
+
+ case 3:
+ getObjects()->update(kObjectCompartmentB, kEntityTatiana, kObjectLocation1, kCursorTalk, kCursorNormal);
+ getObjects()->update(kObject49, kEntityTatiana, kObjectLocation1, kCursorTalk, kCursorNormal);
+ params->param2 = 1;
+ break;
+
+ case 4:
+ case 5:
+ case 6:
+ params->param2 = 0;
+ params->param3 = 1;
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Tatiana, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getSavePoints()->addData(kEntityTatiana, kAction191198209, 0);
+
+ getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject49, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject41, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ getData()->entityPosition = kPosition_5419;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Tatiana, function18)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1) {
+
+ if (getState()->time > kTime1143000 && !params->param2) {
+ params->param2 = 1;
+ getEntities()->drawSequenceRight(kEntityTatiana, "806DS");
+ params->param1 = 1;
+ }
+
+ if (!params->param1) {
+ UPDATE_PARAM_PROC(params->param3, getState()->time, 4500)
+ getEntities()->drawSequenceRight(kEntityTatiana, "806DS");
+ params->param1 = 1;
+ UPDATE_PARAM_PROC_END
+ }
+ }
+
+ if (getData()->entityPosition <= kPosition_2330) {
+ getSavePoints()->push(kEntityTatiana, kEntityAlexei, kAction157159392);
+ getEntities()->clearSequences(kEntityTatiana);
+
+ CALLBACK_ACTION();
+ }
+ break;
+
+ case kActionExitCompartment:
+ getSavePoints()->push(kEntityTatiana, kEntityAlexei, kAction188784532);
+
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ if (getEntities()->isInSalon(kEntityPlayer)) {
+ getEntities()->drawSequenceRight(kEntityTatiana, "806DS");
+ params->param1 = 1;
+ } else {
+ getEntities()->clearSequences(kEntityTatiana);
+ }
+ break;
+
+ case kActionDrawScene:
+ if (!params->param1 && getEntities()->isInSalon(kEntityPlayer)) {
+ getEntities()->drawSequenceRight(kEntityTatiana, "806DS");
+ getEntities()->updateFrame(kEntityTatiana);
+ params->param1 = 1;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Tatiana, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getSound()->isBuffered(kEntityTatiana) || !params->param4 || params->param3 == 2 || getSound()->isBuffered("TAT1066"))
+ goto label_tatiana_chapter1_2;
+
+ UPDATE_PARAM_PROC(params->param5, getState()->timeTicks, 450)
+ getSound()->playSound(kEntityTatiana, params->param3 ? "TAT1069B" : "TAT1069A");
+ getProgress().field_64 = 1;
+ params->param3++;
+ params->param5 = 0;
+ UPDATE_PARAM_PROC_END
+
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 71)) {
+ UPDATE_PARAM_PROC(params->param6, getState()->timeTicks, 75)
+ getSound()->playSound(kEntityTatiana, params->param3 ? "TAT1069B" : "TAT1069A");
+ getProgress().field_64 = 1;
+ params->param3++;
+ params->param6 = 0;
+ UPDATE_PARAM_PROC_END
+ }
+
+label_tatiana_chapter1_2:
+ TIME_CHECK_SAVEPOINT(kTime1084500, params->param7, kEntityTatiana, kEntityPascale, kAction257489762);
+
+ if (params->param1) {
+ UPDATE_PARAM(params->param8, getState()->timeTicks, 90);
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 65);
+ } else {
+ params->param8 = 0;
+ }
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityTatiana, kEntityTables4, kAction136455232);
+ getEntities()->drawSequenceLeft(kEntityTatiana, "014A");
+ break;
+
+ case kActionDrawScene:
+ params->param1 = getEntities()->isPlayerPosition(kCarRestaurant, 67) ? 1 : 0;
+ params->param4 = getEntities()->isPlayerPosition(kCarRestaurant, 69)
+ || getEntities()->isPlayerPosition(kCarRestaurant, 70)
+ || getEntities()->isPlayerPosition(kCarRestaurant, 71);
+ break;
+
+ case kAction122288808:
+ getEntities()->drawSequenceLeft(kEntityTatiana, "014A");
+ break;
+
+ case kAction122358304:
+ getEntities()->drawSequenceLeft(kEntityTatiana, "BLANK");
+ break;
+
+ case kAction124973510:
+ setup_function20();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Tatiana, function20)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ getSavePoints()->push(kEntityTatiana, kEntityAugust, kAction223183000);
+ getEntities()->updatePositionEnter(kEntityTatiana, kCarRestaurant, 67);
+ getSound()->playSound(kEntityTatiana, "TAT1070");
+
+ setCallback(2);
+ setup_callSavepoint("014C", kEntityTables4, kActionDrawTablesWithChairs, "014D");
+ break;
+
+ case 2:
+ getEntities()->updatePositionExit(kEntityTatiana, kCarRestaurant, 67);
+ getSavePoints()->push(kEntityTatiana, kEntityServers0, kAction188893625);
+
+ setCallback(3);
+ setup_function18();
+ break;
+
+ case 3:
+ getSavePoints()->push(kEntityTatiana, kEntityAugust, kAction268620864);
+ setup_function21();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Tatiana, function21)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->clothes = kClothes1;
+
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_8513);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->clothes = kClothesDefault;
+
+ getSound()->playSound(kEntityTatiana, "TAT1071");
+ getEntities()->drawSequenceRight(kEntityTatiana, "604Aa");
+ getEntities()->enterCompartment(kEntityTatiana, kObjectCompartmentA);
+
+ getData()->location = kLocationInsideCompartment;
+
+ if (getEntities()->checkFields19(kEntityPlayer, kCarRedSleeping, kPosition_7850)) {
+ getAction()->playAnimation(isNight() ? kEventCathTurningNight : kEventCathTurningDay);
+ getSound()->playSound(kEntityPlayer, "BUMP");
+ getScenes()->loadSceneFromObject(kObjectCompartmentA, true);
+ }
+
+ setCallback(2);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 2:
+ getEntities()->exitCompartment(kEntityTatiana, kObjectCompartmentA);
+
+ getData()->location = kLocationInsideCompartment;
+
+ getEntities()->clearSequences(kEntityTatiana);
+ getSavePoints()->push(kEntityTatiana, kEntityAlexei, kAction135854208);
+ getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
+ // Fallback to next case
+
+ case 3:
+ if (getSound()->isBuffered(kEntityTatiana)) {
+ setCallback(3);
+ setup_updateFromTime(75);
+ } else {
+ setCallback(4);
+ setup_playSound("TAT1071A");
+ }
+ break;
+
+ case 4:
+ getData()->entityPosition = kPosition_7500;
+
+ getSavePoints()->push(kEntityTatiana, kEntityVassili, kAction168459827);
+
+ setCallback(5);
+ setup_function16(kTime1156500);
+ break;
+
+ case 5:
+ case 6:
+ if (getProgress().field_14 == 29) {
+ setCallback(6);
+ setup_function16(getState()->time + 900);
+ } else {
+ getObjects()->update(kObject49, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ setup_function22();
+ }
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Tatiana, function22)
+ error("Tatiana: callback function 22 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Tatiana, function23)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_7500);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function14();
+ break;
+
+ case 2:
+ setup_function24();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Tatiana, function24)
+ if (savepoint.action == kActionDefault) {
+
+ getData()->entityPosition = kPosition_7500;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getObjects()->update(kObject25, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ getObjects()->update(kObjectTrainTimeTable, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ getEntities()->updatePositionExit(kEntityTatiana, kCarGreenSleeping, 70);
+ getEntities()->updatePositionExit(kEntityTatiana, kCarGreenSleeping, 71);
+ getEntities()->clearSequences(kEntityTatiana);
+
+ getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject49, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject41, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, Tatiana, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter2Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityTatiana);
+
+ getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject49, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject41, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+
+ getData()->entityPosition = kPosition_5420;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothes2;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(26, Tatiana, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime1800000 && params->param1 && getEntities()->isSomebodyInsideRestaurantOrSalon()) {
+ getData()->inventoryItem = kItemNone;
+ setup_function28();
+ }
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+ setup_function28();
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityTatiana, "024A");
+ getSavePoints()->push(kEntityTatiana, kEntityTables5, kAction136455232);
+ getData()->inventoryItem = kItemInvalid;
+ break;
+
+ case kActionDrawScene:
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 64) || getEntities()->isPlayerPosition(kCarRestaurant, 65)) {
+ getData()->inventoryItem = kItemNone;
+ setup_function27();
+ }
+ break;
+
+ case kAction290869168:
+ params->param1 = 1;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(27, Tatiana, function27)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(getEvent(kEventTatianaGivePoem) ? 1 : 2);
+ setup_savegame(kSavegameTypeEvent, getEvent(kEventTatianaGivePoem) ? kEventTatianaBreakfastAlexei : kEventTatianaBreakfast);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ RESET_ENTITY_STATE(kEntityAlexei, Alexei, setup_function30);
+ getAction()->playAnimation(kEventTatianaBreakfastAlexei);
+ getInventory()->addItem(kItemParchemin);
+ getInventory()->setLocationAndProcess(kItem11, kObjectLocation1);
+ setup_function28();
+ break;
+
+ case 2:
+ RESET_ENTITY_STATE(kEntityAlexei, Alexei, setup_function30);
+ getAction()->playAnimation(kEventTatianaBreakfast);
+ if (getInventory()->hasItem(kItemParchemin)) {
+ getAction()->playAnimation(kEventTatianaBreakfastGivePoem);
+ getInventory()->removeItem(kItemParchemin);
+ } else {
+ getAction()->playAnimation(kEventTatianaAlexei);
+ }
+ setup_function28();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(28, Tatiana, function28)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->inventoryItem = kItemNone;
+ getData()->location = kLocationOutsideCompartment;
+
+ getSavePoints()->push(kEntityTatiana, kEntityTables5, kActionDrawTablesWithChairs, "024D");
+ getSavePoints()->push(kEntityTatiana, kEntityAlexei, kAction236053296, (getEvent(kEventTatianaBreakfastAlexei) || getEvent(kEventTatianaBreakfast)) ? 69 : 0);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function29();
+ break;
+
+ case kAction123857088:
+ getEntities()->drawSequenceLeft(kEntityTatiana, "018G");
+
+ setCallback(1);
+ setup_updateFromTime(1800);
+ break;
+
+ case kAction156444784:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->drawSequenceLeft(kEntityTatiana, "BLANK");
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(29, Tatiana, function29)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ getEntities()->updatePositionEnter(kEntityTatiana, kCarRestaurant, 63);
+
+ setCallback(2);
+ setup_callSavepoint("018H", kEntityTables1, kActionDrawTablesWithChairs, "018A");
+ break;
+
+ case 2:
+ getEntities()->updatePositionExit(kEntityTatiana, kCarRestaurant, 63);
+ getSavePoints()->push(kEntityTatiana, kEntityServers1, kAction302203328);
+ getEntities()->drawSequenceRight(kEntityTatiana, "805DS");
+
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityTatiana);
+
+ setCallback(3);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 3:
+ setup_function30();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(30, Tatiana, function30)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_7500);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_function14();
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function16(kTimeEnd);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(31, Tatiana, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityTatiana);
+
+ getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject49, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ getData()->entityPosition = kPosition_1750;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothes2;
+ getData()->inventoryItem = kItemNone;
+
+ // Update inventory
+ getInventory()->get(kItemFirebird)->location = kObjectLocation2;
+
+ if (getEvent(kEventTatianaBreakfastGivePoem) || (getEvent(kEventTatianaGivePoem) && !getEvent(kEventTatianaBreakfastAlexei)))
+ getInventory()->get(kItemParchemin)->location = kObjectLocation2;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(32, Tatiana, chapter3Handler)
+ EntityData::EntityParametersI5S *parameters = (EntityData::EntityParametersI5S*)_data->getCurrentParameters();
+ EntityData::EntityParametersSIII *parameters1 = (EntityData::EntityParametersSIII*)_data->getCurrentParameters(1);
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!parameters->param2 && !parameters->param5) {
+ parameters->param1 -= getState()->timeDelta;
+
+ if (getState()->timeDelta > parameters->param1) {
+
+ getEntities()->drawSequenceLeft(kEntityTatiana, (char *)&parameters1->seq);
+ getSound()->playSound(kEntityTatiana, (char *)&parameters->seq);
+
+ if (parameters->param3 == 4 && getEntities()->isInSalon(kEntityPlayer))
+ getProgress().field_90 = 1;
+
+ parameters->param2 = 1;
+ }
+ }
+
+ if (parameters->param4 && parameters->param5) {
+ UPDATE_PARAM_CHECK(parameters->param4, getState()->time, 6300)
+ if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_updatePosition("110E", kCarRestaurant, 52);
+ }
+ }
+ }
+ break;
+
+ case kActionEndSound:
+ parameters->param2 = 0;
+ ++parameters->param3;
+
+ switch (parameters->param3) {
+ default:
+ parameters->param5 = 1;
+ break;
+
+ case 1:
+ parameters->param1 = 900;
+ getEntities()->drawSequenceLeft(kEntityTatiana, "110A");
+ strcpy((char *)&parameters->seq, "Tat3160B");
+ strcpy((char *)&parameters1->seq, "110A");
+ break;
+
+ case 2:
+ parameters->param1 = 9000;
+ strcpy((char *)&parameters->seq, "Tat3160C");
+ strcpy((char *)&parameters1->seq, "110C");
+ break;
+
+ case 3:
+ parameters->param1 = 13500;
+ getEntities()->drawSequenceLeft(kEntityTatiana, "110B");
+ strcpy((char *)&parameters->seq, "Tat3160D");
+ strcpy((char *)&parameters1->seq, "110D");
+ break;
+
+ case 4:
+ parameters->param1 = 9000;
+ getEntities()->drawSequenceLeft(kEntityTatiana, "110B");
+ strcpy((char *)&parameters->seq, "Tat3160E");
+ strcpy((char *)&parameters1->seq, "110D");
+ break;
+
+ case 5:
+ parameters->param1 = 4500;
+ getEntities()->drawSequenceLeft(kEntityTatiana, "110B");
+ strcpy((char *)&parameters->seq, "Tat3160G");
+ strcpy((char *)&parameters1->seq, "110D");
+ break;
+
+ case 6:
+ parameters->param1 = 4500;
+ getEntities()->drawSequenceLeft(kEntityTatiana, "110B");
+ strcpy((char *)&parameters->seq, "Tat3160B");
+ break;
+ }
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityTatiana, kEntityAlexei, kAction122358304);
+ getSavePoints()->push(kEntityTatiana, kEntityKronos, kAction157159392);
+ getEntities()->drawSequenceLeft(kEntityTatiana, "110C");
+ getSound()->playSound(kEntityTatiana, "Tat3160A");
+
+ parameters->param2 = 1;
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getSavePoints()->push(kEntityTatiana, kEntityAlexei, kAction122288808);
+ setup_function33();
+ }
+ break;
+
+ case kAction101169422:
+ parameters->param4 = 1;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(33, Tatiana, function33)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityTatiana);
+ setCallback(1);
+ setup_updateFromTime(75);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_7500);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function14();
+ break;
+
+ case 3:
+ setup_function34();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(34, Tatiana, function34)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function16(kTime2097000);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getInventory()->get(kItemFirebird)->location = kObjectLocation1;
+ if (getEntities()->checkFields19(kEntityPlayer, kCarRedSleeping, kPosition_7850))
+ getScenes()->loadSceneFromObject(kObjectCompartmentB);
+
+ getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject49, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ setup_function15();
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_updateEntity(kCarKronos, kPosition_9270);
+ break;
+
+ case 3:
+ setup_function35();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(35, Tatiana, function35)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1
+ && getInventory()->hasItem(kItemFirebird)
+ && getEntities()->checkFields19(kEntityPlayer, kCarRedSleeping, kPosition_7850)
+ && (getState()->time < kTime2133000 || getProgress().field_40)) {
+ setCallback(1);
+ setup_function41();
+ break;
+ }
+
+label_callback_1:
+ if (getState()->time > kTime2133000) {
+ if (getData()->car >= kCarRedSleeping || (getData()->car == kCarGreenSleeping && getData()->entityPosition > kPosition_5790))
+ setup_function36();
+ }
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject49, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getEntities()->clearSequences(kEntityTatiana);
+
+ getData()->car = kCarKronos;
+ getData()->entityPosition = kPosition_6000;
+ getData()->location = kLocationInsideCompartment;
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ params->param1 = 1;
+ goto label_callback_1;
+ }
+ break;
+
+ case kAction191668032:
+ setup_function36();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(36, Tatiana, function36)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarGreenSleeping;
+ getData()->entityPosition = kPosition_850;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_7500);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ if (!getEntities()->checkFields19(kEntityPlayer, kCarGreenSleeping, kPosition_7850) || getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_8200)) {
+ setCallback(2);
+ setup_function14();
+ break;
+ }
+
+ if (getInventory()->hasItem(kItemFirebird)) {
+ getAction()->playAnimation(kEventTatianaCompartmentStealEgg);
+ getInventory()->removeItem(kItemFirebird);
+ getInventory()->get(kItemFirebird)->location = kObjectLocation2;
+ } else {
+ getAction()->playAnimation(kEventTatianaCompartment);
+ }
+
+ getScenes()->loadSceneFromObject(kObjectCompartmentB);
+ break;
+
+ case 2:
+ setup_function37();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(37, Tatiana, function37)
+ error("Tatiana: callback function 37 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(38, Tatiana, function38)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param1, getState()->time, 450);
+
+ getEntities()->exitCompartment(kEntityTatiana, kObjectCompartmentF, true);
+
+ setCallback(4);
+ setup_function42(kCarRedSleeping, kPosition_7500);
+ break;
+
+ case kActionDefault:
+ getData()->clothes = kClothes3;
+
+ setCallback(1);
+ setup_enterExitCompartment("673Jb", kObjectCompartmentB);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject49, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ setCallback(2);
+ setup_function42(kCarRedSleeping, kPosition_4070);
+ break;
+
+ case 2:
+ getEntities()->drawSequenceLeft(kEntityTatiana, "673Gf");
+ getEntities()->enterCompartment(kEntityTatiana, kObjectCompartmentF, true);
+
+ setCallback(3);
+ setup_playSound("Tat3164");
+ break;
+
+ case 3:
+ getSavePoints()->push(kEntityTatiana, kEntityAnna, kAction236241630);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_enterExitCompartment2("673Db", kObjectCompartmentB);
+ break;
+
+ case 5:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityTatiana);
+
+ setup_function39();
+ break;
+
+ case 6:
+ getEntities()->exitCompartment(kEntityTatiana, kObjectCompartmentF, true);
+ getEntities()->clearSequences(kEntityTatiana);
+ getData()->location = kLocationInsideCompartment;
+
+ setCallback(7);
+ setup_playSound("ANN3011");
+ break;
+
+ case 7:
+ setCallback(8);
+ setup_updateFromTime(900);
+ break;
+
+ case 8:
+ setCallback(9);
+ setup_enterExitCompartment("673Jf", kObjectCompartmentF);
+ break;
+
+ case 9:
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(10);
+ setup_function42(kCarRedSleeping, kPosition_7500);
+ break;
+
+ case 10:
+ getSavePoints()->push(kEntityTatiana, kEntityAnna, kAction236517970);
+
+ setCallback(11);
+ setup_enterExitCompartment2("673Db", kObjectCompartmentB);
+ break;
+
+ case 11:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityTatiana);
+
+ setup_function39();
+ break;
+ }
+ break;
+
+ case kAction100906246:
+ setCallback(6);
+ setup_enterExitCompartment("673Df", kObjectCompartmentF);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(39, Tatiana, function39)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1 && getEntities()->isDistanceBetweenEntities(kEntityTatiana, kEntityPlayer, 1000)) {
+ params->param1 = 1;
+ getSound()->playSound(kEntityTatiana, "Tat3164"); // Tatiana weeping
+ }
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject49, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(40, Tatiana, function40)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarKronos)
+ || getData()->car != getEntityData(kEntityPlayer)->car
+ || getEntities()->updateEntity(kEntityTatiana, kCarKronos, kPosition_9270))
+ CALLBACK_ACTION();
+ break;
+
+ case kActionExcuseMe:
+ if (getEvent(kEventTatianaAskMatchSpeakRussian) || getEvent(kEventTatianaAskMatch) || getEvent(kEventVassiliSeizure))
+ getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1001A" : "CAT1010");
+ else
+ getSound()->excuseMeCath();
+ break;
+
+ case kActionDefault:
+ if (getEntities()->updateEntity(kEntityTatiana, kCarKronos, kPosition_9270))
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(41, Tatiana, function41)
+ error("Tatiana: callback function 41 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(42, Tatiana, function42, CarIndex, EntityPosition)
+ if (savepoint.action == kActionExcuseMeCath || savepoint.action == kActionExcuseMe) {
+ getSound()->playSound(kEntityPlayer, "Tat3124", getSound()->getSoundFlag(kEntityTatiana));
+ return;
+ }
+
+ Entity::updateEntity(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(43, Tatiana, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityTatiana);
+
+ getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject49, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ getData()->entityPosition = kPosition_7500;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothes2;
+ getData()->inventoryItem = kItemNone;
+
+ ENTITY_PARAM(0, 1) = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(44, Tatiana, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function16(kTime2362500);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function45();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(45, Tatiana, function45)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_enterExitCompartment("673Bb", kObjectCompartmentB);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_540);
+ break;
+
+ case 2:
+ if (getEntities()->isInGreenCarEntrance(kEntityPlayer)) {
+ getSound()->excuseMe(kEntityTatiana);
+
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 62))
+ getScenes()->loadSceneFromPosition(kCarGreenSleeping, 72);
+ }
+
+ getSavePoints()->push(kEntityTatiana, kEntityAlexei, kAction123712592);
+ setup_function46();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(46, Tatiana, function46)
+ error("Tatiana: callback function 46 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(47, Tatiana, function47)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarRedSleeping, kPosition_7500);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_enterExitCompartment2("673Db", kObjectCompartmentB);
+ break;
+
+ case 2:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityTatiana);
+
+ setCallback(3);
+ setup_function16(kTime2407500);
+ break;
+
+ case 3:
+ case 4:
+ if (ENTITY_PARAM(0, 1) && getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1) {
+ setup_function48();
+ } else {
+ setCallback(4);
+ setup_function16(900);
+ }
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(48, Tatiana, function48)
+ error("Tatiana: callback function 48 not implemented!");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(49, Tatiana, function49)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_7500;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject49, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kAction169360385:
+ setup_function50();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(50, Tatiana, function50)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime2520000 && !params->param1) {
+ params->param1 = 1;
+ setup_function51();
+ }
+ break;
+
+ case kActionEndSound:
+ getSound()->playSound(kEntityTatiana, "Tat4166");
+ break;
+
+ case kActionKnock:
+ if (!getSound()->isBuffered("LIB012", true))
+ getSound()->playSound(kEntityPlayer, "LIB012");
+ break;
+
+ case kActionOpenDoor:
+ getSound()->playSound(kEntityPlayer, "LIB014");
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventVassiliDeadAlexei);
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_8200;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject49, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject48, kEntityTatiana, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartmentA, kEntityTatiana, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ if (!getSound()->isBuffered(kEntityTatiana))
+ getSound()->playSound(kEntityTatiana, "Tat4166");
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ if (getSound()->isBuffered("MUS013"))
+ getSound()->processEntry("MUS013");
+
+ getAction()->playAnimation(kEventVassiliDeadAlexei);
+ getSavePoints()->push(kEntityTatiana, kEntityAbbot, kAction104060776);
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 38);
+
+ setup_function51();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(51, Tatiana, function51)
+ if (savepoint.action == kActionDefault) {
+ getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject48, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(52, Tatiana, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityTatiana);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(53, Tatiana, chapter5Handler)
+ if (savepoint.action == kActionProceedChapter5)
+ setup_function54();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(54, Tatiana, function54)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param2) {
+ switch (params->param1) {
+ default:
+ break;
+
+ case 0:
+ getSound()->playSound(kEntityTatiana, "Tat5167A");
+ params->param2 = 1;
+ break;
+
+ case 1:
+ getSound()->playSound(kEntityTatiana, "Tat5167B");
+ params->param2 = 1;
+ break;
+
+ case 2:
+ getSound()->playSound(kEntityTatiana, "Tat5167C");
+ params->param2 = 1;
+ break;
+
+ case 3:
+ getSound()->playSound(kEntityTatiana, "Tat5167D");
+ params->param2 = 1;
+ break;
+ }
+ }
+
+ if (params->param1 > 3) {
+ UPDATE_PARAM(params->param3, getState()->timeTicks, 225);
+
+ params->param1 = 0;
+ params->param3 = 0;
+ }
+ break;
+
+ case kAction1:
+ getData()->inventoryItem = kItemNone;
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventTatianaVassiliTalk);
+ break;
+
+ case kActionEndSound:
+ ++params->param1;
+ params->param2 = 0;
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityTatiana, "033A");
+ getData()->inventoryItem = kItemInvalid;
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ if (getSound()->isBuffered("MUS050"))
+ getSound()->processEntry("MUS050");
+
+ if (getSound()->isBuffered(kEntityTatiana))
+ getSound()->processEntry(kEntityTatiana);
+
+ getAction()->playAnimation(isNight() ? kEventTatianaVassiliTalkNight : kEventTatianaVassiliTalk);
+ getScenes()->processScene();
+
+ params->param1 = 4;
+ params->param2 = 0;
+ params->param3 = 0;
+ }
+ break;
+
+ case kAction203078272:
+ getEntities()->drawSequenceLeft(kEntityTatiana, "033E");
+ break;
+
+ case kAction236060709:
+ getData()->inventoryItem = kItemNone;
+ setup_function55();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(55, Tatiana, function55)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityTatiana);
+ // fall back to next action
+
+ case kActionDrawScene:
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 72))
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 86);
+ break;
+ }
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/tatiana.h b/engines/lastexpress/entities/tatiana.h
new file mode 100644
index 0000000000..8dc5de9b35
--- /dev/null
+++ b/engines/lastexpress/entities/tatiana.h
@@ -0,0 +1,235 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_TATIANA_H
+#define LASTEXPRESS_TATIANA_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Tatiana : public Entity {
+public:
+ Tatiana(LastExpressEngine *engine);
+ ~Tatiana() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Draws the entity
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(draw, const char* sequence)
+
+ /**
+ * Updates the position
+ *
+ * @param sequence1 The sequence to draw
+ * @param car The car
+ * @param position The position
+ */
+ DECLARE_FUNCTION_3(updatePosition, const char* sequence1, CarIndex car, Position position)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Handles entering/exiting a compartment and updates position/play animation
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment2, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Call a savepoint (or draw sequence in default case)
+ *
+ * @param sequence1 The sequence to draw in the default case
+ * @param entity The entity
+ * @param action The action
+ * @param sequence2 The sequence name for the savepoint
+ */
+ DECLARE_FUNCTION_4(callSavepoint, const char* sequence1, EntityIndex entity, ActionIndex action, const char* sequence2)
+
+ /**
+ * Process callback action when the entity direction is not kDirectionRight
+ */
+ DECLARE_FUNCTION(callbackActionOnDirection)
+
+ /**
+ * Updates parameter 2 using ticks value
+ *
+ * @param savepoint The savepoint
+ * - ticks to add
+ */
+ DECLARE_FUNCTION_NOSETUP(updateFromTicks)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param time The time to add
+ */
+ DECLARE_FUNCTION_1(updateFromTime, uint32 time)
+
+ /**
+ * Process callback action when somebody is standing in the restaurant or salon.
+ */
+ DECLARE_FUNCTION(callbackActionRestaurantOrSalon)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ DECLARE_FUNCTION(function14)
+ DECLARE_FUNCTION(function15)
+ DECLARE_FUNCTION_1(function16, uint32)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ DECLARE_FUNCTION(function18)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function20)
+ DECLARE_FUNCTION(function21)
+ DECLARE_FUNCTION(function22)
+ DECLARE_FUNCTION(function23)
+ DECLARE_FUNCTION(function24)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+
+ DECLARE_FUNCTION(function27)
+ DECLARE_FUNCTION(function28)
+ DECLARE_FUNCTION(function29)
+ DECLARE_FUNCTION(function30)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ DECLARE_FUNCTION(function33)
+ DECLARE_FUNCTION(function34)
+ DECLARE_FUNCTION(function35)
+ DECLARE_FUNCTION(function36)
+ DECLARE_FUNCTION(function37)
+ DECLARE_FUNCTION(function38)
+ DECLARE_FUNCTION(function39)
+ DECLARE_FUNCTION(function40)
+ DECLARE_FUNCTION(function41)
+
+ /**
+ * ???
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(function42, CarIndex car, EntityPosition entityPosition)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ DECLARE_FUNCTION(function45)
+ DECLARE_FUNCTION(function46)
+ DECLARE_FUNCTION(function47)
+ DECLARE_FUNCTION(function48)
+ DECLARE_FUNCTION(function49)
+ DECLARE_FUNCTION(function50)
+ DECLARE_FUNCTION(function51)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_FUNCTION(function54)
+ DECLARE_FUNCTION(function55)
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_TATIANA_H
diff --git a/engines/lastexpress/entities/train.cpp b/engines/lastexpress/entities/train.cpp
new file mode 100644
index 0000000000..53f19b1a30
--- /dev/null
+++ b/engines/lastexpress/entities/train.cpp
@@ -0,0 +1,575 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/train.h"
+
+#include "lastexpress/game/action.h"
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savegame.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/state.h"
+#include "lastexpress/game/sound.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+namespace LastExpress {
+
+Train::Train(LastExpressEngine *engine) : Entity(engine, kEntityTrain) {
+ ADD_CALLBACK_FUNCTION(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);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(1, Train, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(2, Train, chapter1)
+ if (savepoint.action == kActionDefault)
+ setup_process();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(3, Train, chapter2)
+ if (savepoint.action == kActionDefault)
+ setup_process();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(4, Train, chapter3)
+ if (savepoint.action == kActionDefault)
+ setup_process();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(5, Train, chapter4)
+ if (savepoint.action == kActionDefault)
+ setup_process();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(6, Train, chapter5)
+ if (savepoint.action == kActionDefault)
+ setup_process();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(7, Train, harem, ObjectIndex, uint32)
+ if (savepoint.action != kActionDefault)
+ return;
+
+ switch (params->param1) {
+ default:
+ error("Train::harem: Invalid value for parameter 1: %d", params->param1);
+ break;
+
+ case kObjectCompartment5:
+ params->param3 = kPosition_4840;
+ break;
+
+ case kObjectCompartment6:
+ params->param3 = kPosition_4070;
+ break;
+
+ case kObjectCompartment7:
+ params->param3 = kPosition_3050;
+ break;
+
+ case kObjectCompartment8:
+ params->param3 = kPosition_2740;
+ break;
+ }
+
+ params->param4 = getEntities()->isInsideCompartment(kEntityAlouan, kCarGreenSleeping, (EntityPosition)params->param3);
+ params->param5 = (ENTITY_PARAM(0, 7) - params->param3) < 1 ? true : false;
+ params->param6 = getEntities()->isInsideCompartment(kEntityYasmin, kCarGreenSleeping, (EntityPosition)params->param3);
+ params->param7 = getEntities()->isInsideCompartment(kEntityHadija, kCarGreenSleeping, (EntityPosition)params->param3);
+
+ getObjects()->update((ObjectIndex)params->param1, kEntityTrain, kObjectLocation3, kCursorNormal, kCursorNormal);
+
+ // Knock / closed door sound
+ getSound()->playSound(kEntityTables5, (params->param2 == 8) ? "LIB012" : "LIB013", SoundManager::kFlagDefault);
+
+ if (params->param4 && params->param5) {
+
+ ENTITY_PARAM(0, 5)++;
+
+ switch (ENTITY_PARAM(0, 5)) {
+ default:
+ params->param8 = 1;
+ break;
+
+ case 1:
+ getSound()->playSound(kEntityTables5, "Har1014", SoundManager::kFlagDefault, 15);
+ break;
+
+ case 2:
+ getSound()->playSound(kEntityTables5, "Har1013", SoundManager::kFlagDefault, 15);
+ getSound()->playSound(kEntityTables5, "Har1016", SoundManager::kFlagDefault, 150);
+ break;
+
+ case 3:
+ getSound()->playSound(kEntityTables5, "Har1015A", SoundManager::kFlagDefault, 15);
+ getSound()->playSound(kEntityTables5, "Har1015", SoundManager::kFlagDefault, 150);
+ break;
+ }
+
+ // Update progress
+ getProgress().field_DC = 1;
+ getProgress().field_E0 = 1;
+
+ handleCompartmentAction();
+
+ // Done with it!
+ return;
+ }
+
+ if (params->param6 && params->param7) {
+
+ ENTITY_PARAM(0, 6)++;
+
+ switch(ENTITY_PARAM(0, 6)) {
+ default:
+ params->param8 = 1;
+ break;
+
+ case 1:
+ getSound()->playSound(kEntityTables5, "Har1014", SoundManager::kFlagDefault, 15);
+ break;
+
+ case 2:
+ getSound()->playSound(kEntityTables5, "Har1013", SoundManager::kFlagDefault, 15);
+ break;
+
+ case 3:
+ getSound()->playSound(kEntityTables5, "Har1013A", SoundManager::kFlagDefault, 15);
+ break;
+ }
+
+ handleCompartmentAction();
+ return;
+ }
+
+ if (!params->param5) {
+
+ if (params->param6) {
+ ENTITY_PARAM(0, 3)++;
+
+ switch(ENTITY_PARAM(0, 3)) {
+ default:
+ params->param8 = 1;
+ break;
+
+ case 1:
+ getSound()->playSound(kEntityTables5, "Har1012", SoundManager::kFlagDefault, 15);
+ break;
+
+ case 2:
+ getSound()->playSound(kEntityTables5, "Har1012A", SoundManager::kFlagDefault, 15);
+ break;
+ }
+
+ handleCompartmentAction();
+ return;
+ } else {
+
+ if (params->param4) {
+ ENTITY_PARAM(0, 1)++;
+
+ if (ENTITY_PARAM(0, 1) <= 1)
+ getSound()->playSound(kEntityTables5, "Har1014", SoundManager::kFlagDefault, 15);
+ else
+ params->param8 = 1;
+
+ getProgress().field_DC = 1;
+
+ handleCompartmentAction();
+ return;
+ }
+
+ if (params->param7) {
+ ENTITY_PARAM(0, 4)++;
+
+ if (ENTITY_PARAM(0, 4) <= 1) {
+ getSound()->playSound(kEntityTables5, "Har1011", SoundManager::kFlagDefault, 15);
+ handleCompartmentAction();
+ return;
+ }
+ }
+ }
+
+ params->param8 = 1;
+ handleCompartmentAction();
+ return;
+ }
+
+ ENTITY_PARAM(0, 2) += 1;
+
+ switch (ENTITY_PARAM(0, 2)) {
+ default:
+ params->param8 = 1;
+ break;
+
+ case 1:
+ getSound()->playSound(kEntityTables5, "Har1013", SoundManager::kFlagDefault, 15);
+ break;
+
+ case 2:
+ getSound()->playSound(kEntityTables5, "Har1013A", SoundManager::kFlagDefault, 15);
+ break;
+ }
+
+ getProgress().field_E0 = 1;
+
+ handleCompartmentAction();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(8, Train, process)
+ EntityData::EntityParametersIIIS *params1 = (EntityData::EntityParametersIIIS*)_data->getCurrentParameters(1);
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ // Play smoke animation
+ if ((getEntities()->isPlayerInCar(kCarGreenSleeping) || getEntities()->isPlayerInCar(kCarRedSleeping))
+ && params->param4 && !params->param5) {
+
+ params->param4 -= 1;
+
+ if (!params->param4 && getProgress().jacket == kJacketGreen) {
+
+ getAction()->playAnimation(isNight() ? kEventCathSmokeNight : kEventCathSmokeDay);
+ params->param5 = 1;
+ getScenes()->processScene();
+ }
+ }
+
+ if (params->param6) {
+ UPDATE_PARAM_GOTO(params1->param7, getState()->time, 900, label_process);
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 58);
+ }
+
+ params1->param7 = 0;
+
+label_process:
+ if (params->param7) {
+ if (!params1->param8) {
+ params1->param8 = getState()->time + 4500;
+
+ if (!params1->param8)
+ params->param7 = 0;
+ }
+
+ if (params1->param8 && params1->param8 < getState()->time) {
+ params->param7 = 0;
+ params1->param8 = 0;
+ }
+ }
+
+ // Update object
+ if (ENTITY_PARAM(0, 8) && !getSound()->isBuffered(kEntityTables5)) {
+ getObjects()->update((ObjectIndex)ENTITY_PARAM(0, 8), getObjects()->get((ObjectIndex)ENTITY_PARAM(0, 8)).entity, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ ENTITY_PARAM(0, 8) = 0;
+ }
+
+ // Play clock sound
+ if (params->param6 && !getSound()->isBuffered("ZFX1001", true))
+ getSound()->playSound(kEntityPlayer, "ZFX1001");
+
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor: {
+ // Handle opening harem compartments
+ ObjectIndex compartment = (ObjectIndex)savepoint.param.intValue;
+ if (compartment == kObjectCompartment5 || compartment == kObjectCompartment6 || compartment == kObjectCompartment7 || compartment == kObjectCompartment8) {
+ setCallback(savepoint.action == kActionKnock ? 3 : 4);
+ setup_harem(compartment, savepoint.action);
+ }
+ break;
+ }
+
+ case kActionDefault:
+ params->param3 = 1;
+ if (getProgress().chapter < kChapter5) {
+ getObjects()->update(kObjectCompartment5, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment6, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment7, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment8, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ }
+ getData()->entityPosition = kPosition_30000;
+ break;
+
+ case kActionDrawScene:
+ getData()->car = getEntityData(kEntityPlayer)->car;
+
+ // Play clock sound
+ if (getEntities()->isPlayerPosition(kCarRestaurant, 81)) {
+ params->param6 = 1;
+ if (!getSound()->isBuffered("ZFX1001"))
+ getSound()->playSound(kEntityPlayer, "ZFX1001");
+ } else {
+ params->param6 = 0;
+ if (getSound()->isBuffered("ZFX1001", true))
+ getSound()->removeFromQueue("ZFX1001");
+ }
+
+ // Draw moving background behind windows
+ if (params->param3) {
+ if (getEntityData(kEntityPlayer)->car != (CarIndex)params->param1 || isNight() != (bool)(params->param2)) {
+ switch (getEntityData(kEntityPlayer)->car) {
+ default:
+ getEntities()->clearSequences(kEntityTrain);
+ break;
+
+ case kCarBaggageRear:
+ case kCarBaggage:
+ if (getProgress().isNightTime)
+ getEntities()->drawSequenceLeft(kEntityTrain, "B1WNM");
+ else
+ getEntities()->drawSequenceLeft(kEntityTrain, isNight() ? "B1WNN" : "B1WND");
+ break;
+
+ case kCarGreenSleeping:
+ case kCarRedSleeping:
+ if (getProgress().isNightTime)
+ getEntities()->drawSequenceLeft(kEntityTrain, "S1WNM");
+ else
+ getEntities()->drawSequenceLeft(kEntityTrain, isNight() ? "S1WNN" : "S1WND");
+ break;
+
+ case kCarRestaurant:
+ getEntities()->drawSequenceLeft(kEntityTrain, isNight() ? "RCWNN" : "RCWND");
+ break;
+ }
+
+ // Set parameters so we do not get called twice
+ params->param1 = getEntityData(kEntityPlayer)->car;
+ params->param2 = isNight();
+ }
+ }
+
+ if (!params->param5) {
+ params->param4 = 2700; // this is the sound file name
+ params->param5 = 0;
+ }
+
+ if (getProgress().jacket == kJacketBlood) {
+ if (getEntities()->isPlayerPosition(kCarRedSleeping, 18)) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventMertensBloodJacket);
+ break;
+ }
+
+ if (getEntities()->isPlayerPosition(kCarGreenSleeping, 22)) {
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventMertensBloodJacket);
+ break;
+ }
+ }
+
+ resetParam8();
+ break;
+
+
+ case kActionCallback: {
+ int action = getCallback();
+ switch(action) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ getAction()->playAnimation(action == 1 ? kEventCoudertBloodJacket : kEventMertensBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
+ resetParam8();
+ break;
+
+ case 5:
+ getAction()->playAnimation(kEventLocomotiveConductorsDiscovered);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverPolice2, true);
+ break;
+
+ case 6:
+ getAction()->playAnimation(kEventCathBreakCeiling);
+ getObjects()->update(kObjectCeiling, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue);
+ getScenes()->processScene();
+ break;
+
+ case 7:
+ getAction()->playAnimation(kEventCathJumpDownCeiling);
+ getScenes()->loadSceneFromPosition(kCarKronos, 89);
+ break;
+
+ case 8:
+ getAction()->playAnimation(kEventCloseMatchbox);
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 51);
+ break;
+ }
+ break;
+ }
+
+ case kAction191070912:
+ ENTITY_PARAM(0, 7) = savepoint.param.intValue;
+ break;
+
+ case kActionTrainStopRunning:
+ params->param3 = 0;
+ getEntities()->clearSequences(kEntityTrain);
+ break;
+
+ case kActionCatchBeetle:
+ setCallback(8);
+ setup_savegame(kSavegameTypeEvent, kEventCloseMatchbox);
+ break;
+
+ case kAction203339360:
+ if (params->param7) {
+ setCallback(5);
+ setup_savegame(kSavegameTypeEvent, kEventLocomotiveConductorsDiscovered);
+ } else {
+ params->param7 = 1;
+ getAction()->playAnimation(kEventLocomotiveConductorsLook);
+ getScenes()->loadSceneFromPosition(kCarCoalTender, 2);
+ }
+ break;
+
+ case kActionTrainStartRunning:
+ if (!params->param3) {
+ params->param1 = 0;
+ params->param3 = 1;
+ getSavePoints()->push(kEntityTrain, kEntityTrain, kActionDrawScene);
+ }
+ break;
+
+ case kAction203863200:
+ if (!strcmp(savepoint.param.charValue, "")) {
+ params->param8 = 1;
+ strcpy((char *)&params1->seq, savepoint.param.charValue); // this is the sound file name
+ }
+ break;
+
+ case kAction222746496:
+ switch(savepoint.param.intValue) {
+ default:
+ break;
+
+ case kObjectCompartment1:
+ case kObjectCompartment2:
+ case kObjectCompartmentA:
+ case kObjectCompartmentB:
+ params1->param1 = (savepoint.param.intValue == kObjectCompartment1 || savepoint.param.intValue == kObjectCompartment2) ? kCarGreenSleeping : kCarRedSleeping;
+ params1->param2 = (savepoint.param.intValue == kObjectCompartment1 || savepoint.param.intValue == kObjectCompartmentA) ? kPosition_8200 : kPosition_7500;
+ params1->param3 = kPosition_7850;
+ break;
+
+ case kObjectCompartment3:
+ case kObjectCompartment4:
+ case kObjectCompartmentC:
+ case kObjectCompartmentD:
+ params1->param1 = (savepoint.param.intValue == kObjectCompartment1 || savepoint.param.intValue == kObjectCompartment2) ? kCarGreenSleeping : kCarRedSleeping;
+ params1->param2 = (savepoint.param.intValue == kObjectCompartment3 || savepoint.param.intValue == kObjectCompartmentC) ? kPosition_6470 : kPosition_5790;
+ params1->param3 = kPosition_6130;
+ break;
+
+ case kObjectCompartment5:
+ case kObjectCompartment6:
+ case kObjectCompartmentE:
+ case kObjectCompartmentF:
+ params1->param1 = (savepoint.param.intValue == kObjectCompartment1 || savepoint.param.intValue == kObjectCompartment2) ? kCarGreenSleeping : kCarRedSleeping;
+ params1->param2 = (savepoint.param.intValue == kObjectCompartment5 || savepoint.param.intValue == kObjectCompartmentE) ? kPosition_4840 : kPosition_4070;
+ params1->param3 = kPosition_4455;
+ break;
+
+ case kObjectCompartment7:
+ case kObjectCompartment8:
+ case kObjectCompartmentG:
+ case kObjectCompartmentH:
+ params1->param1 = (savepoint.param.intValue == kObjectCompartment1 || savepoint.param.intValue == kObjectCompartment2) ? kCarGreenSleeping : kCarRedSleeping;
+ params1->param2 = (savepoint.param.intValue == kObjectCompartment7 || savepoint.param.intValue == kObjectCompartmentG) ? kPosition_3050 : kPosition_2740;
+ params1->param3 = kPositionNone;
+ break;
+ }
+ break;
+
+ case kActionBreakCeiling:
+ setCallback(6);
+ setup_savegame(kSavegameTypeEvent, kEventCathBreakCeiling);
+ break;
+
+ case kActionJumpDownCeiling:
+ setCallback(7);
+ setup_savegame(kSavegameTypeEvent, kEventCathJumpDownCeiling);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Private functions
+//////////////////////////////////////////////////////////////////////////
+void Train::handleCompartmentAction() {
+ EXPOSE_PARAMS(EntityData::EntityParametersIIII)
+
+ if (params->param8)
+ getSavePoints()->push(kEntityTrain, kEntityMahmud, kAction290410610, params->param1);
+
+ getAction()->handleOtherCompartment((ObjectIndex)params->param1, false, !params->param8);
+
+ ENTITY_PARAM(0, 8) = params->param1;
+
+ CALLBACK_ACTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+void Train::resetParam8() {
+ EXPOSE_PARAMS(EntityData::EntityParametersIIII)
+ EntityData::EntityParametersIIIS *params1 = (EntityData::EntityParametersIIIS*)_data->getCurrentParameters(1);
+
+ if (params->param8
+ && !getEntities()->isInsideCompartment(kEntityPlayer, (CarIndex)params1->param1, (EntityPosition)params1->param2)
+ && !getEntities()->isInsideCompartment(kEntityPlayer, (CarIndex)params1->param1, (EntityPosition)params1->param3)) {
+
+ if (getSound()->isBuffered((const char *)&params1->seq))
+ getSound()->processEntry((const char *)&params1->seq);
+
+ params->param8 = 0;
+ }
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/train.h b/engines/lastexpress/entities/train.h
new file mode 100644
index 0000000000..4c6e2989ff
--- /dev/null
+++ b/engines/lastexpress/entities/train.h
@@ -0,0 +1,95 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_TRAIN_H
+#define LASTEXPRESS_TRAIN_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Train : public Entity {
+public:
+ Train(LastExpressEngine *engine);
+ ~Train() {};
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Harem events
+ *
+ * @param compartment The compartment to handle
+ * @param counter ??? (checked to decide which sound to make when knocking)
+ */
+ DECLARE_FUNCTION_2(harem, ObjectIndex compartment, uint32 counter)
+
+ /**
+ * Handles Train events
+ */
+ DECLARE_FUNCTION(process)
+
+private:
+ // Helper methods
+ void resetParam8();
+ void handleCompartmentAction();
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_TRAIN_H
diff --git a/engines/lastexpress/entities/vassili.cpp b/engines/lastexpress/entities/vassili.cpp
new file mode 100644
index 0000000000..951c323f91
--- /dev/null
+++ b/engines/lastexpress/entities/vassili.cpp
@@ -0,0 +1,589 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/vassili.h"
+
+#include "lastexpress/entities/anna.h"
+#include "lastexpress/entities/coudert.h"
+
+#include "lastexpress/game/action.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"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+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(Vassili, chapter1);
+ ADD_CALLBACK_FUNCTION(Vassili, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Vassili, function6);
+ ADD_CALLBACK_FUNCTION(Vassili, function7);
+ ADD_CALLBACK_FUNCTION(Vassili, function8);
+ ADD_CALLBACK_FUNCTION(Vassili, function9);
+ ADD_CALLBACK_FUNCTION(Vassili, seizure);
+ ADD_CALLBACK_FUNCTION(Vassili, drawInBed);
+ ADD_CALLBACK_FUNCTION(Vassili, chapter2);
+ ADD_CALLBACK_FUNCTION(Vassili, sleeping);
+ ADD_CALLBACK_FUNCTION(Vassili, chapter3);
+ ADD_CALLBACK_FUNCTION(Vassili, stealEgg);
+ ADD_CALLBACK_FUNCTION(Vassili, chapter4);
+ ADD_CALLBACK_FUNCTION(Vassili, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Vassili, chapter5);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Vassili, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(2, Vassili, draw)
+ Entity::draw(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(3, Vassili, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(4, Vassili, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject40, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(5, Vassili, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1) {
+ getData()->entityPosition = getEntityData(kEntityTatiana)->entityPosition;
+ getData()->location = getEntityData(kEntityTatiana)->location;
+ } else {
+ if (params->param3 && params->param3 >= getState()->time) {
+ break;
+ }else {
+ params->param3 = getState()->time + 450;
+ if (params->param3 == 0)
+ break;
+ }
+
+ if (!params->param2 && getObjects()->get(kObjectCompartmentA).location == kObjectLocation1) {
+ params->param2 = 1;
+ getEntities()->drawSequenceLeft(kEntityVassili, "303A");
+ getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ }
+ break;
+ }
+ break;
+
+ case kActionDefault:
+ params->param1 = 1;
+ break;
+
+ case kAction122732000:
+ setup_function6();
+ break;
+
+ case kAction168459827:
+ params->param1 = 0;
+ getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(6, Vassili, function6)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_8200)) {
+ UPDATE_PARAM_GOTO(params->param3, getState()->timeTicks, params->param1, label_function7);
+
+ setCallback(1);
+ setup_draw("303B");
+ break;
+ }
+
+ params->param3 = 0;
+
+ if (params->param2)
+ getEntities()->drawSequenceLeft(kEntityVassili, "303A");
+
+label_function7:
+ if (params->param4 != kTimeInvalid && getState()->time > kTime1489500) {
+
+ if (getState()->time <= kTime1503000) {
+
+ if (getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_8200) || !params->param4) {
+
+ params->param4 = getState()->time;
+ if (!params->param4) {
+ setup_function7();
+ break;
+ }
+ }
+
+ if (params->param4 >= getState()->time)
+ break;
+ }
+
+ params->param4 = kTimeInvalid;
+ setup_function7();
+ }
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_8200;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+ params->param1 = 5 * (3 * rnd(25) + 15);
+
+ getEntities()->drawSequenceLeft(kEntityVassili, "303A");
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getEntities()->drawSequenceLeft(kEntityVassili, "303C");
+ params->param1 = 5 * (3 * rnd(25) + 15);
+ params->param2 = 1;
+
+ // Shared part with kActionNone
+ goto label_function7;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(7, Vassili, function7)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param1 != kTimeInvalid && getState()->time > kTime1503000) {
+
+ if (getState()->time <= kTime1512000) {
+ if (getEntities()->isPlayerInCar(kCarRedSleeping) || !params->param1) {
+ params->param1 = getState()->time + 150;
+ if (params->param1) {
+ setup_function8();
+ break;
+ }
+ }
+
+ if (params->param1 >= getState()->time)
+ break;
+ }
+
+ params->param1 = kTimeInvalid;
+ setup_function8();
+ }
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_8200;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getEntities()->clearSequences(kEntityVassili);
+ if (getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_8200))
+ getScenes()->loadSceneFromObject(kObjectCompartmentA);
+
+ getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kAction339669520:
+ setup_function9();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(8, Vassili, function8)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionEndSound:
+ setup_function9();
+ break;
+
+ case kActionDefault:
+ if (!getEntities()->isInsideTrainCar(kEntityPlayer, kCarRedSleeping)) {
+ getSound()->playSound(kEntityPlayer, "BUMP");
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, (getEntityData(kEntityPlayer)->car <= kCarRedSleeping) ? 1 : 40);
+ }
+
+ getSavePoints()->push(kEntityVassili, kEntityAnna, kAction226031488);
+ getSavePoints()->push(kEntityVassili, kEntityVerges, kAction226031488);
+ getSavePoints()->push(kEntityVassili, kEntityCoudert, kAction226031488);
+ getSound()->playSound(kEntityVassili, "VAS1027", SoundManager::kFlagDefault);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(9, Vassili, function9)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionEndSound:
+ if (!getEntities()->isDistanceBetweenEntities(kEntityVassili, kEntityPlayer, 2500))
+ getSound()->playSound(kEntityPlayer, "BUMP");
+
+ setup_seizure();
+ break;
+
+ case kActionDefault:
+ case kActionDrawScene:
+ if ((getObjects()->get(kObjectCompartmentA).location == kObjectLocation2 && getEntities()->isPlayerPosition(kCarRedSleeping, 17))
+ || getEntities()->isPlayerPosition(kCarRedSleeping, 18)
+ || getEntities()->isPlayerPosition(kCarRedSleeping, 37)
+ || getEntities()->isPlayerPosition(kCarRedSleeping, 38)
+ || getEntities()->isPlayerPosition(kCarRedSleeping, 41)) {
+
+ if (savepoint.action == kActionDrawScene)
+ getSound()->processEntry(kEntityVassili);
+
+ setup_seizure();
+ } else {
+ if (savepoint.action == kActionDefault)
+ getSound()->playSound(kEntityVassili, "VAS1028", SoundManager::kFlagDefault);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(10, Vassili, seizure)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ // Check that we have removed the body from the train and changed jacket
+ if (!getProgress().eventCorpseMovedFromFloor) {
+ getAction()->playAnimation(kEventMertensCorpseFloor);
+ getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, false);
+ break;
+ }
+
+ if (!getProgress().eventCorpseThrown) {
+ getAction()->playAnimation(kEventMertensCorpseBed);
+ getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, false);
+ break;
+ }
+
+ if (getProgress().jacket == kJacketBlood) {
+ getAction()->playAnimation(kEventMertensBloodJacket);
+ getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, false);
+ break;
+ }
+
+ // Setup Anna & Coudert
+ RESET_ENTITY_STATE(kEntityAnna, Anna, setup_function37);
+ RESET_ENTITY_STATE(kEntityCoudert, Coudert, setup_function38);
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventVassiliSeizure);
+ break;
+
+ case kActionCallback:
+ if (getCallback() != 1)
+ break;
+
+ getData()->location = kLocationInsideCompartment;
+ getAction()->playAnimation(kEventVassiliSeizure);
+
+ getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getProgress().field_18 = 2;
+
+ getSavePoints()->push(kEntityVassili, kEntityAnna, kAction191477936);
+ getSavePoints()->push(kEntityVassili, kEntityVerges, kAction191477936);
+ getSavePoints()->push(kEntityVassili, kEntityCoudert, kAction191477936);
+ getScenes()->loadSceneFromObject(kObjectCompartmentA);
+
+ setup_drawInBed();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Vassili, drawInBed)
+ if (savepoint.action == kActionDefault)
+ getEntities()->drawSequenceLeft(kEntityVassili, "303A");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Vassili, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_sleeping();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityVassili);
+
+ getData()->entityPosition = kPosition_8200;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->updateLocation2(kObjectCompartmentA, kObjectLocation1);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Vassili, sleeping)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_8200)) {
+ UPDATE_PARAM(params->param3, getState()->timeTicks, params->param1);
+
+ setCallback(1);
+ setup_draw("303B");
+ } else {
+ params->param3 = 0;
+ if (params->param2)
+ getEntities()->drawSequenceLeft(kEntityVassili, "303A");
+ }
+ break;
+
+ case kActionDefault:
+ params->param5 = 5 * (3 * rnd(25) + 15);
+ getEntities()->drawSequenceLeft(kEntityVassili, "303A");
+ break;
+
+ case kActionCallback:
+ if (getCallback() != 1)
+ break;
+
+ getEntities()->drawSequenceLeft(kEntityVassili, "303C");
+ params->param1 = 5 * (3 * rnd(25) + 15);
+ params->param2 = 1;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Vassili, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_stealEgg();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityVassili);
+
+ getData()->entityPosition = kPosition_8200;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Vassili, stealEgg)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_8200)) {
+ UPDATE_PARAM(params->param3, getState()->timeTicks, params->param1);
+
+ setCallback(1);
+ setup_draw("303B");
+ } else {
+ params->param3 = 0;
+ if (params->param2)
+ getEntities()->drawSequenceLeft(kEntityVassili, "303A");
+ }
+ break;
+
+ case kActionOpenDoor:
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventVassiliCompartmentStealEgg);
+ break;
+
+ case kActionDefault:
+ params->param5 = 5 * (3 * rnd(25) + 15);
+ getEntities()->drawSequenceLeft(kEntityVassili, "303A");
+ break;
+
+ case kActionDrawScene:
+ if (getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_7850)
+ && getInventory()->hasItem(kItemFirebird)
+ && !getEvent(kEventVassiliCompartmentStealEgg))
+ getObjects()->update(kObject48, kEntityVassili, kObjectLocationNone, kCursorNormal, kCursorHand);
+ else
+ getObjects()->update(kObject48, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorHand);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceLeft(kEntityVassili, "303C");
+ params->param1 = 5 * (3 * rnd(25) + 15);
+ params->param2 = 1;
+ break;
+
+ case 2:
+ getAction()->playAnimation(kEventVassiliCompartmentStealEgg);
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 67);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Vassili, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityVassili);
+
+ getData()->entityPosition = kPosition_8200;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getObjects()->updateLocation2(kObjectCompartmentA, kObjectLocation1);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Looks identical to sleeping (#13)
+IMPLEMENT_FUNCTION(17, Vassili, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_8200)) {
+ UPDATE_PARAM(params->param3, getState()->timeTicks, params->param1);
+
+ setCallback(1);
+ setup_draw("303B");
+ } else {
+ params->param3 = 0;
+ if (params->param2)
+ getEntities()->drawSequenceLeft(kEntityVassili, "303A");
+ }
+ break;
+
+ case kActionDefault:
+ params->param5 = 5 * (3 * rnd(25) + 15);
+ getEntities()->drawSequenceLeft(kEntityVassili, "303A");
+ break;
+
+ case kActionCallback:
+ if (getCallback() != 1)
+ break;
+
+ getEntities()->drawSequenceLeft(kEntityVassili, "303C");
+ params->param1 = 5 * (3 * rnd(25) + 15);
+ params->param2 = 1;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Vassili, chapter5)
+ if (savepoint.action == kActionDefault) {
+ getEntities()->clearSequences(kEntityVassili);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ }
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/vassili.h b/engines/lastexpress/entities/vassili.h
new file mode 100644
index 0000000000..113bc1d958
--- /dev/null
+++ b/engines/lastexpress/entities/vassili.h
@@ -0,0 +1,110 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_VASSILI_H
+#define LASTEXPRESS_VASSILI_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Vassili : public Entity {
+public:
+ Vassili(LastExpressEngine *engine);
+ ~Vassili() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Draws the entity
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(draw, const char* sequence)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function6)
+ DECLARE_FUNCTION(function7)
+ DECLARE_FUNCTION(function8)
+ DECLARE_FUNCTION(function9)
+ DECLARE_FUNCTION(seizure)
+ DECLARE_FUNCTION(drawInBed)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ DECLARE_FUNCTION(sleeping)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ DECLARE_FUNCTION(stealEgg)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_VASSILI_H
diff --git a/engines/lastexpress/entities/verges.cpp b/engines/lastexpress/entities/verges.cpp
new file mode 100644
index 0000000000..20979ff9f9
--- /dev/null
+++ b/engines/lastexpress/entities/verges.cpp
@@ -0,0 +1,1898 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/verges.h"
+
+#include "lastexpress/game/action.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"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+namespace LastExpress {
+
+Verges::Verges(LastExpressEngine *engine) : Entity(engine, kEntityVerges) {
+ ADD_CALLBACK_FUNCTION(Verges, reset);
+ ADD_CALLBACK_FUNCTION(Verges, draw);
+ ADD_CALLBACK_FUNCTION(Verges, callbackActionOnDirection);
+ ADD_CALLBACK_FUNCTION(Verges, playSound);
+ ADD_CALLBACK_FUNCTION(Verges, playSound16);
+ ADD_CALLBACK_FUNCTION(Verges, callbackActionRestaurantOrSalon);
+ ADD_CALLBACK_FUNCTION(Verges, savegame);
+ ADD_CALLBACK_FUNCTION(Verges, updateEntity);
+ ADD_CALLBACK_FUNCTION(Verges, function9);
+ ADD_CALLBACK_FUNCTION(Verges, function10);
+ ADD_CALLBACK_FUNCTION(Verges, function11);
+ ADD_CALLBACK_FUNCTION(Verges, function12);
+ ADD_CALLBACK_FUNCTION(Verges, function13);
+ ADD_CALLBACK_FUNCTION(Verges, updateFromTime);
+ ADD_CALLBACK_FUNCTION(Verges, function15);
+ ADD_CALLBACK_FUNCTION(Verges, function16);
+ ADD_CALLBACK_FUNCTION(Verges, function17);
+ ADD_CALLBACK_FUNCTION(Verges, chapter1);
+ ADD_CALLBACK_FUNCTION(Verges, talkHarem);
+ ADD_CALLBACK_FUNCTION(Verges, talkPassengerList);
+ ADD_CALLBACK_FUNCTION(Verges, talkGendarmes);
+ ADD_CALLBACK_FUNCTION(Verges, function22);
+ ADD_CALLBACK_FUNCTION(Verges, function23);
+ ADD_CALLBACK_FUNCTION(Verges, policeGettingOffTrain);
+ ADD_CALLBACK_FUNCTION(Verges, function25);
+ ADD_CALLBACK_FUNCTION(Verges, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Verges, chapter2);
+ ADD_CALLBACK_FUNCTION(Verges, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Verges, chapter3);
+ ADD_CALLBACK_FUNCTION(Verges, function30);
+ ADD_CALLBACK_FUNCTION(Verges, function31);
+ ADD_CALLBACK_FUNCTION(Verges, function32);
+ ADD_CALLBACK_FUNCTION(Verges, function33);
+ ADD_CALLBACK_FUNCTION(Verges, function34);
+ ADD_CALLBACK_FUNCTION(Verges, function35);
+ ADD_CALLBACK_FUNCTION(Verges, chapter4);
+ ADD_CALLBACK_FUNCTION(Verges, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Verges, function38);
+ ADD_CALLBACK_FUNCTION(Verges, chapter5);
+ ADD_CALLBACK_FUNCTION(Verges, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(Verges, function41);
+ ADD_CALLBACK_FUNCTION(Verges, function42);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Verges, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(2, Verges, draw)
+ Entity::draw(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(3, Verges, callbackActionOnDirection)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getData()->direction != kDirectionRight)
+ CALLBACK_ACTION();
+ break;
+
+ case kActionExitCompartment:
+ CALLBACK_ACTION();
+ break;
+
+ case kActionExcuseMeCath:
+ if (!params->param1) {
+ getSound()->excuseMe(kEntityVerges);
+ params->param1 = 1;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(4, Verges, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(5, Verges, playSound16)
+ Entity::playSound(savepoint, false, SoundManager::kFlagDefault);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(6, Verges, callbackActionRestaurantOrSalon)
+ Entity::callbackActionRestaurantOrSalon(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(7, Verges, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(8, Verges, updateEntity, CarIndex, EntityPosition)
+ if (savepoint.action == kActionExcuseMeCath) {
+ if (!getSound()->isBuffered(kEntityVerges))
+ getSound()->playSound(kEntityPlayer, "TRA1113", getSound()->getSoundFlag(kEntityVerges));
+
+ return;
+ }
+
+ Entity::updateEntity(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(9, Verges, function9)
+switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObject104, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorHand);
+ getObjects()->update(kObject105, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorHand);
+
+ if (getEntities()->isInBaggageCar(kEntityPlayer) || getEntities()->isInKitchen(kEntityPlayer)) {
+ getAction()->playAnimation(getEntities()->isInBaggageCar(kEntityPlayer) ? kEventVergesBaggageCarOffLimits : kEventVergesCanIHelpYou);
+ getSound()->playSound(kEntityPlayer, "BUMP");
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 65);
+ }
+
+ getScenes()->loadSceneFromItemPosition(kItem9);
+ getData()->car = kCarRestaurant;
+ getData()->entityPosition = kPosition_5900;
+
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+ getSound()->playSound(kEntityVerges, (char *)&params->seq1);
+
+ setCallback(2);
+ setup_draw("813DD");
+ break;
+
+ case 2:
+ if (!getSound()->isBuffered(kEntityVerges))
+ getSound()->playSound(kEntityVerges, (char *)&params->seq1);
+
+ getEntities()->drawSequenceRight(kEntityVerges, "813DS");
+
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityVerges);
+
+ setCallback(3);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function10(kCarGreenSleeping, kPosition_540, (char *)&params->seq1);
+ break;
+
+ case 4:
+ getEntities()->clearSequences(kEntityVerges);
+
+ setCallback(5);
+ setup_updateFromTime(225);
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_function11();
+ break;
+
+ case 6:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_IIS(10, Verges, function10, CarIndex, EntityPosition)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param7) {
+ if (!getSound()->isBuffered(kEntityVerges)) {
+ getSound()->playSound(kEntityVerges, (char *)&params->seq);
+ params->param7 = 1;
+ }
+ }
+
+ if (getEntities()->updateEntity(kEntityVerges, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+ CALLBACK_ACTION();
+ break;
+ }
+
+ if (params->param6) {
+ UPDATE_PARAM(params->param8, getState()->timeTicks, 75);
+
+ getSound()->playSound(kEntityVerges, (char *)&params->seq);
+
+ params->param6 = 0;
+ params->param8 = 0;
+ }
+ break;
+
+ case kActionEndSound:
+ params->param6 = 1;
+ break;
+
+ case kActionDefault:
+ if (!getSound()->isBuffered(kEntityVerges)) {
+ getSound()->playSound(kEntityVerges, (char *)&params->seq);
+ params->param7 = 1;
+ }
+
+ if (getEntities()->updateEntity(kEntityVerges, (CarIndex)params->param1, (EntityPosition)params->param2))
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Verges, function11)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_updateEntity(kCarRestaurant, kPosition_540);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 2:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(3);
+ setup_draw("813US");
+ break;
+
+ case 3:
+ getEntities()->drawSequenceRight(kEntityVerges, "813UD");
+
+ if (getEntities()->isInSalon(kEntityPlayer))
+ getEntities()->updateFrame(kEntityVerges);
+
+ setCallback(4);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 4: {
+ getEntities()->clearSequences(kEntityVerges);
+
+ bool loadscene = true;
+
+ if (getEntities()->isInBaggageCarEntrance(kEntityPlayer))
+ getAction()->playAnimation(kEventVergesEscortToDiningCar);
+ else if (getEntities()->isInBaggageCar(kEntityPlayer))
+ getAction()->playAnimation(kEventVergesBaggageCarOffLimits);
+ else if (getEntities()->isInKitchen(kEntityPlayer))
+ getAction()->playAnimation(kEventVergesCanIHelpYou);
+ else
+ loadscene = false;
+
+ if (loadscene) {
+ getSound()->playSound(kEntityPlayer, "BUMP");
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 65);
+ }
+
+ getInventory()->setLocationAndProcess(kItem9, kObjectLocation1);
+
+ getData()->car = kCarBaggage;
+ getData()->entityPosition = kPosition_5000;
+
+ getObjects()->update(kObject104, kEntityVerges, kObjectLocationNone, kCursorNormal, kCursorHand);
+ getObjects()->update(kObject105, kEntityVerges, kObjectLocationNone, kCursorNormal, kCursorHand);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Verges, function12)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObject104, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorHand);
+ getObjects()->update(kObject105, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorHand);
+
+ if (getEntities()->isInBaggageCar(kEntityPlayer) || getEntities()->isInKitchen(kEntityPlayer)) {
+ getAction()->playAnimation(getEntities()->isInBaggageCar(kEntityPlayer) ? kEventVergesBaggageCarOffLimits : kEventVergesCanIHelpYou);
+ getSound()->playSound(kEntityPlayer, "BUMP");
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 65);
+ }
+
+ getScenes()->loadSceneFromItemPosition(kItem9);
+
+ getData()->car = kCarRestaurant;
+ getData()->entityPosition = kPosition_5900;
+
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_draw("813DD");
+ break;
+
+ case 2:
+ getEntities()->drawSequenceRight(kEntityVerges, "813DS");
+
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityVerges);
+
+ setCallback(3);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_850;
+ getEntities()->clearSequences(kEntityVerges);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(13, Verges, function13, bool)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventVergesSuitcase);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ if (getEvent(kEventVergesSuitcase) || getEvent(kEventVergesSuitcaseNight) || getEvent(kEventVergesSuitcaseOtherEntry) || getEvent(kEventVergesSuitcaseNightOtherEntry))
+ params->param2 = 1;
+
+ if (isNight() && getProgress().chapter != kChapter1)
+ params->param2 = 1;
+
+ if (params->param1) {
+ if (isNight())
+ getAction()->playAnimation(params->param2 ? kEventVergesSuitcaseNightOtherEntryStart : kEventVergesSuitcaseNightOtherEntry);
+ else
+ getAction()->playAnimation(params->param2 ? kEventVergesSuitcaseOtherEntryStart : kEventVergesSuitcaseOtherEntry);
+ } else {
+ if (isNight())
+ getAction()->playAnimation(params->param2 ? kEventVergesSuitcaseNightStart : kEventVergesSuitcaseNight);
+ else
+ getAction()->playAnimation(params->param2 ? kEventVergesSuitcaseStart : kEventVergesSuitcase);
+ }
+
+ getEntities()->clearSequences(kEntityVerges);
+ getScenes()->loadSceneFromPosition(kCarBaggage, 91);
+
+ CALLBACK_ACTION();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(14, Verges, updateFromTime, uint32)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_IS(15, Verges, function15, EntityIndex)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (params->param5 && params->param6) {
+ getSavePoints()->push(kEntityVerges, (EntityIndex)params->param1, kAction125499160);
+
+ if (!getEntities()->isPlayerPosition(kCarGreenSleeping, 2) && !getEntities()->isPlayerPosition(kCarRedSleeping, 2))
+ getData()->entityPosition = kPosition_2088;
+
+ CALLBACK_ACTION();
+ }
+ break;
+
+ case kActionEndSound:
+ params->param5 = 1;
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityVerges, "620F");
+ getSavePoints()->push(kEntityVerges, (EntityIndex)params->param1, kAction171394341);
+ break;
+
+ case kAction155853632:
+ params->param6 = 1;
+ break;
+
+ case kAction202558662:
+ getEntities()->drawSequenceLeft(kEntityVerges, "620E");
+ getSound()->playSound(kEntityVerges, (char *)&params->seq);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_ISS(16, Verges, function16, EntityIndex)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (CURRENT_PARAMS(1, 1) && params->param8) {
+ getSavePoints()->push(kEntityVerges, (EntityIndex)params->param1, kAction125499160);
+
+ if (!getEntities()->isPlayerPosition(kCarGreenSleeping, 2) && !getEntities()->isPlayerPosition(kCarRedSleeping, 2))
+ getData()->entityPosition = kPosition_2088;
+
+ CALLBACK_ACTION();
+ }
+ break;
+
+ case kActionEndSound:
+ CURRENT_PARAMS(1, 1)++;
+
+ if (CURRENT_PARAMS(1, 1) == 1)
+ getSound()->playSound(kEntityVerges, (char *)&params->seq2);
+ break;
+
+ case kActionDefault:
+ getEntities()->drawSequenceLeft(kEntityVerges, "620F");
+ getSavePoints()->push(kEntityVerges, (EntityIndex)params->param1, kAction171394341);
+ break;
+
+ case kAction155853632:
+ params->param8 = 1;
+ break;
+
+ case kAction202558662:
+ getEntities()->drawSequenceLeft(kEntityVerges, "620E");
+ getSound()->playSound(kEntityVerges, (char *)&params->seq1);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Verges, function17)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function12();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function15(kEntityMertens, "TRA1291");
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function11();
+ break;
+
+ case 4:
+ ENTITY_PARAM(0, 3) = 0;
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Verges, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getSavePoints()->addData(kEntityVerges, kActionDeliverMessageToTyler, 0);
+ getSavePoints()->addData(kEntityVerges, kAction226031488, 1);
+ getSavePoints()->addData(kEntityVerges, kAction339669520, 1);
+ getSavePoints()->addData(kEntityVerges, kAction167854368, 4);
+ getSavePoints()->addData(kEntityVerges, kAction158617345, 2);
+ getSavePoints()->addData(kEntityVerges, kAction168255788, 3);
+ getSavePoints()->addData(kEntityVerges, kAction201431954, 5);
+ getSavePoints()->addData(kEntityVerges, kAction168187490, 6);
+
+ getObjects()->update(kObject104, kEntityVerges, kObjectLocationNone, kCursorNormal, kCursorHand);
+ getObjects()->update(kObject105, kEntityVerges, kObjectLocationNone, kCursorNormal, kCursorHand);
+
+ getData()->entityPosition = kPosition_5000;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarBaggage;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(19, Verges, talkHarem)
+ talk(savepoint, "TRA1202", "TRA1201");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Verges, talkPassengerList)
+ talk(savepoint, "TRA1205", "TRA1206");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Verges, talkGendarmes)
+ talk(savepoint, "TRA1250", "TRA1251");
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Verges, function22)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function12();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ break;
+
+ case 2:
+ if (getEvent(kEventMertensAskTylerCompartment) || getEvent(kEventMertensAskTylerCompartmentD) || getEvent(kEventMertensAugustWaiting)) {
+ setCallback(3);
+ setup_function16(kEntityMertens, "TRA1200", "TRA1201");
+ } else {
+ setCallback(4);
+ setup_function16(kEntityMertens, "TRA1200A", "TRA1201");
+ }
+ break;
+
+ case 3:
+ case 4:
+ getSavePoints()->push(kEntityVerges, kEntityMertens, kAction169633856);
+
+ setCallback(5);
+ setup_function11();
+ break;
+
+ case 5:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Verges, function23)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getScenes()->loadSceneFromItemPosition(kItem9);
+
+ getData()->entityPosition = kPosition_8200;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ break;
+
+ case kAction191477936:
+ getData()->entityPosition = kPosition_8200;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ setCallback(1);
+ setup_function11();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Verges, policeGettingOffTrain)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isDistanceBetweenEntities(kEntityVerges, kEntityPlayer, 1000) && getEntityData(kEntityPlayer)->location == kLocationOutsideCompartment) {
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventGendarmesArrestation);
+ }
+ break;
+
+ case kActionEndSound:
+ CALLBACK_ACTION();
+ break;
+
+ case kActionDefault:
+ getSound()->playSound(kEntityVerges, "POL1101", SoundManager::kFlagDefault);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getSound()->processEntry(kEntityVerges);
+ getAction()->playAnimation(kEventGendarmesArrestation);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverPolice1, true);
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, Verges, function25)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_savegame(kSavegameTypeTime, kTimeNone);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getScenes()->loadSceneFromItemPosition(kItem9);
+
+ if (!getEntities()->isInKronosSalon(kEntityPlayer)) {
+
+ if (getEntityData(kEntityPlayer)->car > kCarRedSleeping
+ || (getEntityData(kEntityPlayer)->car == kCarRedSleeping && getEntityData(kEntityPlayer)->entityPosition > kPosition_9270)) {
+ getSound()->playSound(kEntityPlayer, "BUMP");
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 40);
+
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_9270;
+ } else {
+ if (getEntityData(kEntityPlayer)->car > kCarGreenSleeping
+ || (getEntityData(kEntityPlayer)->car == kCarGreenSleeping && getEntityData(kEntityPlayer)->entityPosition < kPosition_4840)) {
+ getSound()->playSound(kEntityPlayer, "BUMP");
+ getScenes()->loadSceneFromObject(kObjectCompartment5, true);
+ }
+
+ getData()->car = kCarGreenSleeping;
+ getData()->entityPosition = kPosition_850;
+ }
+
+ getData()->location = kLocationOutsideCompartment;
+
+ getObjects()->update(kObjectRestaurantCar, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorForward);
+ getObjects()->update(kObjectCompartmentE, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ if (getEntities()->isOutsideAnnaWindow())
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 49);
+
+ if (getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_4840)
+ || getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_4455)) {
+ getAction()->playAnimation(isNight() ? kEventCathTurningNight : kEventCathTurningDay);
+ getSound()->playSound(kEntityPlayer, "BUMP");
+ getScenes()->loadSceneFromObject(kObjectCompartmentE, true);
+ }
+
+ getSavePoints()->push(kEntityVerges, kEntityGendarmes, kAction169499649);
+
+ getProgress().field_3C = 1;
+ getState()->timeDelta = 1;
+
+ if (getData()->car == kCarRedSleeping) {
+ setCallback(6);
+ setup_function10(kCarGreenSleeping, kPosition_540, "TRA1005");
+ } else {
+ setCallback(7);
+ setup_function10(kCarRedSleeping, kPosition_9460, "TRA1006");
+ }
+ break;
+ }
+ // Fallback to next case
+
+ case 2:
+ if (getEvent(kEventKronosConversation)) {
+ getProgress().field_3C = 1;
+ getData()->car = kCarGreenSleeping;
+ getData()->entityPosition = kPosition_540;
+ getData()->location = kLocationOutsideCompartment;
+
+ getState()->timeDelta = 3;
+ getSavePoints()->push(kEntityVerges, kEntityChapters, kAction169629818);
+
+ setCallback(3);
+ setup_policeGettingOffTrain();
+ } else {
+ setCallback(2);
+ setup_updateFromTime(150);
+ }
+ break;
+
+ case 3:
+ getSavePoints()->push(kEntityVerges, kEntityCoudert, kAction168254872);
+
+ setCallback(4);
+ setup_function10(kCarRedSleeping, kPosition_9460, "TRA1006");
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_function11();
+ break;
+
+ case 5:
+ case 11:
+ ENTITY_PARAM(0, 7) = 0;
+
+ CALLBACK_ACTION();
+ break;
+
+ case 6:
+ case 7:
+ getEntities()->clearSequences(kEntityVerges);
+ break;
+
+ case 8:
+ getSavePoints()->push(kEntityVerges, kEntityChapters, kAction169629818);
+
+ setCallback(9);
+ setup_policeGettingOffTrain();
+ break;
+
+ case 9:
+ getObjects()->update(kObjectRestaurantCar, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
+ getObjects()->update(kObjectCompartmentE, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+ getSavePoints()->push(kEntityVerges, kEntityCoudert, kAction168254872);
+
+ setCallback(10);
+ setup_function10(kCarGreenSleeping, kPosition_540, "TRA1006");
+ break;
+
+ case 10:
+ setCallback(11);
+ setup_function11();
+ break;
+ }
+ break;
+
+ case kAction168710784:
+ getData()->car = kCarGreenSleeping;
+
+ if (!(getEntityData(kEntityPlayer)->car == kCarGreenSleeping))
+ getData()->car = kCarRedSleeping;
+
+ getData()->entityPosition = kPosition_8200;
+ getData()->location = kLocationOutsideCompartment;
+
+ getState()->timeDelta = 3;
+
+ setCallback(8);
+ setup_savegame(kSavegameTypeTime, kTimeNone);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(26, Verges, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (ENTITY_PARAM(0, 6)) {
+ params->param1 = 1;
+ params->param2 = 1;
+ params->param3 = 1;
+ params->param4 = 1;
+ params->param5 = 1;
+ params->param6 = 1;
+
+ ENTITY_PARAM(0, 6) = 0;
+ }
+
+ if (ENTITY_PARAM(0, 2)) {
+ setCallback(1);
+ setup_function23();
+ break;
+ }
+
+label_callback1:
+ if (getEntities()->isInBaggageCarEntrance(kEntityPlayer)) {
+ setCallback(2);
+ setup_function13(false);
+ break;
+ }
+
+label_callback2:
+ if (ENTITY_PARAM(0, 7)) {
+ setCallback(3);
+ setup_function25();
+ break;
+ }
+
+label_callback3:
+ if (params->param6)
+ goto label_callback12;
+
+ TIME_CHECK_CALLBACK_1(kTimeChapter1, params->param7, 4, setup_function9, "TRA1001");
+
+label_callback4:
+ TIME_CHECK_CALLBACK(kTime1089000, params->param8, 5, setup_function12);
+
+ params->param8 = 1;
+
+ if (!params->param5) {
+ setCallback(5);
+ setup_function12();
+ break;
+ }
+
+label_callback8:
+ TIME_CHECK_CALLBACK_1(kTime1107000, CURRENT_PARAMS(1, 1), 9, setup_function9, "TRA1001A");
+
+label_callback9:
+ TIME_CHECK_CALLBACK_1(kTime1134000, CURRENT_PARAMS(1, 2), 10, setup_function9, "TRA1002");
+
+label_callback10:
+ TIME_CHECK_CALLBACK_1(kTime1165500, CURRENT_PARAMS(1, 3), 11, setup_function9, "TRA1003");
+
+label_callback11:
+ TIME_CHECK_CALLBACK_1(kTime1225800, CURRENT_PARAMS(1, 4), 12, setup_function9, "TRA1004");
+
+label_callback12:
+ if (ENTITY_PARAM(0, 5) && !params->param2) {
+ setCallback(13);
+ setup_talkGendarmes();
+ break;
+ }
+
+label_callback13:
+ if (getInventory()->hasItem(kItemPassengerList) && !params->param3 && (getState()->time < kTime1134000 || getState()->time > kTime1156500)) {
+ setCallback(14);
+ setup_talkPassengerList();
+ break;
+ }
+
+label_callback14:
+ if (ENTITY_PARAM(0, 3) && !params->param4 && (getState()->time < kTime1134000 || getState()->time > kTime1156500)) {
+ setCallback(15);
+ setup_function17();
+ break;
+ }
+
+label_callback15:
+ if (ENTITY_PARAM(0, 1) && !params->param5) {
+ if (getState()->time < kTime1134000 || getState()->time > kTime1156500) {
+ setCallback(16);
+ setup_function22();
+ }
+ }
+ break;
+
+ case kActionOpenDoor:
+ setCallback(17);
+ setup_function13(savepoint.param.intValue < 106 ? true : false);
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarBaggage;
+ getData()->entityPosition = kPosition_5000;
+ getData()->location = kLocationOutsideCompartment;
+
+ getEntities()->clearSequences(kEntityVerges);
+ getInventory()->setLocationAndProcess(kItem9, kObjectLocation1);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_callback1;
+
+ case 2:
+ goto label_callback2;
+
+ case 3:
+ goto label_callback3;
+
+ case 4:
+ goto label_callback4;
+
+ case 5:
+ setCallback(6);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_function15(kEntityMertens, "TRA1202");
+ break;
+
+ case 7:
+ setCallback(8);
+ setup_function11();
+ break;
+
+ case 8:
+ goto label_callback8;
+
+ case 9:
+ goto label_callback9;
+
+ case 10:
+ goto label_callback10;
+
+ case 11:
+ goto label_callback11;
+
+ case 12:
+ goto label_callback12;
+
+ case 13:
+ params->param2 = 1;
+ goto label_callback13;
+
+ case 14:
+ params->param3 = 1;
+ goto label_callback14;
+
+ case 15:
+ params->param4 = 1;
+ goto label_callback15;
+
+ case 16:
+ params->param5 = 1;
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(27, Verges, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter2Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityVerges);
+
+ getData()->entityPosition = kPosition_5000;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarBaggage;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObject104, kEntityVerges, kObjectLocationNone, kCursorNormal, kCursorHand);
+ getObjects()->update(kObject105, kEntityVerges, kObjectLocationNone, kCursorNormal, kCursorHand);
+
+ ENTITY_PARAM(0, 3) = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(28, Verges, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isInBaggageCarEntrance(kEntityPlayer)) {
+ setCallback(1);
+ setup_function13(false);
+ }
+
+label_callback_1:
+ TIME_CHECK_CALLBACK_1(kTime1818900, params->param1, 2, setup_function9, "Tra2177");
+
+label_callback_2:
+ if (params->param2 == kTimeInvalid || !getState()->time)
+ goto label_callback_6;
+
+ if (getState()->time > kTime1836000) {
+ params->param2 = kTimeInvalid;
+ setCallback(3);
+ setup_function12();
+ break;
+ }
+
+ if (!getEntities()->isPlayerInCar(kCarRedSleeping) || !params->param2) {
+ params->param2 = getState()->time;
+
+ if (!params->param2) {
+ setCallback(3);
+ setup_function12();
+ break;
+ }
+ }
+
+ if (params->param2 >= getState()->time) {
+label_callback_6:
+
+ if (ENTITY_PARAM(0, 3)) {
+ setCallback(7);
+ setup_function17();
+ }
+
+ break;
+ }
+
+ params->param2 = kTimeInvalid;
+ setCallback(3);
+ setup_function12();
+ break;
+
+ case kActionOpenDoor:
+ setCallback(8);
+ setup_function13(savepoint.param.intValue < 106);
+ break;
+
+ case kActionDefault:
+ getInventory()->setLocationAndProcess(kItem9, kObjectLocation1);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_callback_1;
+
+ case 2:
+ goto label_callback_2;
+
+ case 3:
+ setCallback(4);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_function15(kEntityCoudert, "TRA2100");
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_function11();
+ break;
+
+ case 6:
+ goto label_callback_6;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(29, Verges, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_function23();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityVerges);
+
+ getData()->entityPosition = kPosition_540;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObject104, kEntityVerges, kObjectLocationNone, kCursorNormal, kCursorHand);
+ getObjects()->update(kObject105, kEntityVerges, kObjectLocationNone, kCursorNormal, kCursorHand);
+
+ ENTITY_PARAM(0, 3) = 0;
+ ENTITY_PARAM(0, 4) = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(30, Verges, function30)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function12();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function15(kEntityCoudert, (char *)&params->seq1);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function11();
+ break;
+
+ case 4:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(31, Verges, function31)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function12();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function15(kEntityCoudert, "TRA3015");
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function11();
+ break;
+
+ case 4:
+ getProgress().field_48 = 1;
+ ENTITY_PARAM(0, 4) = 0;
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(32, Verges, function32)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CALLBACK_3(kTime2263500, params->param1, 5, setup_function10, kCarRedSleeping, kPosition_9460, "TRA3006");
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObject104, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorHand);
+ getObjects()->update(kObject105, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorHand);
+
+ if (getEntities()->isInBaggageCar(kEntityPlayer) || getEntities()->isInKitchen(kEntityPlayer)) {
+ getAction()->playAnimation(getEntities()->isInBaggageCar(kEntityPlayer) ? kEventVergesBaggageCarOffLimits : kEventVergesCanIHelpYou);
+ getSound()->playSound(kEntityPlayer, "BUMP");
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 65);
+ }
+
+ getScenes()->loadSceneFromItemPosition(kItem9);
+ getData()->car = kCarRestaurant;
+ getData()->entityPosition = kPosition_5900;
+
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->entityPosition = kPosition_8500;
+ getData()->location = kLocationOutsideCompartment;
+ getSound()->playSound(kEntityVerges, "TRA3004");
+
+ setCallback(2);
+ setup_draw("813DD");
+ break;
+
+ case 2:
+ if (!getSound()->isBuffered(kEntityVerges))
+ getSound()->playSound(kEntityVerges, "TRA3004");
+
+ getEntities()->drawSequenceRight(kEntityVerges, "813DS");
+
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityVerges);
+
+ setCallback(3);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_function10(kCarGreenSleeping, kPosition_540, "TRA3004");
+ break;
+
+ case 4:
+ getEntities()->clearSequences(kEntityVerges);
+ break;
+
+ case 5:
+ setCallback(6);
+ setup_function11();
+ break;
+
+ case 6:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(33, Verges, function33)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_draw("813US");
+ break;
+
+ case 2:
+ getEntities()->drawSequenceRight(kEntityVerges, "813UD");
+ if (getEntities()->isInSalon(kEntityPlayer))
+ getEntities()->updateFrame(kEntityVerges);
+
+ setCallback(3);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 3:
+ getEntities()->clearSequences(kEntityVerges);
+ getData()->location = kLocationInsideCompartment;
+ getData()->entityPosition = kPosition_5799;
+
+ setCallback(getProgress().field_3C ? 4 : 5);
+ setup_playSound(getProgress().field_3C ? "ABB3035A" : "ABB3035");
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_playSound("ABB3035");
+ break;
+
+ case 5:
+ getSavePoints()->push(kEntityVerges, kEntityAbbot, kAction192054567);
+
+ setCallback(6);
+ setup_function9("Tra3010");
+ break;
+
+ case 6:
+ setup_function34();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(34, Verges, function34)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isInBaggageCarEntrance(kEntityPlayer)) {
+ setCallback(1);
+ setup_function13(false);
+ break;
+ }
+
+label_callback_1:
+ if (ENTITY_PARAM(0, 4)) {
+ setCallback(2);
+ setup_function31();
+ break;
+ }
+
+label_callback_2:
+ if (ENTITY_PARAM(0, 3)) {
+ setCallback(3);
+ setup_function17();
+ break;
+ }
+
+label_callback_3:
+ TIME_CHECK_CALLBACK_1(kTime1971000, params->param1, 4, setup_function9, "Tra3001");
+
+label_callback_4:
+ TIME_CHECK_CALLBACK_1(kTime1998000, params->param2, 5, setup_function9, "Tra3010a");
+
+label_callback_5:
+ TIME_CHECK_CALLBACK(kTime2016000, params->param3, 6, setup_function35);
+
+label_callback_6:
+ TIME_CHECK_CALLBACK_1(kTime2070000, params->param4, 7, setup_function9, "Tra3002");
+
+label_callback_7:
+ TIME_CHECK_CALLBACK_1(kTime2142000, params->param5, 8, setup_function9, "Tra3003");
+
+label_callback_8:
+ TIME_CHECK_CALLBACK_1(kTime2173500, params->param6, 9, setup_function30, "Tra3012");
+
+label_callback_9:
+ TIME_CHECK_CALLBACK(kTime2218500, params->param7, 10, setup_function32);
+ break;
+
+ case kActionOpenDoor:
+ setCallback(11);
+ setup_function13(savepoint.param.intValue < 106);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_callback_1;
+
+ case 2:
+ goto label_callback_2;
+
+ case 3:
+ goto label_callback_3;
+
+ case 4:
+ goto label_callback_4;
+
+ case 5:
+ goto label_callback_5;
+
+ case 6:
+ goto label_callback_6;
+
+ case 7:
+ goto label_callback_7;
+
+ case 8:
+ goto label_callback_8;
+
+ case 9:
+ goto label_callback_9;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(35, Verges, function35)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function12();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function15(kEntityMertens, "Tra3011A");
+ break;
+
+ case 3:
+ getSavePoints()->push(kEntityVerges, kEntityCoudert, kAction188570113);
+
+ setCallback(4);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_function15(kEntityMertens, "Tra3011");
+ break;
+
+ case 5:
+ getSavePoints()->push(kEntityVerges, kEntityMertens, kAction188635520);
+
+ setCallback(6);
+ setup_function11();
+ break;
+
+ case 6:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(36, Verges, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityVerges);
+
+ getData()->entityPosition = kPosition_5000;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarBaggage;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObject104, kEntityVerges, kObjectLocationNone, kCursorNormal, kCursorHand);
+ getObjects()->update(kObject105, kEntityVerges, kObjectLocationNone, kCursorNormal, kCursorHand);
+
+ ENTITY_PARAM(0, 3) = 0;
+ ENTITY_PARAM(0, 6) = 0;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(37, Verges, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isInBaggageCarEntrance(kEntityPlayer)) {
+ setCallback(1);
+ setup_function13(false);
+ break;
+ }
+
+label_callback_1:
+ if (ENTITY_PARAM(0, 6)) {
+ if (ENTITY_PARAM(0, 3)) {
+ setCallback(2);
+ setup_function17();
+ break;
+ }
+
+label_callback_2:
+ TIME_CHECK_CALLBACK_1(kTime2349000, params->param1, 3, setup_function9, "Tra1001");
+
+label_callback_3:
+ TIME_CHECK_CALLBACK_1(kTime2378700, params->param2, 4, setup_function9, "Tra4001");
+
+label_callback_4:
+ TIME_CHECK_CALLBACK_1(kTime2403000, params->param3, 5, setup_function9, "Tra1001A");
+
+label_callback_5:
+ TIME_CHECK_CALLBACK_1(kTime2414700, params->param4, 6, setup_function9, "Tra4002");
+
+label_callback_6:
+ TIME_CHECK_CALLBACK_1(kTime2484000, params->param5, 7, setup_function9, "Tra4003");
+
+label_callback_7:
+ TIME_CHECK_CALLBACK_1(kTime2511000, params->param6, 8, setup_function9, "Tra4004");
+ }
+
+label_callback_8:
+ TIME_CHECK_CALLBACK_1(kTime2538000, params->param7, 9, setup_function9, "Tra4005");
+
+ break;
+
+ case kActionOpenDoor:
+ setCallback(10);
+ setup_function13(savepoint.param.intValue < 106);
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarBaggage;
+ getData()->entityPosition = kPosition_5000;
+ getData()->location = kLocationOutsideCompartment;
+
+ getInventory()->setLocationAndProcess(kItem9, kObjectLocation1);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ goto label_callback_1;
+
+ case 2:
+ goto label_callback_2;
+
+ case 3:
+ goto label_callback_3;
+
+ case 4:
+ goto label_callback_4;
+
+ case 5:
+ goto label_callback_5;
+
+ case 6:
+ goto label_callback_6;
+
+ case 7:
+ goto label_callback_7;
+
+ case 8:
+ goto label_callback_8;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(38, Verges, function38)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObject104, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorHand);
+ getObjects()->update(kObject105, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorHand);
+ getScenes()->loadSceneFromItemPosition(kItem9);
+ getEntities()->clearSequences(kEntityVerges);
+
+ getData()->entityPosition = kPosition_6469;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->clearSequences(kEntityVerges);
+ setCallback(2);
+ setup_updateFromTime(1800);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function11();
+ break;
+
+ case 3:
+ setup_chapter4Handler();
+ break;
+ }
+ break;
+
+ case kAction125233040:
+ getData()->entityPosition = kPosition_5790;
+
+ setCallback(1);
+ setup_updateEntity(kCarGreenSleeping, kPosition_540);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(39, Verges, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityVerges);
+
+ getData()->entityPosition = kPosition_3650;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObject104, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorHand);
+ getObjects()->update(kObject105, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorHand);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(40, Verges, chapter5Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getEntities()->isInSalon(kEntityPlayer) && !getSound()->isBuffered(kEntityVerges))
+ getSound()->playSound(kEntityVerges, "WAT5000");
+ break;
+
+ case kActionOpenDoor:
+ if (getSound()->isBuffered(kEntityVerges))
+ getSound()->processEntry(kEntityVerges);
+
+ if (getSound()->isBuffered("MUS050"))
+ getSound()->processEntry("MUS050");
+
+ getObjects()->update(kObject65, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventCathFreePassengers);
+ break;
+
+ case kActionDefault:
+ getScenes()->loadSceneFromItemPosition(kItem9);
+ getObjects()->update(kObject65, kEntityVerges, kObjectLocation1, kCursorNormal, kCursorForward);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventCathFreePassengers);
+ getSavePoints()->pushAll(kEntityVerges, kActionProceedChapter5);
+ getScenes()->loadSceneFromPosition(kCarRedSleeping, 40);
+ setup_function41();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(41, Verges, function41)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getObjects()->updateLocation2(kObjectRestaurantCar, kObjectLocation3);
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_9460;
+ getData()->location = kLocationInsideCompartment;
+
+ setCallback(1);
+ setup_function10(kCarRedSleeping, kPosition_2000, "Tra5001");
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getEntities()->drawSequenceLeft(kEntityVerges, "620E");
+ // Fallback to next case
+
+ case 2:
+ if (getSound()->isBuffered(kEntityVerges)) {
+ setCallback(2);
+ setup_updateFromTime(225);
+ } else {
+ setCallback(3);
+ setup_playSound("Con5001");
+ }
+ break;
+
+ case 3:
+ getSavePoints()->push(kEntityVerges, kEntityCoudert, kAction155991520);
+
+ setCallback(4);
+ setup_updateEntity(kCarBaggageRear, kPosition_9460);
+ break;
+
+ case 4:
+ setup_function42();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(42, Verges, function42)
+ if (savepoint.action == kActionDefault)
+ getEntities()->clearSequences(kEntityVerges);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// Private functions
+//////////////////////////////////////////////////////////////////////////
+void Verges::talk(const SavePoint &savepoint, const char *sound1, const char *sound2) {
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_function12();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarRedSleeping, kPosition_2000);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_function15(kEntityCoudert, sound1);
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_updateEntity(kCarGreenSleeping, kPosition_2000);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_function15(kEntityMertens, sound2);
+ break;
+
+ case 5:
+ setup_function11();
+ break;
+
+ case 6:
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/verges.h b/engines/lastexpress/entities/verges.h
new file mode 100644
index 0000000000..3162d4e0ea
--- /dev/null
+++ b/engines/lastexpress/entities/verges.h
@@ -0,0 +1,182 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_VERGES_H
+#define LASTEXPRESS_VERGES_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Verges : public Entity {
+public:
+ Verges(LastExpressEngine *engine);
+ ~Verges() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Draws the entity
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(draw, const char* sequence)
+
+ /**
+ * Process callback action when the entity direction is not kDirectionRight
+ */
+ DECLARE_FUNCTION(callbackActionOnDirection)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Plays sound
+ *
+ * @param savepoint The savepoint
+ * - the sound filename
+ */
+ DECLARE_FUNCTION_NOSETUP(playSound16)
+
+ /**
+ * Process callback action when somebody is standing in the restaurant or salon.
+ */
+ DECLARE_FUNCTION(callbackActionRestaurantOrSalon)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ DECLARE_FUNCTION_1(function9, const char *soundName)
+ DECLARE_FUNCTION_3(function10, CarIndex car, EntityPosition entityPosition, const char *soundName)
+ DECLARE_FUNCTION(function11)
+ DECLARE_FUNCTION(function12)
+ DECLARE_FUNCTION_1(function13, bool)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param time The time to add
+ */
+ DECLARE_FUNCTION_1(updateFromTime, uint32 time)
+
+ DECLARE_FUNCTION_2(function15, EntityIndex entity, const char *soundName)
+ DECLARE_FUNCTION_3(function16, EntityIndex entityIndex, const char *soundName1, const char *soundName2)
+ DECLARE_FUNCTION(function17)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ DECLARE_FUNCTION_NOSETUP(talkHarem)
+ DECLARE_FUNCTION(talkPassengerList)
+ DECLARE_FUNCTION(talkGendarmes)
+ DECLARE_FUNCTION(function22)
+ DECLARE_FUNCTION(function23)
+ DECLARE_FUNCTION(policeGettingOffTrain)
+ DECLARE_FUNCTION(function25)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ DECLARE_FUNCTION_1(function30, const char *soundName)
+ DECLARE_FUNCTION(function31)
+ DECLARE_FUNCTION(function32)
+ DECLARE_FUNCTION(function33)
+ DECLARE_FUNCTION(function34)
+ DECLARE_FUNCTION(function35)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ DECLARE_FUNCTION(function38)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_FUNCTION(function41)
+ DECLARE_FUNCTION(function42)
+
+private:
+ void talk(const SavePoint &savepoint, const char* sound1, const char* sound2);
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_VERGES_H
diff --git a/engines/lastexpress/entities/vesna.cpp b/engines/lastexpress/entities/vesna.cpp
new file mode 100644
index 0000000000..9e0ef09a08
--- /dev/null
+++ b/engines/lastexpress/entities/vesna.cpp
@@ -0,0 +1,1161 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/vesna.h"
+
+#include "lastexpress/game/action.h"
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/fight.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+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(Vesna, callbackActionRestaurantOrSalon);
+ ADD_CALLBACK_FUNCTION(Vesna, callbackActionOnDirection);
+ ADD_CALLBACK_FUNCTION(Vesna, savegame);
+ ADD_CALLBACK_FUNCTION(Vesna, function11);
+ ADD_CALLBACK_FUNCTION(Vesna, chapter1);
+ ADD_CALLBACK_FUNCTION(Vesna, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Vesna, function14);
+ ADD_CALLBACK_FUNCTION(Vesna, function15);
+ ADD_CALLBACK_FUNCTION(Vesna, chapter2);
+ ADD_CALLBACK_FUNCTION(Vesna, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Vesna, function18);
+ ADD_CALLBACK_FUNCTION(Vesna, chapter3);
+ ADD_CALLBACK_FUNCTION(Vesna, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Vesna, function21);
+ ADD_CALLBACK_FUNCTION(Vesna, function22);
+ ADD_CALLBACK_FUNCTION(Vesna, function23);
+ ADD_CALLBACK_FUNCTION(Vesna, chapter4);
+ ADD_CALLBACK_FUNCTION(Vesna, function25);
+ ADD_CALLBACK_FUNCTION(Vesna, function26);
+ ADD_CALLBACK_FUNCTION(Vesna, function27);
+ ADD_CALLBACK_FUNCTION(Vesna, chapter5);
+ ADD_CALLBACK_FUNCTION(Vesna, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(Vesna, function30);
+ ADD_NULL_FUNCTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Vesna, reset)
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(2, Vesna, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(3, Vesna, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(4, Vesna, draw)
+ Entity::draw(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(5, Vesna, updateEntity, CarIndex, EntityPosition)
+ if (savepoint.action == kActionExcuseMeCath) {
+ getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT10150" : "CAT1015A");
+
+ return;
+ }
+
+ Entity::updateEntity(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_I(6, Vesna, updateFromTime, uint32)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(7, Vesna, updateEntity2, CarIndex, EntityPosition)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ 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()->field_49B = 0;
+ params->param3 = 1;
+ }
+
+ if (!params->param3)
+ getEntities()->updateEntity(kEntityVesna, (CarIndex)params->param1, (EntityPosition)params->param2);
+ break;
+
+ case kActionDefault:
+ getEntities()->updateEntity(kEntityVesna, (CarIndex)params->param1, (EntityPosition)params->param2);
+ break;
+
+ case kAction123668192:
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(8, Vesna, callbackActionRestaurantOrSalon)
+ Entity::callbackActionRestaurantOrSalon(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(9, Vesna, callbackActionOnDirection)
+ Entity::callbackActionOnDirection(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(10, Vesna, savegame, SavegameType, uint32)
+ Entity::savegame(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Vesna, function11)
+ // Expose parameters as IIIS and ignore the default exposed parameters
+ EntityData::EntityParametersIIIS *parameters = (EntityData::EntityParametersIIIS*)_data->getCurrentParameters();
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (parameters->param3) {
+ UPDATE_PARAM(parameters->param7, getState()->timeTicks, 75);
+
+ parameters->param2 = 1;
+ parameters->param3 = 0;
+ getObjects()->update(kObjectCompartmentG, kEntityVesna, kObjectLocation1, kCursorNormal, kCursorNormal);
+ }
+
+ parameters->param7 = 0;
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ if (parameters->param3) {
+ getObjects()->update(kObjectCompartmentG, kEntityVesna, kObjectLocation3, kCursorNormal, kCursorNormal);
+
+ setCallback(4);
+ setup_playSound(getSound()->wrongDoorCath());
+ break;
+ }
+
+ parameters->param1++;
+ switch (parameters->param1) {
+ default:
+ strcpy((char *)&parameters->seq, "VES1015C");
+ parameters->param1 = 0;
+ break;
+
+ case 1:
+ strcpy((char *)&parameters->seq, "VES1015A");
+ break;
+
+ case 2:
+ strcpy((char *)&parameters->seq, "VES1015B");
+ break;
+ }
+
+ getObjects()->update(kObjectCompartmentG, kEntityVesna, kObjectLocation3, kCursorNormal, kCursorNormal);
+
+ setCallback(savepoint.action == kActionKnock ? 2 : 1);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObjectCompartmentG, kEntityVesna, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionDrawScene:
+ if (parameters->param2 || parameters->param3) {
+ getObjects()->update(kObjectCompartmentG, kEntityVesna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+
+ parameters->param2 = 0;
+ parameters->param3 = 0;
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ setCallback(3);
+ setup_playSound((char *)&parameters->seq);
+ break;
+
+ case 3:
+ getObjects()->update(kObjectCompartmentG, kEntityVesna, kObjectLocation3, kCursorTalk, kCursorNormal);
+ parameters->param3 = 1;
+ break;
+
+ case 4:
+ parameters->param2 = 1;
+ parameters->param3 = 0;
+ break;
+ }
+ break;
+
+ case kAction55996766:
+ case kAction101687594:
+ CALLBACK_ACTION();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Vesna, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getSavePoints()->addData(kEntityVesna, kAction124190740, 0);
+
+ getData()->entityPosition = kPosition_4689;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Vesna, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ getData()->entityPosition = getEntityData(kEntityMilos)->entityPosition;
+ getData()->location = getEntityData(kEntityMilos)->location;
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getEntities()->clearSequences(kEntityVesna);
+ setup_function14();
+ }
+ break;
+
+ case kAction204832737:
+ setCallback(1);
+ setup_updateEntity2(kCarRedSleeping, kPosition_3050);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Vesna, function14)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ break;
+
+ case kAction190412928:
+ setCallback(1);
+ setup_function11();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Vesna, function15)
+ if (savepoint.action == kActionDefault) {
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+
+ getEntities()->clearSequences(kEntityVesna);
+ getObjects()->update(kObjectCompartmentG, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Vesna, chapter2)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter2Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityVesna);
+
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Vesna, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kAction135024800:
+ setCallback(2);
+ setup_function18();
+ break;
+
+ case kAction137165825:
+ setCallback(1);
+ setup_function11();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Vesna, function18)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_enterExitCompartment("610Bg", kObjectCompartmentG);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ if (getData()->entityPosition < kPosition_2087)
+ getData()->entityPosition = kPosition_2088;
+
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(4);
+ setup_draw("808US");
+ break;
+
+ case 4:
+ getEntities()->drawSequenceRight(kEntityVesna, "808UD");
+ if (getEntities()->isInSalon(kEntityPlayer))
+ getEntities()->updateFrame(kEntityVesna);
+
+ setCallback(5);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 5:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityVesna);
+
+ setCallback(6);
+ setup_updateFromTime(4500);
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 7:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(8);
+ setup_draw("808DD");
+ break;
+
+ case 8:
+ getEntities()->drawSequenceRight(kEntityVesna, "808DS");
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityVesna);
+
+ setCallback(9);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 9:
+ setCallback(10);
+ setup_updateEntity(kCarRedSleeping, kPosition_3050);
+ break;
+
+ case 10:
+ setCallback(11);
+ setup_enterExitCompartment("610Ag", kObjectCompartmentG);
+ break;
+
+ case 11:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityVesna);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Vesna, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityVesna);
+
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Vesna, chapter3Handler)
+ EntityData::EntityParametersIIIS *parameters = (EntityData::EntityParametersIIIS*)_data->getCurrentParameters();
+
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getProgress().field_54 && parameters->param7 != kTimeInvalid) {
+ if (getState()->time > kTime2250000) {
+ parameters->param7 = kTimeInvalid;
+ setup_function22();
+ break;
+ }
+
+ if (!getEntities()->isPlayerInCar(kCarRedSleeping) || !parameters->param7)
+ parameters->param7 = getState()->time;
+
+ if (parameters->param7 < getState()->time) {
+ parameters->param7 = kTimeInvalid;
+ setup_function22();
+ break;
+ }
+ }
+
+ if (parameters->param2) {
+ UPDATE_PARAM(parameters->param8, getState()->timeTicks, 75);
+
+ parameters->param1 = 1;
+ parameters->param2 = 0;
+
+ getObjects()->update(kObjectCompartmentG, kEntityVesna, kObjectLocation1, kCursorNormal, kCursorNormal);
+ }
+
+ parameters->param8 = 0;
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ if (parameters->param2) {
+ getObjects()->update(kObjectCompartmentG, kEntityVesna, kObjectLocation3, kCursorNormal, kCursorNormal);
+
+ setCallback(4);
+ setup_playSound(getSound()->wrongDoorCath());
+ break;
+ }
+
+ ++parameters->param3;
+
+ switch (parameters->param3) {
+ default:
+ break;
+
+ case 1:
+ strcpy((char *)&parameters->seq, "VES1015A");
+ break;
+
+ 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);
+
+ setCallback(savepoint.action == kActionKnock ? 2 : 1);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ getEntities()->clearSequences(kEntityVesna);
+ break;
+
+ case kActionDrawScene:
+ if (parameters->param1 || parameters->param2) {
+ getObjects()->update(kObjectCompartmentG, kEntityVesna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+ parameters->param1 = 0;
+ parameters->param2 = 0;
+ }
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ setCallback(3);
+ setup_playSound((char *)&parameters->seq);
+ break;
+
+ case 3:
+ getObjects()->update(kObjectCompartmentG, kEntityVesna, kObjectLocation3, kCursorTalk, kCursorNormal);
+ parameters->param2 = 1;
+ break;
+
+ case 4:
+ parameters->param1 = 1;
+ parameters->param2 = 0;
+ break;
+ }
+ break;
+
+ case kAction137165825:
+ setCallback(5);
+ setup_function11();
+ break;
+
+ case kAction155913424:
+ setCallback(6);
+ setup_function21();
+ break;
+
+ case kAction203663744:
+ getObjects()->update(kObjectCompartmentG, kEntityVesna, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Vesna, function21)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_enterExitCompartment("610Bg", kObjectCompartmentG);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ if (getData()->entityPosition < kPosition_2087)
+ getData()->entityPosition = kPosition_2088;
+
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(4);
+ setup_draw("808US");
+ break;
+
+ case 4:
+ getEntities()->drawSequenceRight(kEntityVesna, "808UD");
+ if (getEntities()->isInSalon(kEntityPlayer))
+ getEntities()->updateFrame(kEntityVesna);
+
+ setCallback(5);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 5:
+ getEntities()->clearSequences(kEntityVesna);
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationInsideCompartment;
+
+ setCallback(6);
+ setup_updateFromTime(4500);
+ break;
+
+ case 6:
+ setCallback(7);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 7:
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(8);
+ setup_draw("808DD");
+ break;
+
+ case 8:
+ getEntities()->drawSequenceRight(kEntityVesna, "808DS");
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityVesna);
+
+ setCallback(9);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 9:
+ setCallback(10);
+ setup_updateEntity(kCarRedSleeping, kPosition_3050);
+ break;
+
+ case 10:
+ setCallback(11);
+ setup_enterExitCompartment("610Ag", kObjectCompartmentG); /* BUG the original engine passes 3050 here */
+ break;
+
+ case 11:
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityVesna);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(22, Vesna, function22)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityVesna, kEntityMilos, kAction259125998);
+
+ setCallback(1);
+ setup_enterExitCompartment("610Bg", kObjectCompartmentG);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ if (getData()->entityPosition < kPosition_2087)
+ getData()->entityPosition = kPosition_2088;
+
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(4);
+ setup_draw("808US");
+ break;
+
+ case 4:
+ getEntities()->drawSequenceRight(kEntityVesna, "808UD");
+ if (getEntities()->isInSalon(kEntityPlayer))
+ getEntities()->updateFrame(kEntityVesna);
+
+ setCallback(5);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 5:
+ getEntities()->clearSequences(kEntityVesna);
+ getData()->car = kCarBaggage;
+ getSavePoints()->push(kEntityVesna, kEntityAnna, kAction235856512);
+ break;
+
+ case 6:
+ getData()->car = kCarRestaurant;
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(7);
+ setup_draw("808DD");
+ break;
+
+ case 7:
+ getEntities()->drawSequenceRight(kEntityVesna, "808DS");
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityVesna);
+
+ setCallback(8);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 8:
+ setCallback(9);
+ setup_updateEntity(kCarRedSleeping, kPosition_3050);
+ break;
+
+ case 9:
+ setCallback(10);
+ setup_enterExitCompartment("610Ag", kObjectCompartmentG); /* BUG the original engine passes 3050 here */
+ break;
+
+ case 10:
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityVesna);
+
+ setup_function23();
+ break;
+ }
+ break;
+
+ case kAction189299008:
+ setCallback(6);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(23, Vesna, function23)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionKnock:
+ case kActionOpenDoor:
+ getObjects()->update(kObjectCompartmentG, kEntityVesna, kObjectLocation3, kCursorNormal, kCursorNormal);
+ setCallback(savepoint.action == kActionKnock ? 1 : 2);
+ setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+ break;
+
+ case kActionDefault:
+ getData()->car = kCarRedSleeping;
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ setCallback(3);
+ setup_playSound("VES1015A");
+ break;
+
+ case 3:
+ getObjects()->update(kObjectCompartmentG, kEntityVesna, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ break;
+ }
+ break;
+
+ case kAction203663744:
+ getObjects()->update(kObjectCompartmentG, kEntityVesna, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(24, Vesna, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setCallback(1);
+ setup_function11();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityVesna);
+
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->inventoryItem = kItemNone;
+
+ getObjects()->update(kObjectCompartmentG, kEntityVesna, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1)
+ setup_function25();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(25, Vesna, function25)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (getState()->time > kTime2428200 && !params->param1) {
+ params->param1 = 1;
+ setup_function26();
+ }
+ break;
+
+ case kActionDefault:
+ getSavePoints()->push(kEntityVesna, kEntityMilos, kAction135600432);
+
+ setCallback(1);
+ setup_enterExitCompartment("610BG", kObjectCompartmentG);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->location = kLocationOutsideCompartment;
+ if (getData()->entityPosition < kPosition_2087)
+ getData()->entityPosition = kPosition_2088;
+
+ setCallback(2);
+ setup_updateEntity(kCarRestaurant, kPosition_850);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case 3:
+ getData()->entityPosition = kPosition_1540;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(4);
+ setup_draw("808US");
+ break;
+
+ case 4:
+ getEntities()->drawSequenceRight(kEntityVesna, "808UD");
+ if (getEntities()->isInSalon(kEntityPlayer))
+ getEntities()->updateFrame(kEntityVesna);
+
+ setCallback(5);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 5:
+ getEntities()->clearSequences(kEntityVesna);
+ getData()->entityPosition = kPosition_5900;
+ getData()->location = kLocationInsideCompartment;
+
+ // Original game calls clearSequences a second time
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(26, Vesna, function26)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ setCallback(1);
+ setup_callbackActionRestaurantOrSalon();
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->car = kCarRestaurant;
+ getData()->entityPosition = kPosition_5800;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(2);
+ setup_draw("808DD");
+ break;
+
+ case 2:
+ getEntities()->drawSequenceRight(kEntityVesna, "808DS");
+
+ if (getEntities()->isInRestaurant(kEntityPlayer))
+ getEntities()->updateFrame(kEntityVesna);
+
+ setCallback(3);
+ setup_callbackActionOnDirection();
+ break;
+
+ case 3:
+ setCallback(4);
+ setup_updateEntity(kCarRedSleeping, kPosition_3050);
+ break;
+
+ case 4:
+ setCallback(5);
+ setup_enterExitCompartment("610AG", kObjectCompartmentG);
+ break;
+
+ case 5:
+ setup_function27();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(27, Vesna, function27)
+ if (savepoint.action == kActionDefault) {
+ getEntities()->clearSequences(kEntityVesna);
+ getObjects()->update(kObjectCompartmentG, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRedSleeping;
+ getData()->inventoryItem = kItemNone;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(28, Vesna, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityVesna);
+
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(29, Vesna, chapter5Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionOpenDoor:
+ setCallback(1);
+
+ getData()->currentCall++;
+ setup_savegame(kSavegameTypeEvent, kEventCathVesnaRestaurantKilled);
+ break;
+
+ case kActionDefault:
+ getObjects()->update(kObject64, kEntityVesna, kObjectLocationNone, kCursorNormal, kCursorForward);
+ break;
+
+ case kActionCallback:
+ if (getCallback() == 1) {
+ getAction()->playAnimation(kEventCathVesnaRestaurantKilled);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneNone, true);
+ }
+ break;
+
+ case kAction134427424:
+ getObjects()->update(kObject64, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
+ setup_function30();
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(30, Vesna, function30)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ if (!params->param1) {
+ UPDATE_PARAM_PROC(params->param3, getState()->timeTicks, 120)
+ getSound()->playSound(kEntityVesna, "Ves50001", SoundManager::kFlagDefault);
+ params->param1 = 1;
+ UPDATE_PARAM_PROC_END
+ }
+
+ UPDATE_PARAM(params->param4, getState()->timeTicks, 180);
+
+ setCallback(1);
+ setup_savegame(kSavegameTypeEvent, kEventCathVesnaTrainTopKilled);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ case 2:
+ getAction()->playAnimation(kEventCathVesnaTrainTopKilled);
+ getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneNone, true);
+ break;
+
+ case 3:
+ getAction()->playAnimation(kEventCathVesnaTrainTopFight);
+
+ setCallback(4);
+ setup_savegame(kSavegameTypeTime, kTimeNone);
+ break;
+
+ case 4:
+ params->param2 = getFight()->setup(kFightVesna);
+
+ if (params->param2) {
+ getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, params->param2 != Fight::kFightEndExit);
+ } else {
+ getSound()->playSound(kEntityPlayer, "TUNNEL");
+
+ getState()->time += 1800;
+
+ setCallback(5);
+ setup_savegame(kSavegameTypeEvent, kEventCathVesnaTrainTopWin);
+ }
+ break;
+
+ case 5:
+ getAction()->playAnimation(kEventCathVesnaTrainTopWin);
+ getScenes()->loadSceneFromPosition(kCarRestaurant, 11);
+
+ setup_nullfunction();
+ break;
+ }
+ break;
+
+ case kAction167992577:
+ setCallback(3);
+ setup_savegame(kSavegameTypeEvent, kEventCathVesnaTrainTopFight);
+ break;
+
+ case kAction202884544:
+ if (params->param1) {
+ setCallback(2);
+ setup_savegame(kSavegameTypeEvent, kEventCathVesnaTrainTopKilled);
+ } else {
+ getSound()->playSound(kEntityVesna, "Ves5001", SoundManager::kFlagDefault);
+ params->param1 = 1;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_NULL_FUNCTION(31, Vesna)
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/vesna.h b/engines/lastexpress/entities/vesna.h
new file mode 100644
index 0000000000..4a0a8550b2
--- /dev/null
+++ b/engines/lastexpress/entities/vesna.h
@@ -0,0 +1,176 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_VESNA_H
+#define LASTEXPRESS_VESNA_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Vesna : public Entity {
+public:
+ Vesna(LastExpressEngine *engine);
+ ~Vesna() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+
+ /**
+ * Draws the entity
+ *
+ * @param sequence The sequence to draw
+ */
+ DECLARE_FUNCTION_1(draw, const char* sequence)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param time The time to add
+ */
+ DECLARE_FUNCTION_1(updateFromTime, uint32 time)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity2, CarIndex car, EntityPosition entityPosition)
+
+ /**
+ * Process callback action when somebody is standing in the restaurant or salon.
+ */
+ DECLARE_FUNCTION(callbackActionRestaurantOrSalon)
+
+ /**
+ * Process callback action when the entity direction is not kDirectionRight
+ */
+ DECLARE_FUNCTION(callbackActionOnDirection)
+
+ /**
+ * Saves the game
+ *
+ * @param savegameType The type of the savegame
+ * @param param The param for the savegame (EventIndex or TimeValue)
+ */
+ DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
+
+ DECLARE_FUNCTION(function11)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function14)
+ DECLARE_FUNCTION(function15)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+
+ DECLARE_FUNCTION(function18)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ DECLARE_FUNCTION(function21)
+ DECLARE_FUNCTION(function22)
+ DECLARE_FUNCTION(function23)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ DECLARE_FUNCTION(function25)
+ DECLARE_FUNCTION(function26)
+ DECLARE_FUNCTION(function27)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_FUNCTION(function30)
+ DECLARE_NULL_FUNCTION()
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_VESNA_H
diff --git a/engines/lastexpress/entities/yasmin.cpp b/engines/lastexpress/entities/yasmin.cpp
new file mode 100644
index 0000000000..fe7c7fb2bf
--- /dev/null
+++ b/engines/lastexpress/entities/yasmin.cpp
@@ -0,0 +1,490 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lastexpress/entities/yasmin.h"
+
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/helpers.h"
+
+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(Yasmin, function6);
+ ADD_CALLBACK_FUNCTION(Yasmin, function7);
+ ADD_CALLBACK_FUNCTION(Yasmin, chapter1);
+ ADD_CALLBACK_FUNCTION(Yasmin, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Yasmin, function10);
+ ADD_CALLBACK_FUNCTION(Yasmin, chapter2);
+ ADD_CALLBACK_FUNCTION(Yasmin, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Yasmin, chapter3);
+ ADD_CALLBACK_FUNCTION(Yasmin, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Yasmin, chapter4);
+ ADD_CALLBACK_FUNCTION(Yasmin, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Yasmin, function17);
+ ADD_CALLBACK_FUNCTION(Yasmin, chapter5);
+ ADD_CALLBACK_FUNCTION(Yasmin, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(Yasmin, function20);
+ ADD_CALLBACK_FUNCTION(Yasmin, function21);
+ ADD_NULL_FUNCTION();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(1, Yasmin, reset)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionExcuseMeCath:
+ getSound()->excuseMeCath();
+ break;
+
+ case kActionExcuseMe:
+ getSound()->excuseMe(kEntityYasmin);
+ break;
+ }
+
+ // Process default actions
+ Entity::reset(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_SI(2, Yasmin, enterExitCompartment, ObjectIndex)
+ Entity::enterExitCompartment(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_S(3, Yasmin, playSound)
+ Entity::playSound(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_NOSETUP(4, Yasmin, updateFromTime)
+ Entity::updateFromTime(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION_II(5, Yasmin, updateEntity, CarIndex, EntityPosition)
+ Entity::updateEntity(savepoint, true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(6, Yasmin, function6)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_4840;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_enterExitCompartment("615Be", kObjectCompartment5);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarGreenSleeping, kPosition_3050);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_enterExitCompartment("615Ag", kObjectCompartment7);
+ break;
+
+ case 3:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityYasmin);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(7, Yasmin, function7)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationOutsideCompartment;
+
+ setCallback(1);
+ setup_enterExitCompartment("615Bg", kObjectCompartment7);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ setCallback(2);
+ setup_updateEntity(kCarGreenSleeping, kPosition_4840);
+ break;
+
+ case 2:
+ setCallback(3);
+ setup_enterExitCompartment("615Ae", kObjectCompartment5);
+ break;
+
+ case 3:
+ getData()->location = kLocationInsideCompartment;
+ getEntities()->clearSequences(kEntityYasmin);
+
+ CALLBACK_ACTION();
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(8, Yasmin, chapter1)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CHAPTER1(setup_chapter1Handler);
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_4840;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(9, Yasmin, chapter1Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CALLBACK(kTime1093500, params->param1, 1, setup_function6);
+ TIME_CHECK_CALLBACK(kTime1161000, params->param2, 3, setup_function7);
+ TIME_CHECK_PLAYSOUND_UPDATEPOSITION(kTime1162800, params->param3, 4, "Har1102", kPosition_4070);
+ TIME_CHECK_PLAYSOUND(kTime1165500, params->param4, 5, "Har1104");
+ TIME_CHECK_PLAYSOUND(kTime1174500, params->param5, 6, "Har1106");
+ TIME_CHECK_CALLBACK(kTime1183500, params->param6, 7, setup_function6);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->entityPosition = kPosition_2740;
+ setCallback(2);
+ setup_playSound("Har1102");
+ break;
+
+ case 2:
+ TIME_CHECK_CALLBACK(kTime1161000, params->param2, 3, setup_function7);
+ // Fallback to case 3
+
+ case 3:
+ TIME_CHECK_PLAYSOUND_UPDATEPOSITION(kTime1162800, params->param3, 4, "Har1102", kPosition_4070);
+ // Fallback to case 4
+
+ case 4:
+ TIME_CHECK_PLAYSOUND(kTime1165500, params->param4, 5, "Har1104");
+ // Fallback to case 5
+
+ case 5:
+ TIME_CHECK_PLAYSOUND(kTime1174500, params->param5, 6, "Har1106");
+ // Fallback to case 6
+
+ case 6:
+ TIME_CHECK_CALLBACK(kTime1183500, params->param6, 7, setup_function6);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(10, Yasmin, function10)
+ if (savepoint.action == kActionDefault) {
+ getObjects()->update(kObjectCompartment7, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+
+ getEntities()->clearSequences(kEntityYasmin);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(11, Yasmin, chapter2)
+ if (savepoint.action == kActionDefault) {
+ getEntities()->clearSequences(kEntityYasmin);
+
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+
+ setup_chapter2Handler();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(12, Yasmin, chapter2Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CALLBACK(kTime1759500, params->param1, 1, setup_function7);
+
+ if (getState()->time > kTime1800000 && !params->param2) {
+ params->param2 = 1;
+ getData()->entityPosition = kPosition_4070;
+
+ getSavePoints()->push(kEntityYasmin, kEntityTrain, kAction191070912, kPosition_4070);
+ }
+ break;
+
+ case kActionCallback:
+
+ if (getCallback() != 1)
+ break;
+
+ if (getState()->time > kTime1800000 && !params->param2) {
+ params->param2 = 1;
+ getData()->entityPosition = kPosition_4070;
+
+ getSavePoints()->push(kEntityYasmin, kEntityTrain, kAction191070912, kPosition_4070);
+ }
+
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(13, Yasmin, chapter3)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter3Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityYasmin);
+
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(14, Yasmin, chapter3Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CALLBACK(kTime2062800, params->param1, 1, setup_function6);
+ TIME_CHECK_CALLBACK(kTime2106000, params->param2, 2, setup_function7);
+ TIME_CHECK_CALLBACK(kTime2160000, params->param3, 3, setup_function6);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ TIME_CHECK_CALLBACK(kTime2106000, params->param2, 2, setup_function7);
+ // Fallback to case 2
+
+ case 2:
+ TIME_CHECK_CALLBACK(kTime2160000, params->param3, 3, setup_function6);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(15, Yasmin, chapter4)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter4Handler();
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_3050;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(16, Yasmin, chapter4Handler)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ TIME_CHECK_CALLBACK(kTime2457000, params->param1, 1, setup_function7);
+ TIME_CHECK_CALLBACK(kTime2479500, params->param2, 3, setup_function6);
+ break;
+
+ case kActionCallback:
+ switch (getCallback()) {
+ default:
+ break;
+
+ case 1:
+ getData()->entityPosition = kPosition_4070;
+ setCallback(2);
+ setup_playSound("Har1110");
+ break;
+
+ case 2:
+ TIME_CHECK_CALLBACK(kTime2479500, params->param2, 3, setup_function6);
+ break;
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(17, Yasmin, function17)
+ // Same as existing function 10 ?
+ function10(savepoint);
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(18, Yasmin, chapter5)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ setup_chapter5Handler();
+ break;
+
+ case kActionDefault:
+ getEntities()->clearSequences(kEntityYasmin);
+
+ getData()->entityPosition = kPosition_3969;
+ getData()->location = kLocationInsideCompartment;
+ getData()->car = kCarRestaurant;
+ getData()->clothes = kClothesDefault;
+ getData()->inventoryItem = kItemNone;
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(19, Yasmin, chapter5Handler)
+ if (savepoint.action == kActionProceedChapter5)
+ setup_function20();
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(20, Yasmin, function20)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ UPDATE_PARAM(params->param1, getState()->time, 2700);
+ setup_function21();
+ break;
+
+ case kActionDefault:
+ getData()->entityPosition = kPosition_2500;
+ getData()->location = kLocationOutsideCompartment;
+ getData()->car = kCarGreenSleeping;
+ break;
+
+ case kActionDrawScene:
+ if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarGreenSleeping)) {
+ setup_function21();
+ }
+ break;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_FUNCTION(21, Yasmin, function21)
+ switch (savepoint.action) {
+ default:
+ break;
+
+ case kActionNone:
+ case kActionDefault:
+ if (getEntities()->updateEntity(kEntityYasmin, (CarIndex)params->param1, (EntityPosition)params->param2))
+ CALLBACK_ACTION();
+ break;
+
+ case kActionExcuseMeCath:
+ getSound()->excuseMeCath();
+ break;
+
+ case kActionExcuseMe:
+ getSound()->excuseMe(kEntityYasmin);
+ break;
+ }
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/yasmin.h b/engines/lastexpress/entities/yasmin.h
new file mode 100644
index 0000000000..125b11d566
--- /dev/null
+++ b/engines/lastexpress/entities/yasmin.h
@@ -0,0 +1,142 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef LASTEXPRESS_YASMIN_H
+#define LASTEXPRESS_YASMIN_H
+
+#include "lastexpress/entities/entity.h"
+#include "lastexpress/entities/entity_intern.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+
+class Yasmin : public Entity {
+public:
+ Yasmin(LastExpressEngine *engine);
+ ~Yasmin() {};
+
+ /**
+ * Resets the entity
+ */
+ DECLARE_FUNCTION(reset)
+
+ /**
+ * Handles entering/exiting a compartment.
+ *
+ * @param sequence The sequence to draw
+ * @param compartment The compartment
+ */
+ DECLARE_FUNCTION_2(enterExitCompartment, const char* sequence, ObjectIndex compartment)
+
+ /**
+ * Plays sound
+ *
+ * @param filename The sound filename
+ */
+ DECLARE_FUNCTION_1(playSound, const char* filename)
+
+ /**
+ * Updates parameter 2 using time value
+ *
+ * @param savepoint The savepoint
+ * - Time to add
+ */
+ DECLARE_FUNCTION_NOSETUP(updateFromTime)
+
+ /**
+ * Updates the entity
+ *
+ * @param car The car
+ * @param entityPosition The entity position
+ */
+ DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+
+ DECLARE_FUNCTION(function6)
+ DECLARE_FUNCTION(function7)
+
+ /**
+ * Setup Chapter 1
+ */
+ DECLARE_FUNCTION(chapter1)
+
+ /**
+ * Handle Chapter 1 events
+ */
+ DECLARE_FUNCTION(chapter1Handler)
+
+ DECLARE_FUNCTION(function10)
+
+ /**
+ * Setup Chapter 2
+ */
+ DECLARE_FUNCTION(chapter2)
+
+ /**
+ * Handle Chapter 2 events
+ */
+ DECLARE_FUNCTION(chapter2Handler)
+
+ /**
+ * Setup Chapter 3
+ */
+ DECLARE_FUNCTION(chapter3)
+
+ /**
+ * Handle Chapter 3 events
+ */
+ DECLARE_FUNCTION(chapter3Handler)
+
+ /**
+ * Setup Chapter 4
+ */
+ DECLARE_FUNCTION(chapter4)
+
+ /**
+ * Handle Chapter 4 events
+ */
+ DECLARE_FUNCTION(chapter4Handler)
+
+ DECLARE_FUNCTION(function17)
+
+ /**
+ * Setup Chapter 5
+ */
+ DECLARE_FUNCTION(chapter5)
+
+ /**
+ * Handle Chapter 5 events
+ */
+ DECLARE_FUNCTION(chapter5Handler)
+
+ DECLARE_FUNCTION(function20)
+ DECLARE_FUNCTION(function21)
+
+ DECLARE_NULL_FUNCTION()
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_YASMIN_H