Ticket #9144: v0_mm_verb_anim2.patch
File v0_mm_verb_anim2.patch, 13.6 KB (added by , 15 years ago) |
---|
-
actor.cpp
215 215 void Actor::stopActorMoving() { 216 216 if (_walkScript) 217 217 _vm->stopScript(_walkScript); 218 219 // V0 Games will walk on the spot if the actor is stopped mid-walk 220 // So we must set the stand still frame 221 if( _vm->_game.version == 0 ) 222 startWalkAnim( 3, -1 ); 223 218 224 _moving = 0; 219 225 } 220 226 -
costume.cpp
75 75 0x17, 0x00, 0x01, 0x05, 0x16 76 76 }; 77 77 78 const byte v0ActorTalkArray[0x19] = { 79 0x00, 0x06, 0x06, 0x06, 0x06, 80 0x06, 0x06, 0x00, 0x46, 0x06, 81 0x06, 0x06, 0x06, 0xFF, 0xFF, 82 0x06, 0xC0, 0x06, 0x06, 0x00, 83 0xC0, 0xC0, 0x00, 0x06, 0x06 84 }; 78 85 79 86 byte ClassicCostumeRenderer::mainRoutine(int xmoveCur, int ymoveCur) { 80 87 int i, skip = 0; … … 1357 1364 } 1358 1365 1359 1366 void C64CostumeLoader::actorSpeak(ActorC64 *a, int &cmd) { 1367 1368 if( (v0ActorTalkArray[ a->_number ] & 0x80) ) 1369 return; 1370 1360 1371 if ((a->_speaking & 0x80)) 1361 1372 cmd += 0x0C; 1362 1373 else … … 1372 1383 1373 1384 // Enable/Disable speaking flag 1374 1385 if (frame == a->_talkStartFrame) { 1386 if( (v0ActorTalkArray[ a->_number ] & 0x40) ) 1387 return; 1388 1375 1389 A->_speaking = 1; 1376 1390 return; 1377 1391 } … … 1409 1423 int cmd = A->_costCommand; 1410 1424 A->_speakingPrev = A->_speaking; 1411 1425 1412 // Update to use speak frame 1413 if (A->_speaking & 0x80) { 1414 actorSpeak(A, cmd); 1426 actorSpeak(A, cmd); 1415 1427 1416 } else {1417 // Update to use stand frame1418 if (A->_costFrame == A->_standFrame)1419 cmd = dirToDirStop(cmd);1420 }1421 1422 1428 // Update the limb frames 1423 1429 frameUpdate(A, cmd); 1424 1430 } … … 1426 1432 if (A->_moving && _vm->_currentRoom != 1 && _vm->_currentRoom != 44) { 1427 1433 if (a->_cost.soundPos == 0) 1428 1434 a->_cost.soundCounter++; 1429 a->_cost.soundPos = (a->_cost.soundPos + 1) % 3; 1435 1436 // Is this the correct location? 1437 // 0x073C 1438 if( (v0ActorTalkArray[ a->_number ] & 0x3F) ) 1439 a->_cost.soundPos = (a->_cost.soundPos + 1) % 3; 1430 1440 } 1431 1441 1432 1442 // increase each frame pos -
costume.h
28 28 #include "scumm/base-costume.h" 29 29 30 30 namespace Scumm { 31 extern const byte v0ActorTalkArray[0x19]; 31 32 32 33 class ClassicCostumeLoader : public BaseCostumeLoader { 33 34 public: -
script_v0.cpp
635 635 636 636 a = derefActor(VAR(VAR_EGO), "o_loadRoomWithEgo"); 637 637 638 a->putActor(0, 0, room); 638 //0x634F 639 if( (((ActorC64*) a)->_miscflags & 0x40) ) { 640 641 // TODO: Check if this is the correct function 642 // to be calling here 643 stopObjectCode(); 644 return; 645 } 646 647 // The original interpreter seems to set the actors new room X/Y to the last rooms X/Y 648 // This fixes a problem with MM: script 158 in room 12, the 'Oompf!' script 649 // This scripts runs before the actor position is set to the correct location 650 a->putActor(a->getPos().x, a->getPos().y, room); 639 651 _egoPositioned = false; 640 652 641 653 startScene(a->_room, a, obj); … … 815 827 else 816 828 a->_miscflags &= ~mask; 817 829 830 // This flag causes the actor to stop moving (used by script #158, Green Tentacle 'Oomph!') 831 if(a->_miscflags & 0x40) 832 a->stopActorMoving(); 833 818 834 debug(0, "o_setActorBitVar(%d, %d, %d)", act, mask, mod); 819 835 } 820 836 -
scumm.h
878 878 void findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint object, uint room); 879 879 public: 880 880 int getObjectOrActorXY(int object, int &x, int &y); // Used in actor.cpp, hence public 881 int getDist(int x, int y, int x2, int y2); // Also used in actor.cpp 881 882 protected: 882 int getDist(int x, int y, int x2, int y2); 883 883 884 int getObjActToObjActDist(int a, int b); // Not sure how to handle 884 885 const byte *getObjOrActorName(int obj); // these three.. 885 886 void setObjectName(int obj); -
verbs.cpp
154 154 } 155 155 156 156 void ScummEngine_v0::switchActor(int slot) { 157 resetSentence(false); 158 159 if( _currentRoom == 45 ) 160 return; 161 162 // radiation suit? don't let the player switch 163 if( VAR(VAR_EGO) == 8 ) 164 return; 165 166 // verbs disabled? or just new kid button? 167 if( _currentMode == 0 || _currentMode == 1 || _currentMode == 2 ) 168 return; 169 170 // verbs disabled for the current actor 171 ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "switchActor"); 172 if(a->_miscflags & 0x40) 173 return; 174 157 175 VAR(VAR_EGO) = VAR(97 + slot); 176 resetVerbs(); 158 177 actorFollowCamera(VAR(VAR_EGO)); 159 resetVerbs();160 resetSentence(false);161 178 setUserState(247); 162 179 } 163 180 … … 668 685 void ScummEngine_v0::runObject(int obj, int entry) { 669 686 int prev = _v0ObjectInInventory; 670 687 688 if( getVerbEntrypoint(obj, entry) == 0 ) { 689 690 // If nothing was found, attempt to find the 'WHAT-IS' verb script 691 // (which is not really the what-is script, as this verb never actually executes 692 // it merely seems to be some type of fallback) 693 if( getVerbEntrypoint(obj, 0x0F) != 0 ) { 694 695 entry = 0x0F; 696 } 697 } 698 699 _v0ObjectInInventory = prev; 700 671 701 if (getVerbEntrypoint(obj, entry) != 0) { 672 702 _v0ObjectInInventory = prev; 673 703 runObjectScript(obj, entry, false, false, NULL); 704 674 705 } else if (entry != 13 && entry != 15) { 706 675 707 if (_activeVerb != 3) { 676 708 VAR(9) = entry; 677 709 runScript(3, 0, 0, 0); … … 698 730 } 699 731 700 732 bool ScummEngine_v0::verbMoveToActor(int actor) { 701 Actor *a = derefActor(VAR(VAR_EGO), "checkExecVerbs"); 702 Actor *a2 =derefActor(actor, "checkExecVerbs"); 733 Actor *a = derefActor(VAR(VAR_EGO), "verbMoveToActor"); 734 Actor *a2 =derefActor(actor, "verbMoveToActor"); 735 int dist = getDist(a->getRealPos().x, a->getRealPos().y, a2->getRealPos().x, a2->getRealPos().y); 703 736 704 if (!a->_moving) { 705 int dist = getDist(a->getRealPos().x, a->getRealPos().y, a2->getRealPos().x, a2->getRealPos().y); 706 if (dist > 8) 707 a->startWalkActor(a2->getRealPos().x, a2->getRealPos().y, 1); 708 else 737 if (!a->_moving && dist > 4) { 738 739 a->startWalkActor(a2->getRealPos().x, a2->getRealPos().y, -1); 740 } else 741 if( dist <= 4 ) { 742 a->stopActorMoving(); 709 743 return false; 744 } 710 745 711 return true;712 }713 714 746 return true; 715 747 } 716 748 717 749 bool ScummEngine_v0::verbMove(int object, int objectIndex, bool invObject) { 718 750 int x, y, dir; 719 Actor *a = derefActor(VAR(VAR_EGO), " checkExecVerbs");751 Actor *a = derefActor(VAR(VAR_EGO), "verbMove"); 720 752 721 753 if (_currentMode != 3 && _currentMode != 2) 722 754 return false; 723 755 724 if (a->_moving)725 return true;726 727 756 _v0ObjectIndex = true; 728 757 getObjectXYPos(objectIndex, x, y, dir); 729 758 _v0ObjectIndex = false; 759 730 760 // Detect distance from target object 731 761 int dist = getDist(a->getRealPos().x, a->getRealPos().y, x, y); 732 762 733 if (dist > 8) { 763 if( a->_moving ) 764 return true; 765 766 if (dist > 5) { 734 767 a->startWalkActor(x, y, dir); 735 768 VAR(6) = x; 736 769 VAR(7) = y; 737 770 return true; 738 771 } else { 772 739 773 // Finished walk, are we picking up the item? 740 774 if (_verbPickup) { 741 775 int oldActive = _activeObject, oldIndex = _activeObjectIndex; … … 766 800 if (objIndex == 0) 767 801 return false; 768 802 803 // Object in inventory ? 769 804 if (where != WIO_INVENTORY) { 770 805 _v0ObjectIndex = true; 771 806 prep = verbPrep(objIndex); … … 778 813 } else { 779 814 _verbPickup = false; 780 815 } 816 817 818 819 // Ignore verbs? 820 Actor *a = derefActor(VAR(VAR_EGO), "verbObtain"); 821 if( (((ActorC64*) a)->_miscflags & 0x40) ) { 822 resetSentence(false); 823 return false; 824 } 781 825 826 //attempt move to object 782 827 if (verbMove(obj, objIndex, false)) 783 828 return true; 784 829 785 830 if (didPickup && (prep == 1 || prep == 4)) 786 if (_activeVerb != 13 && _activeVerb != 14) 787 _activeInventory = obj; 831 if (_activeVerb != 13 && _activeVerb != 14) { 832 _v0ObjectInInventory = true; 833 834 if( whereIsObject( obj ) == WIO_INVENTORY ) 835 _activeInventory = obj; 836 else 837 resetSentence(); 838 839 _v0ObjectInInventory = false; 840 } 788 841 } 789 842 790 843 return false; … … 795 848 _v0ObjectIndex = true; 796 849 else 797 850 _v0ObjectIndex = false; 851 798 852 byte *ptr = getOBCDFromObject(object); 799 853 _v0ObjectIndex = false; 800 854 assert(ptr); … … 831 885 _activeObjectObtained = true; 832 886 } 833 887 888 // Attempt to obtain/reach object2 834 889 if (_activeObject2 && _activeObject2Index && !_activeObject2Obtained && _currentMode != 0) { 835 890 prep = verbPrep(_activeObject2Index); 836 891 … … 851 906 852 907 // Give-To 853 908 if (_activeVerb == 3 && _activeInventory && _activeActor) { 909 854 910 // FIXME: Actors need to turn and face each other 855 // And walk to each other 856 if (verbMoveToActor(_activeActor)) 911 if (verbMoveToActor(_activeActor)) { 912 // Ignore verbs? 913 Actor *a = derefActor(VAR(VAR_EGO), "verbExec"); 914 if( (((ActorC64*) a)->_miscflags & 0x40) ) { 915 resetSentence(false); 916 return false; 917 } 918 857 919 return true; 858 920 } 859 921 _v0ObjectInInventory = true; 860 922 VAR(5) = _activeActor; 861 923 runObject(_activeInventory , 3); … … 865 927 return false; 866 928 } 867 929 930 // Where we performing an action on an actor? 868 931 if (_activeActor) { 869 932 _v0ObjectIndex = true; 870 933 runObject(_activeActor, entry); … … 905 968 return false; 906 969 } 907 970 971 // Item not in inventory is executed 908 972 if (_activeObject) { 909 973 _v0ObjectIndex = true; 910 974 runObject(_activeObjectIndex, entry); 911 975 _v0ObjectIndex = false; 912 976 } else if (_activeInventory) { 977 978 // Not sure this is the correct way to do this, 979 // however its working for most situations - segra 913 980 if (verbExecutes(_activeInventory, true) == false) { 914 if (_activeObject2 && verbExecutes(_activeObject2, true)) {981 if (_activeObject2 && _activeObject2Inv && verbExecutes(_activeObject2, true)) { 915 982 _v0ObjectInInventory = true; 916 983 917 984 _activeObject = _activeInventory; … … 920 987 runObject(_activeObject, _activeVerb); 921 988 } else { 922 989 _v0ObjectInInventory = true; 923 runObject(_activeInventory, _activeVerb); 990 991 if(_activeObject2) { 992 _activeObject = _activeObject2; 993 994 runObject(_activeObject, _activeVerb); 995 } else 996 runObject(_activeInventory, _activeVerb); 924 997 } 925 998 } else { 999 _v0ObjectInInventory = true; 926 1000 runObject(_activeInventory, _activeVerb); 927 _v0ObjectInInventory = true;928 1001 } 929 1002 } 930 1003 … … 941 1014 } 942 1015 943 1016 void ScummEngine_v0::checkExecVerbs() { 944 Actor *a ;1017 Actor *a = derefActor(VAR(VAR_EGO), "checkExecVerbs"); 945 1018 VirtScreen *zone = findVirtScreen(_mouse.y); 946 1019 947 1020 // Is a verb currently executing … … 961 1034 if (!obj && !act && !over) { 962 1035 resetSentence(false); 963 1036 } else { 964 a = derefActor(VAR(VAR_EGO), "checkExecVerbs");965 1037 a->stopActorMoving(); 966 1038 } 967 1039 } else { 1040 968 1041 if (_verbExecuting && !verbExec()) 969 1042 return; 970 1043 } … … 994 1067 // TODO 995 1068 } else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) { 996 1069 int prevInventory = _activeInventory; 1070 int invOff = _inventoryOffset; 997 1071 998 1072 // Click into V2 inventory 999 1073 checkV2Inventory(_mouse.x, _mouse.y); 1074 1075 // Did the Inventory position changed (arrows pressed, do nothing) 1076 if(invOff != _inventoryOffset) 1077 return; 1078 1079 // No inventory selected? 1000 1080 if (!_activeInventory) 1001 1081 return; 1002 1082 1003 1083 // Did we just change the selected inventory item? 1004 1084 if (prevInventory && prevInventory != _activeInventory && _activeInventory != _activeObject2) { 1085 _v0ObjectInInventory = true; 1086 int prep = verbPrep( _activeInventory ); 1087 _v0ObjectInInventory = true; 1088 int prep2 = verbPrep( prevInventory ); 1089 1090 // Should the new inventory object remain as the secondary selected object 1091 // Or should the new inventory object become primary? 1092 if( prep != prep2 || prep != 1) { 1093 if( prep == 1 || prep == 3) { 1094 int tmp = _activeInventory; 1095 _activeInventory = prevInventory; 1096 prevInventory = tmp; 1097 } 1098 } 1099 1100 // Setup object2 1005 1101 _activeObject = 0; 1006 1102 _activeInvExecute = true; 1007 1103 _activeObject2Inv = true; … … 1019 1115 if (!_activeObject2 || prevInventory != _activeObject2) 1020 1116 return; 1021 1117 1022 if (_activeVerb == 11 && !(( !(_activeObject || _activeInventory)) || !_activeObject2))1118 if (_activeVerb == 11 && !(((_activeObject || _activeInventory)) || !_activeObject2)) 1023 1119 return; 1024 1120 } else { 1025 1121 int over = findVerbAtPos(_mouse.x, _mouse.y); … … 1027 1123 int obj = findObject(_virtualMouse.x, _virtualMouse.y); 1028 1124 int objIdx = findObjectIndex(_virtualMouse.x, _virtualMouse.y); 1029 1125 1126 // If we already have an object selected, and we just clicked an actor 1127 // Clear any object we may of also clicked on 1030 1128 if ((_activeObject || _activeInventory) && act) { 1031 1129 obj = 0; 1032 1130 objIdx = 0; … … 1037 1135 // Disable New-Kid (in the secret lab) 1038 1136 if (_currentMode == 2 || _currentMode == 0) 1039 1137 return; 1040 1041 if (_activeVerb != 7) { 1042 _activeVerb = over; 1043 over = 0; 1138 1139 if( !(((ActorC64*) a)->_miscflags & 0x80) ) { 1140 if (_activeVerb != 7) { 1141 _activeVerb = over; 1142 over = 0; 1143 } 1044 1144 } 1045 1145 1046 1146 if (over) { … … 1064 1164 VAR(7) = _virtualMouse.y / V12_Y_MULTIPLIER; 1065 1165 1066 1166 if (zone->number == kMainVirtScreen) { 1067 a = derefActor(VAR(VAR_EGO), "checkExecVerbs"); 1167 // Ignore verbs? 1168 if( (((ActorC64*) a)->_miscflags & 0x40) ) { 1169 resetSentence(false); 1170 return; 1171 } 1068 1172 a->stopActorMoving(); 1069 a->startWalkActor(_virtualMouse.x / V12_X_MULTIPLIER, _virtualMouse.y / V12_Y_MULTIPLIER, -1); 1173 a->startWalkActor( VAR(6) , VAR(7), -1); 1174 _verbExecuting = true; 1070 1175 } 1071 1176 return; 1072 1177 } … … 1120 1225 } 1121 1226 } 1122 1227 } else { 1228 a->stopActorMoving(); 1229 1123 1230 _activeObject = obj; 1124 1231 _activeObjectIndex = objIdx; 1125 1232