1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "lastexpress/entities/tatiana.h"
24 
25 #include "lastexpress/entities/alexei.h"
26 #include "lastexpress/entities/coudert.h"
27 
28 #include "lastexpress/game/action.h"
29 #include "lastexpress/game/entities.h"
30 #include "lastexpress/game/inventory.h"
31 #include "lastexpress/game/logic.h"
32 #include "lastexpress/game/object.h"
33 #include "lastexpress/game/savepoint.h"
34 #include "lastexpress/game/scenes.h"
35 #include "lastexpress/game/state.h"
36 
37 #include "lastexpress/sound/queue.h"
38 
39 #include "lastexpress/lastexpress.h"
40 
41 namespace LastExpress {
42 
Tatiana(LastExpressEngine * engine)43 Tatiana::Tatiana(LastExpressEngine *engine) : Entity(engine, kEntityTatiana) {
44 	ADD_CALLBACK_FUNCTION(Tatiana, reset);
45 	ADD_CALLBACK_FUNCTION_S(Tatiana, playSound);
46 	ADD_CALLBACK_FUNCTION_S(Tatiana, draw);
47 	ADD_CALLBACK_FUNCTION_SII(Tatiana, updatePosition);
48 	ADD_CALLBACK_FUNCTION_SI(Tatiana, enterExitCompartment);
49 	ADD_CALLBACK_FUNCTION_SI(Tatiana, enterExitCompartment2);
50 	ADD_CALLBACK_FUNCTION_SIIS(Tatiana, callSavepoint);
51 	ADD_CALLBACK_FUNCTION(Tatiana, callbackActionOnDirection);
52 	ADD_CALLBACK_FUNCTION_I(Tatiana, updateFromTicks);
53 	ADD_CALLBACK_FUNCTION_I(Tatiana, updateFromTime);
54 	ADD_CALLBACK_FUNCTION(Tatiana, callbackActionRestaurantOrSalon);
55 	ADD_CALLBACK_FUNCTION_II(Tatiana, savegame);
56 	ADD_CALLBACK_FUNCTION_II(Tatiana, updateEntity);
57 	ADD_CALLBACK_FUNCTION(Tatiana, enterCompartment);
58 	ADD_CALLBACK_FUNCTION(Tatiana, exitCompartment);
59 	ADD_CALLBACK_FUNCTION_I(Tatiana, handleCompartment);
60 	ADD_CALLBACK_FUNCTION(Tatiana, chapter1);
61 	ADD_CALLBACK_FUNCTION(Tatiana, function18);
62 	ADD_CALLBACK_FUNCTION(Tatiana, chapter1Handler);
63 	ADD_CALLBACK_FUNCTION(Tatiana, exitDining);
64 	ADD_CALLBACK_FUNCTION(Tatiana, returnToCompartment);
65 	ADD_CALLBACK_FUNCTION(Tatiana, getSomeAir);
66 	ADD_CALLBACK_FUNCTION(Tatiana, returnToCompartmentAgain);
67 	ADD_CALLBACK_FUNCTION(Tatiana, function24);
68 	ADD_CALLBACK_FUNCTION(Tatiana, chapter2);
69 	ADD_CALLBACK_FUNCTION(Tatiana, chapter2Handler);
70 	ADD_CALLBACK_FUNCTION(Tatiana, breakfastClick);
71 	ADD_CALLBACK_FUNCTION(Tatiana, joinAlexei);
72 	ADD_CALLBACK_FUNCTION(Tatiana, leaveBreakfast);
73 	ADD_CALLBACK_FUNCTION(Tatiana, returnToCompartment2);
74 	ADD_CALLBACK_FUNCTION(Tatiana, chapter3);
75 	ADD_CALLBACK_FUNCTION_TYPE2(Tatiana, playChess, EntityParametersI5S, EntityParametersSIII);
76 	ADD_CALLBACK_FUNCTION(Tatiana, returnToCompartment3);
77 	ADD_CALLBACK_FUNCTION(Tatiana, beforeConcert);
78 	ADD_CALLBACK_FUNCTION(Tatiana, concert);
79 	ADD_CALLBACK_FUNCTION(Tatiana, leaveConcert);
80 	ADD_CALLBACK_FUNCTION(Tatiana, afterConcert);
81 	ADD_CALLBACK_FUNCTION(Tatiana, cryAnna);
82 	ADD_CALLBACK_FUNCTION(Tatiana, function39);
83 	ADD_CALLBACK_FUNCTION(Tatiana, function40);
84 	ADD_CALLBACK_FUNCTION(Tatiana, trapCath);
85 	ADD_CALLBACK_FUNCTION_II(Tatiana, function42);
86 	ADD_CALLBACK_FUNCTION(Tatiana, chapter4);
87 	ADD_CALLBACK_FUNCTION(Tatiana, inCompartment4);
88 	ADD_CALLBACK_FUNCTION(Tatiana, meetAlexei);
89 	ADD_CALLBACK_FUNCTION_TYPE(Tatiana, withAlexei, EntityParametersI5S);
90 	ADD_CALLBACK_FUNCTION(Tatiana, thinking);
91 	ADD_CALLBACK_FUNCTION(Tatiana, seekCath);
92 	ADD_CALLBACK_FUNCTION(Tatiana, function49);
93 	ADD_CALLBACK_FUNCTION(Tatiana, alexeiDead);
94 	ADD_CALLBACK_FUNCTION(Tatiana, function51);
95 	ADD_CALLBACK_FUNCTION(Tatiana, chapter5);
96 	ADD_CALLBACK_FUNCTION(Tatiana, chapter5Handler);
97 	ADD_CALLBACK_FUNCTION(Tatiana, autistic);
98 	ADD_CALLBACK_FUNCTION(Tatiana, function55);
99 }
100 
101 //////////////////////////////////////////////////////////////////////////
102 IMPLEMENT_FUNCTION(1, Tatiana, reset)
103 	Entity::reset(savepoint, kClothes3, true);
104 IMPLEMENT_FUNCTION_END
105 
106 //////////////////////////////////////////////////////////////////////////
107 IMPLEMENT_FUNCTION_S(2, Tatiana, playSound)
108 	Entity::playSound(savepoint);
109 IMPLEMENT_FUNCTION_END
110 
111 //////////////////////////////////////////////////////////////////////////
112 IMPLEMENT_FUNCTION_S(3, Tatiana, draw)
113 	Entity::draw(savepoint);
114 IMPLEMENT_FUNCTION_END
115 
116 //////////////////////////////////////////////////////////////////////////
117 IMPLEMENT_FUNCTION_SII(4, Tatiana, updatePosition, CarIndex, Position)
118 	Entity::updatePosition(savepoint);
119 IMPLEMENT_FUNCTION_END
120 
121 //////////////////////////////////////////////////////////////////////////
122 IMPLEMENT_FUNCTION_SI(5, Tatiana, enterExitCompartment, ObjectIndex)
123 	Entity::enterExitCompartment(savepoint);
124 IMPLEMENT_FUNCTION_END
125 
126 //////////////////////////////////////////////////////////////////////////
127 IMPLEMENT_FUNCTION_SI(6, Tatiana, enterExitCompartment2, ObjectIndex)
128 	Entity::enterExitCompartment(savepoint, kPosition_7500, kPosition_7850, kCarRedSleeping, kObjectCompartmentB);
129 IMPLEMENT_FUNCTION_END
130 
131 //////////////////////////////////////////////////////////////////////////
132 IMPLEMENT_FUNCTION_SIIS(7, Tatiana, callSavepoint, EntityIndex, ActionIndex)
133 	Entity::callSavepoint(savepoint);
134 IMPLEMENT_FUNCTION_END
135 
136 //////////////////////////////////////////////////////////////////////////
137 IMPLEMENT_FUNCTION(8, Tatiana, callbackActionOnDirection)
138 	Entity::callbackActionOnDirection(savepoint);
139 IMPLEMENT_FUNCTION_END
140 
141 //////////////////////////////////////////////////////////////////////////
142 IMPLEMENT_FUNCTION_NOSETUP(9, Tatiana, updateFromTicks)
143 	Entity::updateFromTicks(savepoint);
144 IMPLEMENT_FUNCTION_END
145 
146 //////////////////////////////////////////////////////////////////////////
147 IMPLEMENT_FUNCTION_I(10, Tatiana, updateFromTime, uint32)
148 	Entity::updateFromTime(savepoint);
149 IMPLEMENT_FUNCTION_END
150 
151 //////////////////////////////////////////////////////////////////////////
152 IMPLEMENT_FUNCTION(11, Tatiana, callbackActionRestaurantOrSalon)
153 	Entity::callbackActionRestaurantOrSalon(savepoint);
154 IMPLEMENT_FUNCTION_END
155 
156 //////////////////////////////////////////////////////////////////////////
157 IMPLEMENT_FUNCTION_II(12, Tatiana, savegame, SavegameType, uint32)
158 	Entity::savegame(savepoint);
159 IMPLEMENT_FUNCTION_END
160 
161 //////////////////////////////////////////////////////////////////////////
162 IMPLEMENT_FUNCTION_II(13, Tatiana, updateEntity, CarIndex, EntityPosition)
163 	if (savepoint.action == kActionExcuseMeCath) {
164 		if (getEvent(kEventTatianaAskMatchSpeakRussian) || getEvent(kEventTatianaAskMatch) || getEvent(kEventVassiliSeizure)) {
165 			getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1010" : "CAT1010A");
166 		} else {
167 			getSound()->excuseMeCath();
168 		}
169 		return;
170 	}
171 
172 	Entity::updateEntity(savepoint, true);
173 IMPLEMENT_FUNCTION_END
174 
175 //////////////////////////////////////////////////////////////////////////
176 IMPLEMENT_FUNCTION(14, Tatiana, enterCompartment)
177 	switch (savepoint.action) {
178 	default:
179 		break;
180 
181 	case kActionDefault:
182 		getSavePoints()->push(kEntityTatiana, kEntityCoudert, kAction326348944);
183 		getEntities()->drawSequenceLeft(kEntityTatiana, getProgress().chapter == kChapter1 ? "603Fb" : "673Fb");
184 		getEntities()->enterCompartment(kEntityTatiana, kObjectCompartmentB, true);
185 		break;
186 
187 	case kActionCallback:
188 		if (getCallback() == 1 || getCallback() == 2) {
189 			getEntities()->exitCompartment(kEntityTatiana, kObjectCompartmentB, true);
190 			getData()->location = kLocationInsideCompartment;
191 			getEntities()->clearSequences(kEntityTatiana);
192 
193 			callbackAction();
194 		}
195 		break;
196 
197 	case kAction69239528:
198 		setCallback(getProgress().chapter == kChapter1 ? 1 : 2);
199 		setup_enterExitCompartment2(getProgress().chapter == kChapter1 ? "603Db" : "673Db", kObjectCompartmentB);
200 		break;
201 	}
202 IMPLEMENT_FUNCTION_END
203 
204 //////////////////////////////////////////////////////////////////////////
205 IMPLEMENT_FUNCTION(15, Tatiana, exitCompartment)
206 	switch (savepoint.action) {
207 	default:
208 		break;
209 
210 	case kActionDefault:
211 		setCallback(getProgress().chapter == kChapter1 ? 1 : 2);
212 		setup_enterExitCompartment(getProgress().chapter == kChapter1 ? "603Bb" : "673Bb", kObjectCompartmentB);
213 		break;
214 
215 	case kActionCallback:
216 		if (getCallback() == 1 || getCallback() == 2) {
217 			getData()->location = kLocationOutsideCompartment;
218 			getSavePoints()->push(kEntityTatiana, kEntityCoudert, kAction292048641);
219 
220 			getEntities()->drawSequenceLeft(kEntityTatiana, getProgress().chapter == kChapter1 ? "603Fb" : "673Fb");
221 			getEntities()->enterCompartment(kEntityTatiana, kObjectCompartmentB, true);
222 		}
223 		break;
224 
225 	case kAction69239528:
226 		getEntities()->exitCompartment(kEntityTatiana, kObjectCompartmentB, true);
227 		getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
228 
229 		callbackAction();
230 		break;
231 	}
232 IMPLEMENT_FUNCTION_END
233 
234 //////////////////////////////////////////////////////////////////////////
235 IMPLEMENT_FUNCTION_I(16, Tatiana, handleCompartment, uint32)
236 	switch (savepoint.action) {
237 	default:
238 		break;
239 
240 	case kActionNone:
241 		if (params->param1 < getState()->time && !params->param4) {
242 			params->param4 = 1;
243 
244 			getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
245 			getObjects()->update(kObject49, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
246 
247 			callbackAction();
248 			break;
249 		}
250 
251 		if (params->param2) {
252 			if (!Entity::updateParameter(params->param5, getState()->timeTicks, 75))
253 				break;
254 
255 			params->param2 = 0;
256 			params->param3 = 1;
257 
258 			getObjects()->update(kObjectCompartmentB, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorNormal);
259 			getObjects()->update(kObject49, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorNormal);
260 		}
261 
262 		params->param5 = 0;
263 		break;
264 
265 	case kActionKnock:
266 	case kActionOpenDoor:
267 		if (params->param2) {
268 			getObjects()->update(kObjectCompartmentB, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorNormal);
269 			getObjects()->update(kObject49, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorNormal);
270 
271 			if (savepoint.param.intValue == 49) {
272 				setCallback(4);
273 				setup_playSound(getSound()->justAMinuteCath());
274 				break;
275 			}
276 
277 			if (getInventory()->hasItem(kItemPassengerList)) {
278 				setCallback(5);
279 				setup_playSound(rnd(2) ? "CAT1512" : getSound()->wrongDoorCath());
280 				break;
281 			}
282 
283 			setCallback(6);
284 			setup_playSound(getSound()->wrongDoorCath());
285 		} else {
286 			getObjects()->update(kObjectCompartmentB, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorNormal);
287 			getObjects()->update(kObject49, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorNormal);
288 
289 			setCallback(savepoint.action == kActionKnock ? 1 : 2);
290 			setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
291 		}
292 		break;
293 
294 	case kActionDefault:
295 		getObjects()->update(kObjectCompartmentB, kEntityTatiana, kObjectLocation1, kCursorHandKnock, kCursorHand);
296 		getObjects()->update(kObject49, kEntityTatiana, kObjectLocation1, kCursorHandKnock, kCursorHand);
297 		break;
298 
299 	case kActionDrawScene:
300 		if (params->param2 || params->param3) {
301 			getObjects()->update(kObjectCompartmentB, kEntityTatiana, kObjectLocation1, kCursorHandKnock, kCursorHand);
302 			getObjects()->update(kObject49, kEntityTatiana, kObjectLocation1, kCursorHandKnock, kCursorHand);
303 
304 			params->param2 = 0;
305 			params->param3 = 0;
306 		}
307 		break;
308 
309 	case kActionCallback:
310 		switch (getCallback()) {
311 		default:
312 			break;
313 
314 		case 1:
315 		case 2:
316 			setCallback(3);
317 			setup_playSound(rnd(2) ? "TAT1133A" : "TAT1133B");
318 			break;
319 
320 		case 3:
321 			getObjects()->update(kObjectCompartmentB, kEntityTatiana, kObjectLocation1, kCursorTalk, kCursorNormal);
322 			getObjects()->update(kObject49, kEntityTatiana, kObjectLocation1, kCursorTalk, kCursorNormal);
323 			params->param2 = 1;
324 			break;
325 
326 		case 4:
327 		case 5:
328 		case 6:
329 			params->param2 = 0;
330 			params->param3 = 1;
331 			break;
332 		}
333 		break;
334 	}
335 IMPLEMENT_FUNCTION_END
336 
337 //////////////////////////////////////////////////////////////////////////
338 IMPLEMENT_FUNCTION(17, Tatiana, chapter1)
339 	switch (savepoint.action) {
340 	default:
341 		break;
342 
343 	case kActionNone:
344 		Entity::timeCheck(kTimeChapter1, params->param1, WRAP_SETUP_FUNCTION(Tatiana, setup_chapter1Handler));
345 		break;
346 
347 	case kActionDefault:
348 		getSavePoints()->addData(kEntityTatiana, kAction191198209, 0);
349 
350 		getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
351 		getObjects()->update(kObject49, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
352 		getObjects()->update(kObject41, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
353 
354 		getData()->entityPosition = kPosition_5419;
355 		getData()->location = kLocationInsideCompartment;
356 		getData()->car = kCarRestaurant;
357 		break;
358 	}
359 IMPLEMENT_FUNCTION_END
360 
361 //////////////////////////////////////////////////////////////////////////
362 IMPLEMENT_FUNCTION(18, Tatiana, function18)
363 	switch (savepoint.action) {
364 	default:
365 		break;
366 
367 	case kActionNone:
368 		if (!params->param1) {
369 
370 			if (getState()->time > kTime1143000 && !params->param2) {
371 				params->param2 = 1;
372 				getEntities()->drawSequenceRight(kEntityTatiana, "806DS");
373 				params->param1 = 1;
374 			}
375 
376 			if (!params->param1) {
377 				if (Entity::updateParameter(params->param3, getState()->time, 4500)) {
378 					getEntities()->drawSequenceRight(kEntityTatiana, "806DS");
379 					params->param1 = 1;
380 				}
381 			}
382 		}
383 
384 		if (getData()->entityPosition <= kPosition_2330) {
385 			getSavePoints()->push(kEntityTatiana, kEntityAlexei, kAction157159392);
386 			getEntities()->clearSequences(kEntityTatiana);
387 
388 			callbackAction();
389 		}
390 		break;
391 
392 	case kActionExitCompartment:
393 		getSavePoints()->push(kEntityTatiana, kEntityAlexei, kAction188784532);
394 
395 		callbackAction();
396 		break;
397 
398 	case kActionDefault:
399 		if (getEntities()->isInSalon(kEntityPlayer)) {
400 			getEntities()->drawSequenceRight(kEntityTatiana, "806DS");
401 			params->param1 = 1;
402 		} else {
403 			getEntities()->clearSequences(kEntityTatiana);
404 		}
405 		break;
406 
407 	case kActionDrawScene:
408 		if (!params->param1 && getEntities()->isInSalon(kEntityPlayer)) {
409 			getEntities()->drawSequenceRight(kEntityTatiana, "806DS");
410 			getEntities()->updateFrame(kEntityTatiana);
411 			params->param1 = 1;
412 		}
413 		break;
414 	}
415 IMPLEMENT_FUNCTION_END
416 
417 //////////////////////////////////////////////////////////////////////////
418 IMPLEMENT_FUNCTION(19, Tatiana, chapter1Handler)
419 	switch (savepoint.action) {
420 	default:
421 		break;
422 
423 	case kActionNone:
424 		if (getSoundQueue()->isBuffered(kEntityTatiana) || !params->param4 || params->param3 >= 2 || getSoundQueue()->isBuffered("TAT1066"))
425 			goto label_tatiana_chapter1_2;
426 
427 		if (Entity::updateParameter(params->param5, getState()->timeTicks, 450)) {
428 			getSound()->playSound(kEntityTatiana, params->param3 ? "TAT1069B" : "TAT1069A");
429 			getProgress().field_64 = 1;
430 			params->param3++;
431 			params->param5 = 0;
432 		}
433 
434 		if (getEntities()->isPlayerPosition(kCarRestaurant, 71)) {
435 			if (Entity::updateParameter(params->param6, getState()->timeTicks, 75)) {
436 				getSound()->playSound(kEntityTatiana, params->param3 ? "TAT1069B" : "TAT1069A");
437 				getProgress().field_64 = 1;
438 				params->param3++;
439 				params->param6 = 0;
440 			}
441 		}
442 
443 label_tatiana_chapter1_2:
444 		Entity::timeCheckSavepoint(kTime1084500, params->param7, kEntityTatiana, kEntityPascale, kAction257489762);
445 
446 		if (params->param1) {
447 			if (!Entity::updateParameter(params->param8, getState()->timeTicks, 90))
448 				break;
449 
450 			getScenes()->loadSceneFromPosition(kCarRestaurant, 65);
451 		} else {
452 			params->param8 = 0;
453 		}
454 		break;
455 
456 	case kActionDefault:
457 		getSavePoints()->push(kEntityTatiana, kEntityTables4, kAction136455232);
458 		getEntities()->drawSequenceLeft(kEntityTatiana, "014A");
459 		break;
460 
461 	case kActionDrawScene:
462 		params->param1 = getEntities()->isPlayerPosition(kCarRestaurant, 67) ? 1 : 0;
463 		params->param4 = getEntities()->isPlayerPosition(kCarRestaurant, 69)
464 		              || getEntities()->isPlayerPosition(kCarRestaurant, 70)
465 		              || getEntities()->isPlayerPosition(kCarRestaurant, 71);
466 		break;
467 
468 	case kAction122288808:
469 		getEntities()->drawSequenceLeft(kEntityTatiana, "014A");
470 		break;
471 
472 	case kAction122358304:
473 		getEntities()->drawSequenceLeft(kEntityTatiana, "BLANK");
474 		break;
475 
476 	case kAction124973510:
477 		setup_exitDining();
478 		break;
479 	}
480 IMPLEMENT_FUNCTION_END
481 
482 //////////////////////////////////////////////////////////////////////////
483 IMPLEMENT_FUNCTION(20, Tatiana, exitDining)
484 	switch (savepoint.action) {
485 	default:
486 		break;
487 
488 	case kActionDefault:
489 		setCallback(1);
490 		setup_callbackActionRestaurantOrSalon();
491 		break;
492 
493 	case kActionCallback:
494 		switch (getCallback()) {
495 		default:
496 			break;
497 
498 		case 1:
499 			getData()->location = kLocationOutsideCompartment;
500 			getSavePoints()->push(kEntityTatiana, kEntityAugust, kAction223183000);
501 			getEntities()->updatePositionEnter(kEntityTatiana, kCarRestaurant, 67);
502 			getSound()->playSound(kEntityTatiana, "TAT1070");
503 
504 			setCallback(2);
505 			setup_callSavepoint("014C", kEntityTables4, kActionDrawTablesWithChairs, "014D");
506 			break;
507 
508 		case 2:
509 			getEntities()->updatePositionExit(kEntityTatiana, kCarRestaurant, 67);
510 			getSavePoints()->push(kEntityTatiana, kEntityWaiter1, kAction188893625);
511 
512 			setCallback(3);
513 			setup_function18();
514 			break;
515 
516 		case 3:
517 			getSavePoints()->push(kEntityTatiana, kEntityAugust, kAction268620864);
518 			setup_returnToCompartment();
519 			break;
520 		}
521 		break;
522 	}
523 IMPLEMENT_FUNCTION_END
524 
525 //////////////////////////////////////////////////////////////////////////
526 IMPLEMENT_FUNCTION(21, Tatiana, returnToCompartment)
527 	switch (savepoint.action) {
528 	default:
529 		break;
530 
531 	case kActionDefault:
532 		getData()->clothes = kClothes1;
533 
534 		setCallback(1);
535 		setup_updateEntity(kCarRedSleeping, kPosition_8513);
536 		break;
537 
538 	case kActionCallback:
539 		switch (getCallback()) {
540 		default:
541 			break;
542 
543 		case 1:
544 			getData()->clothes = kClothesDefault;
545 
546 			getSound()->playSound(kEntityTatiana, "TAT1071");
547 			getEntities()->drawSequenceRight(kEntityTatiana, "604Aa");
548 			getEntities()->enterCompartment(kEntityTatiana, kObjectCompartmentA);
549 
550 			getData()->location = kLocationInsideCompartment;
551 
552 			if (getEntities()->checkFields19(kEntityPlayer, kCarRedSleeping, kPosition_7850)) {
553 				getAction()->playAnimation(isNight() ? kEventCathTurningNight : kEventCathTurningDay);
554 				getSound()->playSound(kEntityPlayer, "BUMP");
555 				getScenes()->loadSceneFromObject(kObjectCompartmentA, true);
556 			}
557 
558 			setCallback(2);
559 			setup_callbackActionOnDirection();
560 			break;
561 
562 		case 2:
563 			getEntities()->exitCompartment(kEntityTatiana, kObjectCompartmentA);
564 
565 			getData()->location = kLocationInsideCompartment;
566 
567 			getEntities()->clearSequences(kEntityTatiana);
568 			getSavePoints()->push(kEntityTatiana, kEntityAlexei, kAction135854208);
569 			getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
570 			getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
571 			// fall through
572 
573 		case 3:
574 			if (getSoundQueue()->isBuffered(kEntityTatiana)) {
575 				setCallback(3);
576 				setup_updateFromTime(75);
577 			} else {
578 				setCallback(4);
579 				setup_playSound("TAT1071A");
580 			}
581 			break;
582 
583 		case 4:
584 			getData()->entityPosition = kPosition_7500;
585 
586 			getSavePoints()->push(kEntityTatiana, kEntityVassili, kAction168459827);
587 
588 			setCallback(5);
589 			setup_handleCompartment(kTime1156500);
590 			break;
591 
592 		case 5:
593 		case 6:
594 			if (getProgress().field_14 == 29) {
595 				setCallback(6);
596 				setup_handleCompartment((uint)getState()->time + 900);
597 			} else {
598 				getObjects()->update(kObject49, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
599 
600 				setup_getSomeAir();
601 			}
602 			break;
603 		}
604 		break;
605 	}
606 IMPLEMENT_FUNCTION_END
607 
608 //////////////////////////////////////////////////////////////////////////
609 IMPLEMENT_FUNCTION(22, Tatiana, getSomeAir)
610 	switch (savepoint.action) {
611 	default:
612 		break;
613 
614 	case kActionNone:
615 		if (params->param1 == kTimeInvalid || getState()->time <= kTime1179000)
616 			goto label_update;
617 
618 		if (!Entity::updateParameterTime(kTime1233000, ((!getEvent(kEventTatianaAskMatchSpeakRussian) && !getEvent(kEventTatianaAskMatch)) || getEntities()->isInGreenCarEntrance(kEntityPlayer)), params->param1, 0)) {
619 
620 label_update:
621 			if (!getEvent(kEventTatianaAskMatchSpeakRussian)
622 			 && !getEvent(kEventTatianaAskMatch)
623 			 && getInventory()->hasItem(kItemMatchBox)
624 			 && getEntities()->isInGreenCarEntrance(kEntityPlayer)) {
625 				getObjects()->update(kObject25, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorForward);
626 				getObjects()->update(kObjectTrainTimeTable, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorForward);
627 			}
628 			break;
629 		}
630 
631 		getObjects()->update(kObject25, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
632 		getObjects()->update(kObjectTrainTimeTable, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
633 		getEntities()->updatePositionExit(kEntityTatiana, kCarGreenSleeping, 70);
634 		getEntities()->updatePositionExit(kEntityTatiana, kCarGreenSleeping, 71);
635 
636 		if (getEntities()->isInGreenCarEntrance(kEntityPlayer)) {
637 			getSound()->excuseMe(kEntityTatiana);
638 
639 			if (getEntities()->isPlayerPosition(kCarGreenSleeping, 62))
640 				getScenes()->loadSceneFromPosition(kCarGreenSleeping, 72);
641 		}
642 
643 		getData()->inventoryItem = kItemNone;
644 
645 		setup_returnToCompartmentAgain();
646 		break;
647 
648 	case kAction1:
649 		getData()->inventoryItem = kItemNone;
650 
651 		setCallback(4);
652 		setup_savegame(kSavegameTypeEvent, kEventTatianaGivePoem);
653 		break;
654 
655 	case kActionOpenDoor:
656 		setCallback(3);
657 		setup_savegame(kSavegameTypeEvent, kEventTatianaAskMatchSpeakRussian);
658 		break;
659 
660 	case kActionDefault:
661 		getSavePoints()->push(kEntityTatiana, kEntityVassili, kAction122732000);
662 
663 		setCallback(1);
664 		setup_exitCompartment();
665 		break;
666 
667 	case kActionCallback:
668 		switch (getCallback()) {
669 		default:
670 			break;
671 
672 		case 1:
673 			setCallback(2);
674 			setup_updateEntity(kCarGreenSleeping, kPosition_540);
675 			break;
676 
677 		case 2:
678 			if (getEntities()->isInGreenCarEntrance(kEntityPlayer)) {
679 				getSound()->excuseMe(kEntityTatiana);
680 
681 				if (getEntities()->isPlayerPosition(kCarGreenSleeping, 62))
682 					getScenes()->loadSceneFromPosition(kCarGreenSleeping, 72);
683 			}
684 
685 			getEntities()->drawSequenceLeft(kEntityTatiana, "306B");
686 			getEntities()->updatePositionEnter(kEntityTatiana, kCarGreenSleeping, 70);
687 			getEntities()->updatePositionEnter(kEntityTatiana, kCarGreenSleeping, 71);
688 			break;
689 
690 		case 3:
691 			getAction()->playAnimation(getEvent(kEventAlexeiSalonVassili) ? kEventTatianaAskMatchSpeakRussian : kEventTatianaAskMatch);
692 			getScenes()->loadSceneFromPosition(kCarGreenSleeping, 62);
693 			getData()->inventoryItem = kItemParchemin;
694 
695 			getObjects()->update(kObject25, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
696 			getObjects()->update(kObjectTrainTimeTable, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
697 			break;
698 
699 		case 4:
700 			getAction()->playAnimation(kEventTatianaGivePoem);
701 			getInventory()->removeItem(kItemParchemin);
702 			getScenes()->processScene();
703 			break;
704 		}
705 		break;
706 	}
707 IMPLEMENT_FUNCTION_END
708 
709 //////////////////////////////////////////////////////////////////////////
710 IMPLEMENT_FUNCTION(23, Tatiana, returnToCompartmentAgain)
711 	switch (savepoint.action) {
712 	default:
713 		break;
714 
715 	case kActionDefault:
716 		setCallback(1);
717 		setup_updateEntity(kCarRedSleeping, kPosition_7500);
718 		break;
719 
720 	case kActionCallback:
721 		switch (getCallback()) {
722 		default:
723 			break;
724 
725 		case 1:
726 			setCallback(2);
727 			setup_enterCompartment();
728 			break;
729 
730 		case 2:
731 			setup_function24();
732 			break;
733 		}
734 		break;
735 	}
736 IMPLEMENT_FUNCTION_END
737 
738 //////////////////////////////////////////////////////////////////////////
739 IMPLEMENT_FUNCTION(24, Tatiana, function24)
740 	if (savepoint.action == kActionDefault) {
741 
742 		getData()->entityPosition = kPosition_7500;
743 		getData()->location = kLocationInsideCompartment;
744 		getData()->car = kCarRedSleeping;
745 
746 		getObjects()->update(kObject25, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
747 		getObjects()->update(kObjectTrainTimeTable, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
748 
749 		getEntities()->updatePositionExit(kEntityTatiana, kCarGreenSleeping, 70);
750 		getEntities()->updatePositionExit(kEntityTatiana, kCarGreenSleeping, 71);
751 		getEntities()->clearSequences(kEntityTatiana);
752 
753 		getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
754 		getObjects()->update(kObject49, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
755 		getObjects()->update(kObject41, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
756 	}
757 IMPLEMENT_FUNCTION_END
758 
759 //////////////////////////////////////////////////////////////////////////
760 IMPLEMENT_FUNCTION(25, Tatiana, chapter2)
761 	switch (savepoint.action) {
762 	default:
763 		break;
764 
765 	case kActionNone:
766 		setup_chapter2Handler();
767 		break;
768 
769 	case kActionDefault:
770 		getEntities()->clearSequences(kEntityTatiana);
771 
772 		getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
773 		getObjects()->update(kObject49, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
774 		getObjects()->update(kObject41, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
775 
776 		getData()->entityPosition = kPosition_5420;
777 		getData()->location = kLocationInsideCompartment;
778 		getData()->car = kCarRestaurant;
779 		getData()->clothes = kClothes2;
780 		break;
781 	}
782 IMPLEMENT_FUNCTION_END
783 
784 //////////////////////////////////////////////////////////////////////////
785 IMPLEMENT_FUNCTION(26, Tatiana, chapter2Handler)
786 	switch (savepoint.action) {
787 	default:
788 		break;
789 
790 	case kActionNone:
791 		if (getState()->time > kTime1800000 && params->param1 && getEntities()->isSomebodyInsideRestaurantOrSalon()) {
792 			getData()->inventoryItem = kItemNone;
793 			setup_joinAlexei();
794 		}
795 		break;
796 
797 	case kAction1:
798 		getData()->inventoryItem = kItemNone;
799 		setup_breakfastClick();
800 		break;
801 
802 	case kActionDefault:
803 		getEntities()->drawSequenceLeft(kEntityTatiana, "024A");
804 		getSavePoints()->push(kEntityTatiana, kEntityTables5, kAction136455232);
805 		getData()->inventoryItem = kItemInvalid;
806 		break;
807 
808 	case kActionDrawScene:
809 		if (getEntities()->isPlayerPosition(kCarRestaurant, 64) || getEntities()->isPlayerPosition(kCarRestaurant, 65)) {
810 			getData()->inventoryItem = kItemNone;
811 			setup_breakfastClick();
812 		}
813 		break;
814 
815 	case kAction290869168:
816 		params->param1 = 1;
817 		break;
818 	}
819 IMPLEMENT_FUNCTION_END
820 
821 //////////////////////////////////////////////////////////////////////////
822 IMPLEMENT_FUNCTION(27, Tatiana, breakfastClick)
823 	switch (savepoint.action) {
824 	default:
825 		break;
826 
827 	case kActionDefault:
828 		setCallback(getEvent(kEventTatianaGivePoem) ? 1 : 2);
829 		setup_savegame(kSavegameTypeEvent, getEvent(kEventTatianaGivePoem) ? kEventTatianaBreakfastAlexei : kEventTatianaBreakfast);
830 		break;
831 
832 	case kActionCallback:
833 		switch (getCallback()) {
834 		default:
835 			break;
836 
837 		case 1:
838 			RESET_ENTITY_STATE(kEntityAlexei, Alexei, setup_atBreakfast);
839 			getAction()->playAnimation(kEventTatianaBreakfastAlexei);
840 			getInventory()->addItem(kItemParchemin);
841 			getInventory()->setLocationAndProcess(kItem11, kObjectLocation1);
842 			setup_joinAlexei();
843 			break;
844 
845 		case 2:
846 			RESET_ENTITY_STATE(kEntityAlexei, Alexei, setup_atBreakfast);
847 			getAction()->playAnimation(kEventTatianaBreakfast);
848 			if (getInventory()->hasItem(kItemParchemin)) {
849 				getAction()->playAnimation(kEventTatianaBreakfastGivePoem);
850 				getInventory()->removeItem(kItemParchemin);
851 			} else {
852 				getAction()->playAnimation(kEventTatianaAlexei);
853 			}
854 			setup_joinAlexei();
855 			break;
856 		}
857 		break;
858 	}
859 IMPLEMENT_FUNCTION_END
860 
861 //////////////////////////////////////////////////////////////////////////
862 IMPLEMENT_FUNCTION(28, Tatiana, joinAlexei)
863 	switch (savepoint.action) {
864 	default:
865 		break;
866 
867 	case kActionDefault:
868 		getData()->inventoryItem = kItemNone;
869 		getData()->location = kLocationOutsideCompartment;
870 
871 		getSavePoints()->push(kEntityTatiana, kEntityTables5, kActionDrawTablesWithChairs, "024D");
872 		getSavePoints()->push(kEntityTatiana, kEntityAlexei, kAction236053296, (getEvent(kEventTatianaBreakfastAlexei) || getEvent(kEventTatianaBreakfast)) ? 69 : 0);
873 		break;
874 
875 	case kActionCallback:
876 		if (getCallback() == 1)
877 			setup_leaveBreakfast();
878 		break;
879 
880 	case kAction123857088:
881 		getEntities()->drawSequenceLeft(kEntityTatiana, "018G");
882 
883 		setCallback(1);
884 		setup_updateFromTime(1800);
885 		break;
886 
887 	case kAction156444784:
888 		getData()->location = kLocationInsideCompartment;
889 		getEntities()->drawSequenceLeft(kEntityTatiana, "BLANK");
890 		break;
891 	}
892 IMPLEMENT_FUNCTION_END
893 
894 //////////////////////////////////////////////////////////////////////////
895 IMPLEMENT_FUNCTION(29, Tatiana, leaveBreakfast)
896 	switch (savepoint.action) {
897 	default:
898 		break;
899 
900 	case kActionDefault:
901 		setCallback(1);
902 		setup_callbackActionRestaurantOrSalon();
903 		break;
904 
905 	case kActionCallback:
906 		switch (getCallback()) {
907 		default:
908 			break;
909 
910 		case 1:
911 			getData()->location = kLocationOutsideCompartment;
912 			getEntities()->updatePositionEnter(kEntityTatiana, kCarRestaurant, 63);
913 
914 			setCallback(2);
915 			setup_callSavepoint("018H", kEntityTables1, kActionDrawTablesWithChairs, "018A");
916 			break;
917 
918 		case 2:
919 			getEntities()->updatePositionExit(kEntityTatiana, kCarRestaurant, 63);
920 			getSavePoints()->push(kEntityTatiana, kEntityWaiter2, kAction302203328);
921 			getEntities()->drawSequenceRight(kEntityTatiana, "805DS");
922 
923 			if (getEntities()->isInRestaurant(kEntityPlayer))
924 				getEntities()->updateFrame(kEntityTatiana);
925 
926 			setCallback(3);
927 			setup_callbackActionOnDirection();
928 			break;
929 
930 		case 3:
931 			setup_returnToCompartment2();
932 			break;
933 		}
934 		break;
935 	}
936 IMPLEMENT_FUNCTION_END
937 
938 //////////////////////////////////////////////////////////////////////////
939 IMPLEMENT_FUNCTION(30, Tatiana, returnToCompartment2)
940 	switch (savepoint.action) {
941 	default:
942 		break;
943 
944 	case kActionDefault:
945 		setCallback(1);
946 		setup_updateEntity(kCarRedSleeping, kPosition_7500);
947 		break;
948 
949 	case kActionCallback:
950 		switch (getCallback()) {
951 		default:
952 			break;
953 
954 		case 1:
955 			setCallback(2);
956 			setup_enterCompartment();
957 			break;
958 
959 		case 2:
960 			setCallback(3);
961 			setup_handleCompartment(kTimeEnd);
962 			break;
963 		}
964 		break;
965 	}
966 IMPLEMENT_FUNCTION_END
967 
968 //////////////////////////////////////////////////////////////////////////
969 IMPLEMENT_FUNCTION(31, Tatiana, chapter3)
970 	switch (savepoint.action) {
971 	default:
972 		break;
973 
974 	case kActionNone:
975 		setup_playChess();
976 		break;
977 
978 	case kActionDefault:
979 		getEntities()->clearSequences(kEntityTatiana);
980 
981 		getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
982 		getObjects()->update(kObject49, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
983 
984 		getData()->entityPosition = kPosition_1750;
985 		getData()->location = kLocationInsideCompartment;
986 		getData()->car = kCarRestaurant;
987 		getData()->clothes = kClothes2;
988 		getData()->inventoryItem = kItemNone;
989 
990 		// Update inventory
991 		getInventory()->get(kItemFirebird)->location = kObjectLocation2;
992 
993 		if (getEvent(kEventTatianaBreakfastGivePoem) || (getEvent(kEventTatianaGivePoem) && !getEvent(kEventTatianaBreakfastAlexei)))
994 			getInventory()->get(kItemParchemin)->location = kObjectLocation2;
995 
996 		break;
997 	}
998 IMPLEMENT_FUNCTION_END
999 
1000 //////////////////////////////////////////////////////////////////////////
1001 IMPLEMENT_FUNCTION(32, Tatiana, playChess)
1002 	EntityData::EntityParametersI5S  *parameters = (EntityData::EntityParametersI5S*)_data->getCurrentParameters();
1003 	EntityData::EntityParametersSIII *parameters1 = (EntityData::EntityParametersSIII*)_data->getCurrentParameters(1);
1004 
1005 	switch (savepoint.action) {
1006 	default:
1007 		break;
1008 
1009 	case kActionNone:
1010 		if (!parameters->param2 && !parameters->param5) {
1011 			parameters->param1 -= getState()->timeDelta;
1012 
1013 			if (getState()->timeDelta > parameters->param1) {
1014 
1015 				getEntities()->drawSequenceLeft(kEntityTatiana, (char *)&parameters1->seq);
1016 				getSound()->playSound(kEntityTatiana, (char *)&parameters->seq);
1017 
1018 				if (parameters->param3 == 4 && getEntities()->isInSalon(kEntityPlayer))
1019 					getProgress().field_90 = 1;
1020 
1021 				parameters->param2 = 1;
1022 			}
1023 		}
1024 
1025 		if (parameters->param4 && parameters->param5) {
1026 			if (Entity::updateParameterCheck(parameters1->param4, getState()->time, 6300)) {
1027 				if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
1028 					getData()->location = kLocationOutsideCompartment;
1029 
1030 					setCallback(1);
1031 					setup_updatePosition("110E", kCarRestaurant, 52);
1032 				}
1033 			}
1034 		}
1035 		break;
1036 
1037 	case  kActionEndSound:
1038 		parameters->param2 = 0;
1039 		++parameters->param3;
1040 
1041 		switch (parameters->param3) {
1042 		default:
1043 			parameters->param5 = 1;
1044 			break;
1045 
1046 		case 1:
1047 			parameters->param1 = 900;
1048 			getEntities()->drawSequenceLeft(kEntityTatiana, "110A");
1049 			strcpy((char *)&parameters->seq, "Tat3160B");
1050 			strcpy((char *)&parameters1->seq, "110A");
1051 			break;
1052 
1053 		case 2:
1054 			parameters->param1 = 9000;
1055 			strcpy((char *)&parameters->seq, "Tat3160C");
1056 			strcpy((char *)&parameters1->seq, "110C");
1057 			break;
1058 
1059 		case 3:
1060 			parameters->param1 = 13500;
1061 			getEntities()->drawSequenceLeft(kEntityTatiana, "110B");
1062 			strcpy((char *)&parameters->seq, "Tat3160D");
1063 			strcpy((char *)&parameters1->seq, "110D");
1064 			break;
1065 
1066 		case 4:
1067 			parameters->param1 = 9000;
1068 			getEntities()->drawSequenceLeft(kEntityTatiana, "110B");
1069 			strcpy((char *)&parameters->seq, "Tat3160E");
1070 			strcpy((char *)&parameters1->seq, "110D");
1071 			break;
1072 
1073 		case 5:
1074 			parameters->param1 = 4500;
1075 			getEntities()->drawSequenceLeft(kEntityTatiana, "110B");
1076 			strcpy((char *)&parameters->seq, "Tat3160G");
1077 			strcpy((char *)&parameters1->seq, "110D");
1078 			break;
1079 
1080 		case 6:
1081 			parameters->param1 = 4500;
1082 			getEntities()->drawSequenceLeft(kEntityTatiana, "110B");
1083 			strcpy((char *)&parameters->seq, "Tat3160F");
1084 			break;
1085 		}
1086 		break;
1087 
1088 	case kActionDefault:
1089 		getSavePoints()->push(kEntityTatiana, kEntityAlexei, kAction122358304);
1090 		getSavePoints()->push(kEntityTatiana, kEntityKronos, kAction157159392);
1091 		getEntities()->drawSequenceLeft(kEntityTatiana, "110C");
1092 		getSound()->playSound(kEntityTatiana, "Tat3160A");
1093 
1094 		parameters->param2 = 1;
1095 		break;
1096 
1097 	case kActionCallback:
1098 		if (getCallback() == 1) {
1099 			getSavePoints()->push(kEntityTatiana, kEntityAlexei, kAction122288808);
1100 			setup_returnToCompartment3();
1101 		}
1102 		break;
1103 
1104 	case kAction101169422:
1105 		parameters->param4 = 1;
1106 		break;
1107 	}
1108 IMPLEMENT_FUNCTION_END
1109 
1110 //////////////////////////////////////////////////////////////////////////
1111 IMPLEMENT_FUNCTION(33, Tatiana, returnToCompartment3)
1112 	switch (savepoint.action) {
1113 	default:
1114 		break;
1115 
1116 	case kActionDefault:
1117 		getEntities()->clearSequences(kEntityTatiana);
1118 		setCallback(1);
1119 		setup_updateFromTime(75);
1120 		break;
1121 
1122 	case kActionCallback:
1123 		switch (getCallback()) {
1124 		default:
1125 			break;
1126 
1127 		case 1:
1128 			setCallback(2);
1129 			setup_updateEntity(kCarRedSleeping, kPosition_7500);
1130 			break;
1131 
1132 		case 2:
1133 			setCallback(3);
1134 			setup_enterCompartment();
1135 			break;
1136 
1137 		case 3:
1138 			setup_beforeConcert();
1139 			break;
1140 		}
1141 		break;
1142 	}
1143 IMPLEMENT_FUNCTION_END
1144 
1145 //////////////////////////////////////////////////////////////////////////
1146 IMPLEMENT_FUNCTION(34, Tatiana, beforeConcert)
1147 	switch (savepoint.action) {
1148 	default:
1149 		break;
1150 
1151 	case kActionDefault:
1152 		setCallback(1);
1153 		setup_handleCompartment(kTime2097000);
1154 		break;
1155 
1156 	case kActionCallback:
1157 		switch (getCallback()) {
1158 		default:
1159 			break;
1160 
1161 		case 1:
1162 			getInventory()->get(kItemFirebird)->location = kObjectLocation1;
1163 			if (getEntities()->checkFields19(kEntityPlayer, kCarRedSleeping, kPosition_7850))
1164 				getScenes()->loadSceneFromObject(kObjectCompartmentB);
1165 
1166 			getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
1167 			getObjects()->update(kObject49, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
1168 			setCallback(2);
1169 			setup_exitCompartment();
1170 			break;
1171 
1172 		case 2:
1173 			setCallback(3);
1174 			setup_updateEntity(kCarKronos, kPosition_9270);
1175 			break;
1176 
1177 		case 3:
1178 			setup_concert();
1179 			break;
1180 		}
1181 		break;
1182 	}
1183 IMPLEMENT_FUNCTION_END
1184 
1185 //////////////////////////////////////////////////////////////////////////
1186 IMPLEMENT_FUNCTION(35, Tatiana, concert)
1187 	switch (savepoint.action) {
1188 	default:
1189 		break;
1190 
1191 	case kActionNone:
1192 		if (!params->param1
1193 		 && getInventory()->hasItem(kItemFirebird)
1194 		 && getEntities()->checkFields19(kEntityPlayer, kCarRedSleeping, kPosition_7850)
1195 		 && (getState()->time < kTime2133000 || getProgress().field_40)) {
1196 			setCallback(1);
1197 			setup_trapCath();
1198 			break;
1199 		}
1200 
1201 label_callback_1:
1202 		if (getState()->time > kTime2133000) {
1203 			if (getEntityData(kEntityAugust)->car >= kCarRedSleeping || (getEntityData(kEntityAugust)->car == kCarGreenSleeping && getEntityData(kEntityAugust)->entityPosition > kPosition_5790))
1204 				setup_leaveConcert();
1205 		}
1206 		break;
1207 
1208 	case kActionDefault:
1209 		getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
1210 		getObjects()->update(kObject49, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
1211 		getEntities()->clearSequences(kEntityTatiana);
1212 
1213 		getData()->car = kCarKronos;
1214 		getData()->entityPosition = kPosition_6000;
1215 		getData()->location = kLocationInsideCompartment;
1216 		break;
1217 
1218 	case kActionCallback:
1219 		if (getCallback() == 1) {
1220 			params->param1 = 1;
1221 			goto label_callback_1;
1222 		}
1223 		break;
1224 
1225 	case kAction191668032:
1226 		setup_leaveConcert();
1227 	}
1228 IMPLEMENT_FUNCTION_END
1229 
1230 //////////////////////////////////////////////////////////////////////////
1231 IMPLEMENT_FUNCTION(36, Tatiana, leaveConcert)
1232 	switch (savepoint.action) {
1233 	default:
1234 		break;
1235 
1236 	case kActionDefault:
1237 		getData()->car = kCarGreenSleeping;
1238 		getData()->entityPosition = kPosition_850;
1239 		getData()->location = kLocationOutsideCompartment;
1240 
1241 		setCallback(1);
1242 		setup_updateEntity(kCarRedSleeping, kPosition_7500);
1243 		break;
1244 
1245 	case kActionCallback:
1246 		switch (getCallback()) {
1247 		default:
1248 			break;
1249 
1250 		case 1:
1251 			if (!getEntities()->checkFields19(kEntityPlayer, kCarRedSleeping, kPosition_7850) || getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_8200)) {
1252 				setCallback(2);
1253 				setup_enterCompartment();
1254 				break;
1255 			}
1256 
1257 			if (getInventory()->hasItem(kItemFirebird)) {
1258 				getAction()->playAnimation(kEventTatianaCompartmentStealEgg);
1259 				getInventory()->removeItem(kItemFirebird);
1260 				getInventory()->get(kItemFirebird)->location = kObjectLocation2;
1261 			} else {
1262 				getAction()->playAnimation(kEventTatianaCompartment);
1263 			}
1264 
1265 			getScenes()->loadSceneFromObject(kObjectCompartmentB);
1266 			setup_afterConcert();
1267 			break;
1268 
1269 		case 2:
1270 			setup_afterConcert();
1271 			break;
1272 		}
1273 		break;
1274 	}
1275 IMPLEMENT_FUNCTION_END
1276 
1277 //////////////////////////////////////////////////////////////////////////
1278 IMPLEMENT_FUNCTION(37, Tatiana, afterConcert)
1279 	switch (savepoint.action) {
1280 	default:
1281 		break;
1282 
1283 	case kActionNone:
1284 		if (getInventory()->get(kItemFirebird)->location != kObjectLocation1 && getInventory()->get(kItemFirebird)->location != kObjectLocation2) {
1285 			if(!params->param3)
1286 				params->param3 = (uint)getState()->time + 900;
1287 
1288 			if (params->param4 != kTimeInvalid && params->param3 < getState()->time) {
1289 				if (Entity::updateParameterTime(kTime2227500, !getEntities()->isPlayerInCar(kCarRedSleeping), params->param4, 450)) {
1290 					getProgress().field_5C = 1;
1291 					if (getEntities()->isInsideCompartment(kEntityAnna, kCarRedSleeping, kPosition_4070)) {
1292 						setup_cryAnna();
1293 						break;
1294 					}
1295 				}
1296 			}
1297 		}
1298 
1299 		if (params->param1) {
1300 			if (!Entity::updateParameter(params->param5, getState()->timeTicks, 75))
1301 				break;
1302 
1303 			getObjects()->update(kObjectCompartmentB, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorNormal);
1304 			getObjects()->update(kObject49, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorNormal);
1305 
1306 			params->param1 = 0;
1307 			params->param2 = 1;
1308 		}
1309 
1310 		params->param5 = 0;
1311 		break;
1312 
1313 	case kActionKnock:
1314 	case kActionOpenDoor:
1315 		if (params->param1) {
1316 			getObjects()->update(kObjectCompartmentB, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorNormal);
1317 			getObjects()->update(kObject49, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorNormal);
1318 
1319 			if (savepoint.param.intValue == 49) {
1320 				setCallback(4);
1321 				setup_playSound(getSound()->justAMinuteCath());
1322 				break;
1323 			}
1324 
1325 			if (getInventory()->hasItem(kItemPassengerList)) {
1326 				setCallback(5);
1327 				setup_playSound(rnd(2) ? "CAT1512" : getSound()->wrongDoorCath());
1328 				break;
1329 			}
1330 
1331 			setCallback(6);
1332 			setup_playSound(getSound()->wrongDoorCath());
1333 			break;
1334 		}
1335 
1336 		if (savepoint.param.intValue == 49) {
1337 
1338 			if (getInventory()->hasItem(kItemFirebird)) {
1339 				getAction()->playAnimation(kEventTatianaCompartmentStealEgg);
1340 				getInventory()->removeItem(kItemFirebird);
1341 				getInventory()->get(kItemFirebird)->location = kObjectLocation2;
1342 			} else {
1343 				getAction()->playAnimation(kEventTatianaCompartment);
1344 			}
1345 
1346 			getScenes()->loadSceneFromObject(kObjectCompartmentB);
1347 			break;
1348 		}
1349 
1350 		getObjects()->update(kObjectCompartmentB, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorNormal);
1351 		getObjects()->update(kObject49, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorNormal);
1352 
1353 		setCallback(savepoint.action == kActionKnock ? 1 : 2);
1354 		setup_playSound(savepoint.action == kActionKnock ?  "LIB012" : "LIB013");
1355 		break;
1356 
1357 	case kActionDefault:
1358 		getObjects()->update(kObjectCompartmentB, kEntityTatiana, kObjectLocation1, kCursorHandKnock, kCursorHand);
1359 		getObjects()->update(kObject49, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorHand);
1360 
1361 		getData()->location = kLocationInsideCompartment;
1362 		getEntities()->clearSequences(kEntityTatiana);
1363 		break;
1364 
1365 	case kActionDrawScene:
1366 		if (params->param1 || params->param2) {
1367 			getObjects()->update(kObjectCompartmentB, kEntityTatiana, kObjectLocation1, kCursorHandKnock, kCursorHand);
1368 			getObjects()->update(kObject49, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorHand);
1369 
1370 			params->param1 = 0;
1371 			params->param2 = 0;
1372 		}
1373 		break;
1374 
1375 	case kActionCallback:
1376 		switch (getCallback()) {
1377 		default:
1378 			break;
1379 
1380 		case 1:
1381 		case 2:
1382 			setCallback(3);
1383 			setup_playSound(rnd(2) ? "TAT1133A" : "TAT1133B");
1384 			break;
1385 
1386 		case 3:
1387 			getObjects()->update(kObjectCompartmentB, kEntityTatiana, kObjectLocation1, kCursorTalk, kCursorNormal);
1388 			getObjects()->update(kObject49, kEntityTatiana, kObjectLocation1, kCursorTalk, kCursorNormal);
1389 			params->param1 = 1;
1390 			break;
1391 
1392 		case 4:
1393 		case 5:
1394 		case 6:
1395 			params->param1 = 0;
1396 			params->param2 = 1;
1397 			break;
1398 		}
1399 		break;
1400 	}
1401 IMPLEMENT_FUNCTION_END
1402 
1403 //////////////////////////////////////////////////////////////////////////
1404 IMPLEMENT_FUNCTION(38, Tatiana, cryAnna)
1405 	switch (savepoint.action) {
1406 	default:
1407 		break;
1408 
1409 	case kActionNone:
1410 		if (!Entity::updateParameter(params->param1, getState()->time, 450))
1411 			break;
1412 
1413 		getEntities()->exitCompartment(kEntityTatiana, kObjectCompartmentF, true);
1414 
1415 		setCallback(4);
1416 		setup_function42(kCarRedSleeping, kPosition_7500);
1417 		break;
1418 
1419 	case kActionDefault:
1420 		getData()->clothes = kClothes3;
1421 
1422 		setCallback(1);
1423 		setup_enterExitCompartment("673Jb", kObjectCompartmentB);
1424 		break;
1425 
1426 	case kActionCallback:
1427 		switch (getCallback()) {
1428 		default:
1429 			break;
1430 
1431 		case 1:
1432 			getData()->location = kLocationOutsideCompartment;
1433 			getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
1434 			getObjects()->update(kObject49, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
1435 
1436 			setCallback(2);
1437 			setup_function42(kCarRedSleeping, kPosition_4070);
1438 			break;
1439 
1440 		case 2:
1441 			getEntities()->drawSequenceLeft(kEntityTatiana, "673Gf");
1442 			getEntities()->enterCompartment(kEntityTatiana, kObjectCompartmentF, true);
1443 
1444 			setCallback(3);
1445 			setup_playSound("Tat3164");
1446 			break;
1447 
1448 		case 3:
1449 			getSavePoints()->push(kEntityTatiana, kEntityAnna, kAction236241630);
1450 			break;
1451 
1452 		case 4:
1453 			setCallback(5);
1454 			setup_enterExitCompartment2("673Db", kObjectCompartmentB);
1455 			break;
1456 
1457 		case 5:
1458 			getData()->location = kLocationInsideCompartment;
1459 			getEntities()->clearSequences(kEntityTatiana);
1460 
1461 			setup_function39();
1462 			break;
1463 
1464 		case 6:
1465 			getEntities()->exitCompartment(kEntityTatiana, kObjectCompartmentF, true);
1466 			getEntities()->clearSequences(kEntityTatiana);
1467 			getData()->location = kLocationInsideCompartment;
1468 
1469 			setCallback(7);
1470 			setup_playSound("ANN3011");
1471 			break;
1472 
1473 		case 7:
1474 			setCallback(8);
1475 			setup_updateFromTime(900);
1476 			break;
1477 
1478 		case 8:
1479 			setCallback(9);
1480 			setup_enterExitCompartment("673Jf", kObjectCompartmentF);
1481 			break;
1482 
1483 		case 9:
1484 			getData()->location = kLocationOutsideCompartment;
1485 
1486 			setCallback(10);
1487 			setup_function42(kCarRedSleeping, kPosition_7500);
1488 			break;
1489 
1490 		case 10:
1491 			getSavePoints()->push(kEntityTatiana, kEntityAnna, kAction236517970);
1492 
1493 			setCallback(11);
1494 			setup_enterExitCompartment2("673Db", kObjectCompartmentB);
1495 			break;
1496 
1497 		case 11:
1498 			getData()->location = kLocationInsideCompartment;
1499 			getEntities()->clearSequences(kEntityTatiana);
1500 
1501 			setup_function39();
1502 			break;
1503 		}
1504 		break;
1505 
1506 	case kAction100906246:
1507 		setCallback(6);
1508 		setup_enterExitCompartment("673Df", kObjectCompartmentF);
1509 		break;
1510 	}
1511 IMPLEMENT_FUNCTION_END
1512 
1513 //////////////////////////////////////////////////////////////////////////
1514 IMPLEMENT_FUNCTION(39, Tatiana, function39)
1515 	switch (savepoint.action) {
1516 	default:
1517 		break;
1518 
1519 	case kActionNone:
1520 		if (!params->param1 && getEntities()->isDistanceBetweenEntities(kEntityTatiana, kEntityPlayer, 1000)) {
1521 			params->param1 = 1;
1522 			getSound()->playSound(kEntityTatiana, "Tat3164");	// Tatiana weeping
1523 		}
1524 		break;
1525 
1526 	case kActionDefault:
1527 		getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
1528 		getObjects()->update(kObject49, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
1529 		break;
1530 	}
1531 IMPLEMENT_FUNCTION_END
1532 
1533 //////////////////////////////////////////////////////////////////////////
1534 IMPLEMENT_FUNCTION(40, Tatiana, function40)
1535 	switch (savepoint.action) {
1536 	default:
1537 		break;
1538 
1539 	case kActionNone:
1540 		if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarKronos)
1541 		 || getData()->car != getEntityData(kEntityPlayer)->car
1542 		 || getEntities()->updateEntity(kEntityTatiana, kCarKronos, kPosition_9270))
1543 			callbackAction();
1544 		break;
1545 
1546 	case kActionExcuseMe:
1547 		if (getEvent(kEventTatianaAskMatchSpeakRussian) || getEvent(kEventTatianaAskMatch) || getEvent(kEventVassiliSeizure))
1548 			getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1010A" : "CAT1010");
1549 		else
1550 			getSound()->excuseMeCath();
1551 		break;
1552 
1553 	case kActionDefault:
1554 		if (getEntities()->updateEntity(kEntityTatiana, kCarKronos, kPosition_9270))
1555 			callbackAction();
1556 		break;
1557 	}
1558 IMPLEMENT_FUNCTION_END
1559 
1560 //////////////////////////////////////////////////////////////////////////
1561 IMPLEMENT_FUNCTION(41, Tatiana, trapCath)
1562 	switch (savepoint.action) {
1563 	default:
1564 		break;
1565 
1566 	case kActionNone:
1567 		if (!params->param1)
1568 			break;
1569 
1570 		if (getEntities()->checkFields19(kEntityPlayer, kCarRedSleeping, kPosition_7850)
1571 		 && !getEvent(kEventVassiliCompartmentStealEgg)
1572 		 && (getState()->time <= kTime2133000 || getProgress().field_40)) {
1573 			if (getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_7500)) {
1574 
1575 				getSavePoints()->push(kEntityTatiana, kEntityCoudert, kAction235061888);
1576 				getEntities()->clearSequences(kEntityTatiana);
1577 				getEntities()->exitCompartment(kEntityTatiana, kObjectCompartmentB, true);
1578 				getData()->location = kLocationInsideCompartment;
1579 
1580 				if (getInventory()->hasItem(kItemFirebird)) {
1581 					getAction()->playAnimation(kEventTatianaCompartmentStealEgg);
1582 					getInventory()->removeItem(kItemFirebird);
1583 					getInventory()->get(kItemFirebird)->location = kObjectLocation2;
1584 				} else {
1585 					getAction()->playAnimation(kEventTatianaCompartment);
1586 				}
1587 
1588 				getScenes()->loadSceneFromObject(kObjectCompartmentB);
1589 
1590 				setCallback(4);
1591 				setup_updateFromTime(150);
1592 			}
1593 		} else {
1594 			getEntities()->exitCompartment(kEntityTatiana, kObjectCompartmentB, true);
1595 
1596 			if (getState()->time < kTime2133000 || getProgress().field_40) {
1597 				setCallback(3);
1598 				setup_function40();
1599 				break;
1600 			}
1601 
1602 			getEntities()->clearSequences(kEntityTatiana);
1603 			callbackAction();
1604 		}
1605 		break;
1606 
1607 	case kActionDefault:
1608 		getData()->car = kCarRedSleeping;
1609 		getData()->entityPosition = kPosition_7500;
1610 		getData()->location = kLocationOutsideCompartment;
1611 
1612 		RESET_ENTITY_STATE(kEntityCoudert, Coudert, setup_function51);
1613 
1614 		getEntities()->drawSequenceLeft(kEntityTatiana, "673Fb");
1615 		getEntities()->enterCompartment(kEntityTatiana, kObjectCompartmentB, true);
1616 		break;
1617 
1618 	case kActionCallback:
1619 		switch (getCallback()) {
1620 		default:
1621 			break;
1622 
1623 		case 1:
1624 			setCallback(2);
1625 			setup_playSound("Tat3161B");
1626 			break;
1627 
1628 		case 2:
1629 			getSavePoints()->push(kEntityTatiana, kEntityCoudert, kAction168316032);
1630 			params->param1 = 1;
1631 			break;
1632 
1633 		case 3:
1634 		case 6:
1635 			getEntities()->clearSequences(kEntityTatiana);
1636 
1637 			callbackAction();
1638 			break;
1639 
1640 		case 4:
1641 			setCallback(5);
1642 			setup_exitCompartment();
1643 			break;
1644 
1645 		case 5:
1646 			setCallback(6);
1647 			setup_function40();
1648 			break;
1649 		}
1650 		break;
1651 
1652 	case kAction154071333:
1653 		getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
1654 		getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
1655 
1656 		setCallback(1);
1657 		setup_savegame(kSavegameTypeTime, kTimeNone);
1658 		break;
1659 	}
1660 IMPLEMENT_FUNCTION_END
1661 
1662 //////////////////////////////////////////////////////////////////////////
1663 IMPLEMENT_FUNCTION_II(42, Tatiana, function42, CarIndex, EntityPosition)
1664 	if (savepoint.action == kActionExcuseMeCath || savepoint.action == kActionExcuseMe) {
1665 		getSound()->playSound(kEntityPlayer, "Tat3124", getSound()->getSoundFlag(kEntityTatiana));
1666 		return;
1667 	}
1668 
1669 	Entity::updateEntity(savepoint);
1670 IMPLEMENT_FUNCTION_END
1671 
1672 //////////////////////////////////////////////////////////////////////////
1673 IMPLEMENT_FUNCTION(43, Tatiana, chapter4)
1674 	switch (savepoint.action) {
1675 	default:
1676 		break;
1677 
1678 	case kActionNone:
1679 		setup_inCompartment4();
1680 		break;
1681 
1682 	case kActionDefault:
1683 		getEntities()->clearSequences(kEntityTatiana);
1684 
1685 		getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
1686 		getObjects()->update(kObject49, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
1687 
1688 		getData()->entityPosition = kPosition_7500;
1689 		getData()->location = kLocationInsideCompartment;
1690 		getData()->car = kCarRedSleeping;
1691 		getData()->clothes = kClothes2;
1692 		getData()->inventoryItem = kItemNone;
1693 
1694 		ENTITY_PARAM(0, 1) = 0;
1695 		break;
1696 	}
1697 IMPLEMENT_FUNCTION_END
1698 
1699 //////////////////////////////////////////////////////////////////////////
1700 IMPLEMENT_FUNCTION(44, Tatiana, inCompartment4)
1701 	switch (savepoint.action) {
1702 	default:
1703 		break;
1704 
1705 	case kActionDefault:
1706 		setCallback(1);
1707 		setup_handleCompartment(kTime2362500);
1708 		break;
1709 
1710 	case kActionCallback:
1711 		if (getCallback() == 1)
1712 			setup_meetAlexei();
1713 		break;
1714 	}
1715 IMPLEMENT_FUNCTION_END
1716 
1717 //////////////////////////////////////////////////////////////////////////
1718 IMPLEMENT_FUNCTION(45, Tatiana, meetAlexei)
1719 	switch (savepoint.action) {
1720 	default:
1721 		break;
1722 
1723 	case kActionDefault:
1724 		setCallback(1);
1725 		setup_enterExitCompartment("673Bb", kObjectCompartmentB);
1726 		break;
1727 
1728 	case kActionCallback:
1729 		switch (getCallback()) {
1730 		default:
1731 			break;
1732 
1733 		case 1:
1734 			getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
1735 			getData()->location = kLocationOutsideCompartment;
1736 
1737 			setCallback(2);
1738 			setup_updateEntity(kCarGreenSleeping, kPosition_540);
1739 			break;
1740 
1741 		case 2:
1742 			if (getEntities()->isInGreenCarEntrance(kEntityPlayer)) {
1743 				getSound()->excuseMe(kEntityTatiana);
1744 
1745 				if (getEntities()->isPlayerPosition(kCarGreenSleeping, 62))
1746 					getScenes()->loadSceneFromPosition(kCarGreenSleeping, 72);
1747 			}
1748 
1749 			getSavePoints()->push(kEntityTatiana, kEntityAlexei, kAction123712592);
1750 			setup_withAlexei();
1751 			break;
1752 		}
1753 		break;
1754 	}
1755 IMPLEMENT_FUNCTION_END
1756 
1757 //////////////////////////////////////////////////////////////////////////
1758 IMPLEMENT_FUNCTION(46, Tatiana, withAlexei)
1759 	// Expose parameters as IIIIIS and ignore the default exposed parameters
1760 	EntityData::EntityParametersI5S  *parameters  = (EntityData::EntityParametersI5S*)_data->getCurrentParameters();
1761 
1762 	switch (savepoint.action) {
1763 	default:
1764 		break;
1765 
1766 	case kActionNone:
1767 		if (!parameters->param2 && !parameters->param3) {
1768 			parameters->param1 -= getState()->timeDelta;
1769 
1770 			if (parameters->param1 < getState()->timeDelta) {
1771 				getSound()->playSound(kEntityTatiana, (char *)&parameters->seq);
1772 
1773 				if (getEntities()->isDistanceBetweenEntities(kEntityTatiana, kEntityPlayer, 2000)) {
1774 					if (parameters->param4 == 4)
1775 						getProgress().field_8C = 1;
1776 					else if (parameters->param4 == 7)
1777 						getProgress().field_88 = 1;
1778 				}
1779 
1780 				parameters->param2 = 1;
1781 			}
1782 		}
1783 
1784 		if (CURRENT_PARAM(1, 1) == kTimeInvalid || getState()->time <= kTime2394000)
1785 			break;
1786 
1787 		if (getState()->time > kTime2398500) {
1788 			CURRENT_PARAM(1, 1) = kTimeInvalid;
1789 		} else {
1790 			if (getEntities()->isInGreenCarEntrance(kEntityPlayer) || !CURRENT_PARAM(1, 1))
1791 				CURRENT_PARAM(1, 1) = (uint)getState()->time;
1792 
1793 			if (CURRENT_PARAM(1, 1) >= getState()->time)
1794 				break;
1795 
1796 			CURRENT_PARAM(1, 1) = kTimeInvalid;
1797 		}
1798 
1799 		if (getEntities()->isInGreenCarEntrance(kEntityPlayer)) {
1800 			getSound()->excuseMe(kEntityTatiana);
1801 
1802 			if (getEntities()->isPlayerPosition(kCarGreenSleeping, 62))
1803 				getScenes()->loadSceneFromPosition(kCarGreenSleeping, 72);
1804 		}
1805 
1806 		getSavePoints()->push(kEntityTatiana, kEntityAlexei, kAction123536024);
1807 
1808 		setup_thinking();
1809 		break;
1810 
1811 	case kActionEndSound:
1812 		parameters->param2 = 0;
1813 		++parameters->param4;
1814 
1815 		switch(parameters->param4) {
1816 		default:
1817 			parameters->param1 = 162000;
1818 			break;
1819 
1820 		case 1:
1821 			parameters->param1 = 900;
1822 			strcpy((char *)&parameters->seq, "Tat4165F");
1823 			break;
1824 
1825 		case 2:
1826 			parameters->param1 = 900;
1827 			strcpy((char *)&parameters->seq, "Tat4165B");
1828 			break;
1829 
1830 		case 3:
1831 			parameters->param1 = 1800;
1832 			strcpy((char *)&parameters->seq, "Tat4165G");
1833 			break;
1834 
1835 		case 4:
1836 			parameters->param1 = 900;
1837 			strcpy((char *)&parameters->seq, "Tat4165H");
1838 			break;
1839 
1840 		case 5:
1841 			parameters->param1 = 2700;
1842 			strcpy((char *)&parameters->seq, "Tat4165C");
1843 			break;
1844 
1845 		case 6:
1846 			parameters->param1 = 900;
1847 			strcpy((char *)&parameters->seq, "Tat4165D");
1848 			break;
1849 
1850 		case 7:
1851 			parameters->param1 = 900;
1852 			strcpy((char *)&parameters->seq, "Tat4165E");
1853 			break;
1854 		}
1855 		break;
1856 
1857 	case kActionDefault:
1858 		getEntities()->drawSequenceLeft(kEntityTatiana, "306E");
1859 		parameters->param1 = 450;
1860 		strcpy((char *)&parameters->seq, "Tat4165A");
1861 		break;
1862 
1863 	case kActionDrawScene:
1864 		if (getEntities()->isInGreenCarEntrance(kEntityPlayer)) {
1865 			parameters->param3 = 1;
1866 
1867 			if (parameters->param2) {
1868 				getSoundQueue()->stop(kEntityTatiana);
1869 				getSavePoints()->call(kEntityTatiana, kEntityTatiana, kActionEndSound);
1870 			}
1871 		} else {
1872 			parameters->param3 = 0;
1873 			parameters->param5 = 0;
1874 		}
1875 
1876 		if (getEntities()->isPlayerPosition(kCarGreenSleeping, 62) && !parameters->param5) {
1877 			setCallback(1);
1878 			setup_draw("306D");
1879 		}
1880 		break;
1881 
1882 	case kActionCallback:
1883 		if (getCallback() == 1) {
1884 			getEntities()->drawSequenceLeft(kEntityTatiana, "306E");
1885 			parameters->param5 = 1;
1886 		}
1887 		break;
1888 	}
1889 IMPLEMENT_FUNCTION_END
1890 
1891 //////////////////////////////////////////////////////////////////////////
1892 IMPLEMENT_FUNCTION(47, Tatiana, thinking)
1893 	switch (savepoint.action) {
1894 	default:
1895 		break;
1896 
1897 	case kActionDefault:
1898 		setCallback(1);
1899 		setup_updateEntity(kCarRedSleeping, kPosition_7500);
1900 		break;
1901 
1902 	case kActionCallback:
1903 		switch (getCallback()) {
1904 		default:
1905 			break;
1906 
1907 		case 1:
1908 			setCallback(2);
1909 			setup_enterExitCompartment2("673Db", kObjectCompartmentB);
1910 			break;
1911 
1912 		case 2:
1913 			getData()->location = kLocationInsideCompartment;
1914 			getEntities()->clearSequences(kEntityTatiana);
1915 
1916 			setCallback(3);
1917 			setup_handleCompartment(kTime2407500);
1918 			break;
1919 
1920 		case 3:
1921 		case 4:
1922 			if (ENTITY_PARAM(0, 1) && getObjects()->get(kObjectCompartment1).model == kObjectModel1) {
1923 				setup_seekCath();
1924 			} else {
1925 				setCallback(4);
1926 				setup_handleCompartment(900);
1927 			}
1928 			break;
1929 		}
1930 		break;
1931 	}
1932 IMPLEMENT_FUNCTION_END
1933 
1934 //////////////////////////////////////////////////////////////////////////
1935 IMPLEMENT_FUNCTION(48, Tatiana, seekCath)
1936 	switch (savepoint.action) {
1937 	default:
1938 		break;
1939 
1940 	case kActionNone:
1941 		if (!params->param1) {
1942 			if (!getEvent(kEventTatianaTylerCompartment) && getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, kPosition_8200)) {
1943 				params->param1 = 1;
1944 				getProgress().field_E4 = 1;
1945 				getObjects()->update(kObjectCompartment1, kEntityTatiana, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorHand);
1946 			}
1947 
1948 			if (!params->param1)
1949 				goto label_end;
1950 		}
1951 
1952 		if (!getEntities()->checkFields19(kEntityPlayer, kCarGreenSleeping, kPosition_7850)) {
1953 			getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorHandKnock, kCursorHand);
1954 			params->param1 = 0;
1955 		}
1956 
1957 		if (!params->param1 || getSoundQueue()->isBuffered(kEntityTatiana))
1958 			goto label_end;
1959 
1960 		if (!Entity::updateParameter(params->param2, getState()->timeTicks, 5 * (3 * rnd(5) + 30)))
1961 			goto label_end;
1962 
1963 		getSound()->playSound(kEntityTatiana, "LIB012", kVolumeFull);
1964 		params->param2 = 0;
1965 
1966 label_end:
1967 		if (getEvent(kEventTatianaTylerCompartment) || getState()->time > kTime2475000) {
1968 			if (params->param1)
1969 				getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorHandKnock, kCursorHand);
1970 
1971 			getProgress().field_E4 = 0;
1972 			getEntities()->exitCompartment(kEntityTatiana, kObjectCompartment2, true);
1973 
1974 			setCallback(3);
1975 			setup_updateEntity(kCarRedSleeping, kPosition_7500);
1976 		}
1977 		break;
1978 
1979 	case kActionOpenDoor:
1980 		params->param1 = 0;
1981 
1982 		getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
1983 
1984 		setCallback(5);
1985 		setup_savegame(kSavegameTypeEvent, kEventTatianaTylerCompartment);
1986 		break;
1987 
1988 	case kActionDefault:
1989 		setCallback(1);
1990 		setup_enterExitCompartment("673Bb", kObjectCompartmentB);
1991 		break;
1992 
1993 	case kActionCallback:
1994 		switch (getCallback()) {
1995 		default:
1996 			break;
1997 
1998 		case 1:
1999 			getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
2000 			getData()->location = kLocationOutsideCompartment;
2001 
2002 			setCallback(2);
2003 			setup_updateEntity(kCarGreenSleeping, kPosition_7500);
2004 			break;
2005 
2006 		case 2:
2007 			getEntities()->drawSequenceLeft(kEntityTatiana, "673Fb");
2008 			getEntities()->enterCompartment(kEntityTatiana, kObjectCompartment2, true);
2009 			break;
2010 
2011 		case 3:
2012 			setCallback(4);
2013 			setup_enterExitCompartment2("673Db", kObjectCompartmentB);
2014 			break;
2015 
2016 		case 4:
2017 			getData()->location = kLocationInsideCompartment;
2018 			getEntities()->clearSequences(kEntityTatiana);
2019 
2020 			setup_function49();
2021 			break;
2022 
2023 		case 5:
2024 			getObjects()->update(kObjectOutsideTylerCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
2025 			getAction()->playAnimation(kEventTatianaTylerCompartment);
2026 			getSound()->playSound(kEntityPlayer, "LIB015");
2027 			getScenes()->loadScene(kScene41);
2028 			break;
2029 
2030 		case 6:
2031 			setCallback(7);
2032 			setup_updateEntity(kCarGreenSleeping, kPosition_7500);
2033 			break;
2034 
2035 		case 7:
2036 			getEntities()->drawSequenceLeft(kEntityTatiana, "673Fb");
2037 			getEntities()->enterCompartment(kEntityTatiana, kObjectCompartment2, true);
2038 			break;
2039 		}
2040 		break;
2041 
2042 	case kAction238790488:
2043 		params->param1 = 0;
2044 
2045 		getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorHandKnock, kCursorHand);
2046 		getEntities()->exitCompartment(kEntityTatiana, kObjectCompartment2, true);
2047 		getEntities()->clearSequences(kEntityTatiana);
2048 
2049 		getData()->car = kCarGreenSleeping;
2050 		getData()->entityPosition = kPosition_9460;
2051 
2052 		setCallback(6);
2053 		setup_updateFromTime(1800);
2054 		break;
2055 	}
2056 IMPLEMENT_FUNCTION_END
2057 
2058 //////////////////////////////////////////////////////////////////////////
2059 IMPLEMENT_FUNCTION(49, Tatiana, function49)
2060 	switch (savepoint.action) {
2061 	default:
2062 		break;
2063 
2064 	case kActionDefault:
2065 		getData()->entityPosition = kPosition_7500;
2066 		getData()->location = kLocationInsideCompartment;
2067 		getData()->car = kCarRedSleeping;
2068 
2069 		getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
2070 		getObjects()->update(kObject49, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
2071 		break;
2072 
2073 	case kAction169360385:
2074 		setup_alexeiDead();
2075 		break;
2076 	}
2077 IMPLEMENT_FUNCTION_END
2078 
2079 //////////////////////////////////////////////////////////////////////////
2080 IMPLEMENT_FUNCTION(50, Tatiana, alexeiDead)
2081 	switch (savepoint.action) {
2082 	default:
2083 		break;
2084 
2085 	case kActionNone:
2086 		if (getState()->time > kTime2520000 && !params->param1) {
2087 			params->param1 = 1;
2088 			setup_function51();
2089 		}
2090 		break;
2091 
2092 	case kActionEndSound:
2093 		getSound()->playSound(kEntityTatiana, "Tat4166");
2094 		break;
2095 
2096 	case kActionKnock:
2097 		if (!getSoundQueue()->isBuffered("LIB012", true))
2098 			getSound()->playSound(kEntityPlayer, "LIB012");
2099 		break;
2100 
2101 	case kActionOpenDoor:
2102 		getSound()->playSound(kEntityPlayer, "LIB014");
2103 
2104 		setCallback(1);
2105 		setup_savegame(kSavegameTypeEvent, kEventVassiliDeadAlexei);
2106 		break;
2107 
2108 	case kActionDefault:
2109 		getData()->entityPosition = kPosition_8200;
2110 		getData()->location = kLocationInsideCompartment;
2111 		getData()->car = kCarRedSleeping;
2112 
2113 		getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
2114 		getObjects()->update(kObject49, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
2115 		getObjects()->update(kObject48, kEntityTatiana, kObjectLocationNone, kCursorHandKnock, kCursorHand);
2116 		getObjects()->update(kObjectCompartmentA, kEntityTatiana, kObjectLocationNone, kCursorHandKnock, kCursorHand);
2117 
2118 		if (!getSoundQueue()->isBuffered(kEntityTatiana))
2119 			getSound()->playSound(kEntityTatiana, "Tat4166");
2120 		break;
2121 
2122 	case kActionCallback:
2123 		if (getCallback() == 1) {
2124 			if (getSoundQueue()->isBuffered("MUS013"))
2125 				getSoundQueue()->fade("MUS013");
2126 
2127 			getAction()->playAnimation(kEventVassiliDeadAlexei);
2128 			getSavePoints()->push(kEntityTatiana, kEntityAbbot, kAction104060776);
2129 			getScenes()->loadSceneFromPosition(kCarRedSleeping, 38);
2130 
2131 			setup_function51();
2132 		}
2133 		break;
2134 	}
2135 IMPLEMENT_FUNCTION_END
2136 
2137 //////////////////////////////////////////////////////////////////////////
2138 IMPLEMENT_FUNCTION(51, Tatiana, function51)
2139 	if (savepoint.action == kActionDefault) {
2140 		getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
2141 		getObjects()->update(kObject48, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
2142 	}
2143 IMPLEMENT_FUNCTION_END
2144 
2145 //////////////////////////////////////////////////////////////////////////
2146 IMPLEMENT_FUNCTION(52, Tatiana, chapter5)
2147 	switch (savepoint.action) {
2148 	default:
2149 		break;
2150 
2151 	case kActionNone:
2152 		setup_chapter5Handler();
2153 		break;
2154 
2155 	case kActionDefault:
2156 		getEntities()->clearSequences(kEntityTatiana);
2157 
2158 		getData()->entityPosition = kPosition_3969;
2159 		getData()->location = kLocationInsideCompartment;
2160 		getData()->car = kCarRestaurant;
2161 		getData()->clothes = kClothesDefault;
2162 		getData()->inventoryItem = kItemNone;
2163 		break;
2164 	}
2165 IMPLEMENT_FUNCTION_END
2166 
2167 //////////////////////////////////////////////////////////////////////////
2168 IMPLEMENT_FUNCTION(53, Tatiana, chapter5Handler)
2169 	if (savepoint.action == kActionProceedChapter5)
2170 		setup_autistic();
2171 IMPLEMENT_FUNCTION_END
2172 
2173 //////////////////////////////////////////////////////////////////////////
2174 IMPLEMENT_FUNCTION(54, Tatiana, autistic)
2175 	switch (savepoint.action) {
2176 	default:
2177 		break;
2178 
2179 	case kActionNone:
2180 		if (!params->param2) {
2181 			switch (params->param1) {
2182 			default:
2183 				break;
2184 
2185 			case 0:
2186 				getSound()->playSound(kEntityTatiana, "Tat5167A");
2187 				params->param2 = 1;
2188 				break;
2189 
2190 			case 1:
2191 				getSound()->playSound(kEntityTatiana, "Tat5167B");
2192 				params->param2 = 1;
2193 				break;
2194 
2195 			case 2:
2196 				getSound()->playSound(kEntityTatiana, "Tat5167C");
2197 				params->param2 = 1;
2198 				break;
2199 
2200 			case 3:
2201 				getSound()->playSound(kEntityTatiana, "Tat5167D");
2202 				params->param2 = 1;
2203 				break;
2204 			}
2205 		}
2206 
2207 		if (params->param1 > 3) {
2208 			if (!Entity::updateParameter(params->param3, getState()->timeTicks, 225))
2209 				break;
2210 
2211 			params->param1 = 0;
2212 			params->param3 = 0;
2213 		}
2214 		break;
2215 
2216 	case kAction1:
2217 		getData()->inventoryItem = kItemNone;
2218 
2219 		setCallback(1);
2220 		setup_savegame(kSavegameTypeEvent, kEventTatianaVassiliTalk);
2221 		break;
2222 
2223 	case kActionEndSound:
2224 		++params->param1;
2225 		params->param2 = 0;
2226 		break;
2227 
2228 	case kActionDefault:
2229 		getEntities()->drawSequenceLeft(kEntityTatiana, "033A");
2230 		getData()->inventoryItem = kItemInvalid;
2231 		break;
2232 
2233 	case kActionCallback:
2234 		if (getCallback() == 1) {
2235 			if (getSoundQueue()->isBuffered("MUS050"))
2236 				getSoundQueue()->fade("MUS050");
2237 
2238 			if (getSoundQueue()->isBuffered(kEntityTatiana))
2239 				getSoundQueue()->fade(kEntityTatiana);
2240 
2241 			getAction()->playAnimation(isNight() ? kEventTatianaVassiliTalkNight : kEventTatianaVassiliTalk);
2242 			getScenes()->processScene();
2243 
2244 			params->param1 = 4;
2245 			params->param2 = 0;
2246 			params->param3 = 0;
2247 		}
2248 		break;
2249 
2250 	case kAction203078272:
2251 		getEntities()->drawSequenceLeft(kEntityTatiana, "033E");
2252 		break;
2253 
2254 	case kAction236060709:
2255 		getData()->inventoryItem = kItemNone;
2256 		setup_function55();
2257 		break;
2258 	}
2259 IMPLEMENT_FUNCTION_END
2260 
2261 //////////////////////////////////////////////////////////////////////////
2262 IMPLEMENT_FUNCTION(55, Tatiana, function55)
2263 	switch (savepoint.action) {
2264 	default:
2265 		break;
2266 
2267 	case kActionDefault:
2268 		getEntities()->clearSequences(kEntityTatiana);
2269 		// fall through
2270 
2271 	case kActionDrawScene:
2272 		if (getEntities()->isPlayerPosition(kCarRestaurant, 72))
2273 			getScenes()->loadSceneFromPosition(kCarRestaurant, 86);
2274 		break;
2275 	}
2276 IMPLEMENT_FUNCTION_END
2277 
2278 } // End of namespace LastExpress
2279