diff options
author | Paul Gilbert | 2015-06-21 08:46:38 -0400 |
---|---|---|
committer | Paul Gilbert | 2015-06-21 08:46:38 -0400 |
commit | 3adaf2f999c4af74534beb7d02638aba8cc81a1e (patch) | |
tree | dd6aa325a44c51a8867b2e42093c7c085e5d3853 /engines/sherlock | |
parent | 371d5e1d904898a01292db26703d38ee90558bbd (diff) | |
download | scummvm-rg350-3adaf2f999c4af74534beb7d02638aba8cc81a1e.tar.gz scummvm-rg350-3adaf2f999c4af74534beb7d02638aba8cc81a1e.tar.bz2 scummvm-rg350-3adaf2f999c4af74534beb7d02638aba8cc81a1e.zip |
SHERLOCK: RT: Implement inventory handleEvents
Diffstat (limited to 'engines/sherlock')
-rw-r--r-- | engines/sherlock/inventory.h | 6 | ||||
-rw-r--r-- | engines/sherlock/tattoo/tattoo.cpp | 12 | ||||
-rw-r--r-- | engines/sherlock/tattoo/tattoo.h | 4 | ||||
-rw-r--r-- | engines/sherlock/tattoo/tattoo_map.cpp | 1 | ||||
-rw-r--r-- | engines/sherlock/tattoo/tattoo_user_interface.cpp | 6 | ||||
-rw-r--r-- | engines/sherlock/tattoo/tattoo_user_interface.h | 2 | ||||
-rw-r--r-- | engines/sherlock/tattoo/widget_base.cpp | 55 | ||||
-rw-r--r-- | engines/sherlock/tattoo/widget_base.h | 26 | ||||
-rw-r--r-- | engines/sherlock/tattoo/widget_inventory.cpp | 365 | ||||
-rw-r--r-- | engines/sherlock/tattoo/widget_inventory.h | 38 | ||||
-rw-r--r-- | engines/sherlock/tattoo/widget_verbs.cpp | 4 | ||||
-rw-r--r-- | engines/sherlock/tattoo/widget_verbs.h | 2 |
12 files changed, 490 insertions, 31 deletions
diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index a2c317f2a8..019f5ed6c9 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -62,7 +62,11 @@ struct InventoryItem { Common::String _examine; int _lookFlag; - InventoryItem() : _requiredFlag(0), _lookFlag(0) {} + // Rose Tattoo fields + int _requiredFlag1; + UseType _verb; + + InventoryItem() : _requiredFlag(0), _lookFlag(0), _requiredFlag1(0) {} InventoryItem(int requiredFlag, const Common::String &name, const Common::String &description, const Common::String &examine); diff --git a/engines/sherlock/tattoo/tattoo.cpp b/engines/sherlock/tattoo/tattoo.cpp index 60705f6016..bc4e7d5042 100644 --- a/engines/sherlock/tattoo/tattoo.cpp +++ b/engines/sherlock/tattoo/tattoo.cpp @@ -24,6 +24,7 @@ #include "sherlock/tattoo/tattoo.h" #include "sherlock/tattoo/tattoo_resources.h" #include "sherlock/tattoo/tattoo_scene.h" +#include "sherlock/tattoo/widget_base.h" #include "sherlock/people.h" namespace Sherlock { @@ -38,6 +39,10 @@ TattooEngine::TattooEngine(OSystem *syst, const SherlockGameDescription *gameDes _allowFastMode = true; } +TattooEngine::~TattooEngine() { + WidgetBase::freeInterfaceImages(); +} + void TattooEngine::showOpening() { // TODO } @@ -48,6 +53,9 @@ void TattooEngine::initialize() { // Initialize the base engine SherlockEngine::initialize(); + // Further initialization + WidgetBase::setInterfaceImages(new ImageFile("intrface.vgs")); + // Initialise the global flags _flags.resize(3200); _flags[1] = _flags[4] = _flags[76] = true; @@ -105,6 +113,10 @@ void TattooEngine::eraseCredits() { // TODO } +void TattooEngine::doHangManPuzzle() { + // TODO +} + } // End of namespace Tattoo } // End of namespace Sherlock diff --git a/engines/sherlock/tattoo/tattoo.h b/engines/sherlock/tattoo/tattoo.h index 39f49341a8..d7d2115588 100644 --- a/engines/sherlock/tattoo/tattoo.h +++ b/engines/sherlock/tattoo/tattoo.h @@ -59,7 +59,7 @@ public: bool _fastMode, _allowFastMode; public: TattooEngine(OSystem *syst, const SherlockGameDescription *gameDesc); - virtual ~TattooEngine() {} + virtual ~TattooEngine(); /** * Draw credits on the screen @@ -75,6 +75,8 @@ public: * Erase any area of the screen covered by credits */ void eraseCredits(); + + void doHangManPuzzle(); }; } // End of namespace Tattoo diff --git a/engines/sherlock/tattoo/tattoo_map.cpp b/engines/sherlock/tattoo/tattoo_map.cpp index b8f1b6c55d..365c14a79c 100644 --- a/engines/sherlock/tattoo/tattoo_map.cpp +++ b/engines/sherlock/tattoo/tattoo_map.cpp @@ -306,7 +306,6 @@ void TattooMap::drawMapIcons() { void TattooMap::checkMapNames(bool slamIt) { Events &events = *_vm->_events; - Screen &screen = *_vm->_screen; Common::Point mousePos = events.mousePos() + _currentScroll; // See if the mouse is pointing at any of the map locations diff --git a/engines/sherlock/tattoo/tattoo_user_interface.cpp b/engines/sherlock/tattoo/tattoo_user_interface.cpp index d12f0e7a02..322655fa88 100644 --- a/engines/sherlock/tattoo/tattoo_user_interface.cpp +++ b/engines/sherlock/tattoo/tattoo_user_interface.cpp @@ -575,7 +575,7 @@ void TattooUserInterface::doFileControl() { } void TattooUserInterface::doInventoryControl() { - warning("TODO: ui control (inventory)"); + _inventoryWidget.handleEvents(); } void TattooUserInterface::doVerbControl() { @@ -644,6 +644,10 @@ void TattooUserInterface::freeMenu() { } } +void TattooUserInterface::putMessage(const Common::String &str) { + // TODO +} + } // End of namespace Tattoo } // End of namespace Sherlock diff --git a/engines/sherlock/tattoo/tattoo_user_interface.h b/engines/sherlock/tattoo/tattoo_user_interface.h index 35e1cb8ef0..935e0769ed 100644 --- a/engines/sherlock/tattoo/tattoo_user_interface.h +++ b/engines/sherlock/tattoo/tattoo_user_interface.h @@ -188,6 +188,8 @@ public: * Pick up the selected object */ void pickUpObject(int objNum); + + void putMessage(const Common::String &str); public: /** * Resets the user interface diff --git a/engines/sherlock/tattoo/widget_base.cpp b/engines/sherlock/tattoo/widget_base.cpp index a9422de998..682961fd4e 100644 --- a/engines/sherlock/tattoo/widget_base.cpp +++ b/engines/sherlock/tattoo/widget_base.cpp @@ -29,8 +29,18 @@ namespace Sherlock { namespace Tattoo { +ImageFile *WidgetBase::_interfaceImages; + +void WidgetBase::setInterfaceImages(ImageFile *images) { + _interfaceImages = images; +} + +void WidgetBase::freeInterfaceImages() { + delete _interfaceImages; + _interfaceImages = nullptr; +} + WidgetBase::WidgetBase(SherlockEngine *vm) : _vm(vm) { - _images = nullptr; } void WidgetBase::summonWindow() { @@ -135,32 +145,38 @@ void WidgetBase::checkMenuPosition() { _bounds.moveTo(_bounds.left, SHERLOCK_SCREEN_HEIGHT - _bounds.height()); } -void WidgetBase::makeInfoArea() { +void WidgetBase::makeInfoArea(Surface &s) { + ImageFile &images = *_interfaceImages; + // Draw the four corners of the Info Box - _surface.transBlitFrom((*_images)[0], Common::Point(0, 0)); - _surface.transBlitFrom((*_images)[1], Common::Point(_bounds.width() - (*_images)[1]._width, 0)); - _surface.transBlitFrom((*_images)[2], Common::Point(0, _bounds.height() - (*_images)[2]._height)); - _surface.transBlitFrom((*_images)[3], Common::Point(_bounds.width() - (*_images)[3]._width, _bounds.height())); + s.transBlitFrom(images[0], Common::Point(0, 0)); + s.transBlitFrom(images[1], Common::Point(s.w() - images[1]._width, 0)); + s.transBlitFrom(images[2], Common::Point(0, s.h() - images[2]._height)); + s.transBlitFrom(images[3], Common::Point(s.w() - images[3]._width, s.h())); // Draw the top of the Info Box - _surface.hLine((*_images)[0]._width, 0, _bounds.width() - (*_images)[1]._width, INFO_TOP); - _surface.hLine((*_images)[0]._width, 1, _bounds.width() - (*_images)[1]._width, INFO_MIDDLE); - _surface.hLine((*_images)[0]._width, 2, _bounds.width() - (*_images)[1]._width, INFO_BOTTOM); + s.hLine(images[0]._width, 0, s.w() - images[1]._width, INFO_TOP); + s.hLine(images[0]._width, 1, s.w() - images[1]._width, INFO_MIDDLE); + s.hLine(images[0]._width, 2, s.w() - images[1]._width, INFO_BOTTOM); // Draw the bottom of the Info Box - _surface.hLine((*_images)[0]._width, _bounds.height()- 3, _bounds.width() - (*_images)[1]._width, INFO_TOP); - _surface.hLine((*_images)[0]._width, _bounds.height()- 2, _bounds.width() - (*_images)[1]._width, INFO_MIDDLE); - _surface.hLine((*_images)[0]._width, _bounds.height()- 1, _bounds.width() - (*_images)[1]._width, INFO_BOTTOM); + s.hLine(images[0]._width, s.h()- 3, s.w() - images[1]._width, INFO_TOP); + s.hLine(images[0]._width, s.h()- 2, s.w() - images[1]._width, INFO_MIDDLE); + s.hLine(images[0]._width, s.h()- 1, s.w() - images[1]._width, INFO_BOTTOM); // Draw the left Side of the Info Box - _surface.vLine(0, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_TOP); - _surface.vLine(1, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_MIDDLE); - _surface.vLine(2, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_BOTTOM); + s.vLine(0, images[0]._height, s.h()- images[2]._height, INFO_TOP); + s.vLine(1, images[0]._height, s.h()- images[2]._height, INFO_MIDDLE); + s.vLine(2, images[0]._height, s.h()- images[2]._height, INFO_BOTTOM); // Draw the right Side of the Info Box - _surface.vLine(_bounds.width() - 3, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_TOP); - _surface.vLine(_bounds.width() - 2, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_MIDDLE); - _surface.vLine(_bounds.width() - 1, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_BOTTOM); + s.vLine(s.w() - 3, images[0]._height, s.h()- images[2]._height, INFO_TOP); + s.vLine(s.w() - 2, images[0]._height, s.h()- images[2]._height, INFO_MIDDLE); + s.vLine(s.w() - 1, images[0]._height, s.h()- images[2]._height, INFO_BOTTOM); +} + +void WidgetBase::makeInfoArea() { + makeInfoArea(_surface); } const Common::Point &WidgetBase::getCurrentScroll() const { @@ -168,6 +184,9 @@ const Common::Point &WidgetBase::getCurrentScroll() const { return ui._currentScroll; } +void WidgetBase::checkTabbingKeys(int numOptions) { +} + } // End of namespace Tattoo } // End of namespace Sherlock diff --git a/engines/sherlock/tattoo/widget_base.h b/engines/sherlock/tattoo/widget_base.h index 7e546db248..9d2ddcfc23 100644 --- a/engines/sherlock/tattoo/widget_base.h +++ b/engines/sherlock/tattoo/widget_base.h @@ -39,10 +39,11 @@ class WidgetBase { private: Common::Rect _oldBounds; protected: + static ImageFile *_interfaceImages; +protected: SherlockEngine *_vm; Common::Rect _bounds; Surface _surface; - ImageFile *_images; bool _outsideMenu; /** @@ -55,6 +56,14 @@ protected: */ void checkMenuPosition(); + /** + * Draw a window frame around the dges of the passed surface + */ + void makeInfoArea(Surface &s); + + /** + * Draw a window frame around the widget's surface + */ void makeInfoArea(); /** @@ -62,6 +71,16 @@ protected: */ virtual const Common::Point &getCurrentScroll() const; public: + /** + * Sets the interface images used for drawing the various types of window elements + */ + static void setInterfaceImages(ImageFile *images); + + /** + * Frees the interface images + */ + static void freeInterfaceImages(); +public: WidgetBase(SherlockEngine *vm); virtual ~WidgetBase() {} @@ -76,6 +95,11 @@ public: void draw(); /** + * Used by some descendents to check for keys to mouse the mouse within the dialog + */ + void checkTabbingKeys(int numOptions); + + /** * Summon the window */ virtual void summonWindow(); diff --git a/engines/sherlock/tattoo/widget_inventory.cpp b/engines/sherlock/tattoo/widget_inventory.cpp index dfa4736ccc..ee8faa3759 100644 --- a/engines/sherlock/tattoo/widget_inventory.cpp +++ b/engines/sherlock/tattoo/widget_inventory.cpp @@ -21,6 +21,7 @@ */ #include "sherlock/tattoo/widget_inventory.h" +#include "sherlock/tattoo/tattoo_scene.h" #include "sherlock/tattoo/tattoo_user_interface.h" #include "sherlock/tattoo/tattoo.h" @@ -31,14 +32,26 @@ namespace Tattoo { #define INVENTORY_XSIZE 70 // Width of the box that surrounds inventory items #define INVENTORY_YSIZE 70 // Height of the box that surrounds inventory items #define NUM_INVENTORY_SHOWN 8 // Number of Inventory Items Shown +#define MAX_INV_COMMANDS 10 // Maximum elements in dialog #define BUTTON_SIZE 15 // Button width/height -WidgetInventory::WidgetInventory(SherlockEngine *vm) : WidgetBase(vm) { +// TODO: Refactor into FixedText +#define S_INV6 "Foolscap" +#define S_INV7 "Damp Paper" +#define S_SOLVE "Solve" +#define S_LOOK "Look" +#define S_NO_EFFECT "No effect..." +#define S_WITH "with" + +WidgetInventory::WidgetInventory(SherlockEngine *vm) : WidgetBase(vm), _tooltipWidget(vm) { _invMode = 0; _invVerbMode = 0; _invSelect = _oldInvSelect = 0; _selector = _oldSelector = 0; + _invVerbSelect = _oldInvVerbSelect = -1; _dialogTimer = -1; + _scrollHighlight = 0; + _swapItems = false; } void WidgetInventory::load(int mode) { @@ -72,7 +85,7 @@ void WidgetInventory::load(int mode) { _surface.fill(TRANSPARENCY); // Draw the window background and then the inventory on top of it - makeInfoArea(); + makeInfoArea(_surface); drawInventory(); } @@ -187,6 +200,354 @@ void WidgetInventory::drawDialogRect(const Common::Rect &r, bool raised) { } } +void WidgetInventory::handleEvents() { + TattooEngine &vm = *(TattooEngine *)_vm; + Events &events = *_vm->_events; + Inventory &inv = *_vm->_inventory; + People &people = *_vm->_people; + TattooScene &scene = *(TattooScene *)_vm->_scene; + TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui; + Common::Point mousePos = events.mousePos(); + + if (_invVerbMode == 1) + checkTabbingKeys(MAX_INV_COMMANDS); + else if (_invVerbMode == 0) + checkInvTabbingKeys(); + + if (_invVerbMode != 1) + updateDescription(); + + // Flag is they started pressing outside of the menu + if (events._firstPress && !_bounds.contains(mousePos)) + _outsideMenu = true; + + if (_invVerbMode != 3) + highlightControls(); + + // See if they released a mouse button button + if (events._released || events._rightReleased || ui._keyState.keycode == Common::KEYCODE_ESCAPE) { + _dialogTimer = -1; + _scrollHighlight = 0; + + // See if they have a Verb List open for an Inventry Item + if (_invVerbMode == 1) { + // An inventory item's Verb List is open + + // See if they want to close the menu (by clicking outside the menu) + Common::Rect innerBounds = _bounds; + innerBounds.grow(-3); + + if (_outsideMenu && !innerBounds.contains(mousePos)) { + banishWindow(); + _invVerbMode = 0; + } else if (innerBounds.contains(mousePos)) { + _outsideMenu = false; + + // Check if they are trying to solve the Foolscap puzzle, or looking at the completed puzzle + bool doHangman = !inv[_invSelect]._name.compareToIgnoreCase(S_INV6) && + !_inventCommands[_invVerbSelect].compareToIgnoreCase(S_SOLVE); + doHangman |= (!inv[_invSelect]._name.compareToIgnoreCase(S_INV6) || !inv[_invSelect]._name.compareToIgnoreCase(S_INV7)) + && _inventCommands[_invVerbSelect].compareToIgnoreCase(S_LOOK) && vm.readFlags(299); + + if (doHangman) { + // Close the entire Inventory and return to Standard Mode + banishWindow(); + _invVerbMode = 0; + + _tooltipWidget.banishWindow(); + banishWindow(); + inv.freeInv(); + + events.clearEvents(); + events.setCursor(ARROW); + ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE; + + scene.doBgAnim(); + vm.doHangManPuzzle(); + } else if (_invVerbSelect == 0) { + // They have released the mouse on the Look Verb command, so Look at the inventory item + ui._invLookFlag = true; + inv.freeInv(); + ui._windowOpen = false; + ui._lookPos = mousePos; + ui.printObjectDesc(inv[_invSelect]._examine, true); + } else { + // Clear the window + banishWindow(); + _invVerbMode = 3; + ui._oldBgFound = -1; + + // See if the selected Verb with the selected Iventory Item, is to be used by itself + if (!_inventCommands[_invVerbSelect].compareToIgnoreCase(inv[_invSelect]._verb._verb) || + !inv[_invSelect]._verb._target.compareToIgnoreCase("*SELF")) { + inv.freeInv(); + + ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE; + events.clearEvents(); + ui.checkAction(inv[_invSelect]._verb, 2000); + } else { + _invVerb = _inventCommands[_invVerbSelect]; + } + } + + // If we are still in Inventory Mode, setup the graphic to float in front of the mouse cursor + if (ui._menuMode == INV_MODE) { + ImageFrame &imgFrame = (*inv._invShapes[_invSelect - inv._invIndex])[0]; + _invGraphicBounds = Common::Rect(imgFrame._width, imgFrame._height); + _invGraphicBounds.moveTo(mousePos.x - _invGraphicBounds.width() / 2, + mousePos.y - _invGraphicBounds.height() / 2); + + // Constrain it to the screen + if (_invGraphicBounds.left < 0) + _invGraphicBounds.moveTo(0, _invGraphicBounds.top); + if (_invGraphicBounds.top < 0) + _invGraphicBounds.moveTo(_invGraphicBounds.left, 0); + if (_invGraphicBounds.right > SHERLOCK_SCREEN_WIDTH) + _invGraphicBounds.moveTo(SHERLOCK_SCREEN_WIDTH - _invGraphicBounds.width(), _invGraphicBounds.top); + if (_invGraphicBounds.bottom > SHERLOCK_SCREEN_HEIGHT) + _invGraphicBounds.moveTo(_invGraphicBounds.left, SHERLOCK_SCREEN_HEIGHT - _invGraphicBounds.height()); + + // Make a copy of the inventory image + _invGraphic.create(imgFrame._width, imgFrame._height); + _invGraphic.blitFrom(imgFrame, Common::Point(0, 0)); + } + } + } else if (_invVerbMode == 3) { + // Selecting object after inventory verb has been selected + _tooltipWidget.banishWindow(); + _invGraphic.free(); + inv.freeInv(); + + ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE; + events.clearEvents(); + + if (ui._keyState.keycode != Common::KEYCODE_ESCAPE) { + // If user pointed at an item, use the selected inventory item with this item + bool found = false; + if (ui._bgFound != -1) { + if (ui._personFound) { + for (int idx = 0; idx < 2; ++idx) { + if (!people[ui._bgFound - 1000]._use[idx]._verb.compareToIgnoreCase(_invVerb) && + !people[ui._bgFound - 1000]._use[idx]._target.compareToIgnoreCase(_invTarget)) { + ui.checkAction(people[ui._bgFound - 1000]._use[idx], ui._bgFound); + found = true; + } + } + } else { + for (int idx = 0; idx < 6; ++idx) { + if (!ui._bgShape->_use[idx]._verb.compareToIgnoreCase(_invVerb) && + !ui._bgShape->_use[idx]._target.compareToIgnoreCase(_invTarget)) { + ui.checkAction(ui._bgShape->_use[idx], ui._bgFound); + found = true; + } + } + } + } + + if (!found) + ui.putMessage(S_NO_EFFECT); + } + } else if ((_outsideMenu && !_bounds.contains(mousePos)) || ui._keyState.keycode == Common::KEYCODE_ESCAPE) { + // Want to close the window (clicked outside of it). So close the window and return to Standard + banishWindow(); + inv.freeInv(); + + events.clearEvents(); + events.setCursor(ARROW); + banishWindow(); + ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE; + } else if (_bounds.contains(mousePos)) { + // Mouse button was released inside the inventory window + _outsideMenu = false; + + // See if they are pointing at one of the inventory items + if (_invSelect != -1) { + // See if they are in Use Obj with Inv. Mode (they right clicked on an item + // in the room and selected "Use with Inv.") + if (_invMode == 1) { + _tooltipWidget.banishWindow(); + banishWindow(); + + // See if the item in the room that they started with was a person + bool found = false; + if (ui._activeObj >= 1000) { + // Object was a person, activate anything in his two verb fields + for (int idx = 0; idx < 2; ++idx) { + if (!people[ui._activeObj - 1000]._use[idx]._target.compareToIgnoreCase(inv[_invSelect]._name)) { + ui.checkAction(people[ui._activeObj - 1000]._use[idx], ui._activeObj); + found = true; + } + } + } else { + // Object was a regular object, activate anything in its verb fields + for (int idx = 0; idx < 6; ++idx) { + if (!scene._bgShapes[ui._activeObj]._use[idx]._target.compareToIgnoreCase(inv[_invSelect]._name)) { + ui.checkAction(scene._bgShapes[ui._activeObj]._use[idx], ui._activeObj); + found = true; + } + } + } + if (!found) + ui.putMessage(S_NO_EFFECT); + + } else { + // See if they right clicked on an item + if (events._rightReleased) { + _invVerbMode = 1; + _oldInvVerbSelect = -1; + _tooltipWidget.banishWindow(); + + // Keep track of the name of the inventory object so we can check it against the target fields + // of verbs when we activate it + _invTarget = inv[_invSelect]._name; + + // Make the Verb List for this Inventory Item + _inventCommands.clear(); + _inventCommands.push_back(S_LOOK); + + // Default the Action word to "with" + _action = _vm->getLanguage() == Common::GR_GRE ? "" : S_WITH; + _swapItems = false; + + // Search all the bgshapes for any matching Target Fields + for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) { + Object &obj = scene._bgShapes[idx]; + + if (obj._type != INVALID && obj._type != HIDDEN) { + for (int useNum = 0; useNum < 6; ++useNum) { + if (obj._use[useNum]._verb.hasPrefix("*") && + !obj._use[useNum]._target.compareToIgnoreCase(inv[_invSelect]._name)) { + // Make sure the Verb is not already in the list + bool found1 = false; + for (uint cmdNum = 0; cmdNum < _inventCommands.size() && !found1; ++cmdNum) { + if (!_inventCommands[cmdNum].compareToIgnoreCase(obj._use[useNum]._verb)) + found1 = true; + } + + if (!found1) { + _inventCommands.push_back(obj._use[useNum]._verb); + + // Check for any Special Action commands + for (int nameNum = 0; nameNum < 4; ++nameNum) { + if (!scumm_strnicmp(obj._use[useNum]._names[nameNum].c_str(), "*V", 2)) { + if (!scumm_strnicmp(obj._use[useNum]._names[nameNum].c_str(), "*VSWAP", 6)) + _swapItems = true; + else + _action = Common::String(obj._use[useNum]._names[nameNum].c_str() + 2); + } + } + } + } + } + } + } + + // Search the NPCs for matches as well + for (int idx = 1; idx < MAX_CHARACTERS; ++idx) { + for (int useNum = 0; useNum < 2; ++useNum) { + if (!people[idx]._use[useNum]._target.compareToIgnoreCase(inv[_invSelect]._name) && + !people[idx]._use[useNum]._verb.empty() && !people[idx]._use[useNum]._verb.hasPrefix(" ")) { + bool found1 = false; + for (uint cmdNum = 0; cmdNum < _inventCommands.size() && !found1; ++cmdNum) { + if (!_inventCommands[cmdNum].compareToIgnoreCase(people[idx]._use[cmdNum]._verb)) + found1 = true; + } + + if (!found1) + _inventCommands.push_back(people[idx]._use[useNum]._verb); + } + } + } + + // Finally see if the item itself has a verb + if (!inv[_invSelect]._verb._verb.empty()) { + // Don't add "Solve" to the Foolscap if it's already been "Solved" + if (inv[_invSelect]._verb._verb.compareToIgnoreCase(S_SOLVE) || !vm.readFlags(299)) + _inventCommands.push_back(inv[_invSelect]._verb._verb); + } + + // Now find the widest command in the _inventCommands array + int width = 0; + for (uint idx = 0; idx < _inventCommands.size(); ++idx) + width = MAX(width, _surface.stringWidth(_inventCommands[idx])); + + // Set up bounds for the menu + _menuBounds = Common::Rect(width + _surface.widestChar() * 2 + 6, + (_surface.fontHeight() + 7) * _inventCommands.size() + 3); + _menuBounds.moveTo(mousePos.x + _menuBounds.width() / 2, mousePos.y + _menuBounds.height() / 2); + + // Create the surface + _menuSurface.create(_menuBounds.width(), _menuBounds.height()); + _surface.fill(TRANSPARENCY); + makeInfoArea(_menuSurface); + + // Draw the Verb commands and the lines separating them + ImageFile &images = *_interfaceImages; + for (int idx = 0; idx < (int)_inventCommands.size(); ++idx) { + _menuSurface.writeString(_inventCommands[idx], Common::Point((_menuBounds.width() - + _menuSurface.stringWidth(_inventCommands[idx])) / 2, (_menuSurface.fontHeight() + 7) * idx + 5), INFO_TOP); + + if (idx < (int)_inventCommands.size()- 1) { + _menuSurface.vLine(3, (_menuSurface.fontHeight() + 7) * (idx + 1), _menuBounds.right - 4, INFO_TOP); + _menuSurface.vLine(3, (_menuSurface.fontHeight() + 7) * (idx + 1) + 1, _menuBounds.right - 4, INFO_MIDDLE); + _menuSurface.vLine(3, (_menuSurface.fontHeight() + 7) * (idx + 1) + 2, _menuBounds.right - 4, INFO_BOTTOM); + + _menuSurface.transBlitFrom(images[4], Common::Point(0, (_menuSurface.fontHeight() + 7) * (idx + 1))); + _menuSurface.transBlitFrom(images[5], Common::Point(_menuBounds.width() - images[5]._width, + (_menuSurface.fontHeight() + 7) * (idx + 1) - 1)); + } + } + } else { + // They left clicked on an inventory item, so Look at it + + // Check if they are looking at the solved Foolscap + if ((!inv[_invSelect]._name.compareToIgnoreCase(S_INV6) || !inv[_invSelect]._name.compareToIgnoreCase(S_INV7)) + && vm.readFlags(299)) { + banishWindow(); + _tooltipWidget.erase(); + + _invVerbMode = 0; + inv.freeInv(); + + events.clearEvents(); + events.setCursor(ARROW); + ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE; + + scene.doBgAnim(); + vm.doHangManPuzzle(); + } else { + ui._invLookFlag = true; + inv.freeInv(); + + _tooltipWidget.banishWindow(); + ui._windowOpen = false; + ui._lookPos = mousePos; + ui.printObjectDesc(inv[_invSelect]._examine, true); + } + } + } + } + } + } +} + +void WidgetInventory::updateDescription() { + +} + +void WidgetInventory::checkInvTabbingKeys() { +} + +void WidgetInventory::highlightControls() { + // TODO +} + +void WidgetInventory::banishWindow() { + WidgetBase::banishWindow(); + + _menuSurface.free(); + _menuBounds = _oldMenuBounds = Common::Rect(0, 0, 0, 0); +} } // End of namespace Tattoo diff --git a/engines/sherlock/tattoo/widget_inventory.h b/engines/sherlock/tattoo/widget_inventory.h index 34e25eeaa0..29bcdaa0ea 100644 --- a/engines/sherlock/tattoo/widget_inventory.h +++ b/engines/sherlock/tattoo/widget_inventory.h @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "sherlock/tattoo/widget_base.h" +#include "sherlock/tattoo/widget_tooltip.h" namespace Sherlock { @@ -37,7 +38,19 @@ private: int _invVerbMode; int _invSelect, _oldInvSelect; int _selector, _oldSelector; + int _invVerbSelect, _oldInvVerbSelect; int _dialogTimer; + int _scrollHighlight; + Common::StringArray _inventCommands; + WidgetTooltip _tooltipWidget; + Common::String _invVerb; + Common::String _invTarget; + Common::String _action; + Common::Rect _invGraphicBounds; + Surface _invGraphic; + bool _swapItems; + Common::Rect _menuBounds, _oldMenuBounds; + Surface _menuSurface; /** * Draw the scrollbar for the dialog @@ -48,6 +61,21 @@ private: * Draws all the dialog rectangles for any items that need them */ void drawDialogRect(const Common::Rect &r, bool raised); + + /** + * Displays the description of any inventory item the moues cursor is over + */ + void updateDescription(); + + /** + * Check for keys to mouse the mouse within the inventory dialog + */ + void checkInvTabbingKeys(); + + /** + * Highlights the controls + */ + void highlightControls(); public: int _invMode; public: @@ -60,6 +88,16 @@ public: * Draw the inventory on the surface */ void drawInventory(); + + /** + * Handle events whilst the widget is on-screen + */ + virtual void handleEvents(); + + /** + * Close a currently active menu + */ + virtual void banishWindow(); }; } // End of namespace Tattoo diff --git a/engines/sherlock/tattoo/widget_verbs.cpp b/engines/sherlock/tattoo/widget_verbs.cpp index dfe317b099..9cf4794fc0 100644 --- a/engines/sherlock/tattoo/widget_verbs.cpp +++ b/engines/sherlock/tattoo/widget_verbs.cpp @@ -230,10 +230,6 @@ void WidgetVerbs::execute() { } } -void WidgetVerbs::checkTabbingKeys(int numOptions) { - // TODO -} - void WidgetVerbs::highlightVerbControls() { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; diff --git a/engines/sherlock/tattoo/widget_verbs.h b/engines/sherlock/tattoo/widget_verbs.h index 82b9325681..fa41b3e42c 100644 --- a/engines/sherlock/tattoo/widget_verbs.h +++ b/engines/sherlock/tattoo/widget_verbs.h @@ -58,8 +58,6 @@ public: * Process input for the dialog */ void execute(); - - void checkTabbingKeys(int numOptions); }; } // End of namespace Tattoo |