diff options
| -rw-r--r-- | engines/lastexpress/entities/anna.cpp | 239 | ||||
| -rw-r--r-- | engines/lastexpress/entities/august.cpp | 93 | ||||
| -rw-r--r-- | engines/lastexpress/entities/chapters.cpp | 2 | ||||
| -rw-r--r-- | engines/lastexpress/entities/coudert.cpp | 88 | ||||
| -rw-r--r-- | engines/lastexpress/entities/entity_intern.h | 8 | ||||
| -rw-r--r-- | engines/lastexpress/entities/kahina.cpp | 155 | ||||
| -rw-r--r-- | engines/lastexpress/entities/milos.cpp | 345 | ||||
| -rw-r--r-- | engines/lastexpress/entities/rebecca.cpp | 108 | ||||
| -rw-r--r-- | engines/lastexpress/entities/tatiana.cpp | 100 | ||||
| -rw-r--r-- | engines/lastexpress/game/sound.cpp | 2 | ||||
| -rw-r--r-- | engines/lastexpress/shared.h | 19 | 
11 files changed, 1137 insertions, 22 deletions
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,  | 
