From a621302a719d384560fd8f2765639a948ef0cee9 Mon Sep 17 00:00:00 2001 From: Julien Templier Date: Thu, 21 Oct 2010 23:38:35 +0000 Subject: LASTEXPRESS: Implement 10 more AI logic functions svn-id: r53680 --- engines/lastexpress/entities/anna.cpp | 239 ++++++++++++++++++- engines/lastexpress/entities/august.cpp | 93 +++++++- engines/lastexpress/entities/chapters.cpp | 2 +- engines/lastexpress/entities/coudert.cpp | 88 ++++++- engines/lastexpress/entities/entity_intern.h | 8 + engines/lastexpress/entities/kahina.cpp | 155 +++++++++++- engines/lastexpress/entities/milos.cpp | 345 ++++++++++++++++++++++++++- engines/lastexpress/entities/rebecca.cpp | 108 ++++++++- engines/lastexpress/entities/tatiana.cpp | 100 +++++++- engines/lastexpress/game/sound.cpp | 2 +- engines/lastexpress/shared.h | 19 +- 11 files changed, 1137 insertions(+), 22 deletions(-) (limited to 'engines') diff --git a/engines/lastexpress/entities/anna.cpp b/engines/lastexpress/entities/anna.cpp index e04ff1d1b8..a94e9a3154 100644 --- a/engines/lastexpress/entities/anna.cpp +++ b/engines/lastexpress/entities/anna.cpp @@ -1991,7 +1991,106 @@ IMPLEMENT_FUNCTION(47, Anna, function47) ////////////////////////////////////////////////////////////////////////// IMPLEMENT_FUNCTION(48, Anna, function48) - error("Anna: callback function 48 not implemented!"); + switch (savepoint.action) { + default: + break; + + case kActionNone: + if (!params->param1) + break; + + if (params->param3 != kTimeInvalid && getState()->time > kTime1969200) { + UPDATE_PARAM_PROC_TIME(kTime1983600, (!getEntities()->isInRestaurant(kEntityPlayer) || getSound()->isBuffered(kEntityBoutarel)), params->param3, 150) + setCallback(3); + setup_playSound("Aug3007A"); + break; + UPDATE_PARAM_PROC_END + } + +label_callback_4: + if (ENTITY_PARAM(0, 2)) { + if (!params->param2) + params->param2 = getState()->time + 4500; + + if (params->param4 != kTimeInvalid) { + if (params->param2 >= getState()->time) { + if (!getEntities()->isInRestaurant(kEntityPlayer) || !params->param4) + params->param4 = getState()->time + 450; + + if (params->param4 >= getState()->time) + break; + } + + params->param4 = kTimeInvalid; + + setup_function50(); + } + } + break; + + case kActionDefault: + getEntities()->drawSequenceLeft(kEntityAnna, "026C"); + getData()->location = kLocationInsideCompartment; + + setCallback(1); + setup_updateFromTime(450); + break; + + case kActionCallback: + switch (getCallback()) { + default: + break; + + case 1: + setCallback(2); + setup_playSound("Ann3137B"); + break; + + case 2: + getSavePoints()->push(kEntityAnna, kEntityServers0, kAction218983616); + break; + + case 3: + setCallback(4); + setup_playSound("Aug3006A"); + break; + + case 4: + goto label_callback_4; + + case 5: + setCallback(6); + setup_updateFromTime(900); + break; + + case 6: + setCallback(7); + setup_playSound("Aug3006"); + break; + + case 7: + setCallback(8); + setup_updateFromTime(2700); + break; + + case 8: + getEntities()->drawSequenceLeft(kEntityAnna, "026H"); + params->param1 = 1; + break; + } + break; + + case kAction122288808: + getEntities()->drawSequenceLeft(kEntityAnna, "026C"); + + setCallback(5); + setup_playSound("Ann3138A"); + break; + + case kAction122358304: + getEntities()->drawSequenceLeft(kEntityAnna, "BLANK"); + break; + } } ////////////////////////////////////////////////////////////////////////// @@ -2372,7 +2471,143 @@ IMPLEMENT_FUNCTION(58, Anna, function58) ////////////////////////////////////////////////////////////////////////// IMPLEMENT_FUNCTION(59, Anna, function59) - error("Anna: callback function 59 not implemented!"); + switch (savepoint.action) { + default: + break; + + case kActionNone: + if (getInventory()->hasItem(kItemKey) && params->param4 != kTimeInvalid && getState()->time > kTime2218500) { + if (getState()->time > kTime2248200) { + params->param4 = kTimeInvalid; + setup_function61(); + break; + } + + if (!params->param3 + || !getEntities()->isPlayerInCar(kCarRedSleeping) + && !getEntities()->isInSalon(kEntityPlayer) + && !getEntities()->isInRestaurant(kEntityPlayer) + || !params->param4) + params->param4 = getState()->time; + + if (params->param4 < getState()->time) { + params->param4 = kTimeInvalid; + setup_function61(); + break; + } + } + + if (params->param1) { + UPDATE_PARAM(params->param5, getState()->timeTicks, 75); + + CursorStyle style = getEntities()->isInsideCompartment(kEntityMax, kCarRedSleeping, kPosition_4070) ? kCursorHand : kCursorNormal; + getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorNormal, style); + getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorNormal, style); + + params->param1= 0; + params->param2 = 1; + } + + params->param5 = 0; + break; + + case kActionKnock: + case kActionOpenDoor: + getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal); + getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal); + + if (params->param1) { + if (savepoint.param.intValue == 53) { + setCallback(4); + setup_playSound(getSound()->justAMinuteCath()); + } else if (getInventory()->hasItem(kItemPassengerList)) { + setCallback(5); + setup_playSound(rnd(2) ? getSound()->wrongDoorCath() : (rnd(2) ? "CAT1506" : "CAT1506A")); + } else { + setCallback(6); + setup_playSound(getSound()->wrongDoorCath()); + } + } else { + setCallback(savepoint.action == kActionKnock ? 1 : 2); + setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013"); + } + + break; + + case kActionDefault: + getData()->entityPosition = kPosition_4070; + getData()->location = kLocationInsideCompartment; + getEntities()->clearSequences(kEntityAnna); + + getObjects()->update(kObject107, kEntityPlayer, kObjectLocation2, kCursorKeepValue, kCursorKeepValue); + getObjects()->update(kObjectOutsideAnnaCompartment, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue); + getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand); + getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand); + + if (getEntities()->isPlayerPosition(kCarRedSleeping, 60)) + getScenes()->loadSceneFromPosition(kCarRedSleeping, 78); + break; + + case kActionDrawScene: + if (params->param1 || params->param2) { + getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand); + getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand); + params->param1 = 0; + params->param2 = 0; + } + break; + + case kActionCallback: + switch (getCallback()) { + default: + break; + + case 1: + case 2: + setCallback(3); + setup_playSound("ANN1016"); + break; + + case 3: + getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorTalk, kCursorNormal); + getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorTalk, kCursorNormal); + params->param1 = 1; + break; + + case 4: + case 5: + case 6: + params->param1 = 0; + params->param2 = 1; + break; + + case 7: + getSavePoints()->push(kEntityAnna, kEntityTatiana, kAction100906246); + break; + } + break; + + case kAction156622016: + if (params->param3) { + setCallback(8); + setup_function60(); + } + break; + + case kAction236241630: + getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal); + getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal); + + setCallback(7); + setup_playSound("Ann1016A"); + break; + + case kAction236517970: + params->param3 = 1; + getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand); + getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand); + break; + } } ////////////////////////////////////////////////////////////////////////// diff --git a/engines/lastexpress/entities/august.cpp b/engines/lastexpress/entities/august.cpp index 8b0481f00f..c26313295a 100644 --- a/engines/lastexpress/entities/august.cpp +++ b/engines/lastexpress/entities/august.cpp @@ -1426,7 +1426,98 @@ IMPLEMENT_FUNCTION(37, August, function37) ////////////////////////////////////////////////////////////////////////// IMPLEMENT_FUNCTION(38, August, function38) - error("August: callback function 38 not implemented!"); + switch (savepoint.action) { + default: + break; + + case kActionNone: + TIME_CHECK_SAVEPOINT(kTime1801800, params->param1, kEntityAugust, kEntityRebecca, kAction155980128); + + TIME_CHECK_CALLBACK(kTime1820700, params->param2, 3, setup_callbackActionRestaurantOrSalon); + 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_updatePosition("109A", kCarRestaurant, 56); + break; + + case 2: + getScenes()->loadSceneFromItemPosition(kItem3); + getData()->location = kLocationInsideCompartment; + break; + + case 3: + getData()->location = kLocationOutsideCompartment; + + setCallback(4); + setup_updatePosition("109D2", kCarRestaurant, 56); + break; + + case 4: + getInventory()->setLocationAndProcess(kItem3, kObjectLocation1); + + setCallback(5); + setup_function17(kTime1849500); + break; + + case 5: + setup_function39(); + break; + + case 6: + setCallback(7); + setup_playSound("AUG2114"); + break; + + case 7: + getEntities()->drawSequenceLeft(kEntityAugust, "108C"); + getEntities()->updatePositionEnter(kEntityAugust, kCarRestaurant, 56); + getEntities()->updatePositionEnter(kEntityAugust, kCarRestaurant, 57); + + setCallback(8); + setup_playSound("AUG2114A"); + break; + + case 8: + setCallback(9); + setup_playSound("AUG2115"); + break; + + case 9: + setCallback(10); + setup_draw2("108D1", "108D2", kEntityRebecca); + break; + + case 10: + getEntities()->drawSequenceLeft(kEntityAugust, "109B"); + getEntities()->updatePositionExit(kEntityAugust, kCarRestaurant, 56); + getEntities()->updatePositionExit(kEntityAugust, kCarRestaurant, 57); + getSavePoints()->push(kEntityAugust, kEntityRebecca, kAction125496184); + break; + } + break; + + case kAction169358379: + getSavePoints()->push(kEntityAugust, kEntityRebecca, kAction155465152); + getEntities()->drawSequenceLeft(kEntityAugust, "108A"); + + setCallback(6); + setup_updateFromTime(900); + break; + } } ////////////////////////////////////////////////////////////////////////// diff --git a/engines/lastexpress/entities/chapters.cpp b/engines/lastexpress/entities/chapters.cpp index 31b4dbd654..d145eb6073 100644 --- a/engines/lastexpress/entities/chapters.cpp +++ b/engines/lastexpress/entities/chapters.cpp @@ -1673,7 +1673,7 @@ IMPLEMENT_FUNCTION(22, Chapters, chapter5Handler) if (getState()->time > kTimeTrainStopped2 && !params->param3) { params->param3 = 1; - if (!getEvent(kEventLocomotiveMilos) && !getEvent(kEventLocomotiveMilosNight)) { + if (!getEvent(kEventLocomotiveMilosDay) && !getEvent(kEventLocomotiveMilosNight)) { getSound()->playSound(kEntityChapters, "ARRIVE", SoundManager::kFlag8); getSound()->processEntries(); } diff --git a/engines/lastexpress/entities/coudert.cpp b/engines/lastexpress/entities/coudert.cpp index edf3e9ccf7..6093110c6c 100644 --- a/engines/lastexpress/entities/coudert.cpp +++ b/engines/lastexpress/entities/coudert.cpp @@ -1306,7 +1306,93 @@ IMPLEMENT_FUNCTION(25, Coudert, function25) ////////////////////////////////////////////////////////////////////////// IMPLEMENT_FUNCTION(26, Coudert, function26) - error("Coudert: callback function 26 not implemented!"); + switch (savepoint.action) { + default: + break; + + case kActionNone: + if (params->param1) { + UPDATE_PARAM(params->param2, getState()->timeTicks, 75); + + setCallback(3); + setup_enterExitCompartment2("627Zd", kObjectCompartmentD, kPosition_5790, kPosition_6130); + } + break; + + case kActionDefault: + setCallback(1); + setup_updateEntity(kCarRedSleeping, kPosition_5790); + break; + + case kActionCallback: + switch (getCallback()) { + default: + break; + + case 1: + setCallback(2); + setup_enterExitCompartment("627Vd", kObjectCompartmentD); + break; + + case 2: + getSavePoints()->push(kEntityCoudert, kEntityMmeBoutarel, kAction221683008); + getEntities()->drawSequenceLeft(kEntityCoudert, "627Wd"); + getEntities()->enterCompartment(kEntityCoudert, kObjectCompartmentD, true); + break; + + case 3: + case 7: + getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentD, true); + getData()->location = kLocationInsideCompartment; + getEntities()->clearSequences(kEntityCoudert); + + setCallback(getCallback() == 3 ? 4 : 8); + setup_function20(kObjectCompartmentD, kObject51); + break; + + case 4: + setCallback(5); + setup_enterExitCompartment("697Ad", kObjectCompartmentD); + break; + + case 5: + getData()->location = kLocationOutsideCompartment; + + CALLBACK_ACTION(); + break; + + case 6: + getSavePoints()->push(kEntityCoudert, kEntityMmeBoutarel, kAction122865568); + break; + + case 8: + getSound()->playSound(kEntityCoudert, "JAC1013"); + + setCallback(9); + setup_enterExitCompartment("697Ad", kObjectCompartmentD); + break; + + case 9: + getData()->location = kLocationOutsideCompartment; + getSavePoints()->push(kEntityCoudert, kEntityMmeBoutarel, kAction123852928); + + CALLBACK_ACTION(); + break; + } + break; + + case kAction88652208: + setCallback(7); + setup_enterExitCompartment2("627Zd", kObjectCompartmentD, kPosition_5790, kPosition_6130); + break; + + case kAction123199584: + params->param1 = 1; + + setCallback(6); + setup_playSound("JAC1012"); + break; + } } ////////////////////////////////////////////////////////////////////////// diff --git a/engines/lastexpress/entities/entity_intern.h b/engines/lastexpress/entities/entity_intern.h index 3f8c6e7c76..8b0b158a6b 100644 --- a/engines/lastexpress/entities/entity_intern.h +++ b/engines/lastexpress/entities/entity_intern.h @@ -504,6 +504,14 @@ void class::setup_##name() { \ if (parameter < type) { \ parameter = kTimeInvalid; +#define UPDATE_PARAM_PROC_TIME(timeValue, test, parameter, value) \ + if (getState()->time <= timeValue) { \ + if (test || !parameter) \ + parameter = getState()->time + value; \ + } \ + if (parameter < getState()->time || getState()->time > timeValue) { \ + parameter = kTimeInvalid; + #define UPDATE_PARAM_PROC_END } // Updating parameter with an added check (and code inside the check) diff --git a/engines/lastexpress/entities/kahina.cpp b/engines/lastexpress/entities/kahina.cpp index 2a5a96be48..881ac12700 100644 --- a/engines/lastexpress/entities/kahina.cpp +++ b/engines/lastexpress/entities/kahina.cpp @@ -962,7 +962,160 @@ IMPLEMENT_FUNCTION(24, Kahina, function24) ////////////////////////////////////////////////////////////////////////// IMPLEMENT_FUNCTION(25, Kahina, function25) - error("Kahina: callback function 25 not implemented!"); + switch (savepoint.action) { + default: + break; + + case kActionNone: + if (params->param1 == kTimeInvalid) + break; + + if (getState()->time <= kTime2263500) { + if (!getEntities()->isPlayerInCar(kCarGreenSleeping) || !params->param1) + params->param1 = getState()->time; + + if (params->param1 >= getState()->time) + break; + } + + params->param1 = kTimeInvalid; + + setCallback(12); + setup_enterExitCompartment("616Ba", kObjectCompartment1); + break; + + case kActionDefault: + if (!getEvent(kEventAnnaBaggageArgument)) { + setCallback(1); + setup_function19(kCarGreenSleeping, kPosition_8200); + break; + } + + switch (getInventory()->get(kItemFirebird)->location) { + default: + break; + + case kObjectLocation3: + case kObjectLocation7: + if (getInventory()->get(kItemFirebird)->location == kObjectLocation3) + getProgress().field_7C = 1; + else + getProgress().field_80 = 1; + + getScenes()->loadSceneFromItemPosition(kItemFirebird); + getInventory()->get(kItemFirebird)->location = kObjectLocation5; + getSavePoints()->push(kEntityKahina, kEntityKronos, kAction138085344); + break; + } + + getInventory()->setLocationAndProcess(kItemBriefcase, kObjectLocation2); + getProgress().field_78 = 1; + ENTITY_PARAM(0, 3) = 0; + + CALLBACK_ACTION(); + break; + + case kActionCallback: + switch (getCallback()) { + default: + break; + + case 1: + case 4: + if (getEntities()->isPlayerInCar(kCarGreenSleeping)) { + setCallback(getCallback() == 1 ? 2 : 5); + setup_function19(getCallback() == 1 ? kCarGreenSleeping : kCarKronos, getCallback() == 1 ? kPosition_9460 : kPosition_9270); + break; + } else { + if (getEntities()->checkFields19(kEntityPlayer, kCarGreenSleeping, kPosition_7850) || getEntities()->isOutsideAlexeiWindow()) { + setCallback(6); + setup_playSound("LIB013"); + } else { + setCallback(8); + setup_enterExitCompartment("616Aa", kObjectCompartment1); + } + } + break; + + case 2: + setCallback(3); + setup_updateFromTime(1800); + break; + + case 3: + setCallback(4); + setup_function19(kCarGreenSleeping, kPosition_8200); + break; + + case 5: + case 7: + case 11: + case 13: + getEntities()->clearSequences(kEntityKahina); + + CALLBACK_ACTION(); + break; + + case 6: + setCallback(7); + setup_function19(kCarKronos, kPosition_9270); + break; + + case 8: + getData()->location = kLocationInsideCompartment; + getEntities()->clearSequences(kEntityKahina); + getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorNormal); + getObjects()->update(kObjectHandleBathroom, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorNormal); + + setCallback(9); + setup_updateFromTime(900); + break; + + case 9: + getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand); + getObjects()->update(kObjectHandleBathroom, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand); + + switch (getInventory()->get(kItemFirebird)->location) { + default: + if (ENTITY_PARAM(0, 3)) + getInventory()->setLocationAndProcess(kItemBriefcase, kObjectLocation2); + break; + + case kObjectLocation3: + case kObjectLocation7: + if (getInventory()->get(kItemFirebird)->location == kObjectLocation3) + getProgress().field_7C = 1; + else + getProgress().field_80 = 1; + + getScenes()->loadSceneFromItemPosition(kItemFirebird); + getInventory()->get(kItemFirebird)->location = kObjectLocation5; + getSavePoints()->push(kEntityKahina, kEntityKronos, kAction138085344); + getInventory()->setLocationAndProcess(kItemBriefcase, kObjectLocation2); + getProgress().field_C0 = getState()->time; + getProgress().field_78 = 1; + break; + } + + getProgress().field_78 = 1; + ENTITY_PARAM(0, 3) = 0; + + if (getInventory()->get(kItemFirebird)->location != kObjectLocation18) { + setCallback(10); + setup_enterExitCompartment("616Ba", kObjectCompartment1); + } + break; + + case 10: + case 12: + getData()->location = kLocationOutsideCompartment; + + setCallback(getCallback() == 10 ? 11 : 13); + setup_updateEntity(kCarKronos, kPosition_9270); + break; + } + break; + } } ////////////////////////////////////////////////////////////////////////// diff --git a/engines/lastexpress/entities/milos.cpp b/engines/lastexpress/entities/milos.cpp index 30ed546106..a3e4a962e3 100644 --- a/engines/lastexpress/entities/milos.cpp +++ b/engines/lastexpress/entities/milos.cpp @@ -167,7 +167,67 @@ IMPLEMENT_FUNCTION_I(11, Milos, function11, TimeValue) break; case kActionNone: - error("Milos: callback function 11 not implemented!"); + if (!params->param5 && params->param1 < getState()->time && !params->param7) { + params->param7 = 1; + + CALLBACK_ACTION(); + break; + } + + if (params->param2) { + UPDATE_PARAM_PROC(params->param8, getState()->timeTicks, 75) + params->param2 = 0; + params->param3 = 1; + getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation1, kCursorNormal, kCursorNormal); + UPDATE_PARAM_PROC_END + } + + params->param8 = 0; + + if (getProgress().chapter != kChapter1 || params->param5) + break; + + if (params->param6) { + UPDATE_PARAM_PROC(CURRENT_PARAMS(1, 1), getState()->time, 4500) + params->param6 = 0; + CURRENT_PARAMS(1, 1) = 0; + UPDATE_PARAM_PROC_END + } + + if (!getProgress().field_CC) { + + if (ENTITY_PARAM(0, 3) && !getProgress().field_14 && !params->param6) { + getProgress().field_14 = 14; + getSavePoints()->push(kEntityMilos, kEntityVesna, kAction190412928); + + setCallback(1); + setup_enterExitCompartment("609Cg", kObjectCompartmentG); + } + break; + } + + if (!params->param4) + params->param4 = getState()->time + 18000; + + if (CURRENT_PARAMS(1, 2) != kTimeInvalid) { + if (params->param4 >= getState()->time) { + if (!getEntities()->isDistanceBetweenEntities(kEntityPlayer, kEntityMilos, 2000) || !CURRENT_PARAMS(1, 2)) + CURRENT_PARAMS(1, 2) = getState()->time + 150; + + if (CURRENT_PARAMS(1, 2) >= getState()->time) + break; + } + + CURRENT_PARAMS(1, 2) = kTimeInvalid; + + if (getEntities()->isDistanceBetweenEntities(kEntityPlayer, kEntityMilos, 2000)) + getProgress().field_98 = 1; + + getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorNormal, kCursorNormal); + + setCallback(6); + setup_playSound("MIL1012"); + } break; case kActionKnock: @@ -183,13 +243,8 @@ IMPLEMENT_FUNCTION_I(11, Milos, function11, TimeValue) setup_playSound(getSound()->wrongDoorCath()); } } else { - if (savepoint.action == kActionKnock) { - setCallback(7); - setup_playSound("LIB012"); - } else { - setCallback(8); - setup_playSound("LIB013"); - } + setCallback(savepoint.action == kActionKnock ? 7 : 8); + setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013"); } break; @@ -738,7 +793,182 @@ IMPLEMENT_FUNCTION(23, Milos, function23) ////////////////////////////////////////////////////////////////////////// IMPLEMENT_FUNCTION(24, Milos, function24) - error("Milos: callback function 24 not implemented!"); + switch (savepoint.action) { + default: + break; + + case kActionNone: + if (!params->param4) + params->param4 = getState()->time + 4500; + + if (params->param4 < getState()->time) { + params->param4 = kTimeInvalid; + params->param3 = 1; + } + + if (ENTITY_PARAM(0, 1)) { + setCallback(1); + setup_enterExitCompartment("609Cg", kObjectCompartmentG); + break; + } + + if (params->param1) { + UPDATE_PARAM(params->param5, getState()->timeTicks, 75); + + params->param1 = 0; + params->param2 = 1; + + getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation1, kCursorNormal, kCursorNormal); + } + + params->param5 = 0; + break; + + case kActionKnock: + getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorNormal, kCursorNormal); + + if (params->param1) { + if (getInventory()->hasItem(kItemPassengerList)) { + setCallback(9); + setup_playSound(rnd(2) ? "CAT1504" : getSound()->wrongDoorCath()); + } else { + setCallback(10); + setup_playSound(getSound()->wrongDoorCath()); + } + } else { + setCallback(6); + setup_playSound("LIB012"); + } + break; + + case kActionOpenDoor: + getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorNormal, kCursorNormal); + + if (getEvent(kEventMilosCompartmentVisitAugust) || getState()->time >= kTime2106000) { + setCallback(12); + setup_playSound("LIB013"); + } else { + getData()->location = kLocationInsideCompartment; + + setCallback(11); + setup_savegame(kSavegameTypeEvent, kEventMilosCompartmentVisitAugust); + } + break; + + case kActionDefault: + getData()->entityPosition = kPosition_3050; + getData()->location = kLocationInsideCompartment; + getData()->car = kCarRedSleeping; + + getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorHandKnock, kCursorHand); + break; + + case kActionDrawScene: + if (getEvent(kEventMilosCompartmentVisitAugust) + || getEntities()->isInsideTrainCar(kEntityPlayer, kCarRedSleeping) + || !params->param3 + || getState()->time >= kTime2106000) { + if (params->param1 || params->param2) { + getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorHandKnock, kCursorHand); + params->param1 = 0; + params->param2 = 0; + } + break; + } + + setup_function23(); + break; + + case kActionCallback: + switch (getCallback()) { + default: + break; + + case 1: + getObjects()->update(kObjectCompartmentG, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand); + getSavePoints()->push(kEntityMilos, kEntityVesna, kAction203663744); + getData()->location = kLocationOutsideCompartment; + + setCallback(2); + setup_function26(kTime2223000); + break; + + case 2: + if (ENTITY_PARAM(0, 2)) { + setCallback(3); + setup_savegame(kSavegameTypeEvent, kEventMilosCorridorThanksD); + } else { + setCallback(4); + setup_enterCompartmentDialog(kCarRedSleeping, kPosition_3050); + } + break; + + case 3: + getAction()->playAnimation((getData()->entityPosition < getEntityData(kEntityPlayer)->entityPosition) ? kEventMilosCorridorThanksD : kEventMilosCorridorThanks); + + if (getData()->car == kCarRedSleeping && getEntities()->checkDistanceFromPosition(kEntityMilos, kPosition_3050, 500)) + getData()->entityPosition = kPosition_3550; + + getEntities()->updateEntity(kEntityMilos, kCarRedSleeping, kPosition_3050); + getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + (750 * (getData()->direction == kDirectionDown ? 1 : -1))), getData()->direction != kDirectionDown); + + setCallback(4); + setup_enterCompartmentDialog(kCarRedSleeping, kPosition_3050); + break; + + case 4: + setCallback(5); + setup_enterExitCompartment("609BG", kObjectCompartmentG); + break; + + case 5: + getEntities()->clearSequences(kEntityMilos); + getData()->location = kLocationInsideCompartment; + ENTITY_PARAM(0, 1) = 0; + + setup_function25(); + break; + + case 6: + if (getEvent(kEventMilosCompartmentVisitAugust) || getState()->time >= kTime2106000) { + setCallback(8); + setup_playSound("Mil1117A"); + } else { + setCallback(7); + setup_playSound("Mil1118"); + } + break; + + case 7: + getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorHandKnock, kCursorHand); + break; + + case 8: + case 13: + getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorTalk, kCursorNormal); + params->param1 = 1; + break; + + case 9: + case 10: + params->param1 = 0; + params->param2 = 1; + break; + + case 11: + getAction()->playAnimation(kEventMilosCompartmentVisitAugust); + getScenes()->loadSceneFromPosition(kCarRedSleeping, 5); + getSavePoints()->push(kEntityMilos, kEntityVesna, kAction135024800); + getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorHandKnock, kCursorHand); + break; + + case 12: + setCallback(13); + setup_playSound("MIL1117A"); + break; + } + break; + } } ////////////////////////////////////////////////////////////////////////// @@ -1065,7 +1295,102 @@ IMPLEMENT_FUNCTION(33, Milos, chapter5) ////////////////////////////////////////////////////////////////////////// IMPLEMENT_FUNCTION(34, Milos, chapter5Handler) - error("Milos: callback function 34 not implemented!"); + switch (savepoint.action) { + default: + break; + + case kActionEndSound: + if (!getProgress().isNightTime) { + setCallback(6); + setup_savegame(kSavegameTypeEvent, kEventTrainStopped); + break; + } + + getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneGameOverTrainStopped2, true); + break; + + case kActionCallback: + switch (getCallback()) { + default: + break; + + case 1: + getAction()->playAnimation(isNight() ? kEventLocomotiveMilosShovelingNight : kEventLocomotiveMilosShovelingDay); + getScenes()->processScene(); + break; + + case 2: + if (getSound()->isBuffered("MUS050")) + getSound()->processEntry("MUS050"); + + if (getSound()->isBuffered("ARRIVE")) + getSound()->removeFromQueue("ARRIVE"); + + getSound()->processEntries(); + getAction()->playAnimation(isNight() ? kEventLocomotiveMilosNight : kEventLocomotiveMilosDay); + getSound()->setupEntry(SoundManager::kSoundType7, kEntityMilos); + getScenes()->loadSceneFromPosition(kCarCoalTender, 1); + break; + + case 3: + getAction()->playAnimation(kEventLocomotiveAnnaStopsTrain); + getLogic()->gameOver(kSavegameTypeEvent2, kEventLocomotiveMilosDay, kSceneGameOverTrainStopped, true); + break; + + case 4: + getAction()->playAnimation(kEventLocomotiveRestartTrain); + getAction()->playAnimation(kEventLocomotiveOldBridge); + getSound()->resetState(); + getState()->time = kTime2983500; + + setCallback(5); + setup_savegame(kSavegameTypeTime, kTimeNone); + break; + + case 5: + getScenes()->loadSceneFromPosition(kCarCoalTender, 2, 1); + getSavePoints()->push(kEntityMilos, kEntityAbbot, kAction135600432); + + setup_function35(); + break; + + case 6: + getAction()->playAnimation(kEventTrainStopped); + getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverTrainStopped, true); + break; + } + break; + + case kAction168646401: + if (!getEvent(kEventLocomotiveMilosShovelingDay) && !getEvent(kEventLocomotiveMilosShovelingNight)) { + setCallback(1); + setup_savegame(kSavegameTypeEvent, kEventLocomotiveMilosShovelingDay); + break; + } + + if (!getEvent(kEventLocomotiveMilosDay) && !getEvent(kEventLocomotiveMilosNight)) { + if (getProgress().isNightTime && getState()->time < kTimeTrainStopped2) + getState()->time = kTimeTrainStopped2; + + setCallback(2); + setup_savegame(kSavegameTypeEvent, kEventLocomotiveMilosDay); + } + break; + + case kAction169773228: + if (!getProgress().isNightTime) { + setCallback(3); + setup_savegame(kSavegameTypeEvent, kEventLocomotiveAnnaStopsTrain); + } + + getSound()->processEntry(kEntityMilos); + if (getState()->time < kTimeTrainStopped2) + getState()->time = kTimeTrainStopped2; + + setCallback(4); + setup_savegame(kSavegameTypeEvent, kEventLocomotiveRestartTrain); + break; + } } ////////////////////////////////////////////////////////////////////////// diff --git a/engines/lastexpress/entities/rebecca.cpp b/engines/lastexpress/entities/rebecca.cpp index 4243554744..af3197a210 100644 --- a/engines/lastexpress/entities/rebecca.cpp +++ b/engines/lastexpress/entities/rebecca.cpp @@ -1304,7 +1304,113 @@ IMPLEMENT_FUNCTION(35, Rebecca, function35) ////////////////////////////////////////////////////////////////////////// IMPLEMENT_FUNCTION(36, Rebecca, function36) - error("Rebecca: callback function 36 not implemented!"); + switch (savepoint.action) { + default: + break; + + case kActionNone: + if (!params->param2) + params->param2 = getState()->time + 1800; + + if (params->param4 != kTimeInvalid && params->param2 < getState()->time) { + + if (getState()->time <= kTime2083500) { + if (!getEntities()->isInSalon(kEntityPlayer) || !params->param4) + params->param4 = getState()->time + 300; + } + + if (params->param4 < getState()->time || getState()->time > kTime2083500) { + params->param4 = kTimeInvalid; + getSound()->playSound(kEntityRebecca, "Reb3007"); + + setCallback(2); + setup_updatePosition("118E", kCarRedSleeping, 52); + break; + } + } + + // TODO rewrite using proper if/else blocks instead of goto +label_callback_2: + if (!params->param1) + goto label_callback_3; + + if (!params->param3) + params->param3 = getState()->time + 9000; + + if (params->param5 == kTimeInvalid || params->param3 >= getState()->time) + goto label_callback_3; + + if (getState()->time <= kTime2092500) { + if (!getEntities()->isInSalon(kEntityPlayer) || !params->param5) + params->param5 = getState()->time + 300; + + if (params->param5 >= getState()->time) { +label_callback_3: + if (getState()->time > kTime2097000 && !params->param6) { + params->param6 = 1; + getData()->inventoryItem = kItemNone; + + setCallback(4); + setup_updatePosition("118H", kCarRestaurant, 52); + } + break; + } + } + + params->param5 = kTimeInvalid; + + getData()->inventoryItem = kItemNone; + getSound()->playSound(kEntityRebecca, "Reb3008", SoundManager::kFlagInvalid, 60); + getEntities()->updatePositionEnter(kEntityRebecca, kCarRestaurant, 52); + + setCallback(3); + setup_draw2("118G1", "118G2", kEntitySophie); + break; + + case kAction1: + getData()->inventoryItem = kItemNone; + + setCallback(6); + setup_playSound("SOP3008"); + break; + + case kActionDefault: + setCallback(1); + setup_function17(true); + break; + + case kActionCallback: + switch (getCallback()) { + default: + break; + + case 1: + getEntities()->drawSequenceLeft(kEntityRebecca, "118D"); + break; + + case 2: + params->param1 = 1; + getData()->inventoryItem = kItemInvalid; + getEntities()->drawSequenceLeft(kEntityRebecca, "118F"); + goto label_callback_2; + + case 3: + getEntities()->clearSequences(kEntitySophie); + getEntities()->updatePositionExit(kEntityRebecca, kCarRestaurant, 52); + getEntities()->drawSequenceLeft(kEntityRebecca, "118D"); + goto label_callback_3; + + case 4: + setCallback(5); + setup_function18(); + break; + + case 5: + setup_function37(); + break; + } + break; + } } ////////////////////////////////////////////////////////////////////////// diff --git a/engines/lastexpress/entities/tatiana.cpp b/engines/lastexpress/entities/tatiana.cpp index 14567f8afa..2c6f74dff5 100644 --- a/engines/lastexpress/entities/tatiana.cpp +++ b/engines/lastexpress/entities/tatiana.cpp @@ -26,6 +26,7 @@ #include "lastexpress/entities/tatiana.h" #include "lastexpress/entities/alexei.h" +#include "lastexpress/entities/coudert.h" #include "lastexpress/game/action.h" #include "lastexpress/game/entities.h" @@ -1338,7 +1339,104 @@ IMPLEMENT_FUNCTION(40, Tatiana, function40) ////////////////////////////////////////////////////////////////////////// IMPLEMENT_FUNCTION(41, Tatiana, function41) - error("Tatiana: callback function 41 not implemented!"); + switch (savepoint.action) { + default: + break; + + case kActionNone: + if (!params->param1) + break; + + if (getEntities()->checkFields19(kEntityPlayer, kCarRedSleeping, kPosition_7850) + && !getEvent(kEventVassiliCompartmentStealEgg) + && (getState()->time <= kTime2133000 || getProgress().field_40)) { + if (getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_7500)) { + + getSavePoints()->push(kEntityTatiana, kEntityCoudert, kAction235061888); + getEntities()->clearSequences(kEntityTatiana); + getEntities()->exitCompartment(kEntityTatiana, kObjectCompartmentB, true); + getData()->location = kLocationInsideCompartment; + + if (getInventory()->hasItem(kItemFirebird)) { + getAction()->playAnimation(kEventTatianaCompartmentStealEgg); + getInventory()->removeItem(kItemFirebird); + getInventory()->get(kItemFirebird)->location = kObjectLocation2; + } else { + getAction()->playAnimation(kEventTatianaCompartment); + } + + getScenes()->loadSceneFromObject(kObjectCompartmentB); + + setCallback(4); + setup_updateFromTime(150); + } + } else { + getEntities()->exitCompartment(kEntityTatiana, kObjectCompartmentB, true); + + if (getState()->time < kTime2133000 || getProgress().field_40) { + setCallback(3); + setup_function40(); + break; + } + + getEntities()->clearSequences(kEntityTatiana); + CALLBACK_ACTION(); + } + break; + + case kActionDefault: + getData()->car = kCarRedSleeping; + getData()->entityPosition = kPosition_7500; + getData()->location = kLocationOutsideCompartment; + + RESET_ENTITY_STATE(kEntityCoudert, Coudert, setup_function51); + + getEntities()->drawSequenceLeft(kEntityTatiana, "673Fb"); + getEntities()->enterCompartment(kEntityTatiana, kObjectCompartmentB, true); + break; + + case kActionCallback: + switch (getCallback()) { + default: + break; + + case 1: + setCallback(2); + setup_playSound("Tat3161B"); + break; + + case 2: + getSavePoints()->push(kEntityTatiana, kEntityCoudert, kAction168316032); + params->param1 = 1; + break; + + case 3: + case 6: + getEntities()->clearSequences(kEntityTatiana); + + CALLBACK_ACTION(); + break; + + case 4: + setCallback(5); + setup_function15(); + break; + + case 5: + setCallback(6); + setup_function40(); + break; + } + break; + + case kAction154071333: + getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal); + getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal); + + setCallback(1); + setup_savegame(kSavegameTypeTime, kTimeNone); + break; + } } ////////////////////////////////////////////////////////////////////////// diff --git a/engines/lastexpress/game/sound.cpp b/engines/lastexpress/game/sound.cpp index e826ba8622..348a7f6937 100644 --- a/engines/lastexpress/game/sound.cpp +++ b/engines/lastexpress/game/sound.cpp @@ -884,7 +884,7 @@ const char *SoundManager::getDialogName(EntityIndex entity) const { break; case kEntityMilos: - if (getEvent(kEventLocomotiveMilos) || getEvent(kEventLocomotiveMilosNight)) + if (getEvent(kEventLocomotiveMilosDay) || getEvent(kEventLocomotiveMilosNight)) return "XMIL5"; if (getEvent(kEventMilosCompartmentVisitTyler) && (getProgress().chapter == kChapter3 || getProgress().chapter == kChapter4)) diff --git a/engines/lastexpress/shared.h b/engines/lastexpress/shared.h index a85d535c50..c4c05e68ed 100644 --- a/engines/lastexpress/shared.h +++ b/engines/lastexpress/shared.h @@ -130,22 +130,27 @@ enum TimeValue { kTime1786500 = 1786500, kTime1791000 = 1791000, kTime1800000 = 1800000, + kTime1801800 = 1801800, kTime1806300 = 1806300, kTime1809000 = 1809000, kTimeCityAugsburg = 1809900, kTime1818000 = 1818000, kTime1818900 = 1818900, + kTime1820700 = 1820700, kTime1822500 = 1822500, kTime1836000 = 1836000, kTime1845000 = 1845000, + kTime1849500 = 1849500, kTimeCityMunich = 1852200, // Chapter 3 kTimeChapter3 = 1944000, kTime1953000 = 1953000, kTime1966500 = 1966500, + kTime1969200 = 1969200, kTime1971000 = 1971000, kTimeEnterSalzbourg = 1982700, + kTime1983600 = 1983600, kTimeCitySalzbourg = 1984500, kTime1989000 = 1989000, kTimeExitSalzbourg = 1989900, @@ -196,7 +201,9 @@ enum TimeValue { kTime2196000 = 2196000, kTime2200500 = 2200500, kTime2218500 = 2218500, + kTime2223000 = 2223000, kTime2241000 = 2241000, + kTime2248200 = 2248200, kTime2250000 = 2250000, kTime2254500 = 2254500, kTime2259000 = 2259000, @@ -267,6 +274,7 @@ enum TimeValue { kTime2916000 = 2916000, kTimeCityBelgrade = 2952000, kTimeTrainStopped2 = 2943000, + kTime2983500 = 2983500, kTimeCityNish = 3205800, kTimeCityTzaribrod = 3492000, kTime3645000 = 3645000, @@ -528,6 +536,7 @@ enum EntityPosition { kPosition_3390 = 3390, kPosition_3450 = 3450, kPosition_3500 = 3500, + kPosition_3550 = 3550, kPosition_3650 = 3650, kPosition_3760 = 3760, kPosition_3820 = 3820, @@ -654,7 +663,8 @@ enum ObjectLocation { kObjectLocation5 = 5, kObjectLocation6 = 6, kObjectLocation7 = 7, - kObjectLocation10 = 10 + kObjectLocation10 = 10, + kObjectLocation18 = 18 }; ////////////////////////////////////////////////////////////////////////// @@ -1030,7 +1040,7 @@ enum EventIndex { kEventMilosCorridorThanks = 105, kEventMilosCorridorThanksD = 106, kEventMilosCompartmentVisitTyler = 107, - kEventLocomotiveMilos = 108, + kEventLocomotiveMilosDay = 108, kEventLocomotiveMilosNight = 109, kEventAbbotIntroduction = 110, kEventAbbotWrongCompartment = 111, @@ -1203,7 +1213,7 @@ enum EventIndex { enum ActionIndex { kActionNone = 0, kAction1 = 1, - kActionEndSound = 2, + kActionEndSound = 2, kActionExitCompartment = 3, kAction4 = 4, kActionExcuseMeCath = 5, @@ -1319,6 +1329,7 @@ enum ActionIndex { kAction157026693 = 157026693, kAction168253822 = 168253822, kAction168254872 = 168254872, + kAction168316032 = 168316032, // Tatiana kAction169557824 = 169557824, kAction171394341 = 171394341, // Mertens kAction185671840 = 185671840, @@ -1335,6 +1346,7 @@ enum ActionIndex { kAction223068211 = 223068211, // MmeBoutarel kAction225932896 = 225932896, kAction226031488 = 226031488, // Verges + kAction235061888 = 235061888, // Tatiana kAction238358920 = 238358920, // Anna kAction253868128 = 253868128, // Anna kAction285528346 = 285528346, // Rebecca @@ -1528,6 +1540,7 @@ enum ActionIndex { kAction69239528 = 69239528, kAction123857088 = 123857088, kAction124973510 = 124973510, + kAction154071333 = 154071333, kAction156444784 = 156444784, kAction169360385 = 169360385, kAction191198209 = 191198209, -- cgit v1.2.3