Permalink
Browse files

LASTEXPRESS: more fixes in NPC logic

  • Loading branch information...
grechnik committed Sep 11, 2018
1 parent 4d36385 commit 0cb6b30f67bada2626cbffb8dc0c83c80f3eda63
@@ -742,8 +742,8 @@ IMPLEMENT_FUNCTION(21, Boutarel, chapter1Handler)
if (getEntities()->isPlayerPosition(kCarRedSleeping, 54) || getEntities()->isPlayerPosition(kCarRedSleeping, 44))
getScenes()->loadSceneFromPosition(kCarRedSleeping, 10);
getEntities()->updatePositionExit(kEntityBoutarel, kCarRedSleeping, 54);
getEntities()->updatePositionExit(kEntityBoutarel, kCarRedSleeping, 44);
getEntities()->updatePositionEnter(kEntityBoutarel, kCarRedSleeping, 54);
getEntities()->updatePositionEnter(kEntityBoutarel, kCarRedSleeping, 44);
setCallback(4);
setup_playSound("MRB1074");
@@ -162,7 +162,7 @@ IMPLEMENT_FUNCTION(6, Chapters, firstDream)
break;
case kActionEndSound:
getSound()->playSound(kEntityChapters, "MUS0009", kFlagDefault);
getSound()->playSound(kEntityChapters, "MUS009", kFlagDefault);
break;
case kActionKnock:
@@ -270,6 +270,7 @@ IMPLEMENT_FUNCTION(6, Chapters, firstDream)
getSound()->playSound(kEntityPlayer, "MUS008", kFlagDefault);
getInventory()->unselectItem();
// TODO: fade to black screen
// FIXME add event pump ?
while (getSoundQueue()->isBuffered("MUS008"))
@@ -302,7 +303,7 @@ IMPLEMENT_FUNCTION(6, Chapters, firstDream)
getSound()->playSound(kEntityPlayer, "LIB031");
if (params->param2 == 3) {
getData()->car = kCarGreenSleeping;
getData()->car = kCarLocomotive;
getEntities()->drawSequenceLeft(kEntityChapters, "JUGL");
}
}
@@ -411,7 +412,7 @@ IMPLEMENT_FUNCTION(8, Chapters, chapter1Handler)
label_enter_epernay:
// Entering Epernay station
if (timeCheckEnterStation(kTimeEnterEpernay, params->param8, 1, "Epernay", kCityEpernay))
if (timeCheckEnterStation(kTimeEnterEpernay, params->param8, 2, "Epernay", kCityEpernay))
break;
label_exit_epernay:
@@ -721,6 +722,7 @@ IMPLEMENT_FUNCTION(9, Chapters, chapter1Next)
getSound()->playSound(kEntityPlayer, "MUS008", kFlagDefault);
getInventory()->unselectItem();
// TODO: fade to black screen
while (getSoundQueue()->isBuffered("MUS008"))
getSoundQueue()->updateQueue();
@@ -782,6 +784,8 @@ IMPLEMENT_FUNCTION(11, Chapters, chapter2Init)
// Setup inventory & items location
getInventory()->addItem(kItemGreenJacket);
getInventory()->get(kItemCorpse)->location = kObjectLocationNone;
getInventory()->get(kItemCorpse)->inPocket = false;
getObjects()->update(kObjectHandleOutsideLeft, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHand);
getObjects()->update(kObjectHandleOutsideRight, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHand);
@@ -900,6 +904,8 @@ IMPLEMENT_FUNCTION(14, Chapters, chapter3Init)
ENTITY_PARAM(0, 3) = 0;
}
// TODO: fade to black screen
getScenes()->loadSceneFromPosition(kCarRestaurant, 60);
getInventory()->show();
@@ -1234,6 +1240,8 @@ IMPLEMENT_FUNCTION(18, Chapters, chapter4Init)
ENTITY_PARAM(0, 3) = 0;
}
// TODO: fade to black screen
if (getInventory()->hasItem(kItemFirebird))
getScenes()->loadSceneFromPosition(kCarGreenSleeping, 76);
else
@@ -1528,9 +1536,14 @@ IMPLEMENT_FUNCTION(19, Chapters, chapter4Handler)
ENTITY_PARAM(0, 3) = 0;
}
// BUG: the original game fades to black screen twice, before MUS008 starts playing
// (the second call just makes a delay)
getSound()->playSound(kEntityPlayer, "MUS008", kFlagDefault);
getInventory()->unselectItem();
// TODO: fade to black screen
while (getSoundQueue()->isBuffered("MUS008"))
getSoundQueue()->updateQueue();
@@ -1706,6 +1719,8 @@ IMPLEMENT_FUNCTION(21, Chapters, chapter5Init)
ENTITY_PARAM(0, 3) = 0;
}
// TODO: fade to black screen
getScenes()->loadSceneFromPosition(kCarBaggageRear, 95);
getInventory()->show();
@@ -403,7 +403,7 @@ IMPLEMENT_FUNCTION(10, Cooks, chapter3)
getData()->entityPosition = kPosition_5900;
getData()->car = kCarRestaurant;
getData()->inventoryItem = kItemNone;
getData()->inventoryItem = kItemNone; // not in the original version, but it does no harm, I suppose?
getProgress().field_4C = 0;
@@ -354,7 +354,8 @@ IMPLEMENT_FUNCTION_I(10, Coudert, updateFromTime, uint32)
break;
case kActionNone:
Entity::savegameBloodJacket(1);
if (Entity::savegameBloodJacket(1))
break;
if (!Entity::updateParameter(params->param2, getState()->time, params->param1))
break;
@@ -378,7 +379,8 @@ IMPLEMENT_FUNCTION_I(11, Coudert, updateFromTicks, uint32)
break;
case kActionNone:
Entity::savegameBloodJacket(1);
if (Entity::savegameBloodJacket(1))
break;
if (!Entity::updateParameter(params->param2, getState()->timeTicks, params->param1))
break;
@@ -453,7 +455,7 @@ IMPLEMENT_FUNCTION_II(13, Coudert, function13, bool, EntityIndex)
break;
case kActionNone:
if (Entity::savegameBloodJacket(1))
if (Entity::savegameBloodJacket(3))
break;
if (!params->param2 && !params->param3) {
@@ -764,7 +766,7 @@ IMPLEMENT_FUNCTION_I(17, Coudert, function17, bool)
break;
}
if (params->param2) {
if (ENTITY_PARAM(0, 2)) {
setCallback(2);
setup_bloodJacket("627C");
break;
@@ -1160,7 +1162,7 @@ IMPLEMENT_FUNCTION(22, Coudert, function22)
break;
case 8:
getSound()->playSound(kEntityCoudert, "JAC1013A");
getSound()->playSound(kEntityCoudert, "JAC1030A");
getObjects()->update(kObjectCompartmentG, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
setCallback(9);
@@ -2284,7 +2286,7 @@ IMPLEMENT_FUNCTION(40, Coudert, chapter1Handler)
label_callback_10:
if (getState()->time > kTime1189800 && !ENTITY_PARAM(0, 1) && !ENTITY_PARAM(2, 1)) {
if (Entity::updateParameter(params->param3, getState()->time, 2700)) {
ENTITY_PARAM(0, 2) = 1;
ENTITY_PARAM(0, 2) = 0;
ENTITY_PARAM(0, 1) = 1;
getEntities()->drawSequenceLeft(kEntityCoudert, "697F");
@@ -2700,7 +2702,7 @@ IMPLEMENT_FUNCTION(44, Coudert, chapter3)
getData()->clothes = kClothesDefault;
getData()->inventoryItem = kItemNone;
ENTITY_PARAM(0, 2) = 0;
ENTITY_PARAM(0, 2) = 1;
ENTITY_PARAM(0, 3) = 0;
ENTITY_PARAM(0, 4) = 0;
ENTITY_PARAM(0, 5) = 0;
@@ -3092,7 +3094,7 @@ IMPLEMENT_FUNCTION_I(47, Coudert, function47, bool)
case 3:
getEntities()->drawSequenceLeft(kEntityCoudert, "627Wf");
getEntities()->enterCompartment(kEntityCoudert, kObjectCompartmentF);
getEntities()->enterCompartment(kEntityCoudert, kObjectCompartmentF, true);
// fall through
case 4:
@@ -3481,9 +3483,9 @@ IMPLEMENT_FUNCTION(52, Coudert, chapter4)
getData()->location = kLocationOutsideCompartment;
getData()->car = kCarRedSleeping;
getData()->clothes = kClothesDefault;
getData()->inventoryItem = kItemNone;
getData()->inventoryItem = kItemNone; // not in the original version, but it does no harm, I suppose?
ENTITY_PARAM(0, 2) = 0;
ENTITY_PARAM(0, 2) = 1;
ENTITY_PARAM(0, 3) = 0;
ENTITY_PARAM(0, 4) = 0;
ENTITY_PARAM(0, 5) = 0;
@@ -580,13 +580,13 @@ IMPLEMENT_FUNCTION(13, Francois, haremVisit)
getData()->location = kLocationOutsideCompartment;
setCallback(7);
setup_doWalk(kCarGreenSleeping, kPosition_4840);
setup_doWalk(kCarRedSleeping, kPosition_4840);
break;
case 7:
if (getInventory()->hasItem(kItemWhistle) || getInventory()->get(kItemWhistle)->location == kObjectLocation3) {
setCallback(10);
setup_doWalk(kCarGreenSleeping, kPosition_5790);
setup_doWalk(kCarRedSleeping, kPosition_5790);
break;
}
@@ -605,7 +605,7 @@ IMPLEMENT_FUNCTION(13, Francois, haremVisit)
getEntities()->exitCompartment(kEntityFrancois, kObjectCompartmentE, true);
setCallback(10);
setup_doWalk(kCarGreenSleeping, kPosition_5790);
setup_doWalk(kCarRedSleeping, kPosition_5790);
break;
case 10:
@@ -1151,16 +1151,18 @@ IMPLEMENT_FUNCTION(25, Francois, chapter3Handler)
label_callback_11:
if (getInventory()->get(kItemBeetle)->location == kObjectLocation3) {
if (getState()->time <= kTimeEnd)
if (!getEntities()->isDistanceBetweenEntities(kEntityFrancois, kEntityPlayer, 2000) || !CURRENT_PARAM(1, 4))
CURRENT_PARAM(1, 4) = (uint)(getState()->time + 75);
if (CURRENT_PARAM(1, 4) < getState()->time || getState()->time > kTimeEnd) {
CURRENT_PARAM(1, 4) = kTimeInvalid;
setCallback(12);
setup_playSound("Fra2010");
break;
if (CURRENT_PARAM(1, 4) != kTimeInvalid) {
if (getState()->time <= kTimeEnd)
if (!getEntities()->isDistanceBetweenEntities(kEntityFrancois, kEntityPlayer, 2000) || !CURRENT_PARAM(1, 4))
CURRENT_PARAM(1, 4) = (uint)(getState()->time + 75);
if (CURRENT_PARAM(1, 4) < getState()->time || getState()->time > kTimeEnd) {
CURRENT_PARAM(1, 4) = kTimeInvalid;
setCallback(12);
setup_playSound("Fra2010");
break;
}
}
label_callback_12:
@@ -1174,6 +1176,12 @@ IMPLEMENT_FUNCTION(25, Francois, chapter3Handler)
label_callback_14:
timeCheckCallbackCompartment(kTime2218500, CURRENT_PARAM(1, 7), 15, kObjectCompartmentB, kPosition_7500, "b");
}
// The original game has some code here similar to withMama marked as BUG:
// if [kItemBeetle].location != kObjectLocation3 && !has(kItemWhistle) && [kItemWhistle].location != kObjectLocation3,
// there are several always-false checks (time < N && time > N),
// kTime2040300 with callback 16, kTime2119500 with callback 17, kTime2146500 with callback 18, kTime2218500 with callback 19,
// with takeWalk as a payload.
// No point in reproducing it here.
}
break;
@@ -861,7 +861,7 @@ IMPLEMENT_FUNCTION(20, Kahina, beforeConcert)
case 1:
getAction()->playAnimation(kEventKahinaPunchSuite4);
getLogic()->gameOver(kSavegameTypeEvent2, kEventCathJumpDownCeiling, kSceneNone, false);
getLogic()->gameOver(kSavegameTypeEvent2, kEventCathJumpDownCeiling, kSceneNone, true);
goto label_callback_1;
case 2:
@@ -945,7 +945,7 @@ IMPLEMENT_FUNCTION(21, Kahina, concert)
if (params->param6 != kTimeInvalid) {
if (Entity::updateParameterTime((TimeValue)params->param3, (getEntities()->isPlayerPosition(kCarKronos, 80) || getEntities()->isPlayerPosition(kCarKronos, 88)), params->param6, 0)) {
getSound()->playSound(kEntityPlayer, "LIB014", getSound()->getSoundFlag(kEntityKahina));
getSound()->playSound(kEntityPlayer, "LIB015", getSound()->getSoundFlag(kEntityKahina));
getSound()->playSound(kEntityPlayer, "LIB015", getSound()->getSoundFlag(kEntityKahina), 15);
getEntities()->drawSequenceLeft(kEntityKahina, "202a");
@@ -1181,7 +1181,7 @@ IMPLEMENT_FUNCTION(24, Kahina, seekCath)
case 2:
if (getEntityData(kEntityPlayer)->entityPosition >= getData()->entityPosition)
getAction()->playAnimation(getData()->car == kCarRedSleeping ? kEventKahinaGunYellow : kEventKahinaGunBlue);
getAction()->playAnimation(getData()->car == kCarGreenSleeping ? kEventKahinaGunYellow : kEventKahinaGunBlue);
else
getAction()->playAnimation(kEventKahinaGun);
@@ -1327,8 +1327,11 @@ IMPLEMENT_FUNCTION(25, Kahina, searchCath)
switch (getInventory()->get(kItemFirebird)->location) {
default:
if (ENTITY_PARAM(0, 3))
if (ENTITY_PARAM(0, 3)) {
getInventory()->setLocationAndProcess(kItemBriefcase, kObjectLocation2);
getProgress().field_78 = 1;
ENTITY_PARAM(0, 3) = 0;
}
break;
case kObjectLocation3:
@@ -1344,12 +1347,10 @@ IMPLEMENT_FUNCTION(25, Kahina, searchCath)
getInventory()->setLocationAndProcess(kItemBriefcase, kObjectLocation2);
getProgress().field_C0 = (uint)getState()->time;
getProgress().field_78 = 1;
ENTITY_PARAM(0, 3) = 0;
break;
}
getProgress().field_78 = 1;
ENTITY_PARAM(0, 3) = 0;
if (getInventory()->get(kItemFirebird)->location != kObjectLocation18) {
setCallback(10);
setup_enterExitCompartment("616Ba", kObjectCompartment1);
@@ -1416,9 +1417,9 @@ IMPLEMENT_FUNCTION(26, Kahina, searchTatiana)
break;
case 4:
if (getEntities()->checkFields19(kEntityPlayer, kCarGreenSleeping, kPosition_7850)) {
if (getEntities()->checkFields19(kEntityPlayer, kCarRedSleeping, kPosition_7850)) {
setCallback(5);
setup_function19(kCarRedSleeping, kPosition_9270);
setup_function19(kCarKronos, kPosition_9270);
} else {
setCallback(6);
setup_enterExitCompartment("616Aa", kObjectCompartmentA);
@@ -589,6 +589,7 @@ IMPLEMENT_FUNCTION(20, Kronos, duringConcert)
case 3:
getAction()->playAnimation(kEventCathFallingAsleep);
// TODO: fade to black screen
while (getSoundQueue()->isBuffered("1919.LNK"))
getSoundQueue()->updateQueue();
@@ -696,7 +697,7 @@ IMPLEMENT_FUNCTION(20, Kronos, duringConcert)
break;
case 2:
getData()->entityPosition = kPosition_6000;
getEntityData(kEntityPlayer)->entityPosition = kPosition_6000;
getAction()->playAnimation(kEventConcertLeaveWithBriefcase);
RESET_ENTITY_STATE(kEntityKahina, Kahina, setup_concert);
@@ -821,7 +822,7 @@ IMPLEMENT_FUNCTION(22, Kronos, awaitingCath)
case 1:
getAction()->playAnimation(kEventKronosReturnBriefcase);
getScenes()->loadSceneFromPosition(kCarKronos, 87);
getInventory()->removeItem(kItemFirebird);
getInventory()->removeItem(kItemBriefcase);
getInventory()->removeItem(kItemScarf);
setup_finished();
@@ -1237,16 +1237,16 @@ enum EventIndex {
kEventCathSalkoTrainTopWin = 176,
kEventFrancoisWhistle = 177,
kEventFrancoisWhistleD = 178,
kEventFrancoisWhistleNightD = 179,
kEventFrancoisWhistleNight = 180,
kEventFrancoisWhistleNight = 179,
kEventFrancoisWhistleNightD = 180,
kEventFrancoisShowBeetle = 181,
kEventFrancoisShowBeetleD = 182,
kEventFrancoisTradeWhistle = 183,
kEventFrancoisTradeWhistleD = 184,
kEventFrancoisShowEgg = 185,
kEventFrancoisShowEggD = 186,
kEventFrancoisShowEggNight = 187,
kEventFrancoisShowEggNightD = 188,
kEventFrancoisShowEggNightD = 187,
kEventFrancoisShowEggNight = 188,
kEventKronosBringFirebird = 189,
kEventKronosOpenFirebird = 190,
kEventFinalSequence = 191,

0 comments on commit 0cb6b30

Please sign in to comment.