Work around a script bug in Full Throttle. See bug #1407789.

svn-id: r20080
This commit is contained in:
Torbjörn Andersson 2006-01-18 11:53:07 +00:00
parent 791b5bdc61
commit 34d835e4a2
4 changed files with 17 additions and 3 deletions

View File

@ -909,12 +909,16 @@ void ScummEngine::playActorSounds() {
}
}
bool ScummEngine::isValidActor(int id) const {
return id >= 0 && id < _numActors && _actors[id]._number == id;
}
Actor *ScummEngine::derefActor(int id, const char *errmsg) const {
if (id == 0)
debugC(DEBUG_ACTORS, "derefActor(0, \"%s\") in script %d, opcode 0x%x",
errmsg, vm.slot[_currentScript].number, _opcode);
if (id < 0 || id >= _numActors || _actors[id]._number != id) {
if (!isValidActor(id)) {
if (errmsg)
error("Invalid actor %d in %s", id, errmsg);
else
@ -928,7 +932,7 @@ Actor *ScummEngine::derefActorSafe(int id, const char *errmsg) const {
debugC(DEBUG_ACTORS, "derefActorSafe(0, \"%s\") in script %d, opcode 0x%x",
errmsg, vm.slot[_currentScript].number, _opcode);
if (id < 0 || id >= _numActors || _actors[id]._number != id) {
if (!isValidActor(id)) {
debugC(DEBUG_ACTORS, "Invalid actor %d in %s (script %d, opcode 0x%x)",
id, errmsg, vm.slot[_currentScript].number, _opcode);
return NULL;

View File

@ -1083,6 +1083,14 @@ void ScummEngine::checkAndRunSentenceScript() {
localParamList[0] = _sentence[_sentenceNum].verb;
localParamList[1] = _sentence[_sentenceNum].objectA;
localParamList[2] = _sentence[_sentenceNum].objectB;
// WORKAROUND for bug #1407789. The script clearly assumes that
// one of the two objects is an actor. If that's not the case,
// fall back on what appears to be the usual sentence script.
if (_gameId == GID_FT && sentenceScript == 103 && !isValidActor(localParamList[1]) && !isValidActor(localParamList[2])) {
sentenceScript = 28;
}
}
_currentScript = 0xFF;
if (sentenceScript)

View File

@ -1052,7 +1052,7 @@ void ScummEngine_v5::o5_getActorRoom() {
// WORKAROUND bug #746349. This is a really odd bug in either the script
// or in our script engine. Might be a good idea to investigate this
// further by e.g. looking at the FOA engine a bit closer.
if (_gameId == GID_INDY4 && _roomResource == 94 && vm.slot[_currentScript].number == 206 && act > _numActors) {
if (_gameId == GID_INDY4 && _roomResource == 94 && vm.slot[_currentScript].number == 206 && !isValidActor(act)) {
setResult(0);
return;
}

View File

@ -848,6 +848,8 @@ protected:
void setVerbObject(uint room, uint object, uint verb);
public:
bool isValidActor(int id) const;
/* Should be in Actor class */
Actor *derefActor(int id, const char *errmsg = 0) const;
Actor *derefActorSafe(int id, const char *errmsg) const;