Ticket #9144: v0_mm_verb_anim2.patch

File v0_mm_verb_anim2.patch, 13.6 KB (added by SF/segra, 15 years ago)
  • actor.cpp

     
    215215void Actor::stopActorMoving() {
    216216        if (_walkScript)
    217217                _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
    218224        _moving = 0;
    219225}
    220226
  • costume.cpp

     
    7575        0x17, 0x00, 0x01, 0x05, 0x16
    7676};
    7777
     78const 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};
    7885
    7986byte ClassicCostumeRenderer::mainRoutine(int xmoveCur, int ymoveCur) {
    8087        int i, skip = 0;
     
    13571364}
    13581365
    13591366void C64CostumeLoader::actorSpeak(ActorC64 *a, int &cmd) {
     1367
     1368        if( (v0ActorTalkArray[ a->_number ] & 0x80) )
     1369                return;
     1370
    13601371        if ((a->_speaking & 0x80))
    13611372                cmd += 0x0C;
    13621373        else
     
    13721383
    13731384        // Enable/Disable speaking flag
    13741385        if (frame == a->_talkStartFrame) {
     1386                if( (v0ActorTalkArray[ a->_number ] & 0x40) )
     1387                        return;
     1388
    13751389                A->_speaking = 1;
    13761390                return;
    13771391        }
     
    14091423                int cmd = A->_costCommand;
    14101424                A->_speakingPrev = A->_speaking;
    14111425
    1412                 // Update to use speak frame
    1413                 if (A->_speaking & 0x80) {
    1414                         actorSpeak(A, cmd);
     1426                actorSpeak(A, cmd);
    14151427
    1416                 } else {
    1417                         // Update to use stand frame
    1418                         if (A->_costFrame == A->_standFrame)
    1419                                 cmd = dirToDirStop(cmd);
    1420                 }
    1421 
    14221428                // Update the limb frames
    14231429                frameUpdate(A, cmd);
    14241430        }
     
    14261432        if (A->_moving  && _vm->_currentRoom != 1 && _vm->_currentRoom != 44) {
    14271433                if (a->_cost.soundPos == 0)
    14281434                        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;
    14301440        }
    14311441
    14321442        // increase each frame pos
  • costume.h

     
    2828#include "scumm/base-costume.h"
    2929
    3030namespace Scumm {
     31        extern const byte v0ActorTalkArray[0x19];
    3132
    3233class ClassicCostumeLoader : public BaseCostumeLoader {
    3334public:
  • script_v0.cpp

     
    635635
    636636        a = derefActor(VAR(VAR_EGO), "o_loadRoomWithEgo");
    637637
    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);
    639651        _egoPositioned = false;
    640652
    641653        startScene(a->_room, a, obj);
     
    815827        else
    816828                a->_miscflags &= ~mask;
    817829
     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
    818834        debug(0, "o_setActorBitVar(%d, %d, %d)", act, mask, mod);
    819835}
    820836
  • scumm.h

     
    878878        void findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint object, uint room);
    879879public:
    880880        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
    881882protected:
    882         int getDist(int x, int y, int x2, int y2);
     883
    883884        int getObjActToObjActDist(int a, int b); // Not sure how to handle
    884885        const byte *getObjOrActorName(int obj);          // these three..
    885886        void setObjectName(int obj);
  • verbs.cpp

     
    154154}
    155155
    156156void 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
    157175        VAR(VAR_EGO) = VAR(97 + slot);
     176        resetVerbs();
    158177        actorFollowCamera(VAR(VAR_EGO));
    159         resetVerbs();
    160         resetSentence(false);
    161178        setUserState(247);
    162179}
    163180
     
    668685void ScummEngine_v0::runObject(int obj, int entry) {
    669686        int prev = _v0ObjectInInventory;
    670687
     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
    671701        if (getVerbEntrypoint(obj, entry) != 0) {
    672702                _v0ObjectInInventory = prev;
    673703                runObjectScript(obj, entry, false, false, NULL);
     704
    674705        } else if (entry != 13 && entry != 15) {
     706
    675707                if (_activeVerb != 3) {
    676708                        VAR(9) = entry;
    677709                        runScript(3, 0, 0, 0);
     
    698730}
    699731
    700732bool 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);
    703736
    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();
    709743                        return false;
     744                }
    710745
    711                 return true;
    712         }
    713 
    714746        return true;
    715747}
    716748
    717749bool ScummEngine_v0::verbMove(int object, int objectIndex, bool invObject) {
    718750        int x, y, dir;
    719         Actor *a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
     751        Actor *a = derefActor(VAR(VAR_EGO), "verbMove");
    720752
    721753        if (_currentMode != 3 && _currentMode != 2)
    722754                return false;
    723755
    724         if (a->_moving)
    725                 return true;
    726 
    727756        _v0ObjectIndex = true;
    728757        getObjectXYPos(objectIndex, x, y, dir);
    729758        _v0ObjectIndex = false;
     759
    730760        // Detect distance from target object
    731761        int dist =  getDist(a->getRealPos().x, a->getRealPos().y, x, y);
    732762
    733         if (dist > 8) {
     763        if( a->_moving )
     764                return true;
     765
     766        if (dist > 5) {
    734767                a->startWalkActor(x, y, dir);
    735768                VAR(6) = x;
    736769                VAR(7) = y;
    737770                return true;
    738771        } else {
     772
    739773                // Finished walk, are we picking up the item?
    740774                if (_verbPickup) {
    741775                        int oldActive = _activeObject, oldIndex = _activeObjectIndex;
     
    766800        if (objIndex == 0)
    767801                return false;
    768802
     803        // Object in inventory ?
    769804        if (where != WIO_INVENTORY) {
    770805                _v0ObjectIndex = true;
    771806                prep = verbPrep(objIndex);
     
    778813                } else {
    779814                        _verbPickup = false;
    780815                }
     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                }
    781825
     826                //attempt move to object
    782827                if (verbMove(obj, objIndex, false))
    783828                        return true;
    784829
    785830                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                        }
    788841        }
    789842
    790843        return false;
     
    795848                _v0ObjectIndex = true;
    796849        else
    797850                _v0ObjectIndex = false;
     851
    798852        byte *ptr = getOBCDFromObject(object);
    799853        _v0ObjectIndex = false;
    800854        assert(ptr);
     
    831885                _activeObjectObtained = true;
    832886        }
    833887
     888        // Attempt to obtain/reach object2
    834889        if (_activeObject2 && _activeObject2Index && !_activeObject2Obtained && _currentMode != 0) {
    835890                prep = verbPrep(_activeObject2Index);
    836891
     
    851906
    852907        // Give-To
    853908        if (_activeVerb == 3 && _activeInventory && _activeActor) {
     909
    854910                // 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
    857919                        return true;
    858 
     920                }
    859921                _v0ObjectInInventory = true;
    860922                VAR(5) = _activeActor;
    861923                runObject(_activeInventory , 3);
     
    865927                return false;
    866928        }
    867929
     930        // Where we performing an action on an actor?
    868931        if (_activeActor) {
    869932                _v0ObjectIndex = true;
    870933                runObject(_activeActor, entry);
     
    905968                return false;
    906969        }
    907970
     971        // Item not in inventory is executed
    908972        if (_activeObject) {
    909973                _v0ObjectIndex = true;
    910974                runObject(_activeObjectIndex, entry);
    911975                _v0ObjectIndex = false;
    912976        } else if (_activeInventory) {
     977
     978                // Not sure this is the correct way to do this,
     979                // however its working for most situations - segra
    913980                if (verbExecutes(_activeInventory, true) == false) {
    914                         if (_activeObject2 && verbExecutes(_activeObject2, true)) {
     981                        if (_activeObject2 && _activeObject2Inv && verbExecutes(_activeObject2, true)) {
    915982                                _v0ObjectInInventory = true;
    916983
    917984                                _activeObject = _activeInventory;
     
    920987                                runObject(_activeObject, _activeVerb);
    921988                        } else {
    922989                                _v0ObjectInInventory = true;
    923                                 runObject(_activeInventory, _activeVerb);
     990                                       
     991                                if(_activeObject2) {
     992                                        _activeObject = _activeObject2;
     993
     994                                        runObject(_activeObject, _activeVerb);
     995                                } else
     996                                        runObject(_activeInventory, _activeVerb);
    924997                        }
    925998                } else {
     999                        _v0ObjectInInventory = true;
    9261000                        runObject(_activeInventory, _activeVerb);
    927                         _v0ObjectInInventory = true;
    9281001                }
    9291002        }
    9301003
     
    9411014}
    9421015
    9431016void ScummEngine_v0::checkExecVerbs() {
    944         Actor *a;
     1017        Actor *a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
    9451018        VirtScreen *zone = findVirtScreen(_mouse.y);
    9461019
    9471020        // Is a verb currently executing
     
    9611034                        if (!obj && !act && !over) {
    9621035                                resetSentence(false);
    9631036                        } else {
    964                                 a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
    9651037                                a->stopActorMoving();
    9661038                        }
    9671039                } else {
     1040
    9681041                        if (_verbExecuting && !verbExec())
    9691042                                return;
    9701043                }
     
    9941067                        // TODO
    9951068                } else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) {
    9961069                        int prevInventory = _activeInventory;
     1070                        int invOff = _inventoryOffset;
    9971071
    9981072                        // Click into V2 inventory
    9991073                        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?
    10001080                        if (!_activeInventory)
    10011081                                return;
    10021082
    10031083                        // Did we just change the selected inventory item?
    10041084                        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
    10051101                                _activeObject = 0;
    10061102                                _activeInvExecute = true;
    10071103                                _activeObject2Inv = true;
     
    10191115                                if (!_activeObject2 || prevInventory != _activeObject2)
    10201116                                        return;
    10211117
    1022                         if (_activeVerb == 11 && !((!(_activeObject || _activeInventory)) || !_activeObject2))
     1118                        if (_activeVerb == 11 && !(((_activeObject || _activeInventory)) || !_activeObject2))
    10231119                                return;
    10241120                } else {
    10251121                        int over = findVerbAtPos(_mouse.x, _mouse.y);
     
    10271123                        int obj  = findObject(_virtualMouse.x, _virtualMouse.y);
    10281124                        int objIdx = findObjectIndex(_virtualMouse.x, _virtualMouse.y);
    10291125
     1126                        // If we already have an object selected, and we just clicked an actor
     1127                        // Clear any object we may of also clicked on
    10301128                        if ((_activeObject || _activeInventory) && act) {
    10311129                                obj = 0;
    10321130                                objIdx = 0;
     
    10371135                                // Disable New-Kid (in the secret lab)
    10381136                                if (_currentMode == 2 || _currentMode == 0)
    10391137                                        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                                        }
    10441144                                }
    10451145
    10461146                                if (over) {
     
    10641164                                VAR(7) = _virtualMouse.y / V12_Y_MULTIPLIER;
    10651165
    10661166                                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                                        }
    10681172                                        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;
    10701175                                }
    10711176                                return;
    10721177                        }
     
    11201225                                                }
    11211226                                        }
    11221227                                } else {
     1228                                        a->stopActorMoving();
     1229
    11231230                                        _activeObject = obj;
    11241231                                        _activeObjectIndex = objIdx;
    11251232