diff options
author | Robert Špalek | 2010-06-28 04:04:16 +0000 |
---|---|---|
committer | Robert Špalek | 2010-06-28 04:04:16 +0000 |
commit | c7554c267e6eaf8457611c44476143a54bbb66c0 (patch) | |
tree | eee48d34c2be2e63eaafa0de268dfe38928c134a /engines/draci | |
parent | 048ceb73d36e4729cb9c8dde292043c32a554234 (diff) | |
download | scummvm-rg350-c7554c267e6eaf8457611c44476143a54bbb66c0.tar.gz scummvm-rg350-c7554c267e6eaf8457611c44476143a54bbb66c0.tar.bz2 scummvm-rg350-c7554c267e6eaf8457611c44476143a54bbb66c0.zip |
Implement shortcuts for switching items in the inventory
slash: switch between the last held item and normal mouse
comma, period: replace the currently held item with the previous/next item in the inventory
Also, commented a bit better what happens when ESCAPE is present with respect to map
programs and cut-scenes.
svn-id: r50407
Diffstat (limited to 'engines/draci')
-rw-r--r-- | engines/draci/draci.cpp | 31 | ||||
-rw-r--r-- | engines/draci/game.cpp | 110 | ||||
-rw-r--r-- | engines/draci/game.h | 8 | ||||
-rw-r--r-- | engines/draci/script.cpp | 2 |
4 files changed, 115 insertions, 36 deletions
diff --git a/engines/draci/draci.cpp b/engines/draci/draci.cpp index a87e9a476d..ee883f9881 100644 --- a/engines/draci/draci.cpp +++ b/engines/draci/draci.cpp @@ -253,19 +253,20 @@ void DraciEngine::handleEvents() { if (escRoom >= 0) { // Schedule room change - // TODO: gate 0 (always present) is not - // always best for returning from the - // map, e.g. in the starting location. - // also, after loading the game, we - // shouldn't run any gate program, but - // rather restore the state of all - // objects. + // TODO: gate 0 (always present) is not always best for + // returning from the map, e.g. in the starting location. + // also, after loading the game, we shouldn't run any gate + // program, but rather restore the state of all objects. _game->scheduleEnteringRoomUsingGate(escRoom, 0); - // Immediately cancel any running animation or dubbing. + // Immediately cancel any running animation or dubbing and + // end any currently running GPL programs. In the intro it + // works as intended---skipping the rest of it. + // + // In the map, this causes that animation on newly + // discovered locations will be re-run next time and + // cut-scenes won't be played. _game->setExitLoop(true); - - // End any currently running GPL programs _script->endCurrentProgram(true); } break; @@ -301,6 +302,16 @@ void DraciEngine::handleEvents() { openMainMenuDialog(); } break; + case Common::KEYCODE_COMMA: + case Common::KEYCODE_PERIOD: + case Common::KEYCODE_SLASH: + if ((_game->getLoopStatus() == kStatusOrdinary || + _game->getLoopStatus() == kStatusInventory) && + _game->getLoopSubstatus() == kOuterLoop && + _game->getRoomNum() != _game->getMapRoom()) { + _game->inventorySwitch(event.kbd.keycode); + } + break; default: break; } diff --git a/engines/draci/game.cpp b/engines/draci/game.cpp index 23cb4700c1..4ae0b71280 100644 --- a/engines/draci/game.cpp +++ b/engines/draci/game.cpp @@ -23,6 +23,7 @@ * */ +#include "common/keyboard.h" #include "common/serializer.h" #include "common/stream.h" #include "common/system.h" @@ -202,7 +203,8 @@ void Game::init() { _animUnderCursor = NULL; _currentItem = _itemUnderCursor = NULL; - + _previousItemPosition = -1; + _vm->_mouse->setCursorType(kHighlightedCursor); // anything different from kNormalCursor _objUnderCursor = NULL; @@ -272,8 +274,8 @@ void Game::handleOrdinaryLoop(int x, int y) { if (_vm->_mouse->lButtonPressed()) { _vm->_mouse->lButtonSet(false); - if (_currentItem) { - putItem(_currentItem, 0); + if (getCurrentItem()) { + putItem(getCurrentItem(), getPreviousItemPosition()); updateOrdinaryCursor(); } else { if (_objUnderCursor) { @@ -327,6 +329,16 @@ void Game::handleOrdinaryLoop(int x, int y) { } } +int Game::inventoryPositionFromMouse() { + const int column = CLIP(scummvm_lround( + (_vm->_mouse->getPosX() - kInventoryX + kInventoryItemWidth / 2.) / + kInventoryItemWidth) - 1, 0L, (long) kInventoryColumns - 1); + const int line = CLIP(scummvm_lround( + (_vm->_mouse->getPosY() - kInventoryY + kInventoryItemHeight / 2.) / + kInventoryItemHeight) - 1, 0L, (long) kInventoryLines - 1); + return line * kInventoryColumns + column; +} + void Game::handleInventoryLoop() { if (_loopSubstatus != kOuterLoop) { return; @@ -353,19 +365,12 @@ void Game::handleInventoryLoop() { // If there is an inventory item under the cursor and we aren't // holding any item, run its look GPL program - if (_itemUnderCursor && !_currentItem) { + if (_itemUnderCursor && !getCurrentItem()) { _vm->_script->runWrapper(_itemUnderCursor->_program, _itemUnderCursor->_look, true, false); // Otherwise, if we are holding an item, try to place it inside the // inventory - } else if (_currentItem) { - const int column = CLIP(scummvm_lround( - (_vm->_mouse->getPosX() - kInventoryX + kInventoryItemWidth / 2.) / - kInventoryItemWidth) - 1, 0L, (long) kInventoryColumns - 1); - const int line = CLIP(scummvm_lround( - (_vm->_mouse->getPosY() - kInventoryY + kInventoryItemHeight / 2.) / - kInventoryItemHeight) - 1, 0L, (long) kInventoryLines - 1); - const int index = line * kInventoryColumns + column; - putItem(_currentItem, index); + } else if (getCurrentItem()) { + putItem(getCurrentItem(), inventoryPositionFromMouse()); updateInventoryCursor(); } } else if (_vm->_mouse->rButtonPressed()) { @@ -381,8 +386,9 @@ void Game::handleInventoryLoop() { // The first is that there is no item in our hands. // In that case, just take the inventory item from the inventory. - if (!_currentItem) { - _currentItem = _itemUnderCursor; + if (!getCurrentItem()) { + setCurrentItem(_itemUnderCursor); + setPreviousItemPosition(inventoryPositionFromMouse()); removeItem(_itemUnderCursor); // The second is that there *is* an item in our hands. @@ -623,10 +629,10 @@ void Game::updateOrdinaryCursor() { // If there is no game object under the cursor, try using the room itself if (!_objUnderCursor) { if (_vm->_script->testExpression(_currentRoom._program, _currentRoom._canUse)) { - if (!_currentItem) { + if (!getCurrentItem()) { _vm->_mouse->setCursorType(kHighlightedCursor); } else { - _vm->_mouse->loadItemCursor(_currentItem, true); + _vm->_mouse->loadItemCursor(getCurrentItem(), true); } mouseChanged = true; } @@ -637,10 +643,10 @@ void Game::updateOrdinaryCursor() { // update the cursor image (highlight it). if (_objUnderCursor->_walkDir == 0) { if (_vm->_script->testExpression(_objUnderCursor->_program, _objUnderCursor->_canUse)) { - if (!_currentItem) { + if (!getCurrentItem()) { _vm->_mouse->setCursorType(kHighlightedCursor); } else { - _vm->_mouse->loadItemCursor(_currentItem, true); + _vm->_mouse->loadItemCursor(getCurrentItem(), true); } mouseChanged = true; } @@ -654,10 +660,10 @@ void Game::updateOrdinaryCursor() { // Load the appropriate cursor (item image if an item is held or ordinary cursor // if not) if (!mouseChanged) { - if (!_currentItem) { + if (!getCurrentItem()) { _vm->_mouse->setCursorType(kNormalCursor); } else { - _vm->_mouse->loadItemCursor(_currentItem, false); + _vm->_mouse->loadItemCursor(getCurrentItem(), false); } } } @@ -668,19 +674,19 @@ void Game::updateInventoryCursor() { if (_itemUnderCursor) { if (_vm->_script->testExpression(_itemUnderCursor->_program, _itemUnderCursor->_canUse)) { - if (!_currentItem) { + if (!getCurrentItem()) { _vm->_mouse->setCursorType(kHighlightedCursor); } else { - _vm->_mouse->loadItemCursor(_currentItem, true); + _vm->_mouse->loadItemCursor(getCurrentItem(), true); } mouseChanged = true; } } if (!mouseChanged) { - if (!_currentItem) { + if (!getCurrentItem()) { _vm->_mouse->setCursorType(kNormalCursor); } else { - _vm->_mouse->loadItemCursor(_currentItem, false); + _vm->_mouse->loadItemCursor(getCurrentItem(), false); } } } @@ -732,6 +738,8 @@ const GameObject *Game::getObjectWithAnimation(const Animation *anim) const { } void Game::removeItem(GameItem *item) { + if (!item) + return; for (uint i = 0; i < kInventorySlots; ++i) { if (_inventory[i] == item) { _inventory[i] = NULL; @@ -753,7 +761,7 @@ void Game::loadItemAnimation(GameItem *item) { void Game::putItem(GameItem *item, int position) { // Empty our hands - _currentItem = NULL; + setCurrentItem(NULL); if (!item) return; @@ -767,6 +775,7 @@ void Game::putItem(GameItem *item, int position) { break; } } + setPreviousItemPosition(position); const int line = position / kInventoryColumns + 1; const int column = position % kInventoryColumns + 1; @@ -854,6 +863,55 @@ void Game::inventoryReload() { for (uint i = 0; i < kInventorySlots; ++i) { putItem(_inventory[i], i); } + setPreviousItemPosition(0); +} + +void Game::inventorySwitch(int keycode) { + switch (keycode) { + case Common::KEYCODE_SLASH: + // Switch between holding an item and the ordinary mouse cursor. + if (!getCurrentItem()) { + if (getPreviousItemPosition() >= 0) { + GameItem* last_item = _inventory[getPreviousItemPosition()]; + setCurrentItem(last_item); + removeItem(last_item); + } + } else { + putItem(getCurrentItem(), getPreviousItemPosition()); + } + break; + case Common::KEYCODE_COMMA: + case Common::KEYCODE_PERIOD: + // Iterate between the items in the inventory. + if (getCurrentItem()) { + assert(getPreviousItemPosition() >= 0); + int direction = keycode == Common::KEYCODE_PERIOD ? +1 : -1; + // Find the next available item. + int pos = getPreviousItemPosition() + direction; + while (true) { + if (pos < 0) + pos += kInventorySlots; + else if (pos >= kInventorySlots) + pos -= kInventorySlots; + if (pos == getPreviousItemPosition() || _inventory[pos]) { + break; + } + pos += direction; + } + // Swap it with the current item. + putItem(getCurrentItem(), getPreviousItemPosition()); + GameItem* new_item = _inventory[pos]; + setCurrentItem(new_item); + setPreviousItemPosition(pos); + removeItem(new_item); + } + break; + } + if (getRoomNum() != getMapRoom()) { + updateOrdinaryCursor(); + } else { + updateInventoryCursor(); + } } void Game::dialogueMenu(int dialogueID) { diff --git a/engines/draci/game.h b/engines/draci/game.h index 3d02489da7..1c8cc68a35 100644 --- a/engines/draci/game.h +++ b/engines/draci/game.h @@ -255,6 +255,8 @@ public: GameItem *getItem(int id) { return id >= 0 && id < (int) _info._numItems ? &_items[id] : NULL; } GameItem *getCurrentItem() const { return _currentItem; } void setCurrentItem(GameItem *item) { _currentItem = item; } + int getPreviousItemPosition() const { return _previousItemPosition; } + void setPreviousItemPosition(int pos) { _previousItemPosition = pos; } void removeItem(GameItem *item); void loadItemAnimation(GameItem *item); void putItem(GameItem *item, int position); @@ -292,6 +294,7 @@ public: void inventoryDraw(); void inventoryDone(); void inventoryReload(); + void inventorySwitch(int keycode); void dialogueMenu(int dialogueID); int dialogueDraw(); @@ -325,6 +328,7 @@ public: private: void updateOrdinaryCursor(); void updateInventoryCursor(); + int inventoryPositionFromMouse(); void handleOrdinaryLoop(int x, int y); void handleInventoryLoop(); void handleDialogueLoop(); @@ -353,6 +357,10 @@ private: GameItem *_currentItem; GameItem *_itemUnderCursor; + // Last position in the inventory of the item currently in the hands, resp. of the item that + // was last in our hands. + int _previousItemPosition; + GameItem *_inventory[kInventorySlots]; Room _currentRoom; diff --git a/engines/draci/script.cpp b/engines/draci/script.cpp index a366740526..f46153ccc5 100644 --- a/engines/draci/script.cpp +++ b/engines/draci/script.cpp @@ -553,6 +553,7 @@ void Script::icoStat(const Common::Array<int> ¶ms) { // arrow leading outside a location), set it to standard. if (_vm->_game->getCurrentItem() == item) { _vm->_game->setCurrentItem(NULL); + _vm->_game->setPreviousItemPosition(-1); if (_vm->_mouse->getCursorType() >= kItemCursor) { _vm->_mouse->setCursorType(kNormalCursor); } @@ -561,6 +562,7 @@ void Script::icoStat(const Common::Array<int> ¶ms) { } else { _vm->_game->loadItemAnimation(item); _vm->_game->setCurrentItem(item); + _vm->_game->setPreviousItemPosition(0); // next time, try to place the item from the beginning _vm->_mouse->loadItemCursor(item, false); } } |