diff options
-rw-r--r-- | queen/command.cpp | 51 | ||||
-rw-r--r-- | queen/command.h | 4 | ||||
-rw-r--r-- | queen/logic.cpp | 92 | ||||
-rw-r--r-- | queen/logic.h | 2 | ||||
-rw-r--r-- | queen/xref.txt | 4 |
5 files changed, 120 insertions, 33 deletions
diff --git a/queen/command.cpp b/queen/command.cpp index 8b2d052309..3174e3114e 100644 --- a/queen/command.cpp +++ b/queen/command.cpp @@ -217,8 +217,19 @@ void Command::executeCurrentAction(bool walk) { return; } - // get the number of commands associated with Object/Item - uint16 comMax = countAssociatedCommands(_selCmd.action, _curCmd.subject1, _curCmd.subject2); + uint16 i; + + // get the commands associated with object/item + uint16 comMax = 0; + uint16 matchingCmds[MAX_MATCHING_CMDS]; + CmdListData *cmdList = &_cmdList[1]; + for (i = 1; i <= _numCmdList; ++i, ++cmdList) { + if (cmdList->match(_selCmd.action, _curCmd.subject1, _curCmd.subject2)) { + matchingCmds[comMax] = i; + ++comMax; + } + } + if (comMax == 0) { // no command match was found, so exit // pass ACTION2 as parameter, as a new Command (and a new ACTION2) @@ -233,24 +244,18 @@ void Command::executeCurrentAction(bool walk) { int16 cond = 0; CmdListData *com = &_cmdList[0]; uint16 comId = 0; - uint16 curCommand; - for (curCommand = 1; curCommand <= comMax; ++curCommand) { - ++com; - ++comId; - // try to find a match for the command in COM_LIST - for (; comId <= _numCmdList; ++comId, ++com) { - if (com->match(_selCmd.action, _curCmd.subject1, _curCmd.subject2)) { - break; - } - } + for (i = 1; i <= comMax; ++i) { + + comId = matchingCmds[i - 1]; + com = &_cmdList[comId]; // check the Gamestates and set them if necessary cond = 0; if (com->setConditions) { - cond = setConditions(comId, (curCommand == comMax)); + cond = setConditions(comId, (i == comMax)); } - if (cond == -1 && curCommand == comMax) { + if (cond == -1 && i == comMax) { // only exit on a condition fail if at last command // Joe hasnt spoken, so do normal LOOK command if (_selCmd.action.value() == VERB_LOOK_AT) { @@ -260,7 +265,7 @@ void Command::executeCurrentAction(bool walk) { return; } } - else if (cond == -2 && curCommand == comMax) { + else if (cond == -2 && i == comMax) { // only exit on a condition fail if at last command // Joe has spoken, so skip LOOK command cleanupCurrentAction(); @@ -272,7 +277,7 @@ void Command::executeCurrentAction(bool walk) { } } - debug(0, "Command::executeCurrentAction() - cond = %X, com = %X", cond, curCommand); + debug(0, "Command::executeCurrentAction() - cond = %X, com = %X", cond, comId); if (com->setAreas) { setAreas(comId); @@ -868,20 +873,6 @@ bool Command::executeIfDialog(const char *description) { } -uint16 Command::countAssociatedCommands(const Verb& verb, int16 subj1, int16 subj2) { - - // l.145-150 execute.c - uint16 comMax = 0; - CmdListData *cmdList = &_cmdList[1]; - uint16 i; - for (i = 1; i <= _numCmdList; ++i, ++cmdList) { - if (cmdList->match(verb, subj1, subj2)) { - ++comMax; - } - } - return comMax; -} - bool Command::handleBadCommand(bool walk) { diff --git a/queen/command.h b/queen/command.h index f055571aee..fd11cb63a1 100644 --- a/queen/command.h +++ b/queen/command.h @@ -104,6 +104,9 @@ public: //! return true if command is ready to be executed bool parse() const { return _parse; } + enum { + MAX_MATCHING_CMDS = 50 + }; private: @@ -118,7 +121,6 @@ private: bool executeIfCutaway(const char *description); bool executeIfDialog(const char *description); - uint16 countAssociatedCommands(const Verb& verb, int16 subj1, int16 subj2); bool handleBadCommand(bool walk); void executeStandardStuff(const Verb& action, int16 subj1, int16 subj2); void changeObjectState(const Verb& action, int16 obj, int16 song, bool cutDone); diff --git a/queen/logic.cpp b/queen/logic.cpp index 1a531a7ac5..bc92b7c0b3 100644 --- a/queen/logic.cpp +++ b/queen/logic.cpp @@ -2192,6 +2192,98 @@ void Logic::customMoveJoe(int facing, uint16 areaNum, uint16 walkDataNum) { } +void Logic::handlePinnacleRoom() { + + // camera does not follow Joe anymore + _graphics->cameraBob(-1); + roomDisplay("m1", RDM_NOFADE_JOE, 100, 2, true); + + BobSlot *joe = _graphics->bob(6); + BobSlot *piton = _graphics->bob(7); + + // set scrolling value to mouse position to avoid glitch + _display->horizontalScroll(_input->mousePosX()); + + joe->x = piton->x = 3 * _input->mousePosX() / 4 + 200; + + joe->frameNum = _input->mousePosX() / 36 + 43 + FRAMES_JOE_XTRA; + + // adjust bounding box for fullscreen + joe->box.y2 = piton->box.y2 = GAME_SCREEN_HEIGHT - 1; + + // bobs have been unpacked from animating objects, we don't need them + // to animate anymore ; so turn animating off + joe->animating = piton->animating = false; + + update(); + _display->palFadeIn(0, 223, ROOM_JUNGLE_PINNACLE); + + _entryObj = 0; + uint16 prevObj = 0; + while (_input->mouseButton() == 0 || _entryObj == 0) { + + update(); + int mx = _input->mousePosX(); + int my = _input->mousePosY(); + + // update screen scrolling + _display->horizontalScroll(_input->mousePosX()); + + // update bobs position / frame + joe->x = piton->x = 3 * mx / 4 + 200; + joe->frameNum = mx / 36 + 43 + FRAMES_JOE_XTRA; + + uint16 curObj = findObjectUnderCursor(mx, my); + if (curObj != 0 && curObj != prevObj) { + _entryObj = 0; + curObj += _roomData[_currentRoom]; // global object number + ObjectData *objData = &_objectData[curObj]; + if (objData->name > 0) { + _entryObj = objData->entryObj; + char textCmd[CmdText::MAX_COMMAND_LEN]; + sprintf(textCmd, "%s %s", Verb(VERB_WALK_TO).name(), _objName[objData->name]); + _graphics->textCurrentColor(INK_MAP7); + _graphics->textSetCentered(5, textCmd); + } + prevObj = curObj; + } + } + _input->clearMouseButton(); + + _newRoom = _objectData[_entryObj].room; + joe->active = piton->active = false; + _graphics->textClear(5, 5); + + // There is quite a hack in original source code to handle properly this + // special room. The main problem is described in executed.c l.334-339. + // + // Below is how room switching is handled + // + // ACTION2=10; + // SUBJECT[1]=NOUN+ROOM_DATA[ROOM]; + // EXECUTE_ACTION(NO); + // + // None of the following commands updates gamestate/areas/objects/items : + // + // piton -> crash : 0x216 + // piton -> floda : 0x217 + // piton -> bob : 0x219 + // piton -> embark : 0x218 + // piton -> jungle : 0x20B + // + // But this list is surely not exhaustive... + // + // So basically, EXECUTE_ACTION only performs the playsong calls... + // XXX if (com->song > 0) { playsong(com->song); } + + // camera follows Joe again + _graphics->cameraBob(0); + + // XXX COMPANEL=1; + // XXX panelflag=1; +} + + void Logic::update() { _graphics->update(_currentRoom); _input->delay(); diff --git a/queen/logic.h b/queen/logic.h index 5051718025..80ee67a3b2 100644 --- a/queen/logic.h +++ b/queen/logic.h @@ -263,6 +263,8 @@ public: void customMoveJoe(int facing, uint16 areaNum, uint16 walkDataNum); + void handlePinnacleRoom(); + void update(); diff --git a/queen/xref.txt b/queen/xref.txt index 754a381b4c..0b71f5d273 100644 --- a/queen/xref.txt +++ b/queen/xref.txt @@ -221,7 +221,7 @@ FIND_GRAPHIC() Logic::graphicData FIND_SCALE() Logic::findScale FIND_VERB() Logic::findVerb P3_COPY_FROM() Logic::objectCopy -R_MAP() (handle map 'm1') +R_MAP() Logic::handlePinnacleRoom REDISP_OBJECT() Logic::roomRefreshObject restart_game() SETUP_BOBS() Graphics::bobSetupControl @@ -403,7 +403,7 @@ MOVE_OTHER() Walk::personMove - AREALIST Walk::_areaList AREASTRIKE Walk::_areaStrike -movdata Walk::_moveData +movdata Walk::MOVE_DATA WALK_DATA Walk::_walkData WALKI Walk::_walkDataCount |