diff options
-rw-r--r-- | engines/scumm/object.cpp | 11 | ||||
-rw-r--r-- | engines/scumm/script.cpp | 136 | ||||
-rw-r--r-- | engines/scumm/script_v0.cpp | 68 | ||||
-rw-r--r-- | engines/scumm/script_v2.cpp | 27 | ||||
-rw-r--r-- | engines/scumm/script_v5.cpp | 65 | ||||
-rw-r--r-- | engines/scumm/scumm.cpp | 14 | ||||
-rw-r--r-- | engines/scumm/scumm.h | 2 | ||||
-rw-r--r-- | engines/scumm/scumm_v0.h | 22 | ||||
-rw-r--r-- | engines/scumm/scumm_v2.h | 2 | ||||
-rw-r--r-- | engines/scumm/scumm_v5.h | 2 | ||||
-rw-r--r-- | engines/scumm/verbs.cpp | 410 |
11 files changed, 307 insertions, 452 deletions
diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp index 53dc0151d9..49f1777c86 100644 --- a/engines/scumm/object.cpp +++ b/engines/scumm/object.cpp @@ -434,8 +434,15 @@ void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) { y = od.y_pos + (int16)READ_LE_UINT16(&imhd->old.hotspot[state].y); } } else if (_game.version <= 2) { - x = od.walk_x >> V12_X_SHIFT; - y = od.walk_y >> V12_Y_SHIFT; + if (od.actordir) { + x = od.walk_x; + y = od.walk_y; + } else { + x = od.x_pos + od.width/2; + y = od.y_pos + od.height/2; + } + x = x >> V12_X_SHIFT; + y = y >> V12_Y_SHIFT; } else { x = od.walk_x; y = od.walk_y; 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; diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp index 9b39391246..f4b98a4ba5 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -177,7 +177,7 @@ void ScummEngine_v0::setupOpcodes() { OPCODE(0x70, o_lights); OPCODE(0x71, o_getBitVar); OPCODE(0x72, o_nop); - OPCODE(0x73, o5_getObjectOwner); + OPCODE(0x73, o_getObjectOwner); /* 74 */ OPCODE(0x74, o5_getDist); OPCODE(0x75, o_printEgo_c64); @@ -337,7 +337,7 @@ void ScummEngine_v0::setupOpcodes() { OPCODE(0xf0, o_lights); OPCODE(0xf1, o_getBitVar); OPCODE(0xf2, o_nop); - OPCODE(0xf3, o5_getObjectOwner); + OPCODE(0xf3, o_getObjectOwner); /* F4 */ OPCODE(0xf4, o5_getDist); OPCODE(0xf5, o_stopCurrentScript); @@ -365,7 +365,7 @@ uint ScummEngine_v0::fetchScriptWord() { int ScummEngine_v0::getActiveObject() { if (_opcode & PARAM_2) - return _activeObjectNr; + return _cmdObjectNr; return fetchScriptByte(); } @@ -693,7 +693,7 @@ void ScummEngine_v0::o_putActorAtObject() { void ScummEngine_v0::o_pickupObject() { int objNr = fetchScriptByte(); - int obj = OBJECT_V0((objNr ? objNr : _activeObjectNr), 0); + int obj = OBJECT_V0((objNr ? objNr : _cmdObjectNr), 0); /* Don't take an object twice */ if (whereIsObject(obj) == WIO_INVENTORY) @@ -742,6 +742,12 @@ void ScummEngine_v0::o_setActorBitVar() { debug(0, "o_setActorBitVar(%d, %d, %d)", act, mask, mod); } +void ScummEngine_v0::o_getObjectOwner() { + getResultPos(); + int obj = getVarOrDirectWord(PARAM_1); + setResult(getOwner(obj ? obj : _cmdObjectNr)); +} + void ScummEngine_v0::o_getActorBitVar() { getResultPos(); byte act = getVarOrDirectByte(PARAM_1); @@ -787,17 +793,35 @@ void ScummEngine_v0::o_printEgo_c64() { } void ScummEngine_v0::o_doSentence() { - byte entry = fetchScriptByte(); - byte obj = fetchScriptByte(); - fetchScriptByte(); + byte verb = fetchScriptByte(); + int obj, obj2; + byte b; + + b = fetchScriptByte(); + if (b == 0xFF) { + obj = OBJECT_V0(_cmdObject2Nr, _cmdObject2Type); + } else if (b == 0xFE) { + obj = OBJECT_V0(_cmdObjectNr, _cmdObjectType); + } else { + obj = OBJECT_V0(b, (_opcode & 0x80) ? 1 : 0); + } - runObjectScript(obj, entry, false, false, NULL); + b = fetchScriptByte(); + if (b == 0xFF) { + obj2 = OBJECT_V0(_cmdObject2Nr, _cmdObject2Type); + } else if (b == 0xFE) { + obj2 = OBJECT_V0(_cmdObjectNr, _cmdObjectType); + } else { + obj2 = OBJECT_V0(b, (_opcode & 0x40) ? 1 : 0); + } + + doSentence(verb, obj, obj2); } -bool ScummEngine_v0::ifEqualActiveObject2Common(bool inventoryObject) { +bool ScummEngine_v0::ifEqualActiveObject2Common(bool ignoreType) { byte obj = fetchScriptByte(); - if (!inventoryObject || (_activeObject2Type == kObjectTypeFG)) - return (obj == _activeObject2Nr); + if (!ignoreType || (_cmdObject2Type == kObjectTypeFG)) + return (obj == _cmdObject2Nr); return false; } @@ -894,7 +918,7 @@ void ScummEngine_v0::o_setOwnerOf() { owner = getVarOrDirectByte(PARAM_2); if (obj == 0) - obj = _activeObjectNr; + obj = _cmdObjectNr; // FIXME: the original interpreter seems to set the owner of // an item to remove (new owner 0) to 13 (purple tentacle). @@ -909,21 +933,11 @@ void ScummEngine_v0::o_setOwnerOf() { void ScummEngine_v0::resetSentence(bool walking) { _activeVerb = kVerbWalkTo; - - // If the actor is walking, or the screen is a keypad (no sentence verbs/objects are drawn) - // Then reset all active objects (stops the radio crash, bug #3077966) - if (!walking || !(_userState & 32)) { - _activeObjectNr = 0; - _activeObjectType = kObjectTypeBG; - _activeObject2Nr = 0; - _activeObject2Type = kObjectTypeBG; - } - - _verbExecuting = false; - _verbPickup = false; - - _activeObjectObtained = false; - _activeObject2Obtained = false; + _activeObjectNr = 0; + _activeObjectType = kObjectTypeBG; + _activeObject2Nr = 0; + _activeObject2Type = kObjectTypeBG; + _walkToObjectIdx = 0; } } // End of namespace Scumm diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp index 1ea3257c17..6f6138d411 100644 --- a/engines/scumm/script_v2.cpp +++ b/engines/scumm/script_v2.cpp @@ -1219,20 +1219,23 @@ void ScummEngine_v2::o2_panCameraTo() { panCameraTo(getVarOrDirectByte(PARAM_1) * V12_X_MULTIPLIER, 0); } -void ScummEngine_v2::o2_walkActorToObject() { - int obj; - Actor *a; +void ScummEngine_v2::walkActorToObject(int actor, int obj) { + int x, y, dir; + getObjectXYPos(obj, x, y, dir); - a = derefActor(getVarOrDirectByte(PARAM_1), "o2_walkActorToObject"); - obj = getVarOrDirectWord(PARAM_2); - if (whereIsObject(obj) != WIO_NOT_FOUND) { - int x, y, dir; - getObjectXYPos(obj, x, y, dir); - AdjustBoxResult r = a->adjustXYToBeInBox(x, y); - x = r.x; - y = r.y; + Actor *a = derefActor(actor, "walkActorToObject"); + AdjustBoxResult r = a->adjustXYToBeInBox(x, y); + x = r.x; + y = r.y; + + a->startWalkActor(x, y, dir); +} - a->startWalkActor(x, y, dir); +void ScummEngine_v2::o2_walkActorToObject() { + int actor = getVarOrDirectByte(PARAM_1); + int obj = getVarOrDirectWord(PARAM_2); + if (whereIsObject(obj) != WIO_NOT_FOUND) { + walkActorToObject(actor, obj); } } diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp index 6426b75e1e..1d68e86942 100644 --- a/engines/scumm/script_v5.cpp +++ b/engines/scumm/script_v5.cpp @@ -2464,8 +2464,43 @@ void ScummEngine_v5::o5_walkActorTo() { a->startWalkActor(x, y, -1); } +void ScummEngine_v5::walkActorToActor(int actor, int toActor, int dist) { + Actor *a = derefActor(actor, "walkActorToActor"); + Actor *to = derefActor(toActor, "walkActorToActor(2)"); + + if (_game.version <= 2) { + dist *= V12_X_MULTIPLIER; + } else if (dist == 0xFF) { + dist = a->_scalex * a->_width / 0xFF; + dist += (to->_scalex * to->_width / 0xFF) / 2; + } + int x = to->getPos().x; + int y = to->getPos().y; + if (x < a->getPos().x) + x += dist; + else + x -= dist; + + if (_game.version <= 2) { + x /= V12_X_MULTIPLIER; + y /= V12_Y_MULTIPLIER; + } + if (_game.version <= 3) { + AdjustBoxResult abr = a->adjustXYToBeInBox(x, y); + x = abr.x; + y = abr.y; + } + a->startWalkActor(x, y, -1); + + // WORKAROUND: See bug #2971126 for details on why this is here. + if (_game.version == 0) { + // FIXME(TOBIAS): is this still needed? + // (updateScriptPtr/_currentScript might now be called automatically) + o5_breakHere(); + } +} + void ScummEngine_v5::o5_walkActorToActor() { - int x, y; Actor *a, *a2; int nr = getVarOrDirectByte(PARAM_1); int nr2 = getVarOrDirectByte(PARAM_2); @@ -2499,33 +2534,7 @@ void ScummEngine_v5::o5_walkActorToActor() { if (!a2->isInCurrentRoom()) return; - if (_game.version <= 2) { - dist *= V12_X_MULTIPLIER; - } else if (dist == 0xFF) { - dist = a->_scalex * a->_width / 0xFF; - dist += (a2->_scalex * a2->_width / 0xFF) / 2; - } - x = a2->getPos().x; - y = a2->getPos().y; - if (x < a->getPos().x) - x += dist; - else - x -= dist; - - if (_game.version <= 2) { - x /= V12_X_MULTIPLIER; - y /= V12_Y_MULTIPLIER; - } - if (_game.version <= 3) { - AdjustBoxResult abr = a->adjustXYToBeInBox(x, y); - x = abr.x; - y = abr.y; - } - a->startWalkActor(x, y, -1); - - // WORKAROUND: See bug #2971126 for details on why this is here. - if (_game.version == 0) - o5_breakHere(); + walkActorToActor(nr, nr2, dist); } void ScummEngine_v5::o5_walkActorToObject() { diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 8b2e2ef88e..e6ec2b0dab 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -712,17 +712,19 @@ ScummEngine_v2::ScummEngine_v2(OSystem *syst, const DetectorResult &dr) ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr) : ScummEngine_v2(syst, dr) { - _verbExecuting = false; - _verbPickup = false; _currentMode = 0; _activeVerb = kVerbNone; _activeObjectNr = 0; + _activeObjectType = 0; _activeObject2Nr = 0; - _activeObjectType = kObjectTypeBG; - _activeObject2Type = kObjectTypeBG; - _activeObjectObtained = false; - _activeObject2Obtained = false; + _activeObject2Type = 0; + + _cmdVerb = kVerbNone; + _cmdObjectNr = 0; + _cmdObjectType = 0; + _cmdObject2Nr = 0; + _cmdObject2Type = 0; VAR_ACTIVE_ACTOR = 0xFF; VAR_IS_SOUND_RUNNING = 0xFF; diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index f004176da1..fadc3902c0 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -642,7 +642,7 @@ protected: void updateScriptPtr(); virtual void runInventoryScript(int i); void inventoryScriptIndy3Mac(); - void checkAndRunSentenceScript(); + virtual void checkAndRunSentenceScript(); void runExitScript(); void runEntryScript(); void runAllScripts(); diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index 9b38b108e2..031a73acf9 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -54,8 +54,6 @@ protected: protected: byte _currentMode; - bool _verbExecuting; // is a verb executing - bool _verbPickup; // are we picking up an object during a verb execute int _activeVerb; int _activeObjectNr; // 1st Object Number @@ -63,8 +61,14 @@ protected: int _activeObject2Nr; // 2nd Object Number int _activeObject2Type; // 2nd Object Type (0: inventory (or room), 1: room, 2: actor) - bool _activeObjectObtained; // collected _activeobject? - bool _activeObject2Obtained; // collected _activeObject2? + int _cmdVerb; + int _cmdObjectNr; + int _cmdObjectType; + int _cmdObject2Nr; + int _cmdObject2Type; + + int _walkToObject; + int _walkToObjectIdx; public: ScummEngine_v0(OSystem *syst, const DetectorResult &dr); @@ -83,17 +87,16 @@ protected: virtual void processInput(); - virtual void runObject(int obj, int entry); virtual void saveOrLoad(Serializer *s); // V0 MM Verb commands int getVerbPrepId(); int activeVerbPrep(); - bool verbMove(int object); - bool verbMoveToActor(int actor); - bool verbObtain(int object); - bool verbExec(); + void walkToActorOrObject(int object); + void verbExec(); + virtual void runSentenceScript(); + virtual void checkAndRunSentenceScript(); virtual void checkExecVerbs(); virtual void handleMouseOver(bool updateInventory); int verbPrepIdType(int verbid); @@ -138,6 +141,7 @@ protected: void o_unlockScript(); void o_decrement(); void o_nop(); + void o_getObjectOwner(); void o_getActorBitVar(); void o_setActorBitVar(); void o_getBitVar(); diff --git a/engines/scumm/scumm_v2.h b/engines/scumm/scumm_v2.h index b9cd8a3921..b407fd3f8a 100644 --- a/engines/scumm/scumm_v2.h +++ b/engines/scumm/scumm_v2.h @@ -99,7 +99,7 @@ protected: void drawPreposition(int index); - virtual void setActiveInventory(int object); + void walkActorToObject(int actor, int obj); /* Version 2 script opcodes */ void o2_actorFromPos(); diff --git a/engines/scumm/scumm_v5.h b/engines/scumm/scumm_v5.h index b8a61c1677..0eef04b8de 100644 --- a/engines/scumm/scumm_v5.h +++ b/engines/scumm/scumm_v5.h @@ -87,6 +87,8 @@ protected: void drawFlashlight(); + void walkActorToActor(int actor, int toActor, int dist); + /** * Fetch the next script word, then if cond is *false*, perform a relative jump. * So this corresponds to a "jne" jump instruction. diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 016248c530..376e075daa 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -366,10 +366,6 @@ void ScummEngine_v2::checkV2MouseOver(Common::Point pos) { } } -void ScummEngine_v2::setActiveInventory(int object) { - runInputScript(kInventoryClickArea, object, 0); -} - int ScummEngine_v2::checkV2Inventory(int x, int y) { int inventoryArea = (_game.platform == Common::kPlatformNES) ? 48: 32; int object = 0; @@ -717,142 +713,6 @@ void ScummEngine_v2::checkExecVerbs() { } } -void ScummEngine_v0::runObject(int obj, int entry) { - if (getVerbEntrypoint(obj, entry) == 0) { - // If nothing was found, attempt to find the 'WHAT-IS' verb script - // (which is not really the what-is script, as this verb never actually executes - // it merely seems to be some type of fallback) - if (getVerbEntrypoint(obj, 0x0F) != 0) { - entry = 0x0F; - } - } - - if (getVerbEntrypoint(obj, entry) != 0) { - runObjectScript(obj, entry, false, false, NULL); - } else if (entry != 13 && entry != 15) { - if (_activeVerb == kVerbGive) { - // For some reasons, certain objects don't have a "give" script - if (VAR(VAR_ACTIVE_ACTOR) > 0 && VAR(VAR_ACTIVE_ACTOR) < 8) { - if (OBJECT_V0_TYPE(obj) == kObjectTypeFG) { - assert(false); - setOwnerOf(obj, VAR(VAR_ACTIVE_ACTOR)); - } - } - } else { - VAR(VAR_ACTIVE_VERB) = entry; - runScript(3, 0, 0, 0); - } - } -} - -bool ScummEngine_v0::verbMoveToActor(int actor) { - Actor *a = derefActor(VAR(VAR_EGO), "verbMoveToActor"); - Actor *a2 = derefActor(actor, "verbMoveToActor"); - int dist = getDist(a->getRealPos().x, a->getRealPos().y, a2->getRealPos().x, a2->getRealPos().y); - - if (!a->_moving && dist > 4) { - a->startWalkActor(a2->getRealPos().x, a2->getRealPos().y, -1); - } else { - if (dist <= 4) { - a->stopActorMoving(); - return false; - } - } - - return true; -} - -bool ScummEngine_v0::verbMove(int object) { - int x, y, dir; - Actor *a = derefActor(VAR(VAR_EGO), "verbMove"); - - if (_currentMode != kModeNormal && _currentMode != kModeNoNewKid) - return false; - - getObjectXYPos(object, x, y, dir); - - // Detect distance from target object - int dist = getDist(a->getRealPos().x, a->getRealPos().y, x, y); - - if (a->_moving) - return true; - - if (dist > 5) { - a->startWalkActor(x, y, dir); - VAR(6) = x; - VAR(7) = y; - return true; - } else { - // Finished walk, are we picking up the item? - if (_verbPickup) { - int oldActive = OBJECT_V0(_activeObjectNr, _activeObjectType); - - _activeObjectNr = OBJECT_V0_NR(object); - _activeObjectType = OBJECT_V0_TYPE(object); - - // Execute pickup - runObject(object, 14); - - _activeObjectNr = OBJECT_V0_NR(oldActive); - _activeObjectType = OBJECT_V0_TYPE(oldActive); - - // Finished picking up - _verbPickup = false; - } - } - - return false; -} - -bool ScummEngine_v0::verbObtain(int obj) { - bool didPickup = false; - int prep; - int where; - - if (!obj) - return false; - - where = whereIsObject(obj); - - // Object in inventory ? - if (where != WIO_INVENTORY) { - prep = activeVerbPrep(); - - if (prep == kVerbPrepIn || prep == kVerbPrepTo) { - if (_activeVerb != kVerbWalkTo && _activeVerb != kVerbPickUp) { - _verbPickup = true; - didPickup = true; - } - } else { - _verbPickup = false; - } - - // Ignore verbs? - ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "verbObtain"); - if (a->_miscflags & kActorMiscFlagFreeze) { - resetSentence(false); - return false; - } - - //attempt move to object - if (verbMove(obj)) - return true; - - if (didPickup && (prep == kVerbPrepIn || prep == kVerbPrepTo)) - if (_activeVerb != kVerbWalkTo && _activeVerb != kVerbPickUp) { -// TODO(TOBIAS) -#if 0 - if (whereIsObject(obj) == WIO_INVENTORY) - _activeInventory = obj; - else - resetSentence(false); -#endif - } - } - - return false; -} - int ScummEngine_v0::getVerbPrepId() { if (_verbs[_activeVerb].prep != 0xFF) { return _verbs[_activeVerb].prep; @@ -869,150 +729,44 @@ int ScummEngine_v0::activeVerbPrep() { return getVerbPrepId(); } -bool ScummEngine_v0::verbExec() { - int entry = (_currentMode != kModeCutscene && _currentMode != kModeKeypad) ? _activeVerb : kVerbWhatIs; - - if (_activeObjectNr && getObjectIndex(OBJECT_V0(_activeObjectNr, _activeObjectType)) == -1) { - resetSentence(false); - return false; - } - - // Lets try walk to the object - if (_activeObjectNr && !_activeObjectObtained && _currentMode != kModeCutscene) { - if (verbObtain(OBJECT_V0(_activeObjectNr, _activeObjectType))) - return true; - - _activeObjectObtained = true; - } - - // Attempt to obtain/reach object2 - if (_activeObject2Nr && !_activeObject2Obtained && _currentMode != kModeCutscene) { - if (verbObtain(OBJECT_V0(_activeObject2Nr, _activeObject2Type))) - return true; - - _activeObject2Obtained = true; - } - - // Give-To - if (_activeVerb == kVerbGive && _activeObjectNr && _activeObject2Nr && _activeObject2Type == kObjectTypeActor) { - // FIXME: Actors need to turn and face each other - if (verbMoveToActor(_activeObject2Nr)) { - // Ignore verbs? - Actor *a = derefActor(VAR(VAR_EGO), "verbExec"); - if (((ActorC64 *)a)->_miscflags & kActorMiscFlagFreeze) { - resetSentence(false); - return false; - } - - return true; - } - VAR(VAR_ACTIVE_ACTOR) = _activeObject2Nr; - runObject(OBJECT_V0(_activeObjectNr, _activeObjectType), 3); - - resetSentence(false); - return false; - } - - // Where we performing an action on an actor? - if (_activeObject2Nr && _activeObject2Type == kObjectTypeActor) { - runObject(OBJECT_V0(_activeObject2Nr, _activeObject2Type), entry); - _verbExecuting = false; - - resetSentence(false); - return false; - } - - // If we've finished walking (now near target), execute the action - if (_activeObjectNr && activeVerbPrep() == kVerbPrepWith) { - runObject(OBJECT_V0(_activeObjectNr, _activeObjectType), entry); - _verbExecuting = false; - - if ((_currentMode == kModeNormal || _currentMode == kModeNoNewKid) && _activeVerb == kVerbWalkTo) - return false; - - resetSentence(false); - return false; - } - - // We acted on an inventory item - if (_activeVerb != kVerbGive) { - runObject(OBJECT_V0(_activeObjectNr/*2*/, _activeObjectType/*2*/), _activeVerb); - - _verbExecuting = false; - - if (_currentMode == kModeNormal && _activeVerb == kVerbWalkTo) { - resetSentence(true); - return false; +void ScummEngine_v0::verbExec() { + if (_activeVerb == kVerbWhatIs) + return; + + if (_activeVerb != kVerbWalkTo || _activeObjectNr != 0) { + doSentence(_activeVerb, + OBJECT_V0(_activeObjectNr, _activeObjectType), + OBJECT_V0(_activeObject2Nr, _activeObject2Type)); + if (_activeVerb != kVerbWalkTo) { + _activeVerb = kVerbWalkTo; + _activeObjectNr = 0; } - - resetSentence(false); - return false; - } - - if (_activeObjectNr) { - runObject(OBJECT_V0(_activeObjectNr, _activeObjectType), entry); - } - - _verbExecuting = false; - - if (_activeVerb == kVerbWalkTo) { - resetSentence(true); - return false; + _walkToObjectIdx = 0; + return; } - resetSentence(false); + ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "verbExec"); + int x = _virtualMouse.x / V12_X_MULTIPLIER; + int y = _virtualMouse.y / V12_Y_MULTIPLIER; + //actorSetPosInBox(); - return false; -} + // 0xB31 + VAR(6) = x; + VAR(7) = y; -#if 0 -verbExec() { - cmdStackMaxLeft = 6; - cmdStackPos = 0xFF; - if (verbSelectedID == 15) // WHAT IS - return; - - if (verbSelectedID != 13 || objectSelectedID != 0) { - cmdStackPos++; - cmdVerbID[cmdStackPos] = verbSelectedID; - cmdObjectID[cmdStackPos] = objectSelectedID; - cmdObjectType[cmdStackPos] = objectSelectedType; - cmdVerbPrepID[cmdStackPos] = verbPrepID; - cmdObject2ID[cmdStackPos] = objectSelected2ID; - cmdObject2Type[cmdStackPos] = objectSelected2Type; - - if (verbSelectedID != 13) { // WALK TO - verbSelectedID = 13; - objectSelectedID = 0; - verbPrepID = 0; - } - scriptUpdateSkip = 0; + if (a->_miscflags & kActorMiscFlagFreeze) return; - } - - currentActor = scriptVARS[0]; - roomActor = gActorInRoom[currentActor]; - tmpX = cursorX(); - tmpY = cursorY(); - actorSetPosInBox(); - - scriptVARS[6] = tmpX; - scriptVARS[7] = tmpY; - - if (gActor_miscFlags[scriptVARS[0]] & 0x40) { - rActor_scriptWalkToX[roomActor] = tmpX; - rActor_scriptWalkToX[roomActor] = tmpY; - walk_1C4A(); - } + + a->stopActorMoving(); + a->startWalkActor(VAR(6), VAR(7), -1); } -#endif void ScummEngine_v0::checkExecVerbs() { ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkExecVerbs"); VirtScreen *zone = findVirtScreen(_mouse.y); - int scriptUpdateSkip; int sentenceLineChanged = false; + bool execute = false; /* if (_userPut <= 0 || _mouseAndKeyboardStat == 0) @@ -1024,7 +778,6 @@ void ScummEngine_v0::checkExecVerbs() { int over = findVerbAtPos(_mouse.x, _mouse.y); if (over && _activeVerb != over) { _activeVerb = over; - //_activeVerbPrep = 0; _activeObjectNr = 0; _activeObjectType = 0; _activeObject2Nr = 0; @@ -1045,7 +798,7 @@ void ScummEngine_v0::checkExecVerbs() { } if (_mouseAndKeyboardStat < MBS_MAX_KEY) { - // TODO: Check keypresses + // TODO: check keypresses } else if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK) || _activeVerb == kVerbWhatIs) { if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) { // TODO: handle click into sentence line @@ -1081,130 +834,61 @@ void ScummEngine_v0::checkExecVerbs() { _activeObject2Type = 0; } } else { - //_activeVerbPrep: - // 0: no activeObject or activeObject but no prep - // > 0: activeObject + prep if (activeVerbPrep() == kVerbPrepNone) { if (id == _activeObjectNr && type == _activeObjectType) { - _verbExecuting = true; + execute = true; } else { _activeObjectNr = id; _activeObjectType = type; } - //sentenceLineChanged = true; if (_currentMode == kModeKeypad) - _verbExecuting = true; + execute = true; } else { if (id == _activeObject2Nr && type == _activeObject2Type) - _verbExecuting = true; + execute = true; if (!(id == _activeObjectNr && type == _activeObjectType)) { _activeObject2Nr = id; _activeObject2Type = type; if (_currentMode == kModeKeypad) - _verbExecuting = true; + execute = true; } } } sentenceLineChanged = true; - if (_activeVerb == kVerbWalkTo) { - scriptUpdateSkip = 0; - _verbExecuting = true; + if (_activeVerb == kVerbWalkTo && zone->number == kMainVirtScreen) { + _walkToObjectIdx = 0; + execute = true; } } } } - if (sentenceLineChanged) + if (sentenceLineChanged) { drawSentence(); + sentenceLineChanged = false; + } + + if (!execute || !_activeVerb) + return; if (_activeVerb == kVerbNewKid) { - // TODO if (_currentMode == kModeNormal) { - // get kid + // TODO: get clicked kid _activeVerb = kVerbWalkTo; - resetSentence(false); + drawSentence(); //switchActor(_verbs[over].verbid - 1); } _activeVerb = kVerbWalkTo; } - if (_activeVerb == kVerbWalkTo) { - //exec(); - } - - /* - if (_activeVerbPrep == 0) { - int prep = activeVerbPrep(); - if (prep == kVerbPrepNone) - ; //exec(); - else { - _activeVerbPrep = prep; - ; // draw() - } - } else { - if (_activeObject2 == 0) - ; //drawSentence(); - else - ; // exec(); + if (_activeVerb == kVerbWalkTo) + verbExec(); + else if (_activeObjectNr) { + // execute if we have a 1st object and either have or do not need a 2nd + if (activeVerbPrep() == kVerbPrepNone || _activeObject2Nr) + verbExec(); } - */ - -#if 0 - // Is a verb currently executing - if (_verbExecuting) { - // Check if mouse click - if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) { - int over = findVerbAtPos(_mouse.x, _mouse.y); - int act = getActorFromPos(_virtualMouse.x, _virtualMouse.y); - byte type; - int obj = findObject(_virtualMouse.x, _virtualMouse.y, &type); - - if (over && over != _activeVerb) { - _activeVerb = over; - _verbExecuting = false; - return; - } - - if (!obj && !act && !over) { - resetSentence(false); - } else { - a->stopActorMoving(); - } - } else { - - if (_verbExecuting && !verbExec()) - return; - } - } - - ... - - // Clicked on nothing, walk here? - if (!over && !act && _activeVerb == kVerbWalkTo && !obj && _currentMode != kMode_0) { - // Clear all selected - resetSentence(false); - - // 0xB31 - VAR(6) = _virtualMouse.x / V12_X_MULTIPLIER; - VAR(7) = _virtualMouse.y / V12_Y_MULTIPLIER; - - if (zone->number == kMainVirtScreen) { - // Ignore verbs? - if (a->_miscflags & kActorMiscFlagFreeze) { - resetSentence(false); - return; - } - a->stopActorMoving(); - a->startWalkActor(VAR(6), VAR(7), -1); - _verbExecuting = true; - } - return; - } - _verbExecuting = true; - - } // mouse k/b action -#endif } void ScummEngine::verbMouseOver(int verb) { |