Ticket #9052: v0_mm_verb.patch
File v0_mm_verb.patch, 29.2 KB (added by , 14 years ago) |
---|
-
engines/scumm/object.cpp
181 181 // Alternatively, scan the inventory to see if the object is in there... 182 182 for (i = 0; i < _numInventory; i++) { 183 183 if (_inventory[i] == obj) { 184 assert(WIO_INVENTORY == whereIsObject(obj)); 184 if(_game.version == 0) 185 assert(WIO_INVENTORY == whereIsObjectInventory( obj )); 186 else 187 assert(WIO_INVENTORY == whereIsObject(obj)); 188 185 189 // Found the object! Nuke it from the inventory. 186 190 _res->nukeResource(rtInventory, i); 187 191 _inventory[i] = 0; … … 286 290 // it. Fortunately this does not prevent frustrated players from 287 291 // blowing up the mansion, should they feel the urge to. 288 292 289 if (_game.id == GID_MANIAC && (obj == 182 || obj == 193))293 if (_game.id == GID_MANIAC && _game.version != 0 && (obj == 182 || obj == 193)) 290 294 _objectStateTable[obj] |= kObjectState_08; 291 295 } 292 296 … … 317 321 return -1; 318 322 } 319 323 324 int ScummEngine::whereIsObjectInventory(int object) { 325 int res = 0; 326 _v0ObjectInInventory = true; 327 res = whereIsObject(object); 328 _v0ObjectInInventory = false; 329 330 return res; 331 } 332 320 333 int ScummEngine::whereIsObject(int object) const { 321 334 int i; 322 335 … … 326 339 if (object < 1) 327 340 return WIO_NOT_FOUND; 328 341 329 if ( _objectOwnerTable[object] != OF_OWNER_ROOM) {342 if ((_objectOwnerTable[object] != OF_OWNER_ROOM && _game.version != 0) || _v0ObjectInInventory) { 330 343 for (i = 0; i < _numInventory; i++) 331 344 if (_inventory[i] == object) 332 345 return WIO_INVENTORY; … … 334 347 } 335 348 336 349 for (i = (_numLocalObjects-1); i > 0; i--) 337 if ( _objs[i].obj_nr == object) {350 if ((_objs[i].obj_nr == object && !_v0ObjectIndex) || (_v0ObjectIndex && i == object)) { 338 351 if (_objs[i].fl_object_index) 339 352 return WIO_FLOBJECT; 340 353 return WIO_ROOM; … … 379 392 * Returns X, Y and direction in angles 380 393 */ 381 394 void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) { 382 int idx = getObjectIndex(object); 395 int idx; 396 if(_v0ObjectIndex) 397 idx = object; 398 else 399 idx = getObjectIndex(object); 383 400 assert(idx >= 0); 384 401 ObjectData &od = _objs[idx]; 385 402 int state; … … 475 492 return getDist(x, y, x2, y2); 476 493 } 477 494 495 int ScummEngine_v0::findObjectIndex(int x, int y) { 496 int objIdx; 497 _v0ObjectIndex = true; 498 objIdx = findObject(x, y); 499 _v0ObjectIndex = false; 500 return objIdx; 501 } 502 478 503 int ScummEngine::findObject(int x, int y) { 479 504 int i, b; 480 505 byte a; … … 505 530 #endif 506 531 if (_objs[i].x_pos <= x && _objs[i].width + _objs[i].x_pos > x && 507 532 _objs[i].y_pos <= y && _objs[i].height + _objs[i].y_pos > y) 508 return _objs[i].obj_nr; 533 if(_game.version == 0 && _v0ObjectIndex) 534 return i; 535 else 536 return _objs[i].obj_nr; 509 537 break; 510 538 } 511 539 } while ((_objs[b].state & mask) == a); … … 811 839 if (_dumpScripts) { 812 840 char buf[32]; 813 841 sprintf(buf, "roomobj-%d-", _roomResource); 842 if(_game.version == 0) 843 sprintf(buf + 11, "%d-", od->flags); 844 814 845 dumpResource(buf, od->obj_nr, room + od->OBCDoffset); 815 846 } 816 847 } … … 1033 1064 int i; 1034 1065 ObjectData *od = &_objs[1]; 1035 1066 for (i = 1; i < _numLocalObjects; i++, od++) { 1067 1068 // V0 MM, Room objects with Flag==1 are objects with 'no-state' (room specific objects, non-pickup) 1069 if(_game.version == 0 && od->flags == 1) 1070 continue; 1071 1036 1072 if (od->obj_nr > 0) 1037 1073 od->state = getState(od->obj_nr); 1038 1074 } … … 1155 1191 void ScummEngine::setObjectName(int obj) { 1156 1192 int i; 1157 1193 1158 if (obj < _numActors )1194 if (obj < _numActors && _game.version != 0) 1159 1195 error("Can't set actor %d name with new-name-of", obj); 1160 1196 1161 1197 for (i = 0; i < _numNewNames; i++) { … … 1181 1217 uint32 ScummEngine::getOBCDOffs(int object) const { 1182 1218 int i; 1183 1219 1184 if (_objectOwnerTable[object] != OF_OWNER_ROOM )1220 if (_objectOwnerTable[object] != OF_OWNER_ROOM && (_game.version != 0) || _v0ObjectInInventory) 1185 1221 return 0; 1222 1223 // V0 MM Return by Index 1224 if(_v0ObjectIndex) 1225 return _objs[object].OBCDoffset; 1226 1186 1227 for (i = (_numLocalObjects-1); i > 0; i--) { 1187 1228 if (_objs[i].obj_nr == object) { 1188 1229 if (_objs[i].fl_object_index != 0) … … 1194 1235 } 1195 1236 1196 1237 byte *ScummEngine::getOBCDFromObject(int obj) { 1238 bool useInventory = _v0ObjectInInventory; 1197 1239 int i; 1198 1240 byte *ptr; 1199 1241 1200 if (_objectOwnerTable[obj] != OF_OWNER_ROOM) { 1242 _v0ObjectInInventory = false; 1243 1244 if ((_objectOwnerTable[obj] != OF_OWNER_ROOM && (_game.version != 0)) || useInventory) { 1201 1245 for (i = 0; i < _numInventory; i++) { 1202 1246 if (_inventory[i] == obj) 1203 1247 return getResourceAddress(rtInventory, i); 1204 1248 } 1205 1249 } else { 1206 1250 for (i = (_numLocalObjects-1); i > 0; --i) { 1207 if ( _objs[i].obj_nr == obj) {1251 if ((_objs[i].obj_nr == obj && !_v0ObjectIndex) || (_v0ObjectIndex && i == obj)) { 1208 1252 if (_objs[i].fl_object_index) { 1209 1253 assert(_objs[i].OBCDoffset == 8); 1210 1254 ptr = getResourceAddress(rtFlObject, _objs[i].fl_object_index); -
engines/scumm/saveload.cpp
1370 1370 void ScummEngine_v0::saveOrLoad(Serializer *s) { 1371 1371 ScummEngine::saveOrLoad(s); 1372 1372 1373 // TODO: Save additional variables 1374 // _currentMode 1375 // _currentLights 1373 const SaveLoadEntry v0Entrys[] = { 1374 MKLINE( ScummEngine_v0, _currentMode, sleUint32, VER(77) ), 1375 MKLINE( ScummEngine_v0, _currentLights, sleByte, VER(77) ), 1376 1377 MKEND() 1378 }; 1379 s->saveLoadEntries(this, v0Entrys); 1376 1380 } 1377 1381 1378 1382 void ScummEngine_v5::saveOrLoad(Serializer *s) { -
engines/scumm/script.cpp
133 133 134 134 initializeLocals(slot, vars); 135 135 136 // V0 Ensure we don't try and access objects via index inside the script 137 _v0ObjectIndex = false; 136 138 runScriptNested(slot); 137 139 } 138 140 -
engines/scumm/script_v0.cpp
410 410 actorTalk(buffer); 411 411 } 412 412 413 void ScummEngine_v0::drawSentence() { 414 Common::Rect sentenceline; 413 void ScummEngine_v0::drawSentenceWord( int object, bool usePrep, bool objInInventory) { 415 414 const byte *temp; 416 415 int sentencePrep = 0; 416 417 // If object not in inventory, we except an index 418 if(!objInInventory) 419 _v0ObjectIndex = true; 420 else 421 _v0ObjectInInventory = true; 417 422 418 if (!(_userState & 32)) 419 return; 423 temp = getObjOrActorName(object); 420 424 421 if (getResourceAddress(rtVerb, _activeVerb)) { 422 strcpy(_sentenceBuf, (char*)getResourceAddress(rtVerb, _activeVerb)); 423 } else { 424 return; 425 _v0ObjectInInventory = false; 426 _v0ObjectIndex = false; 427 428 // Append the 'object-name' 429 if (temp) { 430 strcat(_sentenceBuf, " "); 431 strcat(_sentenceBuf, (const char*)temp); 425 432 } 426 433 427 if (_activeObject > 0) { 428 temp = getObjOrActorName(_activeObject); 429 if (temp) { 430 strcat(_sentenceBuf, " "); 431 strcat(_sentenceBuf, (const char*)temp); 432 } 434 // Append the modifier? (With / On / To / In) 435 if(!usePrep) 436 return; 433 437 434 if (_verbs[_activeVerb].prep == 0xFF) { 435 byte *ptr = getOBCDFromObject(_activeObject); 436 assert(ptr); 437 sentencePrep = (*(ptr + 11) >> 5); 438 } else { 439 sentencePrep = _verbs[_activeVerb].prep; 440 } 438 if (_verbs[_activeVerb].prep == 0xFF) { 439 _v0ObjectInInventory = objInInventory; 440 sentencePrep = verbPrep(object); 441 } else { 442 sentencePrep = _verbs[_activeVerb].prep; 441 443 } 442 444 443 445 if (sentencePrep > 0 && sentencePrep <= 4) { 444 446 // The prepositions, like the fonts, were hard code in the engine. Thus 445 447 // we have to do that, too, and provde localized versions for all the 446 448 // languages MM/Zak are available in. 447 const char *prepositions[][5] = {449 static const char *prepositions[][5] = { 448 450 { " ", " in", " with", " on", " to" }, // English 449 451 { " ", " mit", " mit", " mit", " zu" }, // German 450 452 { " ", " dans", " avec", " sur", " <" }, // French … … 471 473 472 474 strcat(_sentenceBuf, prepositions[lang][sentencePrep]); 473 475 } 476 } 474 477 475 if (_activeInventory > 0) { 476 temp = getObjOrActorName(_activeInventory); 477 if (temp) { 478 strcat(_sentenceBuf, " "); 479 strcat(_sentenceBuf, (const char*)temp); 478 void ScummEngine_v0::drawSentence() { 479 Common::Rect sentenceline; 480 bool inventoryFirst = false; 481 482 if (!(_userState & 32)) 483 return; 484 485 // Current Verb, Walk/Use 486 if (getResourceAddress(rtVerb, _activeVerb)) { 487 strcpy(_sentenceBuf, (char*)getResourceAddress(rtVerb, _activeVerb)); 488 } else { 489 return; 490 } 491 492 // If using inventory first, draw it first 493 if( _activeInvExecute && _activeInventory) { 494 drawSentenceWord(_activeInventory, true, true); 495 } else { 496 // Not using inventory, use selected object 497 if(_activeObject) 498 drawSentenceWord(_activeObjectIndex, true, false); 499 else 500 inventoryFirst = true; 501 } 502 503 504 // Draw the inventory? 505 if (_activeInventory > 0 && _activeObject2 == 0) { 506 507 // Only if inventory isnt first (it will already be drawn by now) 508 if(!_activeInvExecute) { 509 drawSentenceWord(_activeInventory, inventoryFirst, true); 510 } else { 511 512 // Draw the active object, which could be inventory based, or room based 513 if(_activeObject && !_activeObjectIndex) { 514 drawSentenceWord(_activeObject, inventoryFirst, true); 515 } else // Room based 516 drawSentenceWord(_activeObjectIndex, inventoryFirst, false); 480 517 } 518 519 // Draw the 2nd active object 520 } else if(_activeObject2) { 521 522 // 2nd Object is in inventory 523 if(_activeObject2Inv) { 524 _v0ObjectInInventory = true; 525 drawSentenceWord(_activeObject2, inventoryFirst, true); 526 } else 527 drawSentenceWord(_activeObject2Index, inventoryFirst, false); 481 528 } 482 529 530 // Draw the active actor 531 if( _activeActor ) { 532 Actor *a = derefActor( _activeActor, "" ); 533 534 strcat(_sentenceBuf, " "); 535 strcat(_sentenceBuf, (const char*)a->getActorName()); 536 } 537 483 538 _string[2].charset = 1; 484 539 _string[2].ypos = _virtscr[kVerbVirtScreen].topline; 485 540 _string[2].xpos = 0; … … 664 719 int act = getVarOrDirectByte(PARAM_1); 665 720 int anim = getVarOrDirectByte(PARAM_2); 666 721 int unk = fetchScriptByte(); 722 667 723 debug(0,"o_animateActor: unk %d", unk); 668 724 669 725 Actor *a = derefActor(act, "o_animateActor"); … … 713 769 if (getObjectIndex(obj) == -1) 714 770 return; 715 771 716 if (whereIsObject (obj) == WIO_INVENTORY) /* Don't take an */772 if (whereIsObjectInventory( _activeObject2 ) == WIO_INVENTORY) /* Don't take an */ 717 773 return; /* object twice */ 718 774 719 775 addObjectToInventory(obj, _roomResource); 720 776 markObjectRectAsDirty(obj); 721 777 putOwner(obj, VAR(VAR_EGO)); … … 900 956 setOwnerOf(obj, owner); 901 957 } 902 958 903 void ScummEngine_v0::resetSentence() { 904 _activeInventory = 0; 905 _activeObject = 0; 959 void ScummEngine_v0::resetSentence( bool walking ) { 906 960 _activeVerb = 13; 961 962 if(!walking) { 963 _activeInventory = 0; 964 _activeObject = 0; 965 _activeObject2 = 0; 966 _activeObjectIndex = 0; 967 _activeObject2Index = 0; 968 } 969 970 _verbExecuting = false; 971 _verbPickup = false; 972 973 _activeActor = 0; 974 _activeInvExecute = false; 975 _activeObject2Inv = false; 976 _activeObjectObtained = false; 977 _activeObject2Obtained = false; 907 978 } 908 979 909 980 } // End of namespace Scumm -
engines/scumm/scumm.cpp
134 134 135 135 136 136 // Init all vars 137 _v0ObjectIndex = false; // V0 MM 138 _v0ObjectInInventory = false; // V0 MM 137 139 _imuse = NULL; 138 140 _imuseDigital = NULL; 139 141 _musicEngine = NULL; … … 664 666 ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr) 665 667 : ScummEngine_v2(syst, dr) { 666 668 669 _verbExecuting = false; 670 _verbPickup = false; 667 671 _currentMode = 0; 672 673 _activeObject2 = 0; 674 _activeObjectIndex = 0; 675 _activeObject2Index = 0; 676 _activeInvExecute = false; 677 _activeObject2Inv = false; 678 _activeObjectObtained = false; 679 _activeObject2Obtained = false; 668 680 } 669 681 670 682 ScummEngine_v6::ScummEngine_v6(OSystem *syst, const DetectorResult &dr) -
engines/scumm/scumm.h
565 565 int32 *_scummVars; 566 566 byte *_bitVars; 567 567 568 bool _v0ObjectIndex; // V0 Use object index, instead of object number 569 bool _v0ObjectInInventory; // V0 Use object number from inventory 570 568 571 /* Global resource tables */ 569 572 int _numVariables, _numBitVariables, _numLocalObjects; 570 573 int _numGlobalObjects, _numArray, _numVerbs, _numFlObject; … … 858 861 int getObjNewDir(int obj); 859 862 int getObjectIndex(int object) const; 860 863 int getObjectImageCount(int object); 864 int whereIsObjectInventory(int object); 861 865 int whereIsObject(int object) const; 862 866 int findObject(int x, int y); 863 867 void findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint object, uint room); -
engines/scumm/scumm_v0.h
36 36 class ScummEngine_v0 : public ScummEngine_v2 { 37 37 protected: 38 38 int _currentMode; 39 bool _verbExecuting; // is a verb executing 40 bool _verbPickup; // are we picking up an object during a verb execute 39 41 42 int _activeActor; // Actor Number 43 int _activeObject2; // 2nd Object Number 44 45 bool _activeInvExecute; // is activeInventory first to be executed 46 bool _activeObject2Inv; // is activeobject2 in the inventory 47 bool _activeObjectObtained; // collected _activeobject? 48 bool _activeObject2Obtained; // collected _activeObject2? 49 50 int _activeObjectIndex; 51 int _activeObject2Index; 52 40 53 public: 41 54 ScummEngine_v0(OSystem *syst, const DetectorResult &dr); 42 55 … … 53 66 54 67 virtual void processInput(); 55 68 69 virtual void runObject(int obj, int entry); 56 70 virtual void saveOrLoad(Serializer *s); 57 71 72 // V0 MM Verb commands 73 int verbPrep(int object); 74 bool verbMove(int object, int objectIndex, bool invObject); 75 bool verbMoveToActor(int actor); 76 bool verbObtain(int object, int objIndex); 77 bool verbExecutes(int object, bool inventory = false); 78 bool verbExec(); 79 80 int findObjectIndex(int x, int y); 81 58 82 virtual void checkExecVerbs(); 59 83 virtual void handleMouseOver(bool updateInventory); 60 84 void resetVerbs(); 61 85 void setNewKidVerbs(); 86 87 void drawSentenceWord(int object, bool usePrep, bool objInInventory); 62 88 void drawSentence(); 63 89 64 90 void switchActor(int slot); … … 68 94 69 95 virtual int getActiveObject(); 70 96 71 virtual void resetSentence( );97 virtual void resetSentence(bool walking = false); 72 98 73 99 /* Version C64 script opcodes */ 74 100 void o_stopCurrentScript(); -
engines/scumm/scumm_v2.h
100 100 101 101 virtual void setBuiltinCursor(int index); 102 102 103 v oid runObject(int obj, int entry);103 virtual void runObject(int obj, int entry); 104 104 105 105 /* Version 2 script opcodes */ 106 106 void o2_actorFromPos(); -
engines/scumm/vars.cpp
538 538 #endif 539 539 540 540 void ScummEngine_v0::resetScummVars() { 541 _activeInventory = 0; 542 _activeObject = 0; 543 _activeVerb = 13; 541 resetSentence(); 544 542 545 543 VAR(VAR_EGO) = 3; 546 544 -
engines/scumm/verbs.cpp
155 155 VAR(VAR_EGO) = VAR(97 + slot); 156 156 actorFollowCamera(VAR(VAR_EGO)); 157 157 resetVerbs(); 158 resetSentence(false); 158 159 setUserState(247); 159 160 } 160 161 … … 376 377 377 378 if (object > 0) { 378 379 if (_game.version == 0) { 379 if (_activeInventory != object) {380 380 _activeInventory = object; 381 } else if (_activeVerb != 3 && _activeVerb != 13) { 382 if (_activeObject) 383 runObject(_activeObject, _activeVerb); 384 else 385 runObject(_activeInventory, _activeVerb); 386 } 381 387 382 } else { 388 383 runInputScript(kInventoryClickArea, object, 0); 389 384 } … … 425 420 _string[1].right = _mouseOverBoxesV2[i].rect.right - 1; 426 421 _string[1].color = _mouseOverBoxesV2[i].color; 427 422 423 _v0ObjectInInventory = true; 428 424 const byte *tmp = getObjOrActorName(obj); 425 _v0ObjectInInventory = false; 429 426 assert(tmp); 430 427 431 428 // Prevent inventory entries from overflowing by truncating the text … … 666 663 } 667 664 } 668 665 666 void ScummEngine_v0::runObject(int obj, int entry) { 667 int prev = _v0ObjectInInventory; 668 669 if (getVerbEntrypoint(obj, entry) != 0) { 670 _v0ObjectInInventory = prev; 671 runObjectScript(obj, entry, false, false, NULL); 672 } else if (entry != 13 && entry != 15) { 673 if( _activeVerb != 0x03 ) { 674 VAR(9) = entry; 675 runScript(3, 0, 0, 0); 676 677 // For some reasons, certain objects don't have a "give" script 678 } else if(VAR(5) > 0 && VAR(5) < 8) 679 if(_activeInventory) 680 setOwnerOf( _activeInventory, VAR(5) ); 681 } 682 } 683 669 684 void ScummEngine_v2::runObject(int obj, int entry) { 670 685 if (getVerbEntrypoint(obj, entry) != 0) { 671 686 runObjectScript(obj, entry, false, false, NULL); … … 679 694 _activeVerb = 13; 680 695 } 681 696 697 static int getDist(int x, int y, int x2, int y2) { 698 int a = ABS(y - y2); 699 int b = ABS(x - x2); 700 return MAX(a, b); 701 } 702 703 bool ScummEngine_v0::verbMoveToActor(int actor) { 704 Actor *a = derefActor(VAR(VAR_EGO), "checkExecVerbs"); 705 Actor *a2 =derefActor(actor, "checkExecVerbs"); 706 707 708 if(!a->_moving) { 709 int dist = getDist(a->getRealPos().x, a->getRealPos().y, a2->getRealPos().x, a2->getRealPos().y); 710 711 if(dist>5) 712 a->startWalkActor( a2->getRealPos().x, a2->getRealPos().y, 1 ); 713 else 714 return false; 715 716 return true; 717 } 718 719 return true; 720 } 721 722 bool ScummEngine_v0::verbMove(int object, int objectIndex, bool invObject) { 723 int x, y, dir; 724 Actor *a = derefActor(VAR(VAR_EGO), "checkExecVerbs"); 725 726 if(_currentMode != 3 && _currentMode != 2) 727 return false; 728 729 if(a->_moving) 730 return true; 731 732 _v0ObjectIndex = true; 733 getObjectXYPos(objectIndex, x, y, dir); 734 _v0ObjectIndex = false; 735 // Detect distance from target object, I wasn't able to use Scumm::getDist, it wouldn't compile 736 // So i c/p it above 737 int dist = getDist(a->getRealPos().x, a->getRealPos().y, x, y); 738 739 // FIXME: This should be changed once the walkbox problem is fixed 740 if(dist>0x5) { 741 a->startWalkActor(x, y, dir); 742 VAR(6) = x; 743 VAR(7) = y; 744 return true; 745 } else { 746 747 // Finished walk, are we picking up the item? 748 if(_verbPickup) { 749 int oldActive = _activeObject, oldIndex = _activeObjectIndex; 750 _activeObject = object; 751 _activeObjectIndex = objectIndex; 752 753 _v0ObjectIndex = true; 754 // Execute pickup 755 runObject(objectIndex, 0x0E ); 756 _v0ObjectIndex = false; 757 758 _activeObject = oldActive; 759 _activeObjectIndex = oldIndex; 760 761 // Finished picking up 762 _verbPickup = false; 763 } 764 } 765 766 return false; 767 } 768 769 bool ScummEngine_v0::verbObtain(int obj, int objIndex) { 770 bool didPickup = false; 771 772 int prep, where = whereIsObjectInventory( obj ); 773 774 if(objIndex==0) 775 return false; 776 777 if(where != WIO_INVENTORY) { 778 _v0ObjectIndex = true; 779 prep = verbPrep( objIndex ); 780 781 if(prep == 1 || prep == 4) { 782 if(_activeVerb != 13 && _activeVerb != 0x0E) { 783 _verbPickup = true; 784 didPickup = true; 785 } 786 } else 787 _verbPickup = false; 788 789 if( verbMove( obj, objIndex, false ) ) 790 return true; 791 792 if(didPickup && (prep == 1 || prep == 4)) 793 if(_activeVerb != 13 && _activeVerb != 0x0E) 794 _activeInventory = obj; 795 } 796 797 return false; 798 } 799 800 int ScummEngine_v0::verbPrep(int object) { 801 if(!_v0ObjectInInventory) 802 _v0ObjectIndex = true; 803 else 804 _v0ObjectIndex = false; 805 byte *ptr = getOBCDFromObject(object); 806 _v0ObjectIndex = false; 807 assert(ptr); 808 return (*(ptr + 11) >> 5); 809 } 810 811 bool ScummEngine_v0::verbExecutes( int object, bool inventory ) { 812 _v0ObjectInInventory = inventory; 813 int prep = verbPrep( object ); 814 815 if( prep == 2 || prep == 0) { 816 return true; 817 } 818 819 return false; 820 } 821 822 bool ScummEngine_v0::verbExec() { 823 int where = 0, prep = 0; 824 int entry = (_currentMode != 0 && _currentMode != 1) ? _activeVerb : 15; 825 826 if((!_activeInvExecute && _activeObject && getObjectIndex(_activeObject)==-1) ) { 827 resetSentence(); 828 return false; 829 } 830 831 // Lets try walk to the object 832 if(_activeObject && _activeObjectIndex && !_activeObjectObtained && _currentMode != 0) { 833 prep = verbPrep(_activeObjectIndex); 834 835 if( verbObtain( _activeObject, _activeObjectIndex ) ) 836 return true; 837 838 _activeObjectObtained = true; 839 } 840 841 if(_activeObject2 && _activeObject2Index && !_activeObject2Obtained && _currentMode != 0) { 842 prep = verbPrep(_activeObject2Index); 843 844 _v0ObjectInInventory = false; 845 if(verbObtain(_activeObject2, _activeObject2Index)) 846 return true; 847 848 if(prep != 1 && prep != 4) { 849 _activeInventory = _activeObject; 850 _activeObject = _activeObject2; 851 _activeObjectIndex = _activeObject2Index; 852 _activeObject2 = 0; 853 _activeObject2Index = 0; 854 } 855 856 _activeObject2Obtained = true; 857 } 858 859 // Give-To 860 if(_activeVerb==0x03 && _activeInventory && _activeActor) { 861 // FIXME: Actors need to turn and face each other 862 // And walk to each other 863 // 864 if( verbMoveToActor(_activeActor) ) 865 return true; 866 867 _v0ObjectInInventory = true; 868 VAR(5) = _activeActor; 869 runObject(_activeInventory , 0x03 ); 870 _v0ObjectInInventory = false; 871 872 resetSentence(); 873 return false; 874 } 875 876 if(_activeActor) { 877 _v0ObjectIndex = true; 878 runObject(_activeActor, entry); 879 _v0ObjectIndex = false; 880 _verbExecuting = false; 881 882 resetSentence(); 883 return false; 884 } 885 886 // If we've finished walking (now near target), execute the action 887 if(_activeObject && _activeObjectIndex && verbPrep(_activeObjectIndex) == 2) { 888 889 _v0ObjectIndex = true; 890 runObject(_activeObjectIndex, entry); 891 _v0ObjectIndex = false; 892 _verbExecuting = false; 893 894 if((_currentMode == 3 || _currentMode == 2) && _activeVerb==13) 895 return false; 896 897 resetSentence(); 898 return false; 899 } 900 901 // We acted on an inventory item 902 if( _activeInventory && verbExecutes(_activeInventory, true) && _activeVerb != 0x03 ) { 903 904 _v0ObjectInInventory = true; 905 runObject(_activeInventory, _activeVerb); 906 907 _verbExecuting = false; 908 909 if(_currentMode == 3 && _activeVerb==13) { 910 resetSentence(true); 911 return false; 912 } 913 914 resetSentence(); 915 return false; 916 } 917 918 if(_activeObject) { 919 _v0ObjectIndex = true; 920 runObject(_activeObjectIndex, entry); 921 _v0ObjectIndex = false; 922 } else if(_activeInventory ) { 923 924 if(verbExecutes(_activeInventory, true) == false) { 925 926 if(_activeObject2 && verbExecutes(_activeObject2, true)) { 927 _v0ObjectInInventory = true; 928 929 _activeObject = _activeInventory; 930 _activeInventory = _activeObject2; 931 932 runObject(_activeObject, _activeVerb); 933 } else { 934 _v0ObjectInInventory = true; 935 runObject(_activeInventory, _activeVerb); 936 } 937 } else { 938 runObject(_activeInventory, _activeVerb); 939 _v0ObjectInInventory = true; 940 } 941 } 942 943 _verbExecuting = false; 944 945 if(_activeVerb==0xD) { 946 resetSentence(true); 947 return false; 948 } 949 950 resetSentence(); 951 952 return false; 953 } 954 682 955 void ScummEngine_v0::checkExecVerbs() { 683 956 Actor *a; 684 957 VirtScreen *zone = findVirtScreen(_mouse.y); 685 958 959 // Is a verb currently executing 960 if( _verbExecuting ) { 961 962 // Check if mouse click 963 if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) { 964 int over = findVerbAtPos(_mouse.x, _mouse.y); 965 int act = getActorFromPos(_virtualMouse.x, _virtualMouse.y); 966 int obj = findObject(_virtualMouse.x, _virtualMouse.y); 967 968 if(over && over != _activeVerb) { 969 _activeVerb = over; 970 _verbExecuting = false; 971 return; 972 } 973 974 if(!obj && !act && !over) { 975 resetSentence( false ); 976 } else { 977 a = derefActor(VAR(VAR_EGO), "checkExecVerbs"); 978 a->stopActorMoving(); 979 } 980 } else { 981 if(_verbExecuting) 982 if(!verbExec()) 983 return; 984 } 985 } 986 987 // What-Is selected, any object we hover over is selected, on mouse press we set to WalkTo 988 if(_activeVerb == 0x0F) { 989 int obj = findObject(_virtualMouse.x, _virtualMouse.y); 990 int objIdx = findObjectIndex(_virtualMouse.x, _virtualMouse.y); 991 _activeObject = obj; 992 _activeObjectIndex = objIdx; 993 994 if((_mouseAndKeyboardStat & MBS_MOUSE_MASK)) 995 _activeVerb = 13; // Walk-To 996 997 return; 998 } 999 686 1000 if (_userPut <= 0 || _mouseAndKeyboardStat == 0) 687 1001 return; 688 1002 … … 693 1007 if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) { 694 1008 // TODO 695 1009 } else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) { 1010 int prevInventory = _activeInventory; 1011 696 1012 // Click into V2 inventory 697 1013 checkV2Inventory(_mouse.x, _mouse.y); 1014 if(!_activeInventory) 1015 return; 1016 1017 // Did we just change the selected inventory item? 1018 if(prevInventory && prevInventory != _activeInventory && _activeInventory != _activeObject2) { 1019 _activeObject = 0; 1020 _activeInvExecute = true; 1021 _activeObject2Inv = true; 1022 _activeObject2 = _activeInventory; 1023 _activeInventory = prevInventory; 1024 return; 1025 } 1026 1027 // is the new selected inventory the same as the last selected?, reset to previous if it is 1028 if(_activeInventory == _activeObject2) 1029 _activeInventory = prevInventory; 1030 1031 // Inventory Selected changed 1032 if(prevInventory != _activeInventory) 1033 if(!_activeObject2 || prevInventory != _activeObject2 ) 1034 return; 1035 1036 if(_activeVerb == 0x0B && !((!(_activeObject || _activeInventory)) || !_activeObject2)) 1037 return; 1038 698 1039 } else { 699 1040 int over = findVerbAtPos(_mouse.x, _mouse.y); 1041 int act = getActorFromPos(_virtualMouse.x, _virtualMouse.y); 1042 int obj = findObject(_virtualMouse.x, _virtualMouse.y); 1043 int objIdx = findObjectIndex(_virtualMouse.x, _virtualMouse.y); 700 1044 1045 if((_activeObject || _activeInventory) && act) { 1046 obj = 0; 1047 objIdx = 0; 1048 } 1049 701 1050 // Handle New Kid verb options 702 if (_activeVerb == 7) { 1051 if (_activeVerb == 7 || over == 7) { 1052 1053 // Disable New-Kid (in the secret lab) 1054 if( _currentMode == 2 || _currentMode == 0) 1055 return; 1056 1057 if(_activeVerb != 7) { 1058 _activeVerb = over; 1059 over = 0; 1060 } 1061 703 1062 if (over) { 704 1063 _activeVerb = 13; 705 1064 switchActor(_verbs[over].verbid - 1); 1065 return; 706 1066 } 1067 1068 setNewKidVerbs(); 1069 707 1070 return; 708 1071 } 1072 1073 // Clicked on nothing, walk here? 1074 if(!over && !act && _activeVerb==13 && !obj && _currentMode != 0 ) { 709 1075 710 if (over) { 711 _activeVerb = _verbs[over].verbid; 712 // Selected New Kid verb 713 if (_activeVerb == 7) 714 setNewKidVerbs(); 1076 // Clear all selected 1077 resetSentence(); 715 1078 1079 // 0xB31 1080 VAR(6) = _virtualMouse.x / V12_X_MULTIPLIER; 1081 VAR(7) = _virtualMouse.y / V12_Y_MULTIPLIER; 1082 1083 if (zone->number == kMainVirtScreen) { 1084 a = derefActor(VAR(VAR_EGO), "checkExecVerbs"); 1085 a->stopActorMoving(); 1086 a->startWalkActor(_virtualMouse.x / V12_X_MULTIPLIER, _virtualMouse.y / V12_Y_MULTIPLIER, -1); 1087 } 716 1088 return; 717 1089 } 718 1090 719 int act = getActorFromPos(_virtualMouse.x, _virtualMouse.y); 720 int obj = findObject(_virtualMouse.x, _virtualMouse.y); 721 if (act != 0 && _activeVerb == 3 && _activeInventory != 0) { 722 // Give inventory item to actor 723 VAR(5) = act; 724 runObject(_activeInventory, _activeVerb); 725 } else if (obj) { 726 if (_currentMode == 3 && _activeVerb != 13 && obj != _activeObject) { 727 _activeObject = obj; 728 return; 1091 // No new verb, use previous 1092 if(over==0) 1093 over = _activeVerb; 1094 1095 // No verb selected, use walk-to 1096 if(!_activeVerb) 1097 _activeVerb = over = 13; // Walk-To 1098 1099 // New verb selected 1100 if(_activeVerb != over) { 1101 _activeVerb = over; 1102 if(_activeVerb==0x0D) { 1103 resetSentence(); 729 1104 } 1105 return; 1106 } 730 1107 731 _activeObject = obj; 732 if (_currentMode == 3) { 733 int x, y, dir; 734 a = derefActor(VAR(VAR_EGO), "checkExecVerbs"); 735 getObjectXYPos(obj, x, y, dir); 736 a->startWalkActor(x, y, dir); 1108 // Only allowing targetting actors if its the GIVE/USE verb 1109 if(_activeVerb == 0x03 || _activeVerb == 0x0B) { 1110 // Different actor selected? 1111 if(act) { 1112 if( _activeActor != act ) { 1113 _activeActor = act; 1114 return; 1115 } 737 1116 } 1117 } 738 1118 739 int entry = (_currentMode == 3) ? _activeVerb : 15; 740 runObject(_activeObject, entry); 741 } else if (zone->number == kMainVirtScreen) { 742 a = derefActor(VAR(VAR_EGO), "checkExecVerbs"); 743 a->startWalkActor(_virtualMouse.x / V12_X_MULTIPLIER, _virtualMouse.y / V12_Y_MULTIPLIER, -1); 1119 if(obj && obj != _activeObject) { 1120 if(!_activeObject) 1121 if(_activeInventory) 1122 _activeInvExecute = true; 1123 1124 // USE 1125 if(_activeVerb == 0x0b || _activeVerb == 0x08) { 1126 if(obj != _activeObject || obj != _activeObject2 ) { 1127 if(!_activeObject || _activeInventory) { 1128 _activeObject = obj; 1129 _activeObjectIndex = objIdx; 1130 return; 1131 } else 1132 if(_activeObject2 != obj) { 1133 _activeObject2 = obj; 1134 _activeObject2Index = objIdx; 1135 return; 1136 } 1137 } 1138 } else { 1139 1140 _activeObject = obj; 1141 _activeObjectIndex = objIdx; 1142 1143 if(_activeVerb!=13) 1144 return; 1145 1146 //return; 1147 } 744 1148 } 1149 } 745 1150 746 _activeInventory = 0; 747 _activeObject = 0; 748 _activeVerb = 13; 749 } 750 } 1151 _verbExecuting = true; 1152 1153 } // mouse k/b action 1154 751 1155 } 752 1156 753 1157 void ScummEngine::verbMouseOver(int verb) {