aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm/script.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/scumm/script.cpp')
-rw-r--r--engines/scumm/script.cpp136
1 files changed, 133 insertions, 3 deletions
diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index d04c3c0891..0864022c59 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -28,6 +28,7 @@
#include "scumm/object.h"
#include "scumm/resource.h"
#include "scumm/util.h"
+#include "scumm/scumm_v0.h"
#include "scumm/scumm_v2.h"
#include "scumm/sound.h"
#include "scumm/verbs.h"
@@ -194,9 +195,14 @@ int ScummEngine::getVerbEntrypoint(int obj, int entry) {
return verboffs + 8 + READ_LE_UINT32(ptr + 1);
} else if (_game.version <= 2) {
do {
- if (!*verbptr)
- return 0;
- if (*verbptr == entry || *verbptr == 0xFF)
+ const int kFallbackEntry = (_game.version == 0 ? 0x0F : 0xFF);
+ if (!*verbptr) {
+ if (_game.version == 0 && entry == kVerbWalkTo)
+ return 13;
+ else
+ return 0;
+ }
+ if (*verbptr == entry || *verbptr == kFallbackEntry)
break;
verbptr += 2;
} while (1);
@@ -1128,6 +1134,130 @@ void ScummEngine::checkAndRunSentenceScript() {
runScript(sentenceScript, 0, 0, localParamList);
}
+void ScummEngine_v0::walkToActorOrObject(int object) {
+ int x, y, dir;
+ ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "walkToObject");
+
+ _walkToObject = object;
+ _walkToObjectIdx = getObjectIndex(object);
+
+ if (OBJECT_V0_TYPE(object) == kObjectTypeActor) {
+ walkActorToActor(VAR(VAR_EGO), OBJECT_V0_NR(object), 4);
+ x = a->getRealPos().x;
+ y = a->getRealPos().y;
+ } else {
+ walkActorToObject(VAR(VAR_EGO), object);
+ getObjectXYPos(object, x, y, dir);
+ }
+
+ VAR(6) = x;
+ VAR(7) = y;
+
+ if (!(a->_miscflags & kActorMiscFlagFreeze)) {
+ // FIXME: walking already started -> should be stopped if condition not true
+ //actorStartWalk();
+ }
+}
+
+void ScummEngine_v0::checkAndRunSentenceScript() {
+ const ScriptSlot *ss;
+
+ if (_walkToObjectIdx) {
+ ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkAndRunSentenceScript");
+ if (a->_moving)
+ return;
+ // TODO: change actor facing
+ _walkToObjectIdx = 0;
+ runSentenceScript();
+ return;
+ }
+
+ if (!_sentenceNum || _sentence[_sentenceNum - 1].freezeCount)
+ return;
+
+ //_sentenceNum--;
+ SentenceTab &st = _sentence[_sentenceNum - 1];
+
+ if (st.preposition && st.objectB == st.objectA)
+ return;
+
+ // FIXME: should this be executed?
+ //_currentScript = 0xFF;
+
+ int obj1Nr = OBJECT_V0_NR(st.objectA);
+ int obj1Type = OBJECT_V0_TYPE(st.objectA);
+ int obj2Nr = OBJECT_V0_NR(st.objectB);
+ int obj2Type = OBJECT_V0_TYPE(st.objectB);
+ assert(obj1Nr);
+
+ // If two objects are involved, at least one must be in the actors inventory
+ if (obj2Nr &&
+ (obj1Type != kObjectTypeFG || _objectOwnerTable[obj1Nr] != VAR(VAR_EGO)) &&
+ (obj2Type != kObjectTypeFG || _objectOwnerTable[obj2Nr] != VAR(VAR_EGO)))
+ {
+ if (getVerbEntrypoint(st.objectA, kVerbPickUp))
+ doSentence(kVerbPickUp, st.objectA, 0);
+ else if (getVerbEntrypoint(st.objectB, kVerbPickUp))
+ doSentence(kVerbPickUp, st.objectB, 0);
+ else
+ _sentenceNum--;
+ return;
+ }
+
+ _cmdVerb = st.verb;
+ _cmdObjectNr = obj1Nr;
+ _cmdObjectType = obj1Type;
+ _cmdObject2Nr = obj2Nr;
+ _cmdObject2Type = obj2Type;
+ _sentenceNum--;
+
+ // TODO: check sentenceNum
+
+ if (whereIsObject(st.objectA) != WIO_INVENTORY) {
+ if (_currentMode != kModeKeypad) {
+ walkToActorOrObject(st.objectA);
+ return;
+ }
+ } else if (st.objectB && whereIsObject(st.objectB) != WIO_INVENTORY) {
+ walkToActorOrObject(st.objectB);
+ return;
+ }
+
+ runSentenceScript();
+ if (_currentMode == kModeKeypad) {
+ _walkToObjectIdx = 0;
+ }
+}
+
+void ScummEngine_v0::runSentenceScript() {
+ int obj = OBJECT_V0(_cmdObjectNr, _cmdObjectType);
+
+ // FIXME: should it really ever return 0xD on WalkTo, seems wrong?
+ if (getVerbEntrypoint(obj, _cmdVerb) != 0) {
+ if (_cmdVerb == kVerbRead && VAR(VAR_CURRENT_LIGHTS) == 0) {
+ //slot = 0xFF;
+ VAR(VAR_ACTIVE_VERB) = _cmdVerb;
+ runScript(3, 0, 0, 0);
+ return;
+ } else {
+ VAR(VAR_ACTIVE_ACTOR) = _cmdObject2Nr;
+ runObjectScript(obj, _cmdVerb, false, false, NULL);
+ return;
+ }
+ } else {
+ if (_cmdVerb == kVerbGive) {
+ if (_cmdObject2Nr < 8)
+ setOwnerOf(obj, _cmdObject2Nr);
+ return;
+ } else if (_cmdVerb == kVerbWalkTo) {
+ //slot = 0xFF;
+ VAR(VAR_ACTIVE_VERB) = _cmdVerb;
+ runScript(3, 0, 0, 0);
+ return;
+ }
+ }
+}
+
void ScummEngine_v2::runInputScript(int clickArea, int val, int mode) {
int args[24];
int verbScript;