diff options
author | Paul Gilbert | 2015-07-17 21:07:03 -0400 |
---|---|---|
committer | Paul Gilbert | 2015-07-17 21:07:03 -0400 |
commit | d0a6af6cb92ec4d12ced8c1af90097ec06679a1d (patch) | |
tree | f5431f30fdcc202133adf5b3b9840483e6224094 /engines/sherlock/tattoo | |
parent | 6cc72fc0c8ed4da4a99bf9db7f0798cf7a566df6 (diff) | |
download | scummvm-rg350-d0a6af6cb92ec4d12ced8c1af90097ec06679a1d.tar.gz scummvm-rg350-d0a6af6cb92ec4d12ced8c1af90097ec06679a1d.tar.bz2 scummvm-rg350-d0a6af6cb92ec4d12ced8c1af90097ec06679a1d.zip |
SHERLOCK: RT: Splitting inventory verb dialog code into it's own class
Diffstat (limited to 'engines/sherlock/tattoo')
-rw-r--r-- | engines/sherlock/tattoo/widget_inventory.cpp | 383 | ||||
-rw-r--r-- | engines/sherlock/tattoo/widget_inventory.h | 28 |
2 files changed, 227 insertions, 184 deletions
diff --git a/engines/sherlock/tattoo/widget_inventory.cpp b/engines/sherlock/tattoo/widget_inventory.cpp index 3ce733b3d6..100eb669f4 100644 --- a/engines/sherlock/tattoo/widget_inventory.cpp +++ b/engines/sherlock/tattoo/widget_inventory.cpp @@ -249,8 +249,209 @@ void WidgetInventoryTooltip::handleEvents() { /*----------------------------------------------------------------*/ +WidgetInventoryVerbs::WidgetInventoryVerbs(SherlockEngine *vm, WidgetInventory *owner) : + WidgetBase(vm), _owner(owner) { +} + +void WidgetInventoryVerbs::load() { + Events &events = *_vm->_events; + Inventory &inv = *_vm->_inventory; + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui; + Common::Point mousePos = events.mousePos(); + + // Make the Verb List for this Inventory Item + _inventCommands.clear(); + _inventCommands.push_back(FIXED(Look)); + + // Default the Action word to "with" + _action = _vm->getLanguage() == Common::GR_GRE ? "" : FIXED(With); + + // 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[_owner->_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)) + _owner->_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[_owner->_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[_owner->_invSelect]._verb._verb.empty()) { + // Don't add "Solve" to the Foolscap if it's already been "Solved" + if (inv[_owner->_invSelect]._verb._verb.compareToIgnoreCase(FIXED(Solve)) || !_vm->readFlags(299)) + _inventCommands.push_back(inv[_owner->_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 + _bounds = Common::Rect(width + _surface.widestChar() * 2 + 6, + (_surface.fontHeight() + 7) * _inventCommands.size() + 3); + _bounds.moveTo(mousePos.x + _bounds.width() / 2, mousePos.y + _bounds.height() / 2); + + // Create the surface + _surface.create(_bounds.width(), _bounds.height()); + _surface.fill(TRANSPARENCY); + makeInfoArea(); + + // Draw the Verb commands and the lines separating them + ImageFile &images = *ui._interfaceImages; + for (int idx = 0; idx < (int)_inventCommands.size(); ++idx) { + _surface.writeString(_inventCommands[idx], Common::Point((_bounds.width() - + _surface.stringWidth(_inventCommands[idx])) / 2, (_surface.fontHeight() + 7) * idx + 5), INFO_TOP); + + if (idx < (int)_inventCommands.size() - 1) { + _surface.vLine(3, (_surface.fontHeight() + 7) * (idx + 1), _bounds.right - 4, INFO_TOP); + _surface.vLine(3, (_surface.fontHeight() + 7) * (idx + 1) + 1, _bounds.right - 4, INFO_MIDDLE); + _surface.vLine(3, (_surface.fontHeight() + 7) * (idx + 1) + 2, _bounds.right - 4, INFO_BOTTOM); + + _surface.transBlitFrom(images[4], Common::Point(0, (_surface.fontHeight() + 7) * (idx + 1))); + _surface.transBlitFrom(images[5], Common::Point(_bounds.width() - images[5]._width, + (_surface.fontHeight() + 7) * (idx + 1) - 1)); + } + } +} + +void WidgetInventoryVerbs::handleEvents() { + Events &events = *_vm->_events; + Inventory &inv = *_vm->_inventory; + TattooScene &scene = *(TattooScene *)_vm->_scene; + Common::Point mousePos = events.mousePos(); + TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui; + TattooEngine &vm = *(TattooEngine *)_vm; + + // 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(); + _owner->_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[_owner->_invSelect]._name.compareToIgnoreCase(FIXED(Inv6)) && + !_inventCommands[_owner->_invVerbSelect].compareToIgnoreCase(FIXED(Solve)); + doHangman |= (!inv[_owner->_invSelect]._name.compareToIgnoreCase(FIXED(Inv6)) || !inv[_owner->_invSelect]._name.compareToIgnoreCase(FIXED(Inv7))) + && _inventCommands[_owner->_invVerbSelect].compareToIgnoreCase(FIXED(Look)) && vm.readFlags(299); + + if (doHangman) { + // Close the entire Inventory and return to Standard Mode + banishWindow(); + _owner->_invVerbMode = 0; + + _owner->_tooltipWidget.banishWindow(); + banishWindow(); + inv.freeInv(); + + events.clearEvents(); + events.setCursor(ARROW); + ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE; + + scene.doBgAnim(); + vm.doHangManPuzzle(); + } else if (_owner->_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[_owner->_invSelect]._examine, true); + } else { + // Clear the window + banishWindow(); + _owner->_invVerbMode = 3; + ui._oldBgFound = -1; + + // See if the selected Verb with the selected Iventory Item, is to be used by itself + if (!_inventCommands[_owner->_invVerbSelect].compareToIgnoreCase(inv[_owner->_invSelect]._verb._verb) || + !inv[_owner->_invSelect]._verb._target.compareToIgnoreCase("*SELF")) { + inv.freeInv(); + + ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE; + events.clearEvents(); + ui.checkAction(inv[_owner->_invSelect]._verb, 2000); + } + else { + _owner->_invVerb = _inventCommands[_owner->_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[_owner->_invSelect - inv._invIndex])[0]; + _owner->_invGraphicBounds = Common::Rect(imgFrame._width, imgFrame._height); + _owner->_invGraphicBounds.moveTo(mousePos.x - _owner->_invGraphicBounds.width() / 2, + mousePos.y - _owner->_invGraphicBounds.height() / 2); + + // Constrain it to the screen + if (_owner->_invGraphicBounds.left < 0) + _owner->_invGraphicBounds.moveTo(0, _owner->_invGraphicBounds.top); + if (_owner->_invGraphicBounds.top < 0) + _owner->_invGraphicBounds.moveTo(_owner->_invGraphicBounds.left, 0); + if (_owner->_invGraphicBounds.right > SHERLOCK_SCREEN_WIDTH) + _owner->_invGraphicBounds.moveTo(SHERLOCK_SCREEN_WIDTH - _owner->_invGraphicBounds.width(), _owner->_invGraphicBounds.top); + if (_owner->_invGraphicBounds.bottom > SHERLOCK_SCREEN_HEIGHT) + _owner->_invGraphicBounds.moveTo(_owner->_invGraphicBounds.left, SHERLOCK_SCREEN_HEIGHT - _owner->_invGraphicBounds.height()); + + // Make a copy of the inventory image + _owner->_invGraphic.create(imgFrame._width, imgFrame._height); + _owner->_invGraphic.blitFrom(imgFrame, Common::Point(0, 0)); + } + } +} + +/*----------------------------------------------------------------*/ -WidgetInventory::WidgetInventory(SherlockEngine *vm) : WidgetBase(vm), _tooltipWidget(vm, this) { +WidgetInventory::WidgetInventory(SherlockEngine *vm) : WidgetBase(vm), + _tooltipWidget(vm, this), _verbList(vm, this) { _invMode = 0; _invVerbMode = 0; _invSelect = _oldInvSelect = -1; @@ -384,87 +585,8 @@ void WidgetInventory::handleEvents() { // 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(FIXED(Inv6)) && - !_inventCommands[_invVerbSelect].compareToIgnoreCase(FIXED(Solve)); - doHangman |= (!inv[_invSelect]._name.compareToIgnoreCase(FIXED(Inv6)) || !inv[_invSelect]._name.compareToIgnoreCase(FIXED(Inv7))) - && _inventCommands[_invVerbSelect].compareToIgnoreCase(FIXED(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]; - } - } + _verbList.handleEvents(); - // 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(); @@ -553,103 +675,9 @@ void WidgetInventory::handleEvents() { // 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(FIXED(Look)); - - // Default the Action word to "with" - _action = _vm->getLanguage() == Common::GR_GRE ? "" : FIXED(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(FIXED(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 = *ui._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)); - } - } + _verbList.load(); } else { // They left clicked on an inventory item, so Look at it @@ -694,8 +722,7 @@ void WidgetInventory::highlightControls() { void WidgetInventory::banishWindow() { WidgetBase::banishWindow(); - _menuSurface.free(); - _menuBounds = _oldMenuBounds = Common::Rect(0, 0, 0, 0); + _verbList.banishWindow(); } void WidgetInventory::draw() { diff --git a/engines/sherlock/tattoo/widget_inventory.h b/engines/sherlock/tattoo/widget_inventory.h index 365dff6299..7b157cbd8c 100644 --- a/engines/sherlock/tattoo/widget_inventory.h +++ b/engines/sherlock/tattoo/widget_inventory.h @@ -61,24 +61,40 @@ public: virtual void handleEvents(); }; +class WidgetInventoryVerbs : public WidgetBase { +private: + WidgetInventory *_owner; + Common::StringArray _inventCommands; + Common::String _action; +public: + WidgetInventoryVerbs(SherlockEngine *vm, WidgetInventory *owner); + virtual ~WidgetInventoryVerbs() {} + + void load(); + + /** + * Handle updating the tooltip state + */ + virtual void handleEvents(); +}; + class WidgetInventory: public WidgetBase { friend class WidgetInventoryTooltip; + friend class WidgetInventoryVerbs; private: int _invVerbMode; - int _invSelect, _oldInvSelect; int _selector, _oldSelector; int _invVerbSelect, _oldInvVerbSelect; + int _invSelect, _oldInvSelect; int _dialogTimer; - Common::StringArray _inventCommands; WidgetInventoryTooltip _tooltipWidget; - Common::String _invVerb; - Common::String _invTarget; - Common::String _action; + WidgetInventoryVerbs _verbList; Common::Rect _invGraphicBounds; Surface _invGraphic; bool _swapItems; - Common::Rect _menuBounds, _oldMenuBounds; Surface _menuSurface; + Common::String _invTarget; + Common::String _invVerb; /** * Draw the bars within the dialog |