aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2015-07-17 21:07:03 -0400
committerPaul Gilbert2015-07-17 21:07:03 -0400
commitd0a6af6cb92ec4d12ced8c1af90097ec06679a1d (patch)
treef5431f30fdcc202133adf5b3b9840483e6224094
parent6cc72fc0c8ed4da4a99bf9db7f0798cf7a566df6 (diff)
downloadscummvm-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
-rw-r--r--engines/sherlock/tattoo/widget_inventory.cpp383
-rw-r--r--engines/sherlock/tattoo/widget_inventory.h28
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